| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561245622456324564245652456624567245682456924570245712457224573245742457524576245772457824579245802458124582245832458424585245862458724588245892459024591245922459324594245952459624597245982459924600246012460224603246042460524606246072460824609246102461124612246132461424615246162461724618246192462024621246222462324624246252462624627246282462924630246312463224633246342463524636246372463824639246402464124642246432464424645246462464724648246492465024651246522465324654246552465624657246582465924660246612466224663246642466524666246672466824669246702467124672246732467424675246762467724678246792468024681246822468324684246852468624687246882468924690246912469224693246942469524696246972469824699247002470124702247032470424705247062470724708247092471024711247122471324714247152471624717247182471924720247212472224723247242472524726247272472824729247302473124732247332473424735247362473724738247392474024741247422474324744247452474624747247482474924750247512475224753247542475524756247572475824759247602476124762247632476424765247662476724768247692477024771247722477324774247752477624777247782477924780247812478224783247842478524786247872478824789247902479124792247932479424795247962479724798247992480024801248022480324804248052480624807248082480924810248112481224813248142481524816248172481824819248202482124822248232482424825248262482724828248292483024831248322483324834248352483624837248382483924840248412484224843248442484524846248472484824849248502485124852248532485424855248562485724858248592486024861248622486324864248652486624867248682486924870248712487224873248742487524876248772487824879248802488124882248832488424885248862488724888248892489024891248922489324894248952489624897248982489924900249012490224903249042490524906249072490824909249102491124912249132491424915249162491724918249192492024921249222492324924249252492624927249282492924930249312493224933249342493524936249372493824939249402494124942249432494424945249462494724948249492495024951249522495324954249552495624957249582495924960249612496224963249642496524966249672496824969249702497124972249732497424975249762497724978249792498024981249822498324984249852498624987249882498924990249912499224993249942499524996249972499824999250002500125002250032500425005250062500725008250092501025011250122501325014250152501625017250182501925020250212502225023250242502525026250272502825029250302503125032250332503425035250362503725038250392504025041250422504325044250452504625047250482504925050250512505225053250542505525056250572505825059250602506125062250632506425065250662506725068250692507025071250722507325074250752507625077250782507925080250812508225083250842508525086250872508825089250902509125092250932509425095250962509725098250992510025101251022510325104251052510625107251082510925110251112511225113251142511525116251172511825119251202512125122251232512425125251262512725128251292513025131251322513325134251352513625137251382513925140251412514225143251442514525146251472514825149251502515125152251532515425155251562515725158251592516025161251622516325164251652516625167251682516925170251712517225173251742517525176251772517825179251802518125182251832518425185251862518725188251892519025191251922519325194251952519625197251982519925200252012520225203252042520525206252072520825209252102521125212252132521425215252162521725218252192522025221252222522325224252252522625227252282522925230252312523225233252342523525236252372523825239252402524125242252432524425245252462524725248252492525025251252522525325254252552525625257252582525925260252612526225263252642526525266252672526825269252702527125272252732527425275252762527725278252792528025281252822528325284252852528625287252882528925290252912529225293252942529525296252972529825299253002530125302253032530425305253062530725308253092531025311253122531325314253152531625317253182531925320253212532225323253242532525326253272532825329253302533125332253332533425335253362533725338253392534025341253422534325344253452534625347253482534925350253512535225353253542535525356253572535825359253602536125362253632536425365253662536725368253692537025371253722537325374253752537625377253782537925380253812538225383253842538525386253872538825389253902539125392253932539425395253962539725398253992540025401254022540325404254052540625407254082540925410254112541225413254142541525416254172541825419254202542125422254232542425425254262542725428254292543025431254322543325434254352543625437254382543925440254412544225443254442544525446254472544825449254502545125452254532545425455254562545725458254592546025461254622546325464254652546625467254682546925470254712547225473254742547525476254772547825479254802548125482254832548425485254862548725488254892549025491254922549325494254952549625497254982549925500255012550225503255042550525506255072550825509255102551125512255132551425515255162551725518255192552025521255222552325524255252552625527255282552925530255312553225533255342553525536255372553825539255402554125542255432554425545255462554725548255492555025551255522555325554255552555625557255582555925560255612556225563255642556525566255672556825569255702557125572255732557425575255762557725578255792558025581255822558325584255852558625587255882558925590255912559225593255942559525596255972559825599256002560125602256032560425605256062560725608256092561025611256122561325614256152561625617256182561925620256212562225623256242562525626256272562825629256302563125632256332563425635256362563725638256392564025641256422564325644256452564625647256482564925650256512565225653256542565525656256572565825659256602566125662256632566425665256662566725668256692567025671256722567325674256752567625677256782567925680256812568225683256842568525686256872568825689256902569125692256932569425695256962569725698256992570025701257022570325704257052570625707257082570925710257112571225713257142571525716257172571825719257202572125722257232572425725257262572725728257292573025731257322573325734257352573625737257382573925740257412574225743257442574525746257472574825749257502575125752257532575425755257562575725758257592576025761257622576325764257652576625767257682576925770257712577225773257742577525776257772577825779257802578125782257832578425785257862578725788257892579025791257922579325794257952579625797257982579925800258012580225803258042580525806258072580825809258102581125812258132581425815258162581725818258192582025821258222582325824258252582625827258282582925830258312583225833258342583525836258372583825839258402584125842258432584425845258462584725848258492585025851258522585325854258552585625857258582585925860258612586225863258642586525866258672586825869258702587125872258732587425875258762587725878258792588025881258822588325884258852588625887258882588925890258912589225893258942589525896258972589825899259002590125902259032590425905259062590725908259092591025911259122591325914259152591625917259182591925920259212592225923259242592525926259272592825929259302593125932259332593425935259362593725938259392594025941259422594325944259452594625947259482594925950259512595225953259542595525956259572595825959259602596125962259632596425965259662596725968259692597025971259722597325974259752597625977259782597925980259812598225983259842598525986259872598825989259902599125992259932599425995259962599725998259992600026001260022600326004260052600626007260082600926010260112601226013260142601526016260172601826019260202602126022260232602426025260262602726028260292603026031260322603326034260352603626037260382603926040260412604226043260442604526046260472604826049260502605126052260532605426055260562605726058260592606026061260622606326064260652606626067260682606926070260712607226073260742607526076260772607826079260802608126082260832608426085260862608726088260892609026091260922609326094260952609626097260982609926100261012610226103261042610526106261072610826109261102611126112261132611426115261162611726118261192612026121261222612326124261252612626127261282612926130261312613226133261342613526136261372613826139261402614126142261432614426145261462614726148261492615026151261522615326154261552615626157261582615926160261612616226163261642616526166261672616826169261702617126172261732617426175261762617726178261792618026181261822618326184261852618626187261882618926190261912619226193261942619526196261972619826199262002620126202262032620426205262062620726208262092621026211262122621326214262152621626217262182621926220262212622226223262242622526226262272622826229262302623126232262332623426235262362623726238262392624026241262422624326244262452624626247262482624926250262512625226253262542625526256262572625826259262602626126262262632626426265262662626726268262692627026271262722627326274262752627626277262782627926280262812628226283262842628526286262872628826289262902629126292262932629426295262962629726298262992630026301263022630326304263052630626307263082630926310263112631226313263142631526316263172631826319263202632126322263232632426325263262632726328263292633026331263322633326334263352633626337263382633926340263412634226343263442634526346263472634826349263502635126352263532635426355263562635726358263592636026361263622636326364263652636626367263682636926370263712637226373263742637526376263772637826379263802638126382263832638426385263862638726388263892639026391263922639326394263952639626397263982639926400264012640226403264042640526406264072640826409264102641126412264132641426415264162641726418264192642026421264222642326424264252642626427264282642926430264312643226433264342643526436264372643826439264402644126442264432644426445264462644726448264492645026451264522645326454264552645626457264582645926460264612646226463264642646526466264672646826469264702647126472264732647426475264762647726478264792648026481264822648326484264852648626487264882648926490264912649226493264942649526496264972649826499265002650126502265032650426505265062650726508265092651026511265122651326514265152651626517265182651926520265212652226523265242652526526265272652826529265302653126532265332653426535265362653726538265392654026541265422654326544265452654626547265482654926550265512655226553265542655526556265572655826559265602656126562265632656426565265662656726568265692657026571265722657326574265752657626577265782657926580265812658226583265842658526586265872658826589265902659126592265932659426595265962659726598265992660026601266022660326604266052660626607266082660926610266112661226613266142661526616266172661826619266202662126622266232662426625266262662726628266292663026631266322663326634266352663626637266382663926640266412664226643266442664526646266472664826649266502665126652266532665426655266562665726658266592666026661266622666326664266652666626667266682666926670266712667226673266742667526676266772667826679266802668126682266832668426685266862668726688266892669026691266922669326694266952669626697266982669926700267012670226703267042670526706267072670826709267102671126712267132671426715267162671726718267192672026721267222672326724267252672626727267282672926730267312673226733267342673526736267372673826739267402674126742267432674426745267462674726748267492675026751267522675326754267552675626757267582675926760267612676226763267642676526766267672676826769267702677126772267732677426775267762677726778267792678026781267822678326784267852678626787267882678926790267912679226793267942679526796267972679826799268002680126802268032680426805268062680726808268092681026811268122681326814268152681626817268182681926820268212682226823268242682526826268272682826829268302683126832268332683426835268362683726838268392684026841268422684326844268452684626847268482684926850268512685226853268542685526856268572685826859268602686126862268632686426865268662686726868268692687026871268722687326874268752687626877268782687926880268812688226883268842688526886268872688826889268902689126892268932689426895268962689726898268992690026901269022690326904269052690626907269082690926910269112691226913269142691526916269172691826919269202692126922269232692426925269262692726928269292693026931269322693326934269352693626937269382693926940269412694226943269442694526946269472694826949269502695126952269532695426955269562695726958269592696026961269622696326964269652696626967269682696926970269712697226973269742697526976269772697826979269802698126982269832698426985269862698726988269892699026991269922699326994269952699626997269982699927000270012700227003270042700527006270072700827009270102701127012270132701427015270162701727018270192702027021270222702327024270252702627027270282702927030270312703227033270342703527036270372703827039270402704127042270432704427045270462704727048270492705027051270522705327054270552705627057270582705927060270612706227063270642706527066270672706827069270702707127072270732707427075270762707727078270792708027081270822708327084270852708627087270882708927090270912709227093270942709527096270972709827099271002710127102271032710427105271062710727108271092711027111271122711327114271152711627117271182711927120271212712227123271242712527126271272712827129271302713127132271332713427135271362713727138271392714027141271422714327144271452714627147271482714927150271512715227153271542715527156271572715827159271602716127162271632716427165271662716727168271692717027171271722717327174271752717627177271782717927180271812718227183271842718527186271872718827189271902719127192271932719427195271962719727198271992720027201272022720327204272052720627207272082720927210272112721227213272142721527216272172721827219272202722127222272232722427225272262722727228272292723027231272322723327234272352723627237272382723927240272412724227243272442724527246272472724827249272502725127252272532725427255272562725727258272592726027261272622726327264272652726627267272682726927270272712727227273272742727527276272772727827279272802728127282272832728427285272862728727288272892729027291272922729327294272952729627297272982729927300273012730227303273042730527306273072730827309273102731127312273132731427315273162731727318273192732027321273222732327324273252732627327273282732927330273312733227333273342733527336273372733827339273402734127342273432734427345273462734727348273492735027351273522735327354273552735627357273582735927360273612736227363273642736527366273672736827369273702737127372273732737427375273762737727378273792738027381273822738327384273852738627387273882738927390273912739227393273942739527396273972739827399274002740127402274032740427405274062740727408274092741027411274122741327414274152741627417274182741927420274212742227423274242742527426274272742827429274302743127432274332743427435274362743727438274392744027441274422744327444274452744627447274482744927450274512745227453274542745527456274572745827459274602746127462274632746427465274662746727468274692747027471274722747327474274752747627477274782747927480274812748227483274842748527486274872748827489274902749127492274932749427495274962749727498274992750027501275022750327504275052750627507275082750927510275112751227513275142751527516275172751827519275202752127522275232752427525275262752727528275292753027531275322753327534275352753627537275382753927540275412754227543275442754527546275472754827549275502755127552275532755427555275562755727558275592756027561275622756327564275652756627567275682756927570275712757227573275742757527576275772757827579275802758127582275832758427585275862758727588275892759027591275922759327594275952759627597275982759927600276012760227603276042760527606276072760827609276102761127612276132761427615276162761727618276192762027621276222762327624276252762627627276282762927630276312763227633276342763527636276372763827639276402764127642276432764427645276462764727648276492765027651276522765327654276552765627657276582765927660276612766227663276642766527666276672766827669276702767127672276732767427675276762767727678276792768027681276822768327684276852768627687276882768927690276912769227693276942769527696276972769827699277002770127702277032770427705277062770727708277092771027711277122771327714277152771627717277182771927720277212772227723277242772527726277272772827729277302773127732277332773427735277362773727738277392774027741277422774327744277452774627747277482774927750277512775227753277542775527756277572775827759277602776127762277632776427765277662776727768277692777027771277722777327774277752777627777277782777927780277812778227783277842778527786277872778827789277902779127792277932779427795277962779727798277992780027801278022780327804278052780627807278082780927810278112781227813278142781527816278172781827819278202782127822278232782427825278262782727828278292783027831278322783327834278352783627837278382783927840278412784227843278442784527846278472784827849278502785127852278532785427855278562785727858278592786027861278622786327864278652786627867278682786927870278712787227873278742787527876278772787827879278802788127882278832788427885278862788727888278892789027891278922789327894278952789627897278982789927900279012790227903279042790527906279072790827909279102791127912279132791427915279162791727918279192792027921279222792327924279252792627927279282792927930279312793227933279342793527936279372793827939279402794127942279432794427945279462794727948279492795027951279522795327954279552795627957279582795927960279612796227963279642796527966279672796827969279702797127972279732797427975279762797727978279792798027981279822798327984279852798627987279882798927990279912799227993279942799527996279972799827999280002800128002280032800428005280062800728008280092801028011280122801328014280152801628017280182801928020280212802228023280242802528026280272802828029280302803128032280332803428035280362803728038280392804028041280422804328044280452804628047280482804928050280512805228053280542805528056280572805828059280602806128062280632806428065280662806728068280692807028071280722807328074280752807628077280782807928080280812808228083280842808528086280872808828089280902809128092280932809428095280962809728098280992810028101281022810328104281052810628107281082810928110281112811228113281142811528116281172811828119281202812128122281232812428125281262812728128281292813028131281322813328134281352813628137281382813928140281412814228143281442814528146281472814828149281502815128152281532815428155281562815728158281592816028161281622816328164281652816628167281682816928170281712817228173281742817528176281772817828179281802818128182281832818428185281862818728188281892819028191281922819328194281952819628197281982819928200282012820228203282042820528206282072820828209282102821128212282132821428215282162821728218282192822028221282222822328224282252822628227282282822928230282312823228233282342823528236282372823828239282402824128242282432824428245282462824728248282492825028251282522825328254282552825628257282582825928260282612826228263282642826528266282672826828269282702827128272282732827428275282762827728278282792828028281282822828328284282852828628287282882828928290282912829228293282942829528296282972829828299283002830128302283032830428305283062830728308283092831028311283122831328314283152831628317283182831928320283212832228323283242832528326283272832828329283302833128332283332833428335283362833728338283392834028341283422834328344283452834628347283482834928350283512835228353283542835528356283572835828359283602836128362283632836428365283662836728368283692837028371283722837328374283752837628377283782837928380283812838228383283842838528386283872838828389283902839128392283932839428395283962839728398283992840028401284022840328404284052840628407284082840928410284112841228413284142841528416284172841828419284202842128422284232842428425284262842728428284292843028431284322843328434284352843628437284382843928440284412844228443284442844528446284472844828449284502845128452284532845428455284562845728458284592846028461284622846328464284652846628467284682846928470284712847228473284742847528476284772847828479284802848128482284832848428485284862848728488284892849028491284922849328494284952849628497284982849928500285012850228503285042850528506285072850828509285102851128512285132851428515285162851728518285192852028521285222852328524285252852628527285282852928530285312853228533285342853528536285372853828539285402854128542285432854428545285462854728548285492855028551285522855328554285552855628557285582855928560285612856228563285642856528566285672856828569285702857128572285732857428575285762857728578285792858028581285822858328584285852858628587285882858928590285912859228593285942859528596285972859828599286002860128602286032860428605286062860728608286092861028611286122861328614286152861628617286182861928620286212862228623286242862528626286272862828629286302863128632286332863428635286362863728638286392864028641286422864328644286452864628647286482864928650286512865228653286542865528656286572865828659286602866128662286632866428665286662866728668286692867028671286722867328674286752867628677286782867928680286812868228683286842868528686286872868828689286902869128692286932869428695286962869728698286992870028701287022870328704287052870628707287082870928710287112871228713287142871528716287172871828719287202872128722287232872428725287262872728728287292873028731287322873328734287352873628737287382873928740287412874228743287442874528746287472874828749287502875128752287532875428755287562875728758287592876028761287622876328764287652876628767287682876928770287712877228773287742877528776287772877828779287802878128782287832878428785287862878728788287892879028791287922879328794287952879628797287982879928800288012880228803288042880528806288072880828809288102881128812288132881428815288162881728818288192882028821288222882328824288252882628827288282882928830288312883228833288342883528836288372883828839288402884128842288432884428845288462884728848288492885028851288522885328854288552885628857288582885928860288612886228863288642886528866288672886828869288702887128872288732887428875288762887728878288792888028881288822888328884288852888628887288882888928890288912889228893288942889528896288972889828899289002890128902289032890428905289062890728908289092891028911289122891328914289152891628917289182891928920289212892228923289242892528926289272892828929289302893128932289332893428935289362893728938289392894028941289422894328944289452894628947289482894928950289512895228953289542895528956289572895828959289602896128962289632896428965289662896728968289692897028971289722897328974289752897628977289782897928980289812898228983289842898528986289872898828989289902899128992289932899428995289962899728998289992900029001290022900329004290052900629007290082900929010290112901229013290142901529016290172901829019290202902129022290232902429025290262902729028290292903029031290322903329034290352903629037290382903929040290412904229043290442904529046290472904829049290502905129052290532905429055290562905729058290592906029061290622906329064290652906629067290682906929070290712907229073290742907529076290772907829079290802908129082290832908429085290862908729088290892909029091290922909329094290952909629097290982909929100291012910229103291042910529106291072910829109291102911129112291132911429115291162911729118291192912029121291222912329124291252912629127291282912929130291312913229133291342913529136291372913829139291402914129142291432914429145291462914729148291492915029151291522915329154291552915629157291582915929160291612916229163291642916529166291672916829169291702917129172291732917429175291762917729178291792918029181291822918329184291852918629187291882918929190291912919229193291942919529196291972919829199292002920129202292032920429205292062920729208292092921029211292122921329214292152921629217292182921929220292212922229223292242922529226292272922829229292302923129232292332923429235292362923729238292392924029241292422924329244292452924629247292482924929250292512925229253292542925529256292572925829259292602926129262292632926429265292662926729268292692927029271292722927329274292752927629277292782927929280292812928229283292842928529286292872928829289292902929129292292932929429295292962929729298292992930029301293022930329304293052930629307293082930929310293112931229313293142931529316293172931829319293202932129322293232932429325293262932729328293292933029331293322933329334293352933629337293382933929340293412934229343293442934529346293472934829349293502935129352293532935429355293562935729358293592936029361293622936329364293652936629367293682936929370293712937229373293742937529376293772937829379293802938129382293832938429385293862938729388293892939029391293922939329394293952939629397293982939929400294012940229403294042940529406294072940829409294102941129412294132941429415294162941729418294192942029421294222942329424294252942629427294282942929430294312943229433294342943529436294372943829439294402944129442294432944429445294462944729448294492945029451294522945329454294552945629457294582945929460294612946229463294642946529466294672946829469294702947129472294732947429475294762947729478294792948029481294822948329484294852948629487294882948929490294912949229493294942949529496294972949829499295002950129502295032950429505295062950729508295092951029511295122951329514295152951629517295182951929520295212952229523295242952529526295272952829529295302953129532295332953429535295362953729538295392954029541295422954329544295452954629547295482954929550295512955229553295542955529556295572955829559295602956129562295632956429565295662956729568295692957029571295722957329574295752957629577295782957929580295812958229583295842958529586295872958829589295902959129592295932959429595295962959729598295992960029601296022960329604296052960629607296082960929610296112961229613296142961529616296172961829619296202962129622296232962429625296262962729628296292963029631296322963329634296352963629637296382963929640296412964229643296442964529646296472964829649296502965129652296532965429655296562965729658296592966029661296622966329664296652966629667296682966929670296712967229673296742967529676296772967829679296802968129682296832968429685296862968729688296892969029691296922969329694296952969629697296982969929700297012970229703297042970529706297072970829709297102971129712297132971429715297162971729718297192972029721297222972329724297252972629727297282972929730297312973229733297342973529736297372973829739297402974129742297432974429745297462974729748297492975029751297522975329754297552975629757297582975929760297612976229763297642976529766297672976829769297702977129772297732977429775297762977729778297792978029781297822978329784297852978629787297882978929790297912979229793297942979529796297972979829799298002980129802298032980429805298062980729808298092981029811298122981329814298152981629817298182981929820298212982229823298242982529826298272982829829298302983129832298332983429835298362983729838298392984029841298422984329844298452984629847298482984929850298512985229853298542985529856298572985829859298602986129862298632986429865298662986729868298692987029871298722987329874298752987629877298782987929880298812988229883298842988529886298872988829889298902989129892298932989429895298962989729898298992990029901299022990329904299052990629907299082990929910299112991229913299142991529916299172991829919299202992129922299232992429925299262992729928299292993029931299322993329934299352993629937299382993929940299412994229943299442994529946299472994829949299502995129952299532995429955299562995729958299592996029961299622996329964299652996629967299682996929970299712997229973299742997529976299772997829979299802998129982299832998429985299862998729988299892999029991299922999329994299952999629997299982999930000300013000230003300043000530006300073000830009300103001130012300133001430015300163001730018300193002030021300223002330024300253002630027300283002930030300313003230033300343003530036300373003830039300403004130042300433004430045300463004730048300493005030051300523005330054300553005630057300583005930060300613006230063300643006530066300673006830069300703007130072300733007430075300763007730078300793008030081300823008330084300853008630087300883008930090300913009230093300943009530096300973009830099301003010130102301033010430105301063010730108301093011030111301123011330114301153011630117301183011930120301213012230123301243012530126301273012830129301303013130132301333013430135301363013730138301393014030141301423014330144301453014630147301483014930150301513015230153301543015530156301573015830159301603016130162301633016430165301663016730168301693017030171301723017330174301753017630177301783017930180301813018230183301843018530186301873018830189301903019130192301933019430195301963019730198301993020030201302023020330204302053020630207302083020930210302113021230213302143021530216302173021830219302203022130222302233022430225302263022730228302293023030231302323023330234302353023630237302383023930240302413024230243302443024530246302473024830249302503025130252302533025430255302563025730258302593026030261302623026330264302653026630267302683026930270302713027230273302743027530276302773027830279302803028130282302833028430285302863028730288302893029030291302923029330294302953029630297302983029930300303013030230303303043030530306303073030830309303103031130312303133031430315303163031730318303193032030321303223032330324303253032630327303283032930330303313033230333303343033530336303373033830339303403034130342303433034430345303463034730348303493035030351303523035330354303553035630357303583035930360303613036230363303643036530366303673036830369303703037130372303733037430375303763037730378303793038030381303823038330384303853038630387303883038930390303913039230393303943039530396303973039830399304003040130402304033040430405304063040730408304093041030411304123041330414304153041630417304183041930420304213042230423304243042530426304273042830429304303043130432304333043430435304363043730438304393044030441304423044330444304453044630447304483044930450304513045230453304543045530456304573045830459304603046130462304633046430465304663046730468304693047030471304723047330474304753047630477304783047930480304813048230483304843048530486304873048830489304903049130492304933049430495304963049730498304993050030501305023050330504305053050630507305083050930510305113051230513305143051530516305173051830519305203052130522305233052430525305263052730528305293053030531305323053330534305353053630537305383053930540305413054230543305443054530546305473054830549305503055130552305533055430555305563055730558305593056030561305623056330564305653056630567305683056930570305713057230573305743057530576305773057830579305803058130582305833058430585305863058730588305893059030591305923059330594305953059630597305983059930600306013060230603306043060530606306073060830609306103061130612306133061430615306163061730618306193062030621306223062330624306253062630627306283062930630306313063230633306343063530636306373063830639306403064130642306433064430645306463064730648306493065030651306523065330654306553065630657306583065930660306613066230663306643066530666306673066830669306703067130672306733067430675306763067730678306793068030681306823068330684306853068630687306883068930690306913069230693306943069530696306973069830699307003070130702307033070430705307063070730708307093071030711307123071330714307153071630717307183071930720307213072230723307243072530726307273072830729307303073130732307333073430735307363073730738307393074030741307423074330744307453074630747307483074930750307513075230753307543075530756307573075830759307603076130762307633076430765307663076730768307693077030771307723077330774307753077630777307783077930780307813078230783307843078530786307873078830789307903079130792307933079430795307963079730798307993080030801308023080330804308053080630807308083080930810308113081230813308143081530816308173081830819308203082130822308233082430825308263082730828308293083030831308323083330834308353083630837308383083930840308413084230843308443084530846308473084830849308503085130852308533085430855308563085730858308593086030861308623086330864308653086630867308683086930870308713087230873308743087530876308773087830879308803088130882308833088430885308863088730888308893089030891308923089330894308953089630897308983089930900309013090230903309043090530906309073090830909309103091130912309133091430915309163091730918309193092030921309223092330924309253092630927309283092930930309313093230933309343093530936309373093830939309403094130942309433094430945309463094730948309493095030951309523095330954309553095630957309583095930960309613096230963309643096530966309673096830969309703097130972309733097430975309763097730978309793098030981309823098330984309853098630987309883098930990309913099230993309943099530996309973099830999310003100131002310033100431005310063100731008310093101031011310123101331014310153101631017310183101931020310213102231023310243102531026310273102831029310303103131032310333103431035310363103731038310393104031041310423104331044310453104631047310483104931050310513105231053310543105531056310573105831059310603106131062310633106431065310663106731068310693107031071310723107331074310753107631077310783107931080310813108231083310843108531086310873108831089310903109131092310933109431095310963109731098310993110031101311023110331104311053110631107311083110931110311113111231113311143111531116311173111831119311203112131122311233112431125311263112731128311293113031131311323113331134311353113631137311383113931140311413114231143311443114531146311473114831149311503115131152311533115431155311563115731158311593116031161311623116331164311653116631167311683116931170311713117231173311743117531176311773117831179311803118131182311833118431185311863118731188311893119031191311923119331194311953119631197311983119931200312013120231203312043120531206312073120831209312103121131212312133121431215312163121731218312193122031221312223122331224312253122631227312283122931230312313123231233312343123531236312373123831239312403124131242312433124431245312463124731248312493125031251312523125331254312553125631257312583125931260312613126231263312643126531266312673126831269312703127131272312733127431275312763127731278312793128031281312823128331284312853128631287312883128931290312913129231293312943129531296312973129831299313003130131302313033130431305313063130731308313093131031311313123131331314313153131631317313183131931320313213132231323313243132531326313273132831329313303133131332313333133431335313363133731338313393134031341313423134331344313453134631347313483134931350313513135231353313543135531356313573135831359313603136131362313633136431365313663136731368313693137031371313723137331374313753137631377313783137931380313813138231383313843138531386313873138831389313903139131392313933139431395313963139731398313993140031401314023140331404314053140631407314083140931410314113141231413314143141531416314173141831419314203142131422314233142431425314263142731428314293143031431314323143331434314353143631437314383143931440314413144231443314443144531446314473144831449314503145131452314533145431455314563145731458314593146031461314623146331464314653146631467314683146931470314713147231473314743147531476314773147831479314803148131482314833148431485314863148731488314893149031491314923149331494314953149631497314983149931500315013150231503315043150531506315073150831509315103151131512315133151431515315163151731518315193152031521315223152331524315253152631527315283152931530315313153231533315343153531536315373153831539315403154131542315433154431545315463154731548315493155031551315523155331554315553155631557315583155931560315613156231563315643156531566315673156831569315703157131572315733157431575315763157731578315793158031581315823158331584315853158631587315883158931590315913159231593315943159531596315973159831599316003160131602316033160431605316063160731608316093161031611316123161331614316153161631617316183161931620316213162231623316243162531626316273162831629316303163131632316333163431635316363163731638316393164031641316423164331644316453164631647316483164931650316513165231653316543165531656316573165831659316603166131662316633166431665316663166731668316693167031671316723167331674316753167631677316783167931680316813168231683316843168531686316873168831689316903169131692316933169431695316963169731698316993170031701317023170331704317053170631707317083170931710317113171231713317143171531716317173171831719317203172131722317233172431725317263172731728317293173031731317323173331734317353173631737317383173931740317413174231743317443174531746317473174831749317503175131752317533175431755317563175731758317593176031761317623176331764317653176631767317683176931770317713177231773317743177531776317773177831779317803178131782317833178431785317863178731788317893179031791317923179331794317953179631797317983179931800318013180231803318043180531806318073180831809318103181131812318133181431815318163181731818318193182031821318223182331824318253182631827318283182931830318313183231833318343183531836318373183831839318403184131842318433184431845318463184731848318493185031851318523185331854318553185631857318583185931860318613186231863318643186531866318673186831869318703187131872318733187431875318763187731878318793188031881318823188331884318853188631887318883188931890318913189231893318943189531896318973189831899319003190131902319033190431905319063190731908319093191031911319123191331914319153191631917319183191931920319213192231923319243192531926319273192831929319303193131932319333193431935319363193731938319393194031941319423194331944319453194631947319483194931950319513195231953319543195531956319573195831959319603196131962319633196431965319663196731968319693197031971319723197331974319753197631977319783197931980319813198231983319843198531986319873198831989319903199131992319933199431995319963199731998319993200032001320023200332004320053200632007320083200932010320113201232013320143201532016320173201832019320203202132022320233202432025320263202732028320293203032031320323203332034320353203632037320383203932040320413204232043320443204532046320473204832049320503205132052320533205432055320563205732058320593206032061320623206332064320653206632067320683206932070320713207232073320743207532076320773207832079320803208132082320833208432085320863208732088320893209032091320923209332094320953209632097320983209932100321013210232103321043210532106321073210832109321103211132112321133211432115321163211732118321193212032121321223212332124321253212632127321283212932130321313213232133321343213532136321373213832139321403214132142321433214432145321463214732148321493215032151321523215332154321553215632157321583215932160321613216232163321643216532166321673216832169321703217132172321733217432175321763217732178321793218032181321823218332184321853218632187321883218932190321913219232193321943219532196321973219832199322003220132202322033220432205322063220732208322093221032211322123221332214322153221632217322183221932220322213222232223322243222532226322273222832229322303223132232322333223432235322363223732238322393224032241322423224332244322453224632247322483224932250322513225232253322543225532256322573225832259322603226132262322633226432265322663226732268322693227032271322723227332274322753227632277322783227932280322813228232283322843228532286322873228832289322903229132292322933229432295322963229732298322993230032301323023230332304323053230632307323083230932310323113231232313323143231532316323173231832319323203232132322323233232432325323263232732328323293233032331323323233332334323353233632337323383233932340323413234232343323443234532346323473234832349323503235132352323533235432355323563235732358323593236032361323623236332364323653236632367323683236932370323713237232373323743237532376323773237832379323803238132382323833238432385323863238732388323893239032391323923239332394323953239632397323983239932400324013240232403324043240532406324073240832409324103241132412324133241432415324163241732418324193242032421324223242332424324253242632427324283242932430324313243232433324343243532436324373243832439324403244132442324433244432445324463244732448324493245032451324523245332454324553245632457324583245932460324613246232463324643246532466324673246832469324703247132472324733247432475324763247732478324793248032481324823248332484324853248632487324883248932490324913249232493324943249532496324973249832499325003250132502325033250432505325063250732508325093251032511325123251332514325153251632517325183251932520325213252232523325243252532526325273252832529325303253132532325333253432535325363253732538325393254032541325423254332544325453254632547325483254932550325513255232553325543255532556325573255832559325603256132562325633256432565325663256732568325693257032571325723257332574325753257632577325783257932580325813258232583325843258532586325873258832589325903259132592325933259432595325963259732598325993260032601326023260332604326053260632607326083260932610326113261232613326143261532616326173261832619326203262132622326233262432625326263262732628326293263032631326323263332634326353263632637326383263932640326413264232643326443264532646326473264832649326503265132652326533265432655326563265732658326593266032661326623266332664326653266632667326683266932670326713267232673326743267532676326773267832679326803268132682326833268432685326863268732688326893269032691326923269332694326953269632697326983269932700327013270232703327043270532706327073270832709327103271132712327133271432715327163271732718327193272032721327223272332724327253272632727327283272932730327313273232733327343273532736327373273832739327403274132742327433274432745327463274732748327493275032751327523275332754327553275632757327583275932760327613276232763327643276532766327673276832769327703277132772327733277432775327763277732778327793278032781327823278332784327853278632787327883278932790327913279232793327943279532796327973279832799328003280132802328033280432805328063280732808328093281032811328123281332814328153281632817328183281932820328213282232823328243282532826328273282832829328303283132832328333283432835328363283732838328393284032841328423284332844328453284632847328483284932850328513285232853328543285532856328573285832859328603286132862328633286432865328663286732868328693287032871328723287332874328753287632877328783287932880328813288232883328843288532886328873288832889328903289132892328933289432895328963289732898328993290032901329023290332904329053290632907329083290932910329113291232913329143291532916329173291832919329203292132922329233292432925329263292732928329293293032931329323293332934329353293632937329383293932940329413294232943329443294532946329473294832949329503295132952329533295432955329563295732958329593296032961329623296332964329653296632967329683296932970329713297232973329743297532976329773297832979329803298132982329833298432985329863298732988329893299032991329923299332994329953299632997329983299933000330013300233003330043300533006330073300833009330103301133012330133301433015330163301733018330193302033021330223302333024330253302633027330283302933030330313303233033330343303533036330373303833039330403304133042330433304433045330463304733048330493305033051330523305333054330553305633057330583305933060330613306233063330643306533066330673306833069330703307133072330733307433075330763307733078330793308033081330823308333084330853308633087330883308933090330913309233093330943309533096330973309833099331003310133102331033310433105331063310733108331093311033111331123311333114331153311633117331183311933120331213312233123331243312533126331273312833129331303313133132331333313433135331363313733138331393314033141331423314333144331453314633147331483314933150331513315233153331543315533156331573315833159331603316133162331633316433165331663316733168331693317033171331723317333174331753317633177331783317933180331813318233183331843318533186331873318833189331903319133192331933319433195331963319733198331993320033201332023320333204332053320633207332083320933210332113321233213332143321533216332173321833219332203322133222332233322433225332263322733228332293323033231332323323333234332353323633237332383323933240332413324233243332443324533246332473324833249332503325133252332533325433255332563325733258332593326033261332623326333264332653326633267332683326933270332713327233273332743327533276332773327833279332803328133282332833328433285332863328733288332893329033291332923329333294332953329633297332983329933300333013330233303333043330533306333073330833309333103331133312333133331433315333163331733318333193332033321333223332333324333253332633327333283332933330333313333233333333343333533336333373333833339333403334133342333433334433345333463334733348333493335033351333523335333354333553335633357333583335933360333613336233363333643336533366333673336833369333703337133372333733337433375333763337733378333793338033381333823338333384333853338633387333883338933390333913339233393333943339533396333973339833399334003340133402334033340433405334063340733408334093341033411334123341333414334153341633417334183341933420334213342233423334243342533426334273342833429334303343133432334333343433435334363343733438334393344033441334423344333444334453344633447334483344933450334513345233453334543345533456334573345833459334603346133462334633346433465334663346733468334693347033471334723347333474334753347633477334783347933480334813348233483334843348533486334873348833489334903349133492334933349433495334963349733498334993350033501335023350333504335053350633507335083350933510335113351233513335143351533516335173351833519335203352133522335233352433525335263352733528335293353033531335323353333534335353353633537335383353933540335413354233543335443354533546335473354833549335503355133552335533355433555335563355733558335593356033561335623356333564335653356633567335683356933570335713357233573335743357533576335773357833579335803358133582335833358433585335863358733588335893359033591335923359333594335953359633597335983359933600336013360233603336043360533606336073360833609336103361133612336133361433615336163361733618336193362033621336223362333624336253362633627336283362933630336313363233633336343363533636336373363833639336403364133642336433364433645336463364733648336493365033651336523365333654336553365633657336583365933660336613366233663336643366533666336673366833669336703367133672336733367433675336763367733678336793368033681336823368333684336853368633687336883368933690336913369233693336943369533696336973369833699337003370133702337033370433705337063370733708337093371033711337123371333714337153371633717337183371933720337213372233723337243372533726337273372833729337303373133732337333373433735337363373733738337393374033741337423374333744337453374633747337483374933750337513375233753337543375533756337573375833759337603376133762337633376433765337663376733768337693377033771337723377333774337753377633777337783377933780337813378233783337843378533786337873378833789337903379133792337933379433795337963379733798337993380033801338023380333804338053380633807338083380933810338113381233813338143381533816338173381833819338203382133822338233382433825338263382733828338293383033831338323383333834338353383633837338383383933840338413384233843338443384533846338473384833849338503385133852338533385433855338563385733858338593386033861338623386333864338653386633867338683386933870338713387233873338743387533876338773387833879338803388133882338833388433885338863388733888338893389033891338923389333894338953389633897338983389933900339013390233903339043390533906339073390833909339103391133912339133391433915339163391733918339193392033921339223392333924339253392633927339283392933930339313393233933339343393533936339373393833939339403394133942339433394433945339463394733948339493395033951339523395333954339553395633957339583395933960339613396233963339643396533966339673396833969339703397133972339733397433975339763397733978339793398033981339823398333984339853398633987339883398933990339913399233993339943399533996339973399833999340003400134002340033400434005340063400734008340093401034011340123401334014340153401634017340183401934020340213402234023340243402534026340273402834029340303403134032340333403434035340363403734038340393404034041340423404334044340453404634047340483404934050340513405234053340543405534056340573405834059340603406134062340633406434065340663406734068340693407034071340723407334074340753407634077340783407934080340813408234083340843408534086340873408834089340903409134092340933409434095340963409734098340993410034101341023410334104341053410634107341083410934110341113411234113341143411534116341173411834119341203412134122341233412434125341263412734128341293413034131341323413334134341353413634137341383413934140341413414234143341443414534146341473414834149341503415134152341533415434155341563415734158341593416034161341623416334164341653416634167341683416934170341713417234173341743417534176341773417834179341803418134182341833418434185341863418734188341893419034191341923419334194341953419634197341983419934200342013420234203342043420534206342073420834209342103421134212342133421434215342163421734218342193422034221342223422334224342253422634227342283422934230342313423234233342343423534236342373423834239342403424134242342433424434245342463424734248342493425034251342523425334254342553425634257342583425934260342613426234263342643426534266342673426834269342703427134272342733427434275342763427734278342793428034281342823428334284342853428634287342883428934290342913429234293342943429534296342973429834299343003430134302343033430434305343063430734308343093431034311343123431334314343153431634317343183431934320343213432234323343243432534326343273432834329343303433134332343333433434335343363433734338343393434034341343423434334344343453434634347343483434934350343513435234353343543435534356343573435834359343603436134362343633436434365343663436734368343693437034371343723437334374343753437634377343783437934380343813438234383343843438534386343873438834389343903439134392343933439434395343963439734398343993440034401344023440334404344053440634407344083440934410344113441234413344143441534416344173441834419344203442134422344233442434425344263442734428344293443034431344323443334434344353443634437344383443934440344413444234443344443444534446344473444834449344503445134452344533445434455344563445734458344593446034461344623446334464344653446634467344683446934470344713447234473344743447534476344773447834479344803448134482344833448434485344863448734488344893449034491344923449334494344953449634497344983449934500345013450234503345043450534506345073450834509345103451134512345133451434515345163451734518345193452034521345223452334524345253452634527345283452934530345313453234533345343453534536345373453834539345403454134542345433454434545345463454734548345493455034551345523455334554345553455634557345583455934560345613456234563345643456534566345673456834569345703457134572345733457434575345763457734578345793458034581345823458334584345853458634587345883458934590345913459234593345943459534596345973459834599346003460134602346033460434605346063460734608346093461034611346123461334614346153461634617346183461934620346213462234623346243462534626346273462834629346303463134632346333463434635346363463734638346393464034641346423464334644346453464634647346483464934650346513465234653346543465534656346573465834659346603466134662346633466434665346663466734668346693467034671346723467334674346753467634677346783467934680346813468234683346843468534686346873468834689346903469134692346933469434695346963469734698346993470034701347023470334704347053470634707347083470934710347113471234713347143471534716347173471834719347203472134722347233472434725347263472734728347293473034731347323473334734347353473634737347383473934740347413474234743347443474534746347473474834749347503475134752347533475434755347563475734758347593476034761347623476334764347653476634767347683476934770347713477234773347743477534776347773477834779347803478134782347833478434785347863478734788347893479034791347923479334794347953479634797347983479934800348013480234803348043480534806348073480834809348103481134812348133481434815348163481734818348193482034821348223482334824348253482634827348283482934830348313483234833348343483534836348373483834839348403484134842348433484434845348463484734848348493485034851348523485334854348553485634857348583485934860348613486234863348643486534866348673486834869348703487134872348733487434875348763487734878348793488034881348823488334884348853488634887348883488934890348913489234893348943489534896348973489834899349003490134902349033490434905349063490734908349093491034911349123491334914349153491634917349183491934920349213492234923349243492534926349273492834929349303493134932349333493434935349363493734938349393494034941349423494334944349453494634947349483494934950349513495234953349543495534956349573495834959349603496134962349633496434965349663496734968349693497034971349723497334974349753497634977349783497934980349813498234983349843498534986349873498834989349903499134992349933499434995349963499734998349993500035001350023500335004350053500635007350083500935010350113501235013350143501535016350173501835019350203502135022350233502435025350263502735028350293503035031350323503335034350353503635037350383503935040350413504235043350443504535046350473504835049350503505135052350533505435055350563505735058350593506035061350623506335064350653506635067350683506935070350713507235073350743507535076350773507835079350803508135082350833508435085350863508735088350893509035091350923509335094350953509635097350983509935100351013510235103351043510535106351073510835109351103511135112351133511435115351163511735118351193512035121351223512335124351253512635127351283512935130351313513235133351343513535136351373513835139351403514135142351433514435145351463514735148351493515035151351523515335154351553515635157351583515935160351613516235163351643516535166351673516835169351703517135172351733517435175351763517735178351793518035181351823518335184351853518635187351883518935190351913519235193351943519535196351973519835199352003520135202352033520435205352063520735208352093521035211352123521335214352153521635217352183521935220352213522235223352243522535226352273522835229352303523135232352333523435235352363523735238352393524035241352423524335244352453524635247352483524935250352513525235253352543525535256352573525835259352603526135262352633526435265352663526735268352693527035271352723527335274352753527635277352783527935280352813528235283352843528535286352873528835289352903529135292352933529435295352963529735298352993530035301353023530335304353053530635307353083530935310353113531235313353143531535316353173531835319353203532135322353233532435325353263532735328353293533035331353323533335334353353533635337353383533935340353413534235343353443534535346353473534835349353503535135352353533535435355353563535735358353593536035361353623536335364353653536635367353683536935370353713537235373353743537535376353773537835379353803538135382353833538435385353863538735388353893539035391353923539335394353953539635397353983539935400354013540235403354043540535406354073540835409354103541135412354133541435415354163541735418354193542035421354223542335424354253542635427354283542935430354313543235433354343543535436354373543835439354403544135442354433544435445354463544735448354493545035451354523545335454354553545635457354583545935460354613546235463354643546535466354673546835469354703547135472354733547435475354763547735478354793548035481354823548335484354853548635487354883548935490354913549235493354943549535496354973549835499355003550135502355033550435505355063550735508355093551035511355123551335514355153551635517355183551935520355213552235523355243552535526355273552835529355303553135532355333553435535355363553735538355393554035541355423554335544355453554635547355483554935550355513555235553355543555535556355573555835559355603556135562355633556435565355663556735568355693557035571355723557335574355753557635577355783557935580355813558235583355843558535586355873558835589355903559135592355933559435595355963559735598355993560035601356023560335604356053560635607356083560935610356113561235613356143561535616356173561835619356203562135622356233562435625356263562735628356293563035631356323563335634356353563635637356383563935640356413564235643356443564535646356473564835649356503565135652356533565435655356563565735658356593566035661356623566335664356653566635667356683566935670356713567235673356743567535676356773567835679356803568135682356833568435685356863568735688356893569035691356923569335694356953569635697356983569935700357013570235703357043570535706357073570835709357103571135712357133571435715357163571735718357193572035721357223572335724357253572635727357283572935730357313573235733357343573535736357373573835739357403574135742357433574435745357463574735748357493575035751357523575335754357553575635757357583575935760357613576235763357643576535766357673576835769357703577135772357733577435775357763577735778357793578035781357823578335784357853578635787357883578935790357913579235793357943579535796357973579835799358003580135802358033580435805358063580735808358093581035811358123581335814358153581635817358183581935820358213582235823358243582535826358273582835829358303583135832358333583435835358363583735838358393584035841358423584335844358453584635847358483584935850358513585235853358543585535856358573585835859358603586135862358633586435865358663586735868358693587035871358723587335874358753587635877358783587935880358813588235883358843588535886358873588835889358903589135892358933589435895358963589735898358993590035901359023590335904359053590635907359083590935910359113591235913359143591535916359173591835919359203592135922359233592435925359263592735928359293593035931359323593335934359353593635937359383593935940359413594235943359443594535946359473594835949359503595135952359533595435955359563595735958359593596035961359623596335964359653596635967359683596935970359713597235973359743597535976359773597835979359803598135982359833598435985359863598735988359893599035991359923599335994359953599635997359983599936000360013600236003360043600536006360073600836009360103601136012360133601436015360163601736018360193602036021360223602336024360253602636027360283602936030360313603236033360343603536036360373603836039360403604136042360433604436045360463604736048360493605036051360523605336054360553605636057360583605936060360613606236063360643606536066360673606836069360703607136072360733607436075360763607736078360793608036081360823608336084360853608636087360883608936090360913609236093360943609536096360973609836099361003610136102361033610436105361063610736108361093611036111361123611336114361153611636117361183611936120361213612236123361243612536126361273612836129361303613136132361333613436135361363613736138361393614036141361423614336144361453614636147361483614936150361513615236153361543615536156361573615836159361603616136162361633616436165361663616736168361693617036171361723617336174361753617636177361783617936180361813618236183361843618536186361873618836189361903619136192361933619436195361963619736198361993620036201362023620336204362053620636207362083620936210362113621236213362143621536216362173621836219362203622136222362233622436225362263622736228362293623036231362323623336234362353623636237362383623936240362413624236243362443624536246362473624836249362503625136252362533625436255362563625736258362593626036261362623626336264362653626636267362683626936270362713627236273362743627536276362773627836279362803628136282362833628436285362863628736288362893629036291362923629336294362953629636297362983629936300363013630236303363043630536306363073630836309363103631136312363133631436315363163631736318363193632036321363223632336324363253632636327363283632936330363313633236333363343633536336363373633836339363403634136342363433634436345363463634736348363493635036351363523635336354363553635636357363583635936360363613636236363363643636536366363673636836369363703637136372363733637436375363763637736378363793638036381363823638336384363853638636387363883638936390363913639236393363943639536396363973639836399364003640136402364033640436405364063640736408364093641036411364123641336414364153641636417364183641936420364213642236423364243642536426364273642836429364303643136432364333643436435364363643736438364393644036441364423644336444364453644636447364483644936450364513645236453364543645536456364573645836459364603646136462364633646436465364663646736468364693647036471364723647336474364753647636477364783647936480364813648236483364843648536486364873648836489364903649136492364933649436495364963649736498364993650036501365023650336504365053650636507365083650936510365113651236513365143651536516365173651836519365203652136522365233652436525365263652736528365293653036531365323653336534365353653636537365383653936540365413654236543365443654536546365473654836549365503655136552365533655436555365563655736558365593656036561365623656336564365653656636567365683656936570365713657236573365743657536576365773657836579365803658136582365833658436585365863658736588365893659036591365923659336594365953659636597365983659936600366013660236603366043660536606366073660836609366103661136612366133661436615366163661736618366193662036621366223662336624366253662636627366283662936630366313663236633366343663536636366373663836639366403664136642366433664436645366463664736648366493665036651366523665336654366553665636657366583665936660366613666236663366643666536666366673666836669366703667136672366733667436675366763667736678366793668036681366823668336684366853668636687366883668936690366913669236693366943669536696366973669836699367003670136702367033670436705367063670736708367093671036711367123671336714367153671636717367183671936720367213672236723367243672536726367273672836729367303673136732367333673436735367363673736738367393674036741367423674336744367453674636747367483674936750367513675236753367543675536756367573675836759367603676136762367633676436765367663676736768367693677036771367723677336774367753677636777367783677936780367813678236783367843678536786367873678836789367903679136792367933679436795367963679736798367993680036801368023680336804368053680636807368083680936810368113681236813368143681536816368173681836819368203682136822368233682436825368263682736828368293683036831368323683336834368353683636837368383683936840368413684236843368443684536846368473684836849368503685136852368533685436855368563685736858368593686036861368623686336864368653686636867368683686936870368713687236873368743687536876368773687836879368803688136882368833688436885368863688736888368893689036891368923689336894368953689636897368983689936900369013690236903369043690536906369073690836909369103691136912369133691436915369163691736918369193692036921369223692336924369253692636927369283692936930369313693236933369343693536936369373693836939369403694136942369433694436945369463694736948369493695036951369523695336954369553695636957369583695936960369613696236963369643696536966369673696836969369703697136972369733697436975369763697736978369793698036981369823698336984369853698636987369883698936990369913699236993369943699536996369973699836999370003700137002370033700437005370063700737008370093701037011370123701337014370153701637017370183701937020370213702237023370243702537026370273702837029370303703137032370333703437035370363703737038370393704037041370423704337044370453704637047370483704937050370513705237053370543705537056370573705837059370603706137062370633706437065370663706737068370693707037071370723707337074370753707637077370783707937080370813708237083370843708537086370873708837089370903709137092370933709437095370963709737098370993710037101371023710337104371053710637107371083710937110371113711237113371143711537116371173711837119371203712137122371233712437125371263712737128371293713037131371323713337134371353713637137371383713937140371413714237143371443714537146371473714837149371503715137152371533715437155371563715737158371593716037161371623716337164371653716637167371683716937170371713717237173371743717537176371773717837179371803718137182371833718437185371863718737188371893719037191371923719337194371953719637197371983719937200372013720237203372043720537206372073720837209372103721137212372133721437215372163721737218372193722037221372223722337224372253722637227372283722937230372313723237233372343723537236372373723837239372403724137242372433724437245372463724737248372493725037251372523725337254372553725637257372583725937260372613726237263372643726537266372673726837269372703727137272372733727437275372763727737278372793728037281372823728337284372853728637287372883728937290372913729237293372943729537296372973729837299373003730137302373033730437305373063730737308373093731037311373123731337314373153731637317373183731937320373213732237323373243732537326373273732837329373303733137332373333733437335373363733737338373393734037341373423734337344373453734637347373483734937350373513735237353373543735537356373573735837359373603736137362373633736437365373663736737368373693737037371373723737337374373753737637377373783737937380373813738237383373843738537386373873738837389373903739137392373933739437395373963739737398373993740037401374023740337404374053740637407374083740937410374113741237413374143741537416374173741837419374203742137422374233742437425374263742737428374293743037431374323743337434374353743637437374383743937440374413744237443374443744537446374473744837449374503745137452374533745437455374563745737458374593746037461374623746337464374653746637467374683746937470374713747237473374743747537476374773747837479374803748137482374833748437485374863748737488374893749037491374923749337494374953749637497374983749937500375013750237503375043750537506375073750837509375103751137512375133751437515375163751737518375193752037521375223752337524375253752637527375283752937530375313753237533375343753537536375373753837539375403754137542375433754437545375463754737548375493755037551375523755337554375553755637557375583755937560375613756237563375643756537566375673756837569375703757137572375733757437575375763757737578375793758037581375823758337584375853758637587375883758937590375913759237593375943759537596375973759837599376003760137602376033760437605376063760737608376093761037611376123761337614376153761637617376183761937620376213762237623376243762537626376273762837629376303763137632376333763437635376363763737638376393764037641376423764337644376453764637647376483764937650376513765237653376543765537656376573765837659376603766137662376633766437665376663766737668376693767037671376723767337674376753767637677376783767937680376813768237683376843768537686376873768837689376903769137692376933769437695376963769737698376993770037701377023770337704377053770637707377083770937710377113771237713377143771537716377173771837719377203772137722377233772437725377263772737728377293773037731377323773337734377353773637737377383773937740377413774237743377443774537746377473774837749377503775137752377533775437755377563775737758377593776037761377623776337764377653776637767377683776937770377713777237773377743777537776377773777837779377803778137782377833778437785377863778737788377893779037791377923779337794377953779637797377983779937800378013780237803378043780537806378073780837809378103781137812378133781437815378163781737818378193782037821378223782337824378253782637827378283782937830378313783237833378343783537836378373783837839378403784137842378433784437845378463784737848378493785037851378523785337854378553785637857378583785937860378613786237863378643786537866378673786837869378703787137872378733787437875378763787737878378793788037881378823788337884378853788637887378883788937890378913789237893378943789537896378973789837899379003790137902379033790437905379063790737908379093791037911379123791337914379153791637917379183791937920379213792237923379243792537926379273792837929379303793137932379333793437935379363793737938379393794037941379423794337944379453794637947379483794937950379513795237953379543795537956379573795837959379603796137962379633796437965379663796737968379693797037971379723797337974379753797637977379783797937980379813798237983379843798537986379873798837989379903799137992379933799437995379963799737998379993800038001380023800338004380053800638007380083800938010380113801238013380143801538016380173801838019380203802138022380233802438025380263802738028380293803038031380323803338034380353803638037380383803938040380413804238043380443804538046380473804838049380503805138052380533805438055380563805738058380593806038061380623806338064380653806638067380683806938070380713807238073380743807538076380773807838079380803808138082380833808438085380863808738088380893809038091380923809338094380953809638097380983809938100381013810238103381043810538106381073810838109381103811138112381133811438115381163811738118381193812038121381223812338124381253812638127381283812938130381313813238133381343813538136381373813838139381403814138142381433814438145381463814738148381493815038151381523815338154381553815638157381583815938160381613816238163381643816538166381673816838169381703817138172381733817438175381763817738178381793818038181381823818338184381853818638187381883818938190381913819238193381943819538196381973819838199382003820138202382033820438205382063820738208382093821038211382123821338214382153821638217382183821938220382213822238223382243822538226382273822838229382303823138232382333823438235382363823738238382393824038241382423824338244382453824638247382483824938250382513825238253382543825538256382573825838259382603826138262382633826438265382663826738268382693827038271382723827338274382753827638277382783827938280382813828238283382843828538286382873828838289382903829138292382933829438295382963829738298382993830038301383023830338304383053830638307383083830938310383113831238313383143831538316383173831838319383203832138322383233832438325383263832738328383293833038331383323833338334383353833638337383383833938340383413834238343383443834538346383473834838349383503835138352383533835438355383563835738358383593836038361383623836338364383653836638367383683836938370383713837238373383743837538376383773837838379383803838138382383833838438385383863838738388383893839038391383923839338394383953839638397383983839938400384013840238403384043840538406384073840838409384103841138412384133841438415384163841738418384193842038421384223842338424384253842638427384283842938430384313843238433384343843538436384373843838439384403844138442384433844438445384463844738448384493845038451384523845338454384553845638457384583845938460384613846238463384643846538466384673846838469384703847138472384733847438475384763847738478384793848038481384823848338484384853848638487384883848938490384913849238493384943849538496384973849838499385003850138502385033850438505385063850738508385093851038511385123851338514385153851638517385183851938520385213852238523385243852538526385273852838529385303853138532385333853438535385363853738538385393854038541385423854338544385453854638547385483854938550385513855238553385543855538556385573855838559385603856138562385633856438565385663856738568385693857038571385723857338574385753857638577385783857938580385813858238583385843858538586385873858838589385903859138592385933859438595385963859738598385993860038601386023860338604386053860638607386083860938610386113861238613386143861538616386173861838619386203862138622386233862438625386263862738628386293863038631386323863338634386353863638637386383863938640386413864238643386443864538646386473864838649386503865138652386533865438655386563865738658386593866038661386623866338664386653866638667386683866938670386713867238673386743867538676386773867838679386803868138682386833868438685386863868738688386893869038691386923869338694386953869638697386983869938700387013870238703387043870538706387073870838709387103871138712387133871438715387163871738718387193872038721387223872338724387253872638727387283872938730387313873238733387343873538736387373873838739387403874138742387433874438745387463874738748387493875038751387523875338754387553875638757387583875938760387613876238763387643876538766387673876838769387703877138772387733877438775387763877738778387793878038781387823878338784387853878638787387883878938790387913879238793387943879538796387973879838799388003880138802388033880438805388063880738808388093881038811388123881338814388153881638817388183881938820388213882238823388243882538826388273882838829388303883138832388333883438835388363883738838388393884038841388423884338844388453884638847388483884938850388513885238853388543885538856388573885838859388603886138862388633886438865388663886738868388693887038871388723887338874388753887638877388783887938880388813888238883388843888538886388873888838889388903889138892388933889438895388963889738898388993890038901389023890338904389053890638907389083890938910389113891238913389143891538916389173891838919389203892138922389233892438925389263892738928389293893038931389323893338934389353893638937389383893938940389413894238943389443894538946389473894838949389503895138952389533895438955389563895738958389593896038961389623896338964389653896638967389683896938970389713897238973389743897538976389773897838979389803898138982389833898438985389863898738988389893899038991389923899338994389953899638997389983899939000390013900239003390043900539006390073900839009390103901139012390133901439015390163901739018390193902039021390223902339024390253902639027390283902939030390313903239033390343903539036390373903839039390403904139042390433904439045390463904739048390493905039051390523905339054390553905639057390583905939060390613906239063390643906539066390673906839069390703907139072390733907439075390763907739078390793908039081390823908339084390853908639087390883908939090390913909239093390943909539096390973909839099391003910139102391033910439105391063910739108391093911039111391123911339114391153911639117391183911939120391213912239123391243912539126391273912839129391303913139132391333913439135391363913739138391393914039141391423914339144391453914639147391483914939150391513915239153391543915539156391573915839159391603916139162391633916439165391663916739168391693917039171391723917339174391753917639177391783917939180391813918239183391843918539186391873918839189391903919139192391933919439195391963919739198391993920039201392023920339204392053920639207392083920939210392113921239213392143921539216392173921839219392203922139222392233922439225392263922739228392293923039231392323923339234392353923639237392383923939240392413924239243392443924539246392473924839249392503925139252392533925439255392563925739258392593926039261392623926339264392653926639267392683926939270392713927239273392743927539276392773927839279392803928139282392833928439285392863928739288392893929039291392923929339294392953929639297392983929939300393013930239303393043930539306393073930839309393103931139312393133931439315393163931739318393193932039321393223932339324393253932639327393283932939330393313933239333393343933539336393373933839339393403934139342393433934439345393463934739348393493935039351393523935339354393553935639357393583935939360393613936239363393643936539366393673936839369393703937139372393733937439375393763937739378393793938039381393823938339384393853938639387393883938939390393913939239393393943939539396393973939839399394003940139402394033940439405394063940739408394093941039411394123941339414394153941639417394183941939420394213942239423394243942539426394273942839429394303943139432394333943439435394363943739438394393944039441394423944339444394453944639447394483944939450394513945239453394543945539456394573945839459394603946139462394633946439465394663946739468394693947039471394723947339474394753947639477394783947939480394813948239483394843948539486394873948839489394903949139492394933949439495394963949739498394993950039501395023950339504395053950639507395083950939510395113951239513395143951539516395173951839519395203952139522395233952439525395263952739528395293953039531395323953339534395353953639537395383953939540395413954239543395443954539546395473954839549395503955139552395533955439555395563955739558395593956039561395623956339564395653956639567395683956939570395713957239573395743957539576395773957839579395803958139582395833958439585395863958739588395893959039591395923959339594395953959639597395983959939600396013960239603396043960539606396073960839609396103961139612396133961439615396163961739618396193962039621396223962339624396253962639627396283962939630396313963239633396343963539636396373963839639396403964139642396433964439645396463964739648396493965039651396523965339654396553965639657396583965939660396613966239663396643966539666396673966839669396703967139672396733967439675396763967739678396793968039681396823968339684396853968639687396883968939690396913969239693396943969539696396973969839699397003970139702397033970439705397063970739708397093971039711397123971339714397153971639717397183971939720397213972239723397243972539726397273972839729397303973139732397333973439735397363973739738397393974039741397423974339744397453974639747397483974939750397513975239753397543975539756397573975839759397603976139762397633976439765397663976739768397693977039771397723977339774397753977639777397783977939780397813978239783397843978539786397873978839789397903979139792397933979439795397963979739798397993980039801398023980339804398053980639807398083980939810398113981239813398143981539816398173981839819398203982139822398233982439825398263982739828398293983039831398323983339834398353983639837398383983939840398413984239843398443984539846398473984839849398503985139852398533985439855398563985739858398593986039861398623986339864398653986639867398683986939870398713987239873398743987539876398773987839879398803988139882398833988439885398863988739888398893989039891398923989339894398953989639897398983989939900399013990239903399043990539906399073990839909399103991139912399133991439915399163991739918399193992039921399223992339924399253992639927399283992939930399313993239933399343993539936399373993839939399403994139942399433994439945399463994739948399493995039951399523995339954399553995639957399583995939960399613996239963399643996539966399673996839969399703997139972399733997439975399763997739978399793998039981399823998339984399853998639987399883998939990399913999239993399943999539996399973999839999400004000140002400034000440005400064000740008400094001040011400124001340014400154001640017400184001940020400214002240023400244002540026400274002840029400304003140032400334003440035400364003740038400394004040041400424004340044400454004640047400484004940050400514005240053400544005540056400574005840059400604006140062400634006440065400664006740068400694007040071400724007340074400754007640077400784007940080400814008240083400844008540086400874008840089400904009140092400934009440095400964009740098400994010040101401024010340104401054010640107401084010940110401114011240113401144011540116401174011840119401204012140122401234012440125401264012740128401294013040131401324013340134401354013640137401384013940140401414014240143401444014540146401474014840149401504015140152401534015440155401564015740158401594016040161401624016340164401654016640167401684016940170401714017240173401744017540176401774017840179401804018140182401834018440185401864018740188401894019040191401924019340194401954019640197401984019940200402014020240203402044020540206402074020840209402104021140212402134021440215402164021740218402194022040221402224022340224402254022640227402284022940230402314023240233402344023540236402374023840239402404024140242402434024440245402464024740248402494025040251402524025340254402554025640257402584025940260402614026240263402644026540266402674026840269402704027140272402734027440275402764027740278402794028040281402824028340284402854028640287402884028940290402914029240293402944029540296402974029840299403004030140302403034030440305403064030740308403094031040311403124031340314403154031640317403184031940320403214032240323403244032540326403274032840329403304033140332403334033440335403364033740338403394034040341403424034340344403454034640347403484034940350403514035240353403544035540356403574035840359403604036140362403634036440365403664036740368403694037040371403724037340374403754037640377403784037940380403814038240383403844038540386403874038840389403904039140392403934039440395403964039740398403994040040401404024040340404404054040640407404084040940410404114041240413404144041540416404174041840419404204042140422404234042440425404264042740428404294043040431404324043340434404354043640437404384043940440404414044240443404444044540446404474044840449404504045140452404534045440455404564045740458404594046040461404624046340464404654046640467404684046940470404714047240473404744047540476404774047840479404804048140482404834048440485404864048740488404894049040491404924049340494404954049640497404984049940500405014050240503405044050540506405074050840509405104051140512405134051440515405164051740518405194052040521405224052340524405254052640527405284052940530405314053240533405344053540536405374053840539405404054140542405434054440545405464054740548405494055040551405524055340554405554055640557405584055940560405614056240563405644056540566405674056840569405704057140572405734057440575405764057740578405794058040581405824058340584405854058640587405884058940590405914059240593405944059540596405974059840599406004060140602406034060440605406064060740608406094061040611406124061340614406154061640617406184061940620406214062240623406244062540626406274062840629406304063140632406334063440635406364063740638406394064040641406424064340644406454064640647406484064940650406514065240653406544065540656406574065840659406604066140662406634066440665406664066740668406694067040671406724067340674406754067640677406784067940680406814068240683406844068540686406874068840689406904069140692406934069440695406964069740698406994070040701407024070340704407054070640707407084070940710407114071240713407144071540716407174071840719407204072140722407234072440725407264072740728407294073040731407324073340734407354073640737407384073940740407414074240743407444074540746407474074840749407504075140752407534075440755407564075740758407594076040761407624076340764407654076640767407684076940770407714077240773407744077540776407774077840779407804078140782407834078440785407864078740788407894079040791407924079340794407954079640797407984079940800408014080240803408044080540806408074080840809408104081140812408134081440815408164081740818408194082040821408224082340824408254082640827408284082940830408314083240833408344083540836408374083840839408404084140842408434084440845408464084740848408494085040851408524085340854408554085640857408584085940860408614086240863408644086540866408674086840869408704087140872408734087440875408764087740878408794088040881408824088340884408854088640887408884088940890408914089240893408944089540896408974089840899409004090140902409034090440905409064090740908409094091040911409124091340914409154091640917409184091940920409214092240923409244092540926409274092840929409304093140932409334093440935409364093740938409394094040941409424094340944409454094640947409484094940950409514095240953409544095540956409574095840959409604096140962409634096440965409664096740968409694097040971409724097340974409754097640977409784097940980409814098240983409844098540986409874098840989409904099140992409934099440995409964099740998409994100041001410024100341004410054100641007410084100941010410114101241013410144101541016410174101841019410204102141022410234102441025410264102741028410294103041031410324103341034410354103641037410384103941040410414104241043410444104541046410474104841049410504105141052410534105441055410564105741058410594106041061410624106341064410654106641067410684106941070410714107241073410744107541076410774107841079410804108141082410834108441085410864108741088410894109041091410924109341094410954109641097410984109941100411014110241103411044110541106411074110841109411104111141112411134111441115411164111741118411194112041121411224112341124411254112641127411284112941130411314113241133411344113541136411374113841139411404114141142411434114441145411464114741148411494115041151411524115341154411554115641157411584115941160411614116241163411644116541166411674116841169411704117141172411734117441175411764117741178411794118041181411824118341184411854118641187411884118941190411914119241193411944119541196411974119841199412004120141202412034120441205412064120741208412094121041211412124121341214412154121641217412184121941220412214122241223412244122541226412274122841229412304123141232412334123441235412364123741238412394124041241412424124341244412454124641247412484124941250412514125241253412544125541256412574125841259412604126141262412634126441265412664126741268412694127041271412724127341274412754127641277412784127941280412814128241283412844128541286412874128841289412904129141292412934129441295412964129741298412994130041301413024130341304413054130641307413084130941310413114131241313413144131541316413174131841319413204132141322413234132441325413264132741328413294133041331413324133341334413354133641337413384133941340413414134241343413444134541346413474134841349413504135141352413534135441355413564135741358413594136041361413624136341364413654136641367413684136941370413714137241373413744137541376413774137841379413804138141382413834138441385413864138741388413894139041391413924139341394413954139641397413984139941400414014140241403414044140541406414074140841409414104141141412414134141441415414164141741418414194142041421414224142341424414254142641427414284142941430414314143241433414344143541436414374143841439414404144141442414434144441445414464144741448414494145041451414524145341454414554145641457414584145941460414614146241463414644146541466414674146841469414704147141472414734147441475414764147741478414794148041481414824148341484414854148641487414884148941490414914149241493414944149541496414974149841499415004150141502415034150441505415064150741508415094151041511415124151341514415154151641517415184151941520415214152241523415244152541526415274152841529415304153141532415334153441535415364153741538415394154041541415424154341544415454154641547415484154941550415514155241553415544155541556415574155841559415604156141562415634156441565415664156741568415694157041571415724157341574415754157641577415784157941580415814158241583415844158541586415874158841589415904159141592415934159441595415964159741598415994160041601416024160341604416054160641607416084160941610416114161241613416144161541616416174161841619416204162141622416234162441625416264162741628416294163041631416324163341634416354163641637416384163941640416414164241643416444164541646416474164841649416504165141652416534165441655416564165741658416594166041661416624166341664416654166641667416684166941670416714167241673416744167541676416774167841679416804168141682416834168441685416864168741688416894169041691416924169341694416954169641697416984169941700417014170241703417044170541706417074170841709417104171141712417134171441715417164171741718417194172041721417224172341724417254172641727417284172941730417314173241733417344173541736417374173841739417404174141742417434174441745417464174741748417494175041751417524175341754417554175641757417584175941760417614176241763417644176541766417674176841769417704177141772417734177441775417764177741778417794178041781417824178341784417854178641787417884178941790417914179241793417944179541796417974179841799418004180141802418034180441805418064180741808418094181041811418124181341814418154181641817418184181941820418214182241823418244182541826418274182841829418304183141832418334183441835418364183741838418394184041841418424184341844418454184641847418484184941850418514185241853418544185541856418574185841859418604186141862418634186441865418664186741868418694187041871418724187341874418754187641877418784187941880418814188241883418844188541886418874188841889418904189141892418934189441895418964189741898418994190041901419024190341904419054190641907419084190941910419114191241913419144191541916419174191841919419204192141922419234192441925419264192741928419294193041931419324193341934419354193641937419384193941940419414194241943419444194541946419474194841949419504195141952419534195441955419564195741958419594196041961419624196341964419654196641967419684196941970419714197241973419744197541976419774197841979419804198141982419834198441985419864198741988419894199041991419924199341994419954199641997419984199942000420014200242003420044200542006420074200842009420104201142012420134201442015420164201742018420194202042021420224202342024420254202642027420284202942030420314203242033420344203542036420374203842039420404204142042420434204442045420464204742048420494205042051420524205342054420554205642057420584205942060420614206242063420644206542066420674206842069420704207142072420734207442075420764207742078420794208042081420824208342084420854208642087420884208942090420914209242093420944209542096420974209842099421004210142102421034210442105421064210742108421094211042111421124211342114421154211642117421184211942120421214212242123421244212542126421274212842129421304213142132421334213442135421364213742138421394214042141421424214342144421454214642147421484214942150421514215242153421544215542156421574215842159421604216142162421634216442165421664216742168421694217042171421724217342174421754217642177421784217942180421814218242183421844218542186421874218842189421904219142192421934219442195421964219742198421994220042201422024220342204422054220642207422084220942210422114221242213422144221542216422174221842219422204222142222422234222442225422264222742228422294223042231422324223342234422354223642237422384223942240422414224242243422444224542246422474224842249422504225142252422534225442255422564225742258422594226042261422624226342264422654226642267422684226942270422714227242273422744227542276422774227842279422804228142282422834228442285422864228742288422894229042291422924229342294422954229642297422984229942300423014230242303423044230542306423074230842309423104231142312423134231442315423164231742318423194232042321423224232342324423254232642327423284232942330423314233242333423344233542336423374233842339423404234142342423434234442345423464234742348423494235042351423524235342354423554235642357423584235942360423614236242363423644236542366423674236842369423704237142372423734237442375423764237742378423794238042381423824238342384423854238642387423884238942390423914239242393423944239542396423974239842399424004240142402424034240442405424064240742408424094241042411424124241342414424154241642417424184241942420424214242242423424244242542426424274242842429424304243142432424334243442435424364243742438424394244042441424424244342444424454244642447424484244942450424514245242453424544245542456424574245842459424604246142462424634246442465424664246742468424694247042471424724247342474424754247642477424784247942480424814248242483424844248542486424874248842489424904249142492424934249442495424964249742498424994250042501425024250342504425054250642507425084250942510425114251242513425144251542516425174251842519425204252142522425234252442525425264252742528425294253042531425324253342534425354253642537425384253942540425414254242543425444254542546425474254842549425504255142552425534255442555425564255742558425594256042561425624256342564425654256642567425684256942570425714257242573425744257542576425774257842579425804258142582425834258442585425864258742588425894259042591425924259342594425954259642597425984259942600426014260242603426044260542606426074260842609426104261142612426134261442615426164261742618426194262042621426224262342624426254262642627426284262942630426314263242633426344263542636426374263842639426404264142642426434264442645426464264742648426494265042651426524265342654426554265642657426584265942660426614266242663426644266542666426674266842669426704267142672426734267442675426764267742678426794268042681426824268342684426854268642687426884268942690426914269242693426944269542696426974269842699427004270142702427034270442705427064270742708427094271042711427124271342714427154271642717427184271942720427214272242723427244272542726427274272842729427304273142732427334273442735427364273742738427394274042741427424274342744427454274642747427484274942750427514275242753427544275542756427574275842759427604276142762427634276442765427664276742768427694277042771427724277342774427754277642777427784277942780427814278242783427844278542786427874278842789427904279142792427934279442795427964279742798427994280042801428024280342804428054280642807428084280942810428114281242813428144281542816428174281842819428204282142822428234282442825428264282742828428294283042831428324283342834428354283642837428384283942840428414284242843428444284542846428474284842849428504285142852428534285442855428564285742858428594286042861428624286342864428654286642867428684286942870428714287242873428744287542876428774287842879428804288142882428834288442885428864288742888428894289042891428924289342894428954289642897428984289942900429014290242903429044290542906429074290842909429104291142912429134291442915429164291742918429194292042921429224292342924429254292642927429284292942930429314293242933429344293542936429374293842939429404294142942429434294442945429464294742948429494295042951429524295342954429554295642957429584295942960429614296242963429644296542966429674296842969429704297142972429734297442975429764297742978429794298042981429824298342984429854298642987429884298942990429914299242993429944299542996429974299842999430004300143002430034300443005430064300743008430094301043011430124301343014430154301643017430184301943020430214302243023430244302543026430274302843029430304303143032430334303443035430364303743038430394304043041430424304343044430454304643047430484304943050430514305243053430544305543056430574305843059430604306143062430634306443065430664306743068430694307043071430724307343074430754307643077430784307943080430814308243083430844308543086430874308843089430904309143092430934309443095430964309743098430994310043101431024310343104431054310643107431084310943110431114311243113431144311543116431174311843119431204312143122431234312443125431264312743128431294313043131431324313343134431354313643137431384313943140431414314243143431444314543146431474314843149431504315143152431534315443155431564315743158431594316043161431624316343164431654316643167431684316943170431714317243173431744317543176431774317843179431804318143182431834318443185431864318743188431894319043191431924319343194431954319643197431984319943200432014320243203432044320543206432074320843209432104321143212432134321443215432164321743218432194322043221432224322343224432254322643227432284322943230432314323243233432344323543236432374323843239432404324143242432434324443245432464324743248432494325043251432524325343254432554325643257432584325943260432614326243263432644326543266432674326843269432704327143272432734327443275432764327743278432794328043281432824328343284432854328643287432884328943290432914329243293432944329543296432974329843299433004330143302433034330443305433064330743308433094331043311433124331343314433154331643317433184331943320433214332243323433244332543326433274332843329433304333143332433334333443335433364333743338433394334043341433424334343344433454334643347433484334943350433514335243353433544335543356433574335843359433604336143362433634336443365433664336743368433694337043371433724337343374433754337643377433784337943380433814338243383433844338543386433874338843389433904339143392433934339443395433964339743398433994340043401434024340343404434054340643407434084340943410434114341243413434144341543416434174341843419434204342143422434234342443425434264342743428434294343043431434324343343434434354343643437434384343943440434414344243443434444344543446434474344843449434504345143452434534345443455434564345743458434594346043461434624346343464434654346643467434684346943470434714347243473434744347543476434774347843479434804348143482434834348443485434864348743488434894349043491434924349343494434954349643497434984349943500435014350243503435044350543506435074350843509435104351143512435134351443515435164351743518435194352043521435224352343524435254352643527435284352943530435314353243533435344353543536435374353843539435404354143542435434354443545435464354743548435494355043551435524355343554435554355643557435584355943560435614356243563435644356543566435674356843569435704357143572435734357443575435764357743578435794358043581435824358343584435854358643587435884358943590435914359243593435944359543596435974359843599436004360143602436034360443605436064360743608436094361043611436124361343614436154361643617436184361943620436214362243623436244362543626436274362843629436304363143632436334363443635436364363743638436394364043641436424364343644436454364643647436484364943650436514365243653436544365543656436574365843659436604366143662436634366443665436664366743668436694367043671436724367343674436754367643677436784367943680436814368243683436844368543686436874368843689436904369143692436934369443695436964369743698436994370043701437024370343704437054370643707437084370943710437114371243713437144371543716437174371843719437204372143722437234372443725437264372743728437294373043731437324373343734437354373643737437384373943740437414374243743437444374543746437474374843749437504375143752437534375443755437564375743758437594376043761437624376343764437654376643767437684376943770437714377243773437744377543776437774377843779437804378143782437834378443785437864378743788437894379043791437924379343794437954379643797437984379943800438014380243803438044380543806438074380843809438104381143812438134381443815438164381743818438194382043821438224382343824438254382643827438284382943830438314383243833438344383543836438374383843839438404384143842438434384443845438464384743848438494385043851438524385343854438554385643857438584385943860438614386243863438644386543866438674386843869438704387143872438734387443875438764387743878438794388043881438824388343884438854388643887438884388943890438914389243893438944389543896438974389843899439004390143902439034390443905439064390743908439094391043911439124391343914439154391643917439184391943920439214392243923439244392543926439274392843929439304393143932439334393443935439364393743938439394394043941439424394343944439454394643947439484394943950439514395243953439544395543956439574395843959439604396143962439634396443965439664396743968439694397043971439724397343974439754397643977439784397943980439814398243983439844398543986439874398843989439904399143992439934399443995439964399743998439994400044001440024400344004440054400644007440084400944010440114401244013440144401544016440174401844019440204402144022440234402444025440264402744028440294403044031440324403344034440354403644037440384403944040440414404244043440444404544046440474404844049440504405144052440534405444055440564405744058440594406044061440624406344064440654406644067440684406944070440714407244073440744407544076440774407844079440804408144082440834408444085440864408744088440894409044091440924409344094440954409644097440984409944100441014410244103441044410544106441074410844109441104411144112441134411444115441164411744118441194412044121441224412344124441254412644127441284412944130441314413244133441344413544136441374413844139441404414144142441434414444145441464414744148441494415044151441524415344154441554415644157441584415944160441614416244163441644416544166441674416844169441704417144172441734417444175441764417744178441794418044181441824418344184441854418644187441884418944190441914419244193441944419544196441974419844199442004420144202442034420444205442064420744208442094421044211442124421344214442154421644217442184421944220442214422244223442244422544226442274422844229442304423144232442334423444235442364423744238442394424044241442424424344244442454424644247442484424944250442514425244253442544425544256442574425844259442604426144262442634426444265442664426744268442694427044271442724427344274442754427644277442784427944280442814428244283442844428544286442874428844289442904429144292442934429444295442964429744298442994430044301443024430344304443054430644307443084430944310443114431244313443144431544316443174431844319443204432144322443234432444325443264432744328443294433044331443324433344334443354433644337443384433944340443414434244343443444434544346443474434844349443504435144352443534435444355443564435744358443594436044361443624436344364443654436644367443684436944370443714437244373443744437544376443774437844379443804438144382443834438444385443864438744388443894439044391443924439344394443954439644397443984439944400444014440244403444044440544406444074440844409444104441144412444134441444415444164441744418444194442044421444224442344424444254442644427444284442944430444314443244433444344443544436444374443844439444404444144442444434444444445444464444744448444494445044451444524445344454444554445644457444584445944460444614446244463444644446544466444674446844469444704447144472444734447444475444764447744478444794448044481444824448344484444854448644487444884448944490444914449244493444944449544496444974449844499445004450144502445034450444505445064450744508445094451044511445124451344514445154451644517445184451944520445214452244523445244452544526445274452844529445304453144532445334453444535445364453744538445394454044541445424454344544445454454644547445484454944550445514455244553445544455544556445574455844559445604456144562445634456444565445664456744568445694457044571445724457344574445754457644577445784457944580445814458244583445844458544586445874458844589445904459144592445934459444595445964459744598445994460044601446024460344604446054460644607446084460944610446114461244613446144461544616446174461844619446204462144622446234462444625446264462744628446294463044631446324463344634446354463644637446384463944640446414464244643446444464544646446474464844649446504465144652446534465444655446564465744658446594466044661446624466344664446654466644667446684466944670446714467244673446744467544676446774467844679446804468144682446834468444685446864468744688446894469044691446924469344694446954469644697446984469944700447014470244703447044470544706447074470844709447104471144712447134471444715447164471744718447194472044721447224472344724447254472644727447284472944730447314473244733447344473544736447374473844739447404474144742447434474444745447464474744748447494475044751447524475344754447554475644757447584475944760447614476244763447644476544766447674476844769447704477144772447734477444775447764477744778447794478044781447824478344784447854478644787447884478944790447914479244793447944479544796447974479844799448004480144802448034480444805448064480744808448094481044811448124481344814448154481644817448184481944820448214482244823448244482544826448274482844829448304483144832448334483444835448364483744838448394484044841448424484344844448454484644847448484484944850448514485244853448544485544856448574485844859448604486144862448634486444865448664486744868448694487044871448724487344874448754487644877448784487944880448814488244883448844488544886448874488844889448904489144892448934489444895448964489744898448994490044901449024490344904449054490644907449084490944910449114491244913449144491544916449174491844919449204492144922449234492444925449264492744928449294493044931449324493344934449354493644937449384493944940449414494244943449444494544946449474494844949449504495144952449534495444955449564495744958449594496044961449624496344964449654496644967449684496944970449714497244973449744497544976449774497844979449804498144982449834498444985449864498744988449894499044991449924499344994449954499644997449984499945000450014500245003450044500545006450074500845009450104501145012450134501445015450164501745018450194502045021450224502345024450254502645027450284502945030450314503245033450344503545036450374503845039450404504145042450434504445045450464504745048450494505045051450524505345054450554505645057450584505945060450614506245063450644506545066450674506845069450704507145072450734507445075450764507745078450794508045081450824508345084450854508645087450884508945090450914509245093450944509545096450974509845099451004510145102451034510445105451064510745108451094511045111451124511345114451154511645117451184511945120451214512245123451244512545126451274512845129451304513145132451334513445135451364513745138451394514045141451424514345144451454514645147451484514945150451514515245153451544515545156451574515845159451604516145162451634516445165451664516745168451694517045171451724517345174451754517645177451784517945180451814518245183451844518545186451874518845189451904519145192451934519445195451964519745198451994520045201452024520345204452054520645207452084520945210452114521245213452144521545216452174521845219452204522145222452234522445225452264522745228452294523045231452324523345234452354523645237452384523945240452414524245243452444524545246452474524845249452504525145252452534525445255452564525745258452594526045261452624526345264452654526645267452684526945270452714527245273452744527545276452774527845279452804528145282452834528445285452864528745288452894529045291452924529345294452954529645297452984529945300453014530245303453044530545306453074530845309453104531145312453134531445315453164531745318453194532045321453224532345324453254532645327453284532945330453314533245333453344533545336453374533845339453404534145342453434534445345453464534745348453494535045351453524535345354453554535645357453584535945360453614536245363453644536545366453674536845369453704537145372453734537445375453764537745378453794538045381453824538345384453854538645387453884538945390453914539245393453944539545396453974539845399454004540145402454034540445405454064540745408454094541045411454124541345414454154541645417454184541945420454214542245423454244542545426454274542845429454304543145432454334543445435454364543745438454394544045441454424544345444454454544645447454484544945450454514545245453454544545545456454574545845459454604546145462454634546445465454664546745468454694547045471454724547345474454754547645477454784547945480454814548245483454844548545486454874548845489454904549145492454934549445495454964549745498454994550045501455024550345504455054550645507455084550945510455114551245513455144551545516455174551845519455204552145522455234552445525455264552745528455294553045531455324553345534455354553645537455384553945540455414554245543455444554545546455474554845549455504555145552455534555445555455564555745558455594556045561455624556345564455654556645567455684556945570455714557245573455744557545576455774557845579455804558145582455834558445585455864558745588455894559045591455924559345594455954559645597455984559945600456014560245603456044560545606456074560845609456104561145612456134561445615456164561745618456194562045621456224562345624456254562645627456284562945630456314563245633456344563545636456374563845639456404564145642456434564445645456464564745648456494565045651456524565345654456554565645657456584565945660456614566245663456644566545666456674566845669456704567145672456734567445675456764567745678456794568045681456824568345684456854568645687456884568945690456914569245693456944569545696456974569845699457004570145702457034570445705457064570745708457094571045711457124571345714457154571645717457184571945720457214572245723457244572545726457274572845729457304573145732457334573445735457364573745738457394574045741457424574345744457454574645747457484574945750457514575245753457544575545756457574575845759457604576145762457634576445765457664576745768457694577045771457724577345774457754577645777457784577945780457814578245783457844578545786457874578845789457904579145792457934579445795457964579745798457994580045801458024580345804458054580645807458084580945810458114581245813458144581545816458174581845819458204582145822458234582445825458264582745828458294583045831458324583345834458354583645837458384583945840458414584245843458444584545846458474584845849458504585145852458534585445855458564585745858458594586045861458624586345864458654586645867458684586945870458714587245873458744587545876458774587845879458804588145882458834588445885458864588745888458894589045891458924589345894458954589645897458984589945900459014590245903459044590545906459074590845909459104591145912459134591445915459164591745918459194592045921459224592345924459254592645927459284592945930459314593245933459344593545936459374593845939459404594145942459434594445945459464594745948459494595045951459524595345954459554595645957459584595945960459614596245963459644596545966459674596845969459704597145972459734597445975459764597745978459794598045981459824598345984459854598645987459884598945990459914599245993459944599545996459974599845999460004600146002460034600446005460064600746008460094601046011460124601346014460154601646017460184601946020460214602246023460244602546026460274602846029460304603146032460334603446035460364603746038460394604046041460424604346044460454604646047460484604946050460514605246053460544605546056460574605846059460604606146062460634606446065460664606746068460694607046071460724607346074460754607646077460784607946080460814608246083460844608546086460874608846089460904609146092460934609446095460964609746098460994610046101461024610346104461054610646107461084610946110461114611246113461144611546116461174611846119461204612146122461234612446125461264612746128461294613046131461324613346134461354613646137461384613946140461414614246143461444614546146461474614846149461504615146152461534615446155461564615746158461594616046161461624616346164461654616646167461684616946170461714617246173461744617546176461774617846179461804618146182461834618446185461864618746188461894619046191461924619346194461954619646197461984619946200462014620246203462044620546206462074620846209462104621146212462134621446215462164621746218462194622046221462224622346224462254622646227462284622946230462314623246233462344623546236462374623846239462404624146242462434624446245462464624746248462494625046251462524625346254462554625646257462584625946260462614626246263462644626546266462674626846269462704627146272462734627446275462764627746278462794628046281462824628346284462854628646287462884628946290462914629246293462944629546296462974629846299463004630146302463034630446305463064630746308463094631046311463124631346314463154631646317463184631946320463214632246323463244632546326463274632846329463304633146332463334633446335463364633746338463394634046341463424634346344463454634646347463484634946350463514635246353463544635546356463574635846359463604636146362463634636446365463664636746368463694637046371463724637346374463754637646377463784637946380463814638246383463844638546386463874638846389463904639146392463934639446395463964639746398463994640046401464024640346404464054640646407464084640946410464114641246413464144641546416464174641846419464204642146422464234642446425464264642746428464294643046431464324643346434464354643646437464384643946440464414644246443464444644546446464474644846449464504645146452464534645446455464564645746458464594646046461464624646346464464654646646467464684646946470464714647246473464744647546476464774647846479464804648146482464834648446485464864648746488464894649046491464924649346494464954649646497464984649946500465014650246503465044650546506465074650846509465104651146512465134651446515465164651746518465194652046521465224652346524465254652646527465284652946530465314653246533465344653546536465374653846539465404654146542465434654446545465464654746548465494655046551465524655346554465554655646557465584655946560465614656246563465644656546566465674656846569465704657146572465734657446575465764657746578465794658046581465824658346584465854658646587465884658946590465914659246593465944659546596465974659846599466004660146602466034660446605466064660746608466094661046611466124661346614466154661646617466184661946620466214662246623466244662546626466274662846629466304663146632466334663446635466364663746638466394664046641466424664346644466454664646647466484664946650466514665246653466544665546656466574665846659466604666146662466634666446665466664666746668466694667046671466724667346674466754667646677466784667946680466814668246683466844668546686466874668846689466904669146692466934669446695466964669746698466994670046701467024670346704467054670646707467084670946710467114671246713467144671546716467174671846719467204672146722467234672446725467264672746728467294673046731467324673346734467354673646737467384673946740467414674246743467444674546746467474674846749467504675146752467534675446755467564675746758467594676046761467624676346764467654676646767467684676946770467714677246773467744677546776467774677846779467804678146782467834678446785467864678746788467894679046791467924679346794467954679646797467984679946800468014680246803468044680546806468074680846809468104681146812468134681446815468164681746818468194682046821468224682346824468254682646827468284682946830468314683246833468344683546836468374683846839468404684146842468434684446845468464684746848468494685046851468524685346854468554685646857468584685946860468614686246863468644686546866468674686846869468704687146872468734687446875468764687746878468794688046881468824688346884468854688646887468884688946890468914689246893468944689546896468974689846899469004690146902469034690446905469064690746908469094691046911469124691346914469154691646917469184691946920469214692246923469244692546926469274692846929469304693146932469334693446935469364693746938469394694046941469424694346944469454694646947469484694946950469514695246953469544695546956469574695846959469604696146962469634696446965469664696746968469694697046971469724697346974469754697646977469784697946980469814698246983469844698546986469874698846989469904699146992469934699446995469964699746998469994700047001470024700347004470054700647007470084700947010470114701247013470144701547016470174701847019470204702147022470234702447025470264702747028470294703047031470324703347034470354703647037470384703947040470414704247043470444704547046470474704847049470504705147052470534705447055470564705747058470594706047061470624706347064470654706647067470684706947070470714707247073470744707547076470774707847079470804708147082470834708447085470864708747088470894709047091470924709347094470954709647097470984709947100471014710247103471044710547106471074710847109471104711147112471134711447115471164711747118471194712047121471224712347124471254712647127471284712947130471314713247133471344713547136471374713847139471404714147142471434714447145471464714747148471494715047151471524715347154471554715647157471584715947160471614716247163471644716547166471674716847169471704717147172471734717447175471764717747178471794718047181471824718347184471854718647187471884718947190471914719247193471944719547196471974719847199472004720147202472034720447205472064720747208472094721047211472124721347214472154721647217472184721947220472214722247223472244722547226472274722847229472304723147232472334723447235472364723747238472394724047241472424724347244472454724647247472484724947250472514725247253472544725547256472574725847259472604726147262472634726447265472664726747268472694727047271472724727347274472754727647277472784727947280472814728247283472844728547286472874728847289472904729147292472934729447295472964729747298472994730047301473024730347304473054730647307473084730947310473114731247313473144731547316473174731847319473204732147322473234732447325473264732747328473294733047331473324733347334473354733647337473384733947340473414734247343473444734547346473474734847349473504735147352473534735447355473564735747358473594736047361473624736347364473654736647367473684736947370473714737247373473744737547376473774737847379473804738147382473834738447385473864738747388473894739047391473924739347394473954739647397473984739947400474014740247403474044740547406474074740847409474104741147412474134741447415474164741747418474194742047421474224742347424474254742647427474284742947430474314743247433474344743547436474374743847439474404744147442474434744447445474464744747448474494745047451474524745347454474554745647457474584745947460474614746247463474644746547466474674746847469474704747147472474734747447475474764747747478474794748047481474824748347484474854748647487474884748947490474914749247493474944749547496474974749847499475004750147502475034750447505475064750747508475094751047511475124751347514475154751647517475184751947520475214752247523475244752547526475274752847529475304753147532475334753447535475364753747538475394754047541475424754347544475454754647547475484754947550475514755247553475544755547556475574755847559475604756147562475634756447565475664756747568475694757047571475724757347574475754757647577475784757947580475814758247583475844758547586475874758847589475904759147592475934759447595475964759747598475994760047601476024760347604476054760647607476084760947610476114761247613476144761547616476174761847619476204762147622476234762447625476264762747628476294763047631476324763347634476354763647637476384763947640476414764247643476444764547646476474764847649476504765147652476534765447655476564765747658476594766047661476624766347664476654766647667476684766947670476714767247673476744767547676476774767847679476804768147682476834768447685476864768747688476894769047691476924769347694476954769647697476984769947700477014770247703477044770547706477074770847709477104771147712477134771447715477164771747718477194772047721477224772347724477254772647727477284772947730477314773247733477344773547736477374773847739477404774147742477434774447745477464774747748477494775047751477524775347754477554775647757477584775947760477614776247763477644776547766477674776847769477704777147772477734777447775477764777747778477794778047781477824778347784477854778647787477884778947790477914779247793477944779547796477974779847799478004780147802478034780447805478064780747808478094781047811478124781347814478154781647817478184781947820478214782247823478244782547826478274782847829478304783147832478334783447835478364783747838478394784047841478424784347844478454784647847478484784947850478514785247853478544785547856478574785847859478604786147862478634786447865478664786747868478694787047871478724787347874478754787647877478784787947880478814788247883478844788547886478874788847889478904789147892478934789447895478964789747898478994790047901479024790347904479054790647907479084790947910479114791247913479144791547916479174791847919479204792147922479234792447925479264792747928479294793047931479324793347934479354793647937479384793947940479414794247943479444794547946479474794847949479504795147952479534795447955479564795747958479594796047961479624796347964479654796647967479684796947970479714797247973479744797547976479774797847979479804798147982479834798447985479864798747988479894799047991479924799347994479954799647997479984799948000480014800248003480044800548006480074800848009480104801148012480134801448015480164801748018480194802048021480224802348024480254802648027480284802948030480314803248033480344803548036480374803848039480404804148042480434804448045480464804748048480494805048051480524805348054480554805648057480584805948060480614806248063480644806548066480674806848069480704807148072480734807448075480764807748078480794808048081480824808348084480854808648087480884808948090480914809248093480944809548096480974809848099481004810148102481034810448105481064810748108481094811048111481124811348114481154811648117481184811948120481214812248123481244812548126481274812848129481304813148132481334813448135481364813748138481394814048141481424814348144481454814648147481484814948150481514815248153481544815548156481574815848159481604816148162481634816448165481664816748168481694817048171481724817348174481754817648177481784817948180481814818248183481844818548186481874818848189481904819148192481934819448195481964819748198481994820048201482024820348204482054820648207482084820948210482114821248213482144821548216482174821848219482204822148222482234822448225482264822748228482294823048231482324823348234482354823648237482384823948240482414824248243482444824548246482474824848249482504825148252482534825448255482564825748258482594826048261482624826348264482654826648267482684826948270482714827248273482744827548276482774827848279482804828148282482834828448285482864828748288482894829048291482924829348294482954829648297482984829948300483014830248303483044830548306483074830848309483104831148312483134831448315483164831748318483194832048321483224832348324483254832648327483284832948330483314833248333483344833548336483374833848339483404834148342483434834448345483464834748348483494835048351483524835348354483554835648357483584835948360483614836248363483644836548366483674836848369483704837148372483734837448375483764837748378483794838048381483824838348384483854838648387483884838948390483914839248393483944839548396483974839848399484004840148402484034840448405484064840748408484094841048411484124841348414484154841648417484184841948420484214842248423484244842548426484274842848429484304843148432484334843448435484364843748438484394844048441484424844348444484454844648447484484844948450484514845248453484544845548456484574845848459484604846148462484634846448465484664846748468484694847048471484724847348474484754847648477484784847948480484814848248483484844848548486484874848848489484904849148492484934849448495484964849748498484994850048501485024850348504485054850648507485084850948510485114851248513485144851548516485174851848519485204852148522485234852448525485264852748528485294853048531485324853348534485354853648537485384853948540485414854248543485444854548546485474854848549485504855148552485534855448555485564855748558485594856048561485624856348564485654856648567485684856948570485714857248573485744857548576485774857848579485804858148582485834858448585485864858748588485894859048591485924859348594485954859648597485984859948600486014860248603486044860548606486074860848609486104861148612486134861448615486164861748618486194862048621486224862348624486254862648627486284862948630486314863248633486344863548636486374863848639486404864148642486434864448645486464864748648486494865048651486524865348654486554865648657486584865948660486614866248663486644866548666486674866848669486704867148672486734867448675486764867748678486794868048681486824868348684486854868648687486884868948690486914869248693486944869548696486974869848699487004870148702487034870448705487064870748708487094871048711487124871348714487154871648717487184871948720487214872248723487244872548726487274872848729487304873148732487334873448735487364873748738487394874048741487424874348744487454874648747487484874948750487514875248753487544875548756487574875848759487604876148762487634876448765487664876748768487694877048771487724877348774487754877648777487784877948780487814878248783487844878548786487874878848789487904879148792487934879448795487964879748798487994880048801488024880348804488054880648807488084880948810488114881248813488144881548816488174881848819488204882148822488234882448825488264882748828488294883048831488324883348834488354883648837488384883948840488414884248843488444884548846488474884848849488504885148852488534885448855488564885748858488594886048861488624886348864488654886648867488684886948870488714887248873488744887548876488774887848879488804888148882488834888448885488864888748888488894889048891488924889348894488954889648897488984889948900489014890248903489044890548906489074890848909489104891148912489134891448915489164891748918489194892048921489224892348924489254892648927489284892948930489314893248933489344893548936489374893848939489404894148942489434894448945489464894748948489494895048951489524895348954489554895648957489584895948960489614896248963489644896548966489674896848969489704897148972489734897448975489764897748978489794898048981489824898348984489854898648987489884898948990489914899248993489944899548996489974899848999490004900149002490034900449005490064900749008490094901049011490124901349014490154901649017490184901949020490214902249023490244902549026490274902849029490304903149032490334903449035490364903749038490394904049041490424904349044490454904649047490484904949050490514905249053490544905549056490574905849059490604906149062490634906449065490664906749068490694907049071490724907349074490754907649077490784907949080490814908249083490844908549086490874908849089490904909149092490934909449095490964909749098490994910049101491024910349104491054910649107491084910949110491114911249113491144911549116491174911849119491204912149122491234912449125491264912749128491294913049131491324913349134491354913649137491384913949140491414914249143491444914549146491474914849149491504915149152491534915449155491564915749158491594916049161491624916349164491654916649167491684916949170491714917249173491744917549176491774917849179491804918149182491834918449185491864918749188491894919049191491924919349194491954919649197491984919949200492014920249203492044920549206492074920849209492104921149212492134921449215492164921749218492194922049221492224922349224492254922649227492284922949230492314923249233492344923549236492374923849239492404924149242492434924449245492464924749248492494925049251492524925349254492554925649257492584925949260492614926249263492644926549266492674926849269492704927149272492734927449275492764927749278492794928049281492824928349284492854928649287492884928949290492914929249293492944929549296492974929849299493004930149302493034930449305493064930749308493094931049311493124931349314493154931649317493184931949320493214932249323493244932549326493274932849329493304933149332493334933449335493364933749338493394934049341493424934349344493454934649347493484934949350493514935249353493544935549356493574935849359493604936149362493634936449365493664936749368493694937049371493724937349374493754937649377493784937949380493814938249383493844938549386493874938849389493904939149392493934939449395493964939749398493994940049401494024940349404494054940649407494084940949410494114941249413494144941549416494174941849419494204942149422494234942449425494264942749428494294943049431494324943349434494354943649437494384943949440494414944249443494444944549446494474944849449494504945149452494534945449455494564945749458494594946049461494624946349464494654946649467494684946949470494714947249473494744947549476494774947849479494804948149482494834948449485494864948749488494894949049491494924949349494494954949649497494984949949500495014950249503495044950549506495074950849509495104951149512495134951449515495164951749518495194952049521495224952349524495254952649527495284952949530495314953249533495344953549536495374953849539495404954149542495434954449545495464954749548495494955049551495524955349554495554955649557495584955949560495614956249563495644956549566495674956849569495704957149572495734957449575495764957749578495794958049581495824958349584495854958649587495884958949590495914959249593495944959549596495974959849599496004960149602496034960449605496064960749608496094961049611496124961349614496154961649617496184961949620496214962249623496244962549626496274962849629496304963149632496334963449635496364963749638496394964049641496424964349644496454964649647496484964949650496514965249653496544965549656496574965849659496604966149662496634966449665496664966749668496694967049671496724967349674496754967649677496784967949680496814968249683496844968549686496874968849689496904969149692496934969449695496964969749698496994970049701497024970349704497054970649707497084970949710497114971249713497144971549716497174971849719497204972149722497234972449725497264972749728497294973049731497324973349734497354973649737497384973949740497414974249743497444974549746497474974849749497504975149752497534975449755497564975749758497594976049761497624976349764497654976649767497684976949770497714977249773497744977549776497774977849779497804978149782497834978449785497864978749788497894979049791497924979349794497954979649797497984979949800498014980249803498044980549806498074980849809498104981149812498134981449815498164981749818498194982049821498224982349824498254982649827498284982949830498314983249833498344983549836498374983849839498404984149842498434984449845498464984749848498494985049851498524985349854498554985649857498584985949860498614986249863498644986549866498674986849869498704987149872498734987449875498764987749878498794988049881498824988349884498854988649887498884988949890498914989249893498944989549896498974989849899499004990149902499034990449905499064990749908499094991049911499124991349914499154991649917499184991949920499214992249923499244992549926499274992849929499304993149932499334993449935499364993749938499394994049941499424994349944499454994649947499484994949950499514995249953499544995549956499574995849959499604996149962499634996449965499664996749968499694997049971499724997349974499754997649977499784997949980499814998249983499844998549986499874998849989499904999149992499934999449995499964999749998499995000050001500025000350004500055000650007500085000950010500115001250013500145001550016500175001850019500205002150022500235002450025500265002750028500295003050031500325003350034500355003650037500385003950040500415004250043500445004550046500475004850049500505005150052500535005450055500565005750058500595006050061500625006350064500655006650067500685006950070500715007250073500745007550076500775007850079500805008150082500835008450085500865008750088500895009050091500925009350094500955009650097500985009950100501015010250103501045010550106501075010850109501105011150112501135011450115501165011750118501195012050121501225012350124501255012650127501285012950130501315013250133501345013550136501375013850139501405014150142501435014450145501465014750148501495015050151501525015350154501555015650157501585015950160501615016250163501645016550166501675016850169501705017150172501735017450175501765017750178501795018050181501825018350184501855018650187501885018950190501915019250193501945019550196501975019850199502005020150202502035020450205502065020750208502095021050211502125021350214502155021650217502185021950220502215022250223502245022550226502275022850229502305023150232502335023450235502365023750238502395024050241502425024350244502455024650247502485024950250502515025250253502545025550256502575025850259502605026150262502635026450265502665026750268502695027050271502725027350274502755027650277502785027950280502815028250283502845028550286502875028850289502905029150292502935029450295502965029750298502995030050301503025030350304503055030650307503085030950310503115031250313503145031550316503175031850319503205032150322503235032450325503265032750328503295033050331503325033350334503355033650337503385033950340503415034250343503445034550346503475034850349503505035150352503535035450355503565035750358503595036050361503625036350364503655036650367503685036950370503715037250373503745037550376503775037850379503805038150382503835038450385503865038750388503895039050391503925039350394503955039650397503985039950400504015040250403504045040550406504075040850409504105041150412504135041450415504165041750418504195042050421504225042350424504255042650427504285042950430504315043250433504345043550436504375043850439504405044150442504435044450445504465044750448504495045050451504525045350454504555045650457504585045950460504615046250463504645046550466504675046850469504705047150472504735047450475504765047750478504795048050481504825048350484504855048650487504885048950490504915049250493504945049550496504975049850499505005050150502505035050450505505065050750508505095051050511505125051350514505155051650517505185051950520505215052250523505245052550526505275052850529505305053150532505335053450535505365053750538505395054050541505425054350544505455054650547505485054950550505515055250553505545055550556505575055850559505605056150562505635056450565505665056750568505695057050571505725057350574505755057650577505785057950580505815058250583505845058550586505875058850589505905059150592505935059450595505965059750598505995060050601506025060350604506055060650607506085060950610506115061250613506145061550616506175061850619506205062150622506235062450625506265062750628506295063050631506325063350634506355063650637506385063950640506415064250643506445064550646506475064850649506505065150652506535065450655506565065750658506595066050661506625066350664506655066650667506685066950670506715067250673506745067550676506775067850679506805068150682506835068450685506865068750688506895069050691506925069350694506955069650697506985069950700507015070250703507045070550706507075070850709507105071150712507135071450715507165071750718507195072050721507225072350724507255072650727507285072950730507315073250733507345073550736507375073850739507405074150742507435074450745507465074750748507495075050751507525075350754507555075650757507585075950760507615076250763507645076550766507675076850769507705077150772507735077450775507765077750778507795078050781507825078350784507855078650787507885078950790507915079250793507945079550796507975079850799508005080150802508035080450805508065080750808508095081050811508125081350814508155081650817508185081950820508215082250823508245082550826508275082850829508305083150832508335083450835508365083750838508395084050841508425084350844508455084650847508485084950850508515085250853508545085550856508575085850859508605086150862508635086450865508665086750868508695087050871508725087350874508755087650877508785087950880508815088250883508845088550886508875088850889508905089150892508935089450895508965089750898508995090050901509025090350904509055090650907509085090950910509115091250913509145091550916509175091850919509205092150922509235092450925509265092750928509295093050931509325093350934509355093650937509385093950940509415094250943509445094550946509475094850949509505095150952509535095450955509565095750958509595096050961509625096350964509655096650967509685096950970509715097250973509745097550976509775097850979509805098150982509835098450985509865098750988509895099050991509925099350994509955099650997509985099951000510015100251003510045100551006510075100851009510105101151012510135101451015510165101751018510195102051021510225102351024510255102651027510285102951030510315103251033510345103551036510375103851039510405104151042510435104451045510465104751048510495105051051510525105351054510555105651057510585105951060510615106251063510645106551066510675106851069510705107151072510735107451075510765107751078510795108051081510825108351084510855108651087510885108951090510915109251093510945109551096510975109851099511005110151102511035110451105511065110751108511095111051111511125111351114511155111651117511185111951120511215112251123511245112551126511275112851129511305113151132511335113451135511365113751138511395114051141511425114351144511455114651147511485114951150511515115251153511545115551156511575115851159511605116151162511635116451165511665116751168511695117051171511725117351174511755117651177511785117951180511815118251183511845118551186511875118851189511905119151192511935119451195511965119751198511995120051201512025120351204512055120651207512085120951210512115121251213512145121551216512175121851219512205122151222512235122451225512265122751228512295123051231512325123351234512355123651237512385123951240512415124251243512445124551246512475124851249512505125151252512535125451255512565125751258512595126051261512625126351264512655126651267512685126951270512715127251273512745127551276512775127851279512805128151282512835128451285512865128751288512895129051291512925129351294512955129651297512985129951300513015130251303513045130551306513075130851309513105131151312513135131451315513165131751318513195132051321513225132351324513255132651327513285132951330513315133251333513345133551336513375133851339513405134151342513435134451345513465134751348513495135051351513525135351354513555135651357513585135951360513615136251363513645136551366513675136851369513705137151372513735137451375513765137751378513795138051381513825138351384513855138651387513885138951390513915139251393513945139551396513975139851399514005140151402514035140451405514065140751408514095141051411514125141351414514155141651417514185141951420514215142251423514245142551426514275142851429514305143151432514335143451435514365143751438514395144051441514425144351444514455144651447514485144951450514515145251453514545145551456514575145851459514605146151462514635146451465514665146751468514695147051471514725147351474514755147651477514785147951480514815148251483514845148551486514875148851489514905149151492514935149451495514965149751498514995150051501515025150351504515055150651507515085150951510515115151251513515145151551516515175151851519515205152151522515235152451525515265152751528515295153051531515325153351534515355153651537515385153951540515415154251543515445154551546515475154851549515505155151552515535155451555515565155751558515595156051561515625156351564515655156651567515685156951570515715157251573515745157551576515775157851579515805158151582515835158451585515865158751588515895159051591515925159351594515955159651597515985159951600516015160251603516045160551606516075160851609516105161151612516135161451615516165161751618516195162051621516225162351624516255162651627516285162951630516315163251633516345163551636516375163851639516405164151642516435164451645516465164751648516495165051651516525165351654516555165651657516585165951660516615166251663516645166551666516675166851669516705167151672516735167451675516765167751678516795168051681516825168351684516855168651687516885168951690516915169251693516945169551696516975169851699517005170151702517035170451705517065170751708517095171051711517125171351714517155171651717517185171951720517215172251723517245172551726517275172851729517305173151732517335173451735517365173751738517395174051741517425174351744517455174651747517485174951750517515175251753517545175551756517575175851759517605176151762517635176451765517665176751768517695177051771517725177351774517755177651777517785177951780517815178251783517845178551786517875178851789517905179151792517935179451795517965179751798517995180051801518025180351804518055180651807518085180951810518115181251813518145181551816518175181851819518205182151822518235182451825518265182751828518295183051831518325183351834518355183651837518385183951840518415184251843518445184551846518475184851849518505185151852518535185451855518565185751858518595186051861518625186351864518655186651867518685186951870518715187251873518745187551876518775187851879518805188151882518835188451885518865188751888518895189051891518925189351894518955189651897518985189951900519015190251903519045190551906519075190851909519105191151912519135191451915519165191751918519195192051921519225192351924519255192651927519285192951930519315193251933519345193551936519375193851939519405194151942519435194451945519465194751948519495195051951519525195351954519555195651957519585195951960519615196251963519645196551966519675196851969519705197151972519735197451975519765197751978519795198051981519825198351984519855198651987519885198951990519915199251993519945199551996519975199851999520005200152002520035200452005520065200752008520095201052011520125201352014520155201652017520185201952020520215202252023520245202552026520275202852029520305203152032520335203452035520365203752038520395204052041520425204352044520455204652047520485204952050520515205252053520545205552056520575205852059520605206152062520635206452065520665206752068520695207052071520725207352074520755207652077520785207952080520815208252083520845208552086520875208852089520905209152092520935209452095520965209752098520995210052101521025210352104521055210652107521085210952110521115211252113521145211552116521175211852119521205212152122521235212452125521265212752128521295213052131521325213352134521355213652137521385213952140521415214252143521445214552146521475214852149521505215152152521535215452155521565215752158521595216052161521625216352164521655216652167521685216952170521715217252173521745217552176521775217852179521805218152182521835218452185521865218752188521895219052191521925219352194521955219652197521985219952200522015220252203522045220552206522075220852209522105221152212522135221452215522165221752218522195222052221522225222352224522255222652227522285222952230522315223252233522345223552236522375223852239522405224152242522435224452245522465224752248522495225052251522525225352254522555225652257522585225952260522615226252263522645226552266522675226852269522705227152272522735227452275522765227752278522795228052281522825228352284522855228652287522885228952290522915229252293522945229552296522975229852299523005230152302523035230452305523065230752308523095231052311523125231352314523155231652317523185231952320523215232252323523245232552326523275232852329523305233152332523335233452335523365233752338523395234052341523425234352344523455234652347523485234952350523515235252353523545235552356523575235852359523605236152362523635236452365523665236752368523695237052371523725237352374523755237652377523785237952380523815238252383523845238552386523875238852389523905239152392523935239452395523965239752398523995240052401524025240352404524055240652407524085240952410524115241252413524145241552416524175241852419524205242152422524235242452425524265242752428524295243052431524325243352434524355243652437524385243952440524415244252443524445244552446524475244852449524505245152452524535245452455524565245752458524595246052461524625246352464524655246652467524685246952470524715247252473524745247552476524775247852479524805248152482524835248452485524865248752488524895249052491524925249352494524955249652497524985249952500525015250252503525045250552506525075250852509525105251152512525135251452515525165251752518525195252052521525225252352524525255252652527525285252952530525315253252533525345253552536525375253852539525405254152542525435254452545525465254752548525495255052551525525255352554525555255652557525585255952560525615256252563525645256552566525675256852569525705257152572525735257452575525765257752578525795258052581525825258352584525855258652587525885258952590525915259252593525945259552596525975259852599526005260152602526035260452605526065260752608526095261052611526125261352614526155261652617526185261952620526215262252623526245262552626526275262852629526305263152632526335263452635526365263752638526395264052641526425264352644526455264652647526485264952650526515265252653526545265552656526575265852659526605266152662526635266452665526665266752668526695267052671526725267352674526755267652677526785267952680526815268252683526845268552686526875268852689526905269152692526935269452695526965269752698526995270052701527025270352704527055270652707527085270952710527115271252713527145271552716527175271852719527205272152722527235272452725527265272752728527295273052731527325273352734527355273652737527385273952740527415274252743527445274552746527475274852749527505275152752527535275452755527565275752758527595276052761527625276352764527655276652767527685276952770527715277252773527745277552776527775277852779527805278152782527835278452785527865278752788527895279052791527925279352794527955279652797527985279952800528015280252803528045280552806528075280852809528105281152812528135281452815528165281752818528195282052821528225282352824528255282652827528285282952830528315283252833528345283552836528375283852839528405284152842528435284452845528465284752848528495285052851528525285352854528555285652857528585285952860528615286252863528645286552866528675286852869528705287152872528735287452875528765287752878528795288052881528825288352884528855288652887528885288952890528915289252893528945289552896528975289852899529005290152902529035290452905529065290752908529095291052911529125291352914529155291652917529185291952920529215292252923529245292552926529275292852929529305293152932529335293452935529365293752938529395294052941529425294352944529455294652947529485294952950529515295252953529545295552956529575295852959529605296152962529635296452965529665296752968529695297052971529725297352974529755297652977529785297952980529815298252983529845298552986529875298852989529905299152992529935299452995529965299752998529995300053001530025300353004530055300653007530085300953010530115301253013530145301553016530175301853019530205302153022530235302453025530265302753028530295303053031530325303353034530355303653037530385303953040530415304253043530445304553046530475304853049530505305153052530535305453055530565305753058530595306053061530625306353064530655306653067530685306953070530715307253073530745307553076530775307853079530805308153082530835308453085530865308753088530895309053091530925309353094530955309653097530985309953100531015310253103531045310553106531075310853109531105311153112531135311453115531165311753118531195312053121531225312353124531255312653127531285312953130531315313253133531345313553136531375313853139531405314153142531435314453145531465314753148531495315053151531525315353154531555315653157531585315953160531615316253163531645316553166531675316853169531705317153172531735317453175531765317753178531795318053181531825318353184531855318653187531885318953190531915319253193531945319553196531975319853199532005320153202532035320453205532065320753208532095321053211532125321353214532155321653217532185321953220532215322253223532245322553226532275322853229532305323153232532335323453235532365323753238532395324053241532425324353244532455324653247532485324953250532515325253253532545325553256532575325853259532605326153262532635326453265532665326753268532695327053271532725327353274532755327653277532785327953280532815328253283532845328553286532875328853289532905329153292532935329453295532965329753298532995330053301533025330353304533055330653307533085330953310533115331253313533145331553316533175331853319533205332153322533235332453325533265332753328533295333053331533325333353334533355333653337533385333953340533415334253343533445334553346533475334853349533505335153352533535335453355533565335753358533595336053361533625336353364533655336653367533685336953370533715337253373533745337553376533775337853379533805338153382533835338453385533865338753388533895339053391533925339353394533955339653397533985339953400534015340253403534045340553406534075340853409534105341153412534135341453415534165341753418534195342053421534225342353424534255342653427534285342953430534315343253433534345343553436534375343853439534405344153442534435344453445534465344753448534495345053451534525345353454534555345653457534585345953460534615346253463534645346553466534675346853469534705347153472534735347453475534765347753478534795348053481534825348353484534855348653487534885348953490534915349253493534945349553496534975349853499535005350153502535035350453505535065350753508535095351053511535125351353514535155351653517535185351953520535215352253523535245352553526535275352853529535305353153532535335353453535535365353753538535395354053541535425354353544535455354653547535485354953550535515355253553535545355553556535575355853559535605356153562535635356453565535665356753568535695357053571535725357353574535755357653577535785357953580535815358253583535845358553586535875358853589535905359153592535935359453595535965359753598535995360053601536025360353604536055360653607536085360953610536115361253613536145361553616536175361853619536205362153622536235362453625536265362753628536295363053631536325363353634536355363653637536385363953640536415364253643536445364553646536475364853649536505365153652536535365453655536565365753658536595366053661536625366353664536655366653667536685366953670536715367253673536745367553676536775367853679536805368153682536835368453685536865368753688536895369053691536925369353694536955369653697536985369953700537015370253703537045370553706537075370853709537105371153712537135371453715537165371753718537195372053721537225372353724537255372653727537285372953730537315373253733537345373553736537375373853739537405374153742537435374453745537465374753748537495375053751537525375353754537555375653757537585375953760537615376253763537645376553766537675376853769537705377153772537735377453775537765377753778537795378053781537825378353784537855378653787537885378953790537915379253793537945379553796537975379853799538005380153802538035380453805538065380753808538095381053811538125381353814538155381653817538185381953820538215382253823538245382553826538275382853829538305383153832538335383453835538365383753838538395384053841538425384353844538455384653847538485384953850538515385253853538545385553856538575385853859538605386153862538635386453865538665386753868538695387053871538725387353874538755387653877538785387953880538815388253883538845388553886538875388853889538905389153892538935389453895538965389753898538995390053901539025390353904539055390653907539085390953910539115391253913539145391553916539175391853919539205392153922539235392453925539265392753928539295393053931539325393353934539355393653937539385393953940539415394253943539445394553946539475394853949539505395153952539535395453955539565395753958539595396053961539625396353964539655396653967539685396953970539715397253973539745397553976539775397853979539805398153982539835398453985539865398753988539895399053991539925399353994539955399653997539985399954000540015400254003540045400554006540075400854009540105401154012540135401454015540165401754018540195402054021540225402354024540255402654027540285402954030540315403254033540345403554036540375403854039540405404154042540435404454045540465404754048540495405054051540525405354054540555405654057540585405954060540615406254063540645406554066540675406854069540705407154072540735407454075540765407754078540795408054081540825408354084540855408654087540885408954090540915409254093540945409554096540975409854099541005410154102541035410454105541065410754108541095411054111541125411354114541155411654117541185411954120541215412254123541245412554126541275412854129541305413154132541335413454135541365413754138541395414054141541425414354144541455414654147541485414954150541515415254153541545415554156541575415854159541605416154162541635416454165541665416754168541695417054171541725417354174541755417654177541785417954180541815418254183541845418554186541875418854189541905419154192541935419454195541965419754198541995420054201542025420354204542055420654207542085420954210542115421254213542145421554216542175421854219542205422154222542235422454225542265422754228542295423054231542325423354234542355423654237542385423954240542415424254243542445424554246542475424854249542505425154252542535425454255542565425754258542595426054261542625426354264542655426654267542685426954270542715427254273542745427554276542775427854279542805428154282542835428454285542865428754288542895429054291542925429354294542955429654297542985429954300543015430254303543045430554306543075430854309543105431154312543135431454315543165431754318543195432054321543225432354324543255432654327543285432954330543315433254333543345433554336543375433854339543405434154342543435434454345543465434754348543495435054351543525435354354543555435654357543585435954360543615436254363543645436554366543675436854369543705437154372543735437454375543765437754378543795438054381543825438354384543855438654387543885438954390543915439254393543945439554396543975439854399544005440154402544035440454405544065440754408544095441054411544125441354414544155441654417544185441954420544215442254423544245442554426544275442854429544305443154432544335443454435544365443754438544395444054441544425444354444544455444654447544485444954450544515445254453544545445554456544575445854459544605446154462544635446454465544665446754468544695447054471544725447354474544755447654477544785447954480544815448254483544845448554486544875448854489544905449154492544935449454495544965449754498544995450054501545025450354504545055450654507545085450954510545115451254513545145451554516545175451854519545205452154522545235452454525545265452754528545295453054531545325453354534545355453654537545385453954540545415454254543545445454554546545475454854549545505455154552545535455454555545565455754558545595456054561545625456354564545655456654567545685456954570545715457254573545745457554576545775457854579545805458154582545835458454585545865458754588545895459054591545925459354594545955459654597545985459954600546015460254603546045460554606546075460854609546105461154612546135461454615546165461754618546195462054621546225462354624546255462654627546285462954630546315463254633546345463554636546375463854639546405464154642546435464454645546465464754648546495465054651546525465354654546555465654657546585465954660546615466254663546645466554666546675466854669546705467154672546735467454675546765467754678546795468054681546825468354684546855468654687546885468954690546915469254693546945469554696546975469854699547005470154702547035470454705547065470754708547095471054711547125471354714547155471654717547185471954720547215472254723547245472554726547275472854729547305473154732547335473454735547365473754738547395474054741547425474354744547455474654747547485474954750547515475254753547545475554756547575475854759547605476154762547635476454765547665476754768547695477054771547725477354774547755477654777547785477954780547815478254783547845478554786547875478854789547905479154792547935479454795547965479754798547995480054801548025480354804548055480654807548085480954810548115481254813548145481554816548175481854819548205482154822548235482454825548265482754828548295483054831548325483354834548355483654837548385483954840548415484254843548445484554846548475484854849548505485154852548535485454855548565485754858548595486054861548625486354864548655486654867548685486954870548715487254873548745487554876548775487854879548805488154882548835488454885548865488754888548895489054891548925489354894548955489654897548985489954900549015490254903549045490554906549075490854909549105491154912549135491454915549165491754918549195492054921549225492354924549255492654927549285492954930549315493254933549345493554936549375493854939549405494154942549435494454945549465494754948549495495054951549525495354954549555495654957549585495954960549615496254963549645496554966549675496854969549705497154972549735497454975549765497754978549795498054981549825498354984549855498654987549885498954990549915499254993549945499554996549975499854999550005500155002550035500455005550065500755008550095501055011550125501355014550155501655017550185501955020550215502255023550245502555026550275502855029550305503155032550335503455035550365503755038550395504055041550425504355044550455504655047550485504955050550515505255053550545505555056550575505855059550605506155062550635506455065550665506755068550695507055071550725507355074550755507655077550785507955080550815508255083550845508555086550875508855089550905509155092550935509455095550965509755098550995510055101551025510355104551055510655107551085510955110551115511255113551145511555116551175511855119551205512155122551235512455125551265512755128551295513055131551325513355134551355513655137551385513955140551415514255143551445514555146551475514855149551505515155152551535515455155551565515755158551595516055161551625516355164551655516655167551685516955170551715517255173551745517555176551775517855179551805518155182551835518455185551865518755188551895519055191551925519355194551955519655197551985519955200552015520255203552045520555206552075520855209552105521155212552135521455215552165521755218552195522055221552225522355224552255522655227552285522955230552315523255233552345523555236552375523855239552405524155242552435524455245552465524755248552495525055251552525525355254552555525655257552585525955260552615526255263552645526555266552675526855269552705527155272552735527455275552765527755278552795528055281552825528355284552855528655287552885528955290552915529255293552945529555296552975529855299553005530155302553035530455305553065530755308553095531055311553125531355314553155531655317553185531955320553215532255323553245532555326553275532855329553305533155332553335533455335553365533755338553395534055341553425534355344553455534655347553485534955350553515535255353553545535555356553575535855359553605536155362553635536455365553665536755368553695537055371553725537355374553755537655377553785537955380553815538255383553845538555386553875538855389553905539155392553935539455395553965539755398553995540055401554025540355404554055540655407554085540955410554115541255413554145541555416554175541855419554205542155422554235542455425554265542755428554295543055431554325543355434554355543655437554385543955440554415544255443554445544555446554475544855449554505545155452554535545455455554565545755458554595546055461554625546355464554655546655467554685546955470554715547255473554745547555476554775547855479554805548155482554835548455485554865548755488554895549055491554925549355494554955549655497554985549955500555015550255503555045550555506555075550855509555105551155512555135551455515555165551755518555195552055521555225552355524555255552655527555285552955530555315553255533555345553555536555375553855539555405554155542555435554455545555465554755548555495555055551555525555355554555555555655557555585555955560555615556255563555645556555566555675556855569555705557155572555735557455575555765557755578555795558055581555825558355584555855558655587555885558955590555915559255593555945559555596555975559855599556005560155602556035560455605556065560755608556095561055611556125561355614556155561655617556185561955620556215562255623556245562555626556275562855629556305563155632556335563455635556365563755638556395564055641556425564355644556455564655647556485564955650556515565255653556545565555656556575565855659556605566155662556635566455665556665566755668556695567055671556725567355674556755567655677556785567955680556815568255683556845568555686556875568855689556905569155692556935569455695556965569755698556995570055701557025570355704557055570655707557085570955710557115571255713557145571555716557175571855719557205572155722557235572455725557265572755728557295573055731557325573355734557355573655737557385573955740557415574255743557445574555746557475574855749557505575155752557535575455755557565575755758557595576055761557625576355764557655576655767557685576955770557715577255773557745577555776557775577855779557805578155782557835578455785557865578755788557895579055791557925579355794557955579655797557985579955800558015580255803558045580555806558075580855809558105581155812558135581455815558165581755818558195582055821558225582355824558255582655827558285582955830558315583255833558345583555836558375583855839558405584155842558435584455845558465584755848558495585055851558525585355854558555585655857558585585955860558615586255863558645586555866558675586855869558705587155872558735587455875558765587755878558795588055881558825588355884558855588655887558885588955890558915589255893558945589555896558975589855899559005590155902559035590455905559065590755908559095591055911559125591355914559155591655917559185591955920559215592255923559245592555926559275592855929559305593155932559335593455935559365593755938559395594055941559425594355944559455594655947559485594955950559515595255953559545595555956559575595855959559605596155962559635596455965559665596755968559695597055971559725597355974559755597655977559785597955980559815598255983559845598555986559875598855989559905599155992559935599455995559965599755998559995600056001560025600356004560055600656007560085600956010560115601256013560145601556016560175601856019560205602156022560235602456025560265602756028560295603056031560325603356034560355603656037560385603956040560415604256043560445604556046560475604856049560505605156052560535605456055560565605756058560595606056061560625606356064560655606656067560685606956070560715607256073560745607556076560775607856079560805608156082560835608456085560865608756088560895609056091560925609356094560955609656097560985609956100561015610256103561045610556106561075610856109561105611156112561135611456115561165611756118561195612056121561225612356124561255612656127561285612956130561315613256133561345613556136561375613856139561405614156142561435614456145561465614756148561495615056151561525615356154561555615656157561585615956160561615616256163561645616556166561675616856169561705617156172561735617456175561765617756178561795618056181561825618356184561855618656187561885618956190561915619256193561945619556196561975619856199562005620156202562035620456205562065620756208562095621056211562125621356214562155621656217562185621956220562215622256223562245622556226562275622856229562305623156232562335623456235562365623756238562395624056241562425624356244562455624656247562485624956250562515625256253562545625556256562575625856259562605626156262562635626456265562665626756268562695627056271562725627356274562755627656277562785627956280562815628256283562845628556286562875628856289562905629156292562935629456295562965629756298562995630056301563025630356304563055630656307563085630956310563115631256313563145631556316563175631856319563205632156322563235632456325563265632756328563295633056331563325633356334563355633656337563385633956340563415634256343563445634556346563475634856349563505635156352563535635456355563565635756358563595636056361563625636356364563655636656367563685636956370563715637256373563745637556376563775637856379563805638156382563835638456385563865638756388563895639056391563925639356394563955639656397563985639956400564015640256403564045640556406564075640856409564105641156412564135641456415564165641756418564195642056421564225642356424564255642656427564285642956430564315643256433564345643556436564375643856439564405644156442564435644456445564465644756448564495645056451564525645356454564555645656457564585645956460564615646256463564645646556466564675646856469564705647156472564735647456475564765647756478564795648056481564825648356484564855648656487564885648956490564915649256493564945649556496564975649856499565005650156502565035650456505565065650756508565095651056511565125651356514565155651656517565185651956520565215652256523565245652556526565275652856529565305653156532565335653456535565365653756538565395654056541565425654356544565455654656547565485654956550565515655256553565545655556556565575655856559565605656156562565635656456565565665656756568565695657056571565725657356574565755657656577565785657956580565815658256583565845658556586565875658856589565905659156592565935659456595565965659756598565995660056601566025660356604566055660656607566085660956610566115661256613566145661556616566175661856619566205662156622566235662456625566265662756628566295663056631566325663356634566355663656637566385663956640566415664256643566445664556646566475664856649566505665156652566535665456655566565665756658566595666056661566625666356664566655666656667566685666956670566715667256673566745667556676566775667856679566805668156682566835668456685566865668756688566895669056691566925669356694566955669656697566985669956700567015670256703567045670556706567075670856709567105671156712567135671456715567165671756718567195672056721567225672356724567255672656727567285672956730567315673256733567345673556736567375673856739567405674156742567435674456745567465674756748567495675056751567525675356754567555675656757567585675956760567615676256763567645676556766567675676856769567705677156772567735677456775567765677756778567795678056781567825678356784567855678656787567885678956790567915679256793567945679556796567975679856799568005680156802568035680456805568065680756808568095681056811568125681356814568155681656817568185681956820568215682256823568245682556826568275682856829568305683156832568335683456835568365683756838568395684056841568425684356844568455684656847568485684956850568515685256853568545685556856568575685856859568605686156862568635686456865568665686756868568695687056871568725687356874568755687656877568785687956880568815688256883568845688556886568875688856889568905689156892568935689456895568965689756898568995690056901569025690356904569055690656907569085690956910569115691256913569145691556916569175691856919569205692156922569235692456925569265692756928569295693056931569325693356934569355693656937569385693956940569415694256943569445694556946569475694856949569505695156952569535695456955569565695756958569595696056961569625696356964569655696656967569685696956970569715697256973569745697556976569775697856979569805698156982569835698456985569865698756988569895699056991569925699356994569955699656997569985699957000570015700257003570045700557006570075700857009570105701157012570135701457015570165701757018570195702057021570225702357024570255702657027570285702957030570315703257033570345703557036570375703857039570405704157042570435704457045570465704757048570495705057051570525705357054570555705657057570585705957060570615706257063570645706557066570675706857069570705707157072570735707457075570765707757078570795708057081570825708357084570855708657087570885708957090570915709257093570945709557096570975709857099571005710157102571035710457105571065710757108571095711057111571125711357114571155711657117571185711957120571215712257123571245712557126571275712857129571305713157132571335713457135571365713757138571395714057141571425714357144571455714657147571485714957150571515715257153571545715557156571575715857159571605716157162571635716457165571665716757168571695717057171571725717357174571755717657177571785717957180571815718257183571845718557186571875718857189571905719157192571935719457195571965719757198571995720057201572025720357204572055720657207572085720957210572115721257213572145721557216572175721857219572205722157222572235722457225572265722757228572295723057231572325723357234572355723657237572385723957240572415724257243572445724557246572475724857249572505725157252572535725457255572565725757258572595726057261572625726357264572655726657267572685726957270572715727257273572745727557276572775727857279572805728157282572835728457285572865728757288572895729057291572925729357294572955729657297572985729957300573015730257303573045730557306573075730857309573105731157312573135731457315573165731757318573195732057321573225732357324573255732657327573285732957330573315733257333573345733557336573375733857339573405734157342573435734457345573465734757348573495735057351573525735357354573555735657357573585735957360573615736257363573645736557366573675736857369573705737157372573735737457375573765737757378573795738057381573825738357384573855738657387573885738957390573915739257393573945739557396573975739857399574005740157402574035740457405574065740757408574095741057411574125741357414574155741657417574185741957420574215742257423574245742557426574275742857429574305743157432574335743457435574365743757438574395744057441574425744357444574455744657447574485744957450574515745257453574545745557456574575745857459574605746157462574635746457465574665746757468574695747057471574725747357474574755747657477574785747957480574815748257483574845748557486574875748857489574905749157492574935749457495574965749757498574995750057501575025750357504575055750657507575085750957510575115751257513575145751557516575175751857519575205752157522575235752457525575265752757528575295753057531575325753357534575355753657537575385753957540575415754257543575445754557546575475754857549575505755157552575535755457555575565755757558575595756057561575625756357564575655756657567575685756957570575715757257573575745757557576575775757857579575805758157582575835758457585575865758757588575895759057591575925759357594575955759657597575985759957600576015760257603576045760557606576075760857609576105761157612576135761457615576165761757618576195762057621576225762357624576255762657627576285762957630576315763257633576345763557636576375763857639576405764157642576435764457645576465764757648576495765057651576525765357654576555765657657576585765957660576615766257663576645766557666576675766857669576705767157672576735767457675576765767757678576795768057681576825768357684576855768657687576885768957690576915769257693576945769557696576975769857699577005770157702577035770457705577065770757708577095771057711577125771357714577155771657717577185771957720577215772257723577245772557726577275772857729577305773157732577335773457735577365773757738577395774057741577425774357744577455774657747577485774957750577515775257753577545775557756577575775857759577605776157762577635776457765577665776757768577695777057771577725777357774577755777657777577785777957780577815778257783577845778557786577875778857789577905779157792577935779457795577965779757798577995780057801578025780357804578055780657807578085780957810578115781257813578145781557816578175781857819578205782157822578235782457825578265782757828578295783057831578325783357834578355783657837578385783957840578415784257843578445784557846578475784857849578505785157852578535785457855578565785757858578595786057861578625786357864578655786657867578685786957870578715787257873578745787557876578775787857879578805788157882578835788457885578865788757888578895789057891578925789357894578955789657897578985789957900579015790257903579045790557906579075790857909579105791157912579135791457915579165791757918579195792057921579225792357924579255792657927579285792957930579315793257933579345793557936579375793857939579405794157942579435794457945579465794757948579495795057951579525795357954579555795657957579585795957960579615796257963579645796557966579675796857969579705797157972579735797457975579765797757978579795798057981579825798357984579855798657987579885798957990579915799257993579945799557996579975799857999580005800158002580035800458005580065800758008580095801058011580125801358014580155801658017580185801958020580215802258023580245802558026580275802858029580305803158032580335803458035580365803758038580395804058041580425804358044580455804658047580485804958050580515805258053580545805558056580575805858059580605806158062580635806458065580665806758068580695807058071580725807358074580755807658077580785807958080580815808258083580845808558086580875808858089580905809158092580935809458095580965809758098580995810058101581025810358104581055810658107581085810958110581115811258113581145811558116581175811858119581205812158122581235812458125581265812758128581295813058131581325813358134581355813658137581385813958140581415814258143581445814558146581475814858149581505815158152581535815458155581565815758158581595816058161581625816358164581655816658167581685816958170581715817258173581745817558176581775817858179581805818158182581835818458185581865818758188581895819058191581925819358194581955819658197581985819958200582015820258203582045820558206582075820858209582105821158212582135821458215582165821758218582195822058221582225822358224582255822658227582285822958230582315823258233582345823558236582375823858239582405824158242582435824458245582465824758248582495825058251582525825358254582555825658257582585825958260582615826258263582645826558266582675826858269582705827158272582735827458275582765827758278582795828058281582825828358284582855828658287582885828958290582915829258293582945829558296582975829858299583005830158302583035830458305583065830758308583095831058311583125831358314583155831658317583185831958320583215832258323583245832558326583275832858329583305833158332583335833458335583365833758338583395834058341583425834358344583455834658347583485834958350583515835258353583545835558356583575835858359583605836158362583635836458365583665836758368583695837058371583725837358374583755837658377583785837958380583815838258383583845838558386583875838858389583905839158392583935839458395583965839758398583995840058401584025840358404584055840658407584085840958410584115841258413584145841558416584175841858419584205842158422584235842458425584265842758428584295843058431584325843358434584355843658437584385843958440584415844258443584445844558446584475844858449584505845158452584535845458455584565845758458584595846058461584625846358464584655846658467584685846958470584715847258473584745847558476584775847858479584805848158482584835848458485584865848758488584895849058491584925849358494584955849658497584985849958500585015850258503585045850558506585075850858509585105851158512585135851458515585165851758518585195852058521585225852358524585255852658527585285852958530585315853258533585345853558536585375853858539585405854158542585435854458545585465854758548585495855058551585525855358554585555855658557585585855958560585615856258563585645856558566585675856858569585705857158572585735857458575585765857758578585795858058581585825858358584585855858658587585885858958590585915859258593585945859558596585975859858599586005860158602586035860458605586065860758608586095861058611586125861358614586155861658617586185861958620586215862258623586245862558626586275862858629586305863158632586335863458635586365863758638586395864058641586425864358644586455864658647586485864958650586515865258653586545865558656586575865858659586605866158662586635866458665586665866758668586695867058671586725867358674586755867658677586785867958680586815868258683586845868558686586875868858689586905869158692586935869458695586965869758698586995870058701587025870358704587055870658707587085870958710587115871258713587145871558716587175871858719587205872158722587235872458725587265872758728587295873058731587325873358734587355873658737587385873958740587415874258743587445874558746587475874858749587505875158752587535875458755587565875758758587595876058761587625876358764587655876658767587685876958770587715877258773587745877558776587775877858779587805878158782587835878458785587865878758788587895879058791587925879358794587955879658797587985879958800588015880258803588045880558806588075880858809588105881158812588135881458815588165881758818588195882058821588225882358824588255882658827588285882958830588315883258833588345883558836588375883858839588405884158842588435884458845588465884758848588495885058851588525885358854588555885658857588585885958860588615886258863588645886558866588675886858869588705887158872588735887458875588765887758878588795888058881588825888358884588855888658887588885888958890588915889258893588945889558896588975889858899589005890158902589035890458905589065890758908589095891058911589125891358914589155891658917589185891958920589215892258923589245892558926589275892858929589305893158932589335893458935589365893758938589395894058941589425894358944589455894658947589485894958950589515895258953589545895558956589575895858959589605896158962589635896458965589665896758968589695897058971589725897358974589755897658977589785897958980589815898258983589845898558986589875898858989589905899158992589935899458995589965899758998589995900059001590025900359004590055900659007590085900959010590115901259013590145901559016590175901859019590205902159022590235902459025590265902759028590295903059031590325903359034590355903659037590385903959040590415904259043590445904559046590475904859049590505905159052590535905459055590565905759058590595906059061590625906359064590655906659067590685906959070590715907259073590745907559076590775907859079590805908159082590835908459085590865908759088590895909059091590925909359094590955909659097590985909959100591015910259103591045910559106591075910859109591105911159112591135911459115591165911759118591195912059121591225912359124591255912659127591285912959130591315913259133591345913559136591375913859139591405914159142591435914459145591465914759148591495915059151591525915359154591555915659157591585915959160591615916259163591645916559166591675916859169591705917159172591735917459175591765917759178591795918059181591825918359184591855918659187591885918959190591915919259193591945919559196591975919859199592005920159202592035920459205592065920759208592095921059211592125921359214592155921659217592185921959220592215922259223592245922559226592275922859229592305923159232592335923459235592365923759238592395924059241592425924359244592455924659247592485924959250592515925259253592545925559256592575925859259592605926159262592635926459265592665926759268592695927059271592725927359274592755927659277592785927959280592815928259283592845928559286592875928859289592905929159292592935929459295592965929759298592995930059301593025930359304593055930659307593085930959310593115931259313593145931559316593175931859319593205932159322593235932459325593265932759328593295933059331593325933359334593355933659337593385933959340593415934259343593445934559346593475934859349593505935159352593535935459355593565935759358593595936059361593625936359364593655936659367593685936959370593715937259373593745937559376593775937859379593805938159382593835938459385593865938759388593895939059391593925939359394593955939659397593985939959400594015940259403594045940559406594075940859409594105941159412594135941459415594165941759418594195942059421594225942359424594255942659427594285942959430594315943259433594345943559436594375943859439594405944159442594435944459445594465944759448594495945059451594525945359454594555945659457594585945959460594615946259463594645946559466594675946859469594705947159472594735947459475594765947759478594795948059481594825948359484594855948659487594885948959490594915949259493594945949559496594975949859499595005950159502595035950459505595065950759508595095951059511595125951359514595155951659517595185951959520595215952259523595245952559526595275952859529595305953159532595335953459535595365953759538595395954059541595425954359544595455954659547595485954959550595515955259553595545955559556595575955859559595605956159562595635956459565595665956759568595695957059571595725957359574595755957659577595785957959580595815958259583595845958559586595875958859589595905959159592595935959459595595965959759598595995960059601596025960359604596055960659607596085960959610596115961259613596145961559616596175961859619596205962159622596235962459625596265962759628596295963059631596325963359634596355963659637596385963959640596415964259643596445964559646596475964859649596505965159652596535965459655596565965759658596595966059661596625966359664596655966659667596685966959670596715967259673596745967559676596775967859679596805968159682596835968459685596865968759688596895969059691596925969359694596955969659697596985969959700597015970259703597045970559706597075970859709597105971159712597135971459715597165971759718597195972059721597225972359724597255972659727597285972959730597315973259733597345973559736597375973859739597405974159742597435974459745597465974759748597495975059751597525975359754597555975659757597585975959760597615976259763597645976559766597675976859769597705977159772597735977459775597765977759778597795978059781597825978359784597855978659787597885978959790597915979259793597945979559796597975979859799598005980159802598035980459805598065980759808598095981059811598125981359814598155981659817598185981959820598215982259823598245982559826598275982859829598305983159832598335983459835598365983759838598395984059841598425984359844598455984659847598485984959850598515985259853598545985559856598575985859859598605986159862598635986459865598665986759868598695987059871598725987359874598755987659877598785987959880598815988259883598845988559886598875988859889598905989159892598935989459895598965989759898598995990059901599025990359904599055990659907599085990959910599115991259913599145991559916599175991859919599205992159922599235992459925599265992759928599295993059931599325993359934599355993659937599385993959940599415994259943599445994559946599475994859949599505995159952599535995459955599565995759958599595996059961599625996359964599655996659967599685996959970599715997259973599745997559976599775997859979599805998159982599835998459985599865998759988599895999059991599925999359994599955999659997599985999960000600016000260003600046000560006600076000860009600106001160012600136001460015600166001760018600196002060021600226002360024600256002660027600286002960030600316003260033600346003560036600376003860039600406004160042600436004460045600466004760048600496005060051600526005360054600556005660057600586005960060600616006260063600646006560066600676006860069600706007160072600736007460075600766007760078600796008060081600826008360084600856008660087600886008960090600916009260093600946009560096600976009860099601006010160102601036010460105601066010760108601096011060111601126011360114601156011660117601186011960120601216012260123601246012560126601276012860129601306013160132601336013460135601366013760138601396014060141601426014360144601456014660147601486014960150601516015260153601546015560156601576015860159601606016160162601636016460165601666016760168601696017060171601726017360174601756017660177601786017960180601816018260183601846018560186601876018860189601906019160192601936019460195601966019760198601996020060201602026020360204602056020660207602086020960210602116021260213602146021560216602176021860219602206022160222602236022460225602266022760228602296023060231602326023360234602356023660237602386023960240602416024260243602446024560246602476024860249602506025160252602536025460255602566025760258602596026060261602626026360264602656026660267602686026960270602716027260273602746027560276602776027860279602806028160282602836028460285602866028760288602896029060291602926029360294602956029660297602986029960300603016030260303603046030560306603076030860309603106031160312603136031460315603166031760318603196032060321603226032360324603256032660327603286032960330603316033260333603346033560336603376033860339603406034160342603436034460345603466034760348603496035060351603526035360354603556035660357603586035960360603616036260363603646036560366603676036860369603706037160372603736037460375603766037760378603796038060381603826038360384603856038660387603886038960390603916039260393603946039560396603976039860399604006040160402604036040460405604066040760408604096041060411604126041360414604156041660417604186041960420604216042260423604246042560426604276042860429604306043160432604336043460435604366043760438604396044060441604426044360444604456044660447604486044960450604516045260453604546045560456604576045860459604606046160462604636046460465604666046760468604696047060471604726047360474604756047660477604786047960480604816048260483604846048560486604876048860489604906049160492604936049460495604966049760498604996050060501605026050360504605056050660507605086050960510605116051260513605146051560516605176051860519605206052160522605236052460525605266052760528605296053060531605326053360534605356053660537605386053960540605416054260543605446054560546605476054860549605506055160552605536055460555605566055760558605596056060561605626056360564605656056660567605686056960570605716057260573605746057560576605776057860579605806058160582605836058460585605866058760588605896059060591605926059360594605956059660597605986059960600606016060260603606046060560606606076060860609606106061160612606136061460615606166061760618606196062060621606226062360624606256062660627606286062960630606316063260633606346063560636606376063860639606406064160642606436064460645606466064760648606496065060651606526065360654606556065660657606586065960660606616066260663606646066560666606676066860669606706067160672606736067460675606766067760678606796068060681606826068360684606856068660687606886068960690606916069260693606946069560696606976069860699607006070160702607036070460705607066070760708607096071060711607126071360714607156071660717607186071960720607216072260723607246072560726607276072860729607306073160732607336073460735607366073760738607396074060741607426074360744607456074660747607486074960750607516075260753607546075560756607576075860759607606076160762607636076460765607666076760768607696077060771607726077360774607756077660777607786077960780607816078260783607846078560786607876078860789607906079160792607936079460795607966079760798607996080060801608026080360804608056080660807608086080960810608116081260813608146081560816608176081860819608206082160822608236082460825608266082760828608296083060831608326083360834608356083660837608386083960840608416084260843608446084560846608476084860849608506085160852608536085460855608566085760858608596086060861608626086360864608656086660867608686086960870608716087260873608746087560876608776087860879608806088160882608836088460885608866088760888608896089060891608926089360894608956089660897608986089960900609016090260903609046090560906609076090860909609106091160912609136091460915609166091760918609196092060921609226092360924609256092660927609286092960930609316093260933609346093560936609376093860939609406094160942609436094460945609466094760948609496095060951609526095360954609556095660957609586095960960609616096260963609646096560966609676096860969609706097160972609736097460975609766097760978609796098060981609826098360984609856098660987609886098960990609916099260993609946099560996609976099860999610006100161002610036100461005610066100761008610096101061011610126101361014610156101661017610186101961020610216102261023610246102561026610276102861029610306103161032610336103461035610366103761038610396104061041610426104361044610456104661047610486104961050610516105261053610546105561056610576105861059610606106161062610636106461065610666106761068610696107061071610726107361074610756107661077610786107961080610816108261083610846108561086610876108861089610906109161092610936109461095610966109761098610996110061101611026110361104611056110661107611086110961110611116111261113611146111561116611176111861119611206112161122611236112461125611266112761128611296113061131611326113361134611356113661137611386113961140611416114261143611446114561146611476114861149611506115161152611536115461155611566115761158611596116061161611626116361164611656116661167611686116961170611716117261173611746117561176611776117861179611806118161182611836118461185611866118761188611896119061191611926119361194611956119661197611986119961200612016120261203612046120561206612076120861209612106121161212612136121461215612166121761218612196122061221612226122361224612256122661227612286122961230612316123261233612346123561236612376123861239612406124161242612436124461245612466124761248612496125061251612526125361254612556125661257612586125961260612616126261263612646126561266612676126861269612706127161272612736127461275612766127761278612796128061281612826128361284612856128661287612886128961290612916129261293612946129561296612976129861299613006130161302613036130461305613066130761308613096131061311613126131361314613156131661317613186131961320613216132261323613246132561326613276132861329613306133161332613336133461335613366133761338613396134061341613426134361344613456134661347613486134961350613516135261353613546135561356613576135861359613606136161362613636136461365613666136761368613696137061371613726137361374613756137661377613786137961380613816138261383613846138561386613876138861389613906139161392613936139461395613966139761398613996140061401614026140361404614056140661407614086140961410614116141261413614146141561416614176141861419614206142161422614236142461425614266142761428614296143061431614326143361434614356143661437614386143961440614416144261443614446144561446614476144861449614506145161452614536145461455614566145761458614596146061461614626146361464614656146661467614686146961470614716147261473614746147561476614776147861479614806148161482614836148461485614866148761488614896149061491614926149361494614956149661497614986149961500615016150261503615046150561506615076150861509615106151161512615136151461515615166151761518615196152061521615226152361524615256152661527615286152961530615316153261533615346153561536615376153861539615406154161542615436154461545615466154761548615496155061551615526155361554615556155661557615586155961560615616156261563615646156561566615676156861569615706157161572615736157461575615766157761578615796158061581615826158361584615856158661587615886158961590615916159261593615946159561596615976159861599616006160161602616036160461605616066160761608616096161061611616126161361614616156161661617616186161961620616216162261623616246162561626616276162861629616306163161632616336163461635616366163761638616396164061641616426164361644616456164661647616486164961650616516165261653616546165561656616576165861659616606166161662616636166461665616666166761668616696167061671616726167361674616756167661677616786167961680616816168261683616846168561686616876168861689616906169161692616936169461695616966169761698616996170061701617026170361704617056170661707617086170961710617116171261713617146171561716617176171861719617206172161722617236172461725617266172761728617296173061731617326173361734617356173661737617386173961740617416174261743617446174561746617476174861749617506175161752617536175461755617566175761758617596176061761617626176361764617656176661767617686176961770617716177261773617746177561776617776177861779617806178161782617836178461785617866178761788617896179061791617926179361794617956179661797617986179961800618016180261803618046180561806618076180861809618106181161812618136181461815618166181761818618196182061821618226182361824618256182661827618286182961830618316183261833618346183561836618376183861839618406184161842618436184461845618466184761848618496185061851618526185361854618556185661857618586185961860618616186261863618646186561866618676186861869618706187161872618736187461875618766187761878618796188061881618826188361884618856188661887618886188961890618916189261893618946189561896618976189861899619006190161902619036190461905619066190761908619096191061911619126191361914619156191661917619186191961920619216192261923619246192561926619276192861929619306193161932619336193461935619366193761938619396194061941619426194361944619456194661947619486194961950619516195261953619546195561956619576195861959619606196161962619636196461965619666196761968619696197061971619726197361974619756197661977619786197961980619816198261983619846198561986619876198861989619906199161992619936199461995619966199761998619996200062001620026200362004620056200662007620086200962010620116201262013620146201562016620176201862019620206202162022620236202462025620266202762028620296203062031620326203362034620356203662037620386203962040620416204262043620446204562046620476204862049620506205162052620536205462055620566205762058620596206062061620626206362064620656206662067620686206962070620716207262073620746207562076620776207862079620806208162082620836208462085620866208762088620896209062091620926209362094620956209662097620986209962100621016210262103621046210562106621076210862109621106211162112621136211462115621166211762118621196212062121621226212362124621256212662127621286212962130621316213262133621346213562136621376213862139621406214162142621436214462145621466214762148621496215062151621526215362154621556215662157621586215962160621616216262163621646216562166621676216862169621706217162172621736217462175621766217762178621796218062181621826218362184621856218662187621886218962190621916219262193621946219562196621976219862199622006220162202622036220462205622066220762208622096221062211622126221362214622156221662217622186221962220622216222262223622246222562226622276222862229622306223162232622336223462235622366223762238622396224062241622426224362244622456224662247622486224962250622516225262253622546225562256622576225862259622606226162262622636226462265622666226762268622696227062271622726227362274622756227662277622786227962280622816228262283622846228562286622876228862289622906229162292622936229462295622966229762298622996230062301623026230362304623056230662307623086230962310623116231262313623146231562316623176231862319623206232162322623236232462325623266232762328623296233062331623326233362334623356233662337623386233962340623416234262343623446234562346623476234862349623506235162352623536235462355623566235762358623596236062361623626236362364623656236662367623686236962370623716237262373623746237562376623776237862379623806238162382623836238462385623866238762388623896239062391623926239362394623956239662397623986239962400624016240262403624046240562406624076240862409624106241162412624136241462415624166241762418624196242062421624226242362424624256242662427624286242962430624316243262433624346243562436624376243862439624406244162442624436244462445624466244762448624496245062451624526245362454624556245662457624586245962460624616246262463624646246562466624676246862469624706247162472624736247462475624766247762478624796248062481624826248362484624856248662487624886248962490624916249262493624946249562496624976249862499625006250162502625036250462505625066250762508625096251062511625126251362514625156251662517625186251962520625216252262523625246252562526625276252862529625306253162532625336253462535625366253762538625396254062541625426254362544625456254662547625486254962550625516255262553625546255562556625576255862559625606256162562625636256462565625666256762568625696257062571625726257362574625756257662577625786257962580625816258262583625846258562586625876258862589625906259162592625936259462595625966259762598625996260062601626026260362604626056260662607626086260962610626116261262613626146261562616626176261862619626206262162622626236262462625626266262762628626296263062631626326263362634626356263662637626386263962640626416264262643626446264562646626476264862649626506265162652626536265462655626566265762658626596266062661626626266362664626656266662667626686266962670626716267262673626746267562676626776267862679626806268162682626836268462685626866268762688626896269062691626926269362694626956269662697626986269962700627016270262703 | (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.XlsxPopulate = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){"use strict";var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var _ = require("lodash");var xmlq = require("./xmlq");var ArgHandler = require("./ArgHandler");/** * App properties * @ignore */var AppProperties = function () {    /**     * Creates a new instance of AppProperties     * @param {{}} node - The node.     */    function AppProperties(node) {        _classCallCheck(this, AppProperties);        this._node = node;    }    _createClass(AppProperties, [{        key: "isSecure",        value: function isSecure(value) {            var _this = this;            return new ArgHandler("Range.formula").case(function () {                var docSecurityNode = xmlq.findChild(_this._node, "DocSecurity");                if (!docSecurityNode) return false;                return docSecurityNode.children[0] === 1;            }).case('boolean', function (value) {                var docSecurityNode = xmlq.appendChildIfNotFound(_this._node, "DocSecurity");                docSecurityNode.children = [value ? 1 : 0];                return _this;            }).handle(arguments);        }        /**         * Convert the collection to an XML object.         * @returns {{}} The XML.         */    }, {        key: "toXml",        value: function toXml() {            return this._node;        }    }]);    return AppProperties;}();module.exports = AppProperties;/*docProps/app.xml<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">    <Application>Microsoft Excel</Application><DocSecurity>1</DocSecurity><ScaleCrop>false</ScaleCrop><HeadingPairs><vt:vector size="2" baseType="variant">    <vt:variant><vt:lpstr>Worksheets</vt:lpstr></vt:variant><vt:variant><vt:i4>1</vt:i4></vt:variant></vt:vector></HeadingPairs><TitlesOfParts><vt:vector size="1" baseType="lpstr">    <vt:lpstr>Sheet1</vt:lpstr></vt:vector></TitlesOfParts><Company/><LinksUpToDate>false</LinksUpToDate><SharedDoc>false</SharedDoc><HyperlinksChanged>false</HyperlinksChanged><AppVersion>16.0300</AppVersion></Properties> */},{"./ArgHandler":2,"./xmlq":29,"lodash":193}],2:[function(require,module,exports){"use strict";var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var _ = require("lodash");/** * Method argument handler. Used for overloading methods. * @private */var ArgHandler = function () {    /**     * Creates a new instance of ArgHandler.     * @param {string} name - The method name to use in error messages.     */    function ArgHandler(name) {        _classCallCheck(this, ArgHandler);        this._name = name;        this._cases = [];    }    /**     * Add a case.     * @param {string|Array.<string>} [types] - The type or types of arguments to match this case.     * @param {Function} handler - The function to call when this case is matched.     * @returns {ArgHandler} The handler for chaining.     */    _createClass(ArgHandler, [{        key: "case",        value: function _case(types, handler) {            if (arguments.length === 1) {                handler = types;                types = [];            }            if (!Array.isArray(types)) types = [types];            this._cases.push({ types: types, handler: handler });            return this;        }        /**         * Handle the method arguments by checking each case in order until one matches and then call its handler.         * @param {Arguments|Array.<*>} args - The method arguments.         * @returns {*} The result of the handler.         * @throws {Error} Throws if no case matches.         */    }, {        key: "handle",        value: function handle(args) {            for (var i = 0; i < this._cases.length; i++) {                var c = this._cases[i];                if (this._argsMatchTypes(args, c.types)) {                    return c.handler.apply(null, args);                }            }            throw new Error(this._name + ": Invalid arguments.");        }        /**         * Check if the arguments match the given types.         * @param {Arguments} args - The arguments.         * @param {Array.<string>} types - The types.         * @returns {boolean} True if matches, false otherwise.         * @throws {Error} Throws if unknown type.         * @private         */    }, {        key: "_argsMatchTypes",        value: function _argsMatchTypes(args, types) {            if (args.length !== types.length) return false;            return _.every(args, function (arg, i) {                var type = types[i];                if (type === '*') return true;                if (type === 'nil') return _.isNil(arg);                if (type === 'string') return typeof arg === "string";                if (type === 'boolean') return typeof arg === "boolean";                if (type === 'number') return typeof arg === "number";                if (type === 'integer') return typeof arg === "number" && _.isInteger(arg);                if (type === 'function') return typeof arg === "function";                if (type === 'array') return Array.isArray(arg);                if (type === 'date') return arg && arg.constructor === Date;                if (type === 'object') return arg && arg.constructor === Object;                if (arg && arg.constructor && arg.constructor.name === type) return true;                throw new Error("Unknown type: " + type);            });        }    }]);    return ArgHandler;}();module.exports = ArgHandler;},{"lodash":193}],3:[function(require,module,exports){"use strict";var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var _ = require("lodash");var ArgHandler = require("./ArgHandler");var addressConverter = require("./addressConverter");var dateConverter = require("./dateConverter");var regexify = require("./regexify");var xmlq = require("./xmlq");var FormulaError = require("./FormulaError");var Style = require("./Style");var RichText = require("./RichText");/** * A cell */var Cell = function () {    // /**    //  * Creates a new instance of cell.    //  * @param {Row} row - The parent row.    //  * @param {{}} node - The cell node.    //  */    function Cell(row, node, styleId) {        _classCallCheck(this, Cell);        this._row = row;        this._init(node, styleId);    }    /* PUBLIC */    /**     * Gets a value indicating whether the cell is the active cell in the sheet.     * @returns {boolean} True if active, false otherwise.     */ /**        * Make the cell the active cell in the sheet.        * @param {boolean} active - Must be set to `true`. Deactivating directly is not supported. To deactivate, you should activate a different cell instead.        * @returns {Cell} The cell.        */    _createClass(Cell, [{        key: "active",        value: function active() {            var _this = this;            return new ArgHandler('Cell.active').case(function () {                return _this.sheet().activeCell() === _this;            }).case('boolean', function (active) {                if (!active) throw new Error("Deactivating cell directly not supported. Activate a different cell instead.");                _this.sheet().activeCell(_this);                return _this;            }).handle(arguments);        }        /**         * Get the address of the column.         * @param {{}} [opts] - Options         * @param {boolean} [opts.includeSheetName] - Include the sheet name in the address.         * @param {boolean} [opts.rowAnchored] - Anchor the row.         * @param {boolean} [opts.columnAnchored] - Anchor the column.         * @param {boolean} [opts.anchored] - Anchor both the row and the column.         * @returns {string} The address         */    }, {        key: "address",        value: function address(opts) {            return addressConverter.toAddress({                type: 'cell',                rowNumber: this.rowNumber(),                columnNumber: this.columnNumber(),                sheetName: opts && opts.includeSheetName && this.sheet().name(),                rowAnchored: opts && (opts.rowAnchored || opts.anchored),                columnAnchored: opts && (opts.columnAnchored || opts.anchored)            });        }        /**         * Gets the parent column of the cell.         * @returns {Column} The parent column.         */    }, {        key: "column",        value: function column() {            return this.sheet().column(this.columnNumber());        }        /**         * Clears the contents from the cell.         * @returns {Cell} The cell.         */    }, {        key: "clear",        value: function clear() {            var hostSharedFormulaId = this._formulaRef && this._sharedFormulaId;            delete this._value;            delete this._formulaType;            delete this._formula;            delete this._sharedFormulaId;            delete this._formulaRef;            // TODO in future version: Move shared formula to some other cell. This would require parsing the formula...            if (!_.isNil(hostSharedFormulaId)) this.sheet().clearCellsUsingSharedFormula(hostSharedFormulaId);            return this;        }        /**         * Gets the column name of the cell.         * @returns {string} The column name.         */    }, {        key: "columnName",        value: function columnName() {            return addressConverter.columnNumberToName(this.columnNumber());        }        /**         * Gets the column number of the cell (1-based).         * @returns {number} The column number.         */    }, {        key: "columnNumber",        value: function columnNumber() {            return this._columnNumber;        }        /**         * Find the given pattern in the cell and optionally replace it.         * @param {string|RegExp} pattern - The pattern to look for. Providing a string will result in a case-insensitive substring search. Use a RegExp for more sophisticated searches.         * @param {string|function} [replacement] - The text to replace or a String.replace callback function. If pattern is a string, all occurrences of the pattern in the cell will be replaced.         * @returns {boolean} A flag indicating if the pattern was found.         */    }, {        key: "find",        value: function find(pattern, replacement) {            pattern = regexify(pattern);            var value = this.value();            if (typeof value !== 'string') return false;            if (_.isNil(replacement)) {                return pattern.test(value);            } else {                var replaced = value.replace(pattern, replacement);                if (replaced === value) return false;                this.value(replaced);                return true;            }        }        /**         * Gets the formula in the cell. Note that if a formula was set as part of a range, the getter will return 'SHARED'. This is a limitation that may be addressed in a future release.         * @returns {string} The formula in the cell.         */ /**            * Sets the formula in the cell.            * @param {string} formula - The formula to set.            * @returns {Cell} The cell.            */    }, {        key: "formula",        value: function formula() {            var _this2 = this;            return new ArgHandler('Cell.formula').case(function () {                // TODO in future: Return translated formula.                if (_this2._formulaType === "shared" && !_this2._formulaRef) return "SHARED";                return _this2._formula;            }).case('nil', function () {                _this2.clear();                return _this2;            }).case('string', function (formula) {                _this2.clear();                _this2._formulaType = "normal";                _this2._formula = formula;                return _this2;            }).handle(arguments);        }        /**         * Gets the hyperlink attached to the cell.         * @returns {string|undefined} The hyperlink or undefined if not set.         */ /**            * Set or clear the hyperlink on the cell.            * @param {string|Cell|undefined} hyperlink - The hyperlink to set or undefined to clear.            * @returns {Cell} The cell.            */ /**               * Set the hyperlink options on the cell.               * @param {{}|Cell} opts - Options or Cell. If opts is a Cell then an internal hyperlink is added.               * @param {string|Cell} [opts.hyperlink] - The hyperlink to set, can be a Cell or an internal/external string.               * @param {string} [opts.tooltip] - Additional text to help the user understand more about the hyperlink.               * @param {string} [opts.email] - Email address, ignored if opts.hyperlink is set.               * @param {string} [opts.emailSubject] - Email subject, ignored if opts.hyperlink is set.               * @returns {Cell} The cell.               */    }, {        key: "hyperlink",        value: function hyperlink() {            var _this3 = this;            return new ArgHandler('Cell.hyperlink').case(function () {                return _this3.sheet().hyperlink(_this3.address());            }).case('string', function (hyperlink) {                _this3.sheet().hyperlink(_this3.address(), hyperlink);                return _this3;            }).case(['object'], function (opts) {                _this3.sheet().hyperlink(_this3.address(), opts);                return _this3;            }).handle(arguments);        }        /**         * Gets the data validation object attached to the cell.         * @returns {object|undefined} The data validation or undefined if not set.         */ /**            * Set or clear the data validation object of the cell.            * @param {object|undefined} dataValidation - Object or null to clear.            * @returns {Cell} The cell.            */    }, {        key: "dataValidation",        value: function dataValidation() {            var _this4 = this;            return new ArgHandler('Cell.dataValidation').case(function () {                return _this4.sheet().dataValidation(_this4.address());            }).case('boolean', function (obj) {                return _this4.sheet().dataValidation(_this4.address(), obj);            }).case('*', function (obj) {                _this4.sheet().dataValidation(_this4.address(), obj);                return _this4;            }).handle(arguments);        }        /**         * Callback used by tap.         * @callback Cell~tapCallback         * @param {Cell} cell - The cell         * @returns {undefined}         */ /**            * Invoke a callback on the cell and return the cell. Useful for method chaining.            * @param {Cell~tapCallback} callback - The callback function.            * @returns {Cell} The cell.            */    }, {        key: "tap",        value: function tap(callback) {            callback(this);            return this;        }        /**         * Callback used by thru.         * @callback Cell~thruCallback         * @param {Cell} cell - The cell         * @returns {*} The value to return from thru.         */ /**            * Invoke a callback on the cell and return the value provided by the callback. Useful for method chaining.            * @param {Cell~thruCallback} callback - The callback function.            * @returns {*} The return value of the callback.            */    }, {        key: "thru",        value: function thru(callback) {            return callback(this);        }        /**         * Create a range from this cell and another.         * @param {Cell|string} cell - The other cell or cell address to range to.         * @returns {Range} The range.         */    }, {        key: "rangeTo",        value: function rangeTo(cell) {            return this.sheet().range(this, cell);        }        /**         * Returns a cell with a relative position given the offsets provided.         * @param {number} rowOffset - The row offset (0 for the current row).         * @param {number} columnOffset - The column offset (0 for the current column).         * @returns {Cell} The relative cell.         */    }, {        key: "relativeCell",        value: function relativeCell(rowOffset, columnOffset) {            var row = rowOffset + this.rowNumber();            var column = columnOffset + this.columnNumber();            return this.sheet().cell(row, column);        }        /**         * Gets the parent row of the cell.         * @returns {Row} The parent row.         */    }, {        key: "row",        value: function row() {            return this._row;        }        /**         * Gets the row number of the cell (1-based).         * @returns {number} The row number.         */    }, {        key: "rowNumber",        value: function rowNumber() {            return this.row().rowNumber();        }        /**         * Gets the parent sheet.         * @returns {Sheet} The parent sheet.         */    }, {        key: "sheet",        value: function sheet() {            return this.row().sheet();        }        /**         * Gets an individual style.         * @param {string} name - The name of the style.         * @returns {*} The style.         */ /**            * Gets multiple styles.            * @param {Array.<string>} names - The names of the style.            * @returns {object.<string, *>} Object whose keys are the style names and values are the styles.            */ /**               * Sets an individual style.               * @param {string} name - The name of the style.               * @param {*} value - The value to set.               * @returns {Cell} The cell.               */ /**                  * Sets the styles in the range starting with the cell.                  * @param {string} name - The name of the style.                  * @param {Array.<Array.<*>>} - 2D array of values to set.                  * @returns {Range} The range that was set.                  */ /**                     * Sets multiple styles.                     * @param {object.<string, *>} styles - Object whose keys are the style names and values are the styles to set.                     * @returns {Cell} The cell.                     */ /**                        * Sets to a specific style                        * @param {Style} style - Style object given from stylesheet.createStyle                        * @returns {Cell} The cell.                        */    }, {        key: "style",        value: function style() {            var _this5 = this;            if (!this._style && !(arguments[0] instanceof Style)) {                this._style = this.workbook().styleSheet().createStyle(this._styleId);            }            return new ArgHandler("Cell.style").case('string', function (name) {                // Get single value                return _this5._style.style(name);            }).case('array', function (names) {                // Get list of values                var values = {};                names.forEach(function (name) {                    values[name] = _this5.style(name);                });                return values;            }).case(["string", "array"], function (name, values) {                var numRows = values.length;                var numCols = values[0].length;                var range = _this5.rangeTo(_this5.relativeCell(numRows - 1, numCols - 1));                return range.style(name, values);            }).case(['string', '*'], function (name, value) {                // Set a single value for all cells to a single value                _this5._style.style(name, value);                return _this5;            }).case('object', function (nameValues) {                // Object of key value pairs to set                for (var name in nameValues) {                    if (!nameValues.hasOwnProperty(name)) continue;                    var value = nameValues[name];                    _this5.style(name, value);                }                return _this5;            }).case('Style', function (style) {                _this5._style = style;                _this5._styleId = style.id();                return _this5;            }).handle(arguments);        }        /**         * Gets the value of the cell.         * @returns {string|boolean|number|Date|RichText|undefined} The value of the cell.         */ /**            * Sets the value of the cell.            * @param {string|boolean|number|null|undefined|RichText} value - The value to set.            * @returns {Cell} The cell.            */ /**               * Sets the values in the range starting with the cell.               * @param {Array.<Array.<string|boolean|number|null|undefined>>} - 2D array of values to set.               * @returns {Range} The range that was set.               */    }, {        key: "value",        value: function value() {            var _this6 = this;            return new ArgHandler('Cell.value').case(function () {                if (_this6._value instanceof RichText) {                    return _this6._value.getInstanceWithCellRef(_this6);                }                return _this6._value;            }).case("array", function (values) {                var numRows = values.length;                var numCols = values[0].length;                var range = _this6.rangeTo(_this6.relativeCell(numRows - 1, numCols - 1));                return range.value(values);            }).case('*', function (value) {                _this6.clear();                if (value instanceof RichText) {                    _this6._value = value.copy(_this6);                } else {                    _this6._value = value;                }                return _this6;            }).handle(arguments);        }        /**         * Gets the parent workbook.         * @returns {Workbook} The parent workbook.         */    }, {        key: "workbook",        value: function workbook() {            return this.row().workbook();        }        /**         * Append horizontal page break after the cell.         * @returns {Cell} the cell.         */    }, {        key: "addHorizontalPageBreak",        value: function addHorizontalPageBreak() {            this.row().addPageBreak();            return this;        }        /* INTERNAL */        /**         * Gets the formula if a shared formula ref cell.         * @returns {string|undefined} The formula.         * @ignore         */    }, {        key: "getSharedRefFormula",        value: function getSharedRefFormula() {            return this._formulaType === "shared" ? this._formulaRef && this._formula : undefined;        }        /**         * Check if this cell uses a given shared a formula ID.         * @param {number} id - The shared formula ID.         * @returns {boolean} A flag indicating if shared.         * @ignore         */    }, {        key: "sharesFormula",        value: function sharesFormula(id) {            return this._formulaType === "shared" && this._sharedFormulaId === id;        }        /**         * Set a shared formula on the cell.         * @param {number} id - The shared formula index.         * @param {string} [formula] - The formula (if the reference cell).         * @param {string} [sharedRef] - The address of the shared range (if the reference cell).         * @returns {undefined}         * @ignore         */    }, {        key: "setSharedFormula",        value: function setSharedFormula(id, formula, sharedRef) {            this.clear();            this._formulaType = "shared";            this._sharedFormulaId = id;            this._formula = formula;            this._formulaRef = sharedRef;        }        /**         * Convert the cell to an XML object.         * @returns {{}} The XML form.         * @ignore         */    }, {        key: "toXml",        value: function toXml() {            // Create a node.            var node = {                name: 'c',                attributes: this._remainingAttributes || {}, // Start with any remaining attributes we don't current handle.                children: []            };            // Set the address.            node.attributes.r = this.address();            if (!_.isNil(this._formulaType)) {                // Add the formula.                var fNode = {                    name: 'f',                    attributes: this._remainingFormulaAttributes || {}                };                if (this._formulaType !== "normal") fNode.attributes.t = this._formulaType;                if (!_.isNil(this._formulaRef)) fNode.attributes.ref = this._formulaRef;                if (!_.isNil(this._sharedFormulaId)) fNode.attributes.si = this._sharedFormulaId;                if (!_.isNil(this._formula)) fNode.children = [this._formula];                node.children.push(fNode);            } else if (!_.isNil(this._value)) {                // Add the value. Don't emit value if a formula is set as Excel will show this stale value.                var type = void 0,                    text = void 0;                if (typeof this._value === "string") {                    type = "s";                    text = this.workbook().sharedStrings().getIndexForString(this._value);                } else if (typeof this._value === "boolean") {                    type = "b";                    text = this._value ? 1 : 0;                } else if (typeof this._value === "number") {                    text = this._value;                } else if (this._value instanceof Date) {                    text = dateConverter.dateToNumber(this._value);                } else if (this._value instanceof RichText || _typeof(this._value) === "object" && this._value.constructor.name === "RichText") {                    // Hack to make Jasmine test work                    type = "s";                    text = this.workbook().sharedStrings().getIndexForString(this._value.toXml());                }                if (type) node.attributes.t = type;                var vNode = { name: 'v', children: [text] };                node.children.push(vNode);            }            // If the style is set, set the style ID.            if (!_.isNil(this._style)) {                node.attributes.s = this._style.id();            } else if (!_.isNil(this._styleId)) {                node.attributes.s = this._styleId;            }            // Add any remaining children that we don't currently handle.            if (this._remainingChildren) {                node.children = node.children.concat(this._remainingChildren);            }            return node;        }        /* PRIVATE */        /**         * Initialize the cell node.         * @param {{}|number} nodeOrColumnNumber - The existing node or the column number of a new cell.         * @param {number} [styleId] - The style ID for the new cell.         * @returns {undefined}         * @private         */    }, {        key: "_init",        value: function _init(nodeOrColumnNumber, styleId) {            if (_.isObject(nodeOrColumnNumber)) {                // Parse the existing node.                this._parseNode(nodeOrColumnNumber);            } else {                // This is a new cell.                this._columnNumber = nodeOrColumnNumber;                if (!_.isNil(styleId)) this._styleId = styleId;            }        }        /**         * Parse the existing node.         * @param {{}} node - The existing node.         * @returns {undefined}         * @private         */    }, {        key: "_parseNode",        value: function _parseNode(node) {            // Parse the column numbr out of the address.            var ref = addressConverter.fromAddress(node.attributes.r);            this._columnNumber = ref.columnNumber;            // Store the style ID if present.            if (!_.isNil(node.attributes.s)) this._styleId = node.attributes.s;            // Parse the formula if present..            var fNode = xmlq.findChild(node, 'f');            if (fNode) {                this._formulaType = fNode.attributes.t || "normal";                this._formulaRef = fNode.attributes.ref;                this._formula = fNode.children[0];                this._sharedFormulaId = fNode.attributes.si;                if (!_.isNil(this._sharedFormulaId)) {                    // Update the sheet's max shared formula ID so we can set future IDs an index beyond this.                    this.sheet().updateMaxSharedFormulaId(this._sharedFormulaId);                }                // Delete the known attributes.                delete fNode.attributes.t;                delete fNode.attributes.ref;                delete fNode.attributes.si;                // If any unknown attributes are still present, store them for later output.                if (!_.isEmpty(fNode.attributes)) this._remainingFormulaAttributes = fNode.attributes;            }            // Parse the value.            var type = node.attributes.t;            if (type === "s") {                // String value.                var vNode = xmlq.findChild(node, 'v');                if (vNode) {                    var sharedIndex = vNode.children[0];                    this._value = this.workbook().sharedStrings().getStringByIndex(sharedIndex);                    // rich text                    if (_.isArray(this._value)) {                        this._value = new RichText(this._value);                    }                } else {                    this._value = '';                }            } else if (type === "str") {                // Simple string value.                var _vNode = xmlq.findChild(node, 'v');                this._value = _vNode && _vNode.children[0];            } else if (type === "inlineStr") {                // Inline string value: can be simple text or rich text.                var isNode = xmlq.findChild(node, 'is');                if (isNode.children[0].name === "t") {                    var tNode = isNode.children[0];                    this._value = tNode.children[0];                } else {                    this._value = isNode.children;                }            } else if (type === "b") {                // Boolean value.                this._value = xmlq.findChild(node, 'v').children[0] === 1;            } else if (type === "e") {                // Error value.                var error = xmlq.findChild(node, 'v').children[0];                this._value = FormulaError.getError(error);            } else {                // Number value.                var _vNode2 = xmlq.findChild(node, 'v');                this._value = _vNode2 && Number(_vNode2.children[0]);            }            // Delete known attributes.            delete node.attributes.r;            delete node.attributes.s;            delete node.attributes.t;            // If any unknown attributes are still present, store them for later output.            if (!_.isEmpty(node.attributes)) this._remainingAttributes = node.attributes;            // Delete known children.            xmlq.removeChild(node, 'f');            xmlq.removeChild(node, 'v');            xmlq.removeChild(node, 'is');            // If any unknown children are still present, store them for later output.            if (!_.isEmpty(node.children)) this._remainingChildren = node.children;        }    }]);    return Cell;}();module.exports = Cell;/*<c r="A6" s="1" t="s">    <v>2</v></c>*/},{"./ArgHandler":2,"./FormulaError":8,"./RichText":12,"./Style":17,"./addressConverter":23,"./dateConverter":26,"./regexify":28,"./xmlq":29,"lodash":193}],4:[function(require,module,exports){"use strict";var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var ArgHandler = require("./ArgHandler");var addressConverter = require('./addressConverter');// Default column width.var defaultColumnWidth = 9.140625;/** * A column. */var Column = function () {    // /**    //  * Creates a new Column.    //  * @param {Sheet} sheet - The parent sheet.    //  * @param {{}} node - The column node.    //  * @constructor    //  * @ignore    //  * @private    //  */    function Column(sheet, node) {        _classCallCheck(this, Column);        this._sheet = sheet;        this._node = node;    }    /* PUBLIC */    /**     * Get the address of the column.     * @param {{}} [opts] - Options     * @param {boolean} [opts.includeSheetName] - Include the sheet name in the address.     * @param {boolean} [opts.anchored] - Anchor the address.     * @returns {string} The address     */    _createClass(Column, [{        key: "address",        value: function address(opts) {            return addressConverter.toAddress({                type: 'column',                columnName: this.columnName(),                sheetName: opts && opts.includeSheetName && this.sheet().name(),                columnAnchored: opts && opts.anchored            });        }        /**         * Get a cell within the column.         * @param {number} rowNumber - The row number.         * @returns {Cell} The cell in the column with the given row number.         */    }, {        key: "cell",        value: function cell(rowNumber) {            return this.sheet().cell(rowNumber, this.columnNumber());        }        /**         * Get the name of the column.         * @returns {string} The column name.         */    }, {        key: "columnName",        value: function columnName() {            return addressConverter.columnNumberToName(this.columnNumber());        }        /**         * Get the number of the column.         * @returns {number} The column number.         */    }, {        key: "columnNumber",        value: function columnNumber() {            return this._node.attributes.min;        }        /**         * Gets a value indicating whether the column is hidden.         * @returns {boolean} A flag indicating whether the column is hidden.         */ /**            * Sets whether the column is hidden.            * @param {boolean} hidden - A flag indicating whether to hide the column.            * @returns {Column} The column.            */    }, {        key: "hidden",        value: function hidden() {            var _this = this;            return new ArgHandler("Column.hidden").case(function () {                return _this._node.attributes.hidden === 1;            }).case('boolean', function (hidden) {                if (hidden) _this._node.attributes.hidden = 1;else delete _this._node.attributes.hidden;                return _this;            }).handle(arguments);        }        /**         * Get the parent sheet.         * @returns {Sheet} The parent sheet.         */    }, {        key: "sheet",        value: function sheet() {            return this._sheet;        }        /**         * Gets an individual style.         * @param {string} name - The name of the style.         * @returns {*} The style.         */ /**            * Gets multiple styles.            * @param {Array.<string>} names - The names of the style.            * @returns {object.<string, *>} Object whose keys are the style names and values are the styles.            */ /**               * Sets an individual style.               * @param {string} name - The name of the style.               * @param {*} value - The value to set.               * @returns {Cell} The cell.               */ /**                  * Sets multiple styles.                  * @param {object.<string, *>} styles - Object whose keys are the style names and values are the styles to set.                  * @returns {Cell} The cell.                  */ /**                     * Sets to a specific style                     * @param {Style} style - Style object given from stylesheet.createStyle                     * @returns {Cell} The cell.                     */    }, {        key: "style",        value: function style() {            var _this2 = this;            return new ArgHandler("Column.style").case('string', function (name) {                // Get single value                _this2._createStyleIfNeeded();                return _this2._style.style(name);            }).case('array', function (names) {                // Get list of values                var values = {};                names.forEach(function (name) {                    values[name] = _this2.style(name);                });                return values;            }).case(['string', '*'], function (name, value) {                // If a row node is already defined that intersects with this column and that row has a style set, we                // need to make sure that a cell node exists at the intersection so we can style it appropriately.                // Fetching the cell will force a new cell node to be created with a style matching the column. So we                // will fetch and style the cell at each row that intersects this column if it is already present or it                // has a style defined.                _this2.sheet().forEachExistingRow(function (row) {                    if (row.hasStyle() || row.hasCell(_this2.columnNumber())) {                        row.cell(_this2.columnNumber()).style(name, value);                    }                });                // Set a single value for all cells to a single value                _this2._createStyleIfNeeded();                _this2._style.style(name, value);                return _this2;            }).case('object', function (nameValues) {                // Object of key value pairs to set                for (var name in nameValues) {                    if (!nameValues.hasOwnProperty(name)) continue;                    var value = nameValues[name];                    _this2.style(name, value);                }                return _this2;            }).case('Style', function (style) {                // See Large Comment Above                _this2.sheet().forEachExistingRow(function (row) {                    if (row.hasStyle() || row.hasCell(_this2.columnNumber())) {                        row.cell(_this2.columnNumber()).style(style);                    }                });                _this2._style = style;                _this2._node.attributes.style = style.id();                return _this2;            }).handle(arguments);        }        /**         * Gets the width.         * @returns {undefined|number} The width (or undefined).         */ /**            * Sets the width.            * @param {number} width - The width of the column.            * @returns {Column} The column.            */    }, {        key: "width",        value: function width(_width) {            var _this3 = this;            return new ArgHandler("Column.width").case(function () {                return _this3._node.attributes.customWidth ? _this3._node.attributes.width : undefined;            }).case('number', function (width) {                _this3._node.attributes.width = width;                _this3._node.attributes.customWidth = 1;                return _this3;            }).case('nil', function () {                delete _this3._node.attributes.width;                delete _this3._node.attributes.customWidth;                return _this3;            }).handle(arguments);        }        /**         * Get the parent workbook.         * @returns {Workbook} The parent workbook.         */    }, {        key: "workbook",        value: function workbook() {            return this.sheet().workbook();        }        /**         * Append vertical page break after the column.         * @returns {Column} the column.         */    }, {        key: "addPageBreak",        value: function addPageBreak() {            this.sheet().verticalPageBreaks().add(this.columnNumber());            return this;        }        /* INTERNAL */        /**         * Convert the column to an XML object.         * @returns {{}} The XML form.         * @ignore         */    }, {        key: "toXml",        value: function toXml() {            return this._node;        }        /* PRIVATE */        /**         * Create a style for this column if it doesn't already exist.         * @returns {undefined}         * @private         */    }, {        key: "_createStyleIfNeeded",        value: function _createStyleIfNeeded() {            if (!this._style) {                var styleId = this._node.attributes.style;                this._style = this.workbook().styleSheet().createStyle(styleId);                this._node.attributes.style = this._style.id();                if (!this.width()) this.width(defaultColumnWidth);            }        }    }]);    return Column;}();module.exports = Column;},{"./ArgHandler":2,"./addressConverter":23}],5:[function(require,module,exports){"use strict";var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var _ = require("lodash");/** * A content type collection. * @ignore */var ContentTypes = function () {    /**     * Creates a new instance of ContentTypes     * @param {{}} node - The node.     */    function ContentTypes(node) {        _classCallCheck(this, ContentTypes);        this._node = node;    }    /**     * Add a new content type.     * @param {string} partName - The part name.     * @param {string} contentType - The content type.     * @returns {{}} The new content type.     */    _createClass(ContentTypes, [{        key: "add",        value: function add(partName, contentType) {            var node = {                name: "Override",                attributes: {                    PartName: partName,                    ContentType: contentType                }            };            this._node.children.push(node);            return node;        }        /**         * Find a content type by part name.         * @param {string} partName - The part name.         * @returns {{}|undefined} The matching content type or undefined if not found.         */    }, {        key: "findByPartName",        value: function findByPartName(partName) {            return _.find(this._node.children, function (node) {                return node.attributes.PartName === partName;            });        }        /**         * Convert the collection to an XML object.         * @returns {{}} The XML.         */    }, {        key: "toXml",        value: function toXml() {            return this._node;        }    }]);    return ContentTypes;}();module.exports = ContentTypes;/*[Content_Types].xml<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">    <Default Extension="bin" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings"/>    <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>    <Default Extension="xml" ContentType="application/xml"/>    <Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>    <Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>    <Override PartName="/xl/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/>    <Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>    <Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>    <Override PartName="/xl/calcChain.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml"/>    <Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>    <Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/></Types>*/},{"lodash":193}],6:[function(require,module,exports){"use strict";var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var allowedProperties = {    title: "dc:title",    subject: "dc:subject",    author: "dc:creator",    creator: "dc:creator",    description: "dc:description",    keywords: "cp:keywords",    category: "cp:category"};/** * Core properties * @ignore */var CoreProperties = function () {    function CoreProperties(node) {        _classCallCheck(this, CoreProperties);        this._node = node;        this._properties = {};    }    /**     * Sets a specific property.     * @param {string} name - The name of the property.     * @param {*} value - The value of the property.     * @returns {CoreProperties} CoreProperties.     */    _createClass(CoreProperties, [{        key: "set",        value: function set(name, value) {            var key = name.toLowerCase();            if (typeof allowedProperties[key] === "undefined") {                throw new Error("Unknown property name: \"" + name + "\"");            }            this._properties[key] = value;            return this;        }        /**         * Get a specific property.         * @param {string} name - The name of the property.         * @returns {*} The property value.         */    }, {        key: "get",        value: function get(name) {            var key = name.toLowerCase();            if (typeof allowedProperties[key] === "undefined") {                throw new Error("Unknown property name: \"" + name + "\"");            }            return this._properties[key];        }        /**         * Convert the collection to an XML object.         * @returns {{}} The XML.         */    }, {        key: "toXml",        value: function toXml() {            for (var key in this._properties) {                if (!this._properties.hasOwnProperty(key)) continue;                this._node.children.push({                    name: allowedProperties[key],                    children: [this._properties[key]]                });            }            return this._node;        }    }]);    return CoreProperties;}();module.exports = CoreProperties;/*docProps/core.xml<?xml version="1.0" encoding="UTF-8" standalone="yes"?><cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title>Title</dc:title><dc:subject>Subject</dc:subject><dc:creator>Creator</dc:creator><cp:keywords>Keywords</cp:keywords><dc:description>Description</dc:description><cp:category>Category</cp:category></cp:coreProperties> */},{}],7:[function(require,module,exports){(function (Buffer){"use strict";/** * OOXML uses the CFB file format with Agile Encryption. The details of the encryption are here: * https://msdn.microsoft.com/en-us/library/dd950165(v=office.12).aspx * * Helpful guidance also take from this Github project: * https://github.com/nolze/ms-offcrypto-tool */var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var _ = require("lodash");var cfb = require("cfb");var crypto = require("crypto");var externals = require("./externals");var XmlParser = require("./XmlParser");var XmlBuilder = require("./XmlBuilder");var xmlq = require("./xmlq");var ENCRYPTION_INFO_PREFIX = Buffer.from([0x04, 0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00]); // First 4 bytes are the version number, second 4 bytes are reserved.var PACKAGE_ENCRYPTION_CHUNK_SIZE = 4096;var PACKAGE_OFFSET = 8; // First 8 bytes are the size of the stream// Block keys used for encryptionvar BLOCK_KEYS = {    dataIntegrity: {        hmacKey: Buffer.from([0x5f, 0xb2, 0xad, 0x01, 0x0c, 0xb9, 0xe1, 0xf6]),        hmacValue: Buffer.from([0xa0, 0x67, 0x7f, 0x02, 0xb2, 0x2c, 0x84, 0x33])    },    key: Buffer.from([0x14, 0x6e, 0x0b, 0xe7, 0xab, 0xac, 0xd0, 0xd6]),    verifierHash: {        input: Buffer.from([0xfe, 0xa7, 0xd2, 0x76, 0x3b, 0x4b, 0x9e, 0x79]),        value: Buffer.from([0xd7, 0xaa, 0x0f, 0x6d, 0x30, 0x61, 0x34, 0x4e])    }};/** * Encrypts/decrypts XLSXs. * @private */var Encryptor = function () {    function Encryptor() {        _classCallCheck(this, Encryptor);    }    _createClass(Encryptor, [{        key: "encrypt",        /**         * Encrypt the data with the password.         * @param {Buffer} data - The data to encrypt         * @param {string} password - The password         * @returns {Buffer} The encrypted data         */        value: function encrypt(data, password) {            // Generate a random key to use to encrypt the document. Excel uses 32 bytes. We'll use the password to encrypt this key.            // N.B. The number of bits needs to correspond to an algorithm available in crypto (e.g. aes-256-cbc).            var packageKey = crypto.randomBytes(32);            // Create the encryption info. We'll use this for all of the encryption operations and for building the encryption info XML entry            var encryptionInfo = {                package: { // Info on the encryption of the package.                    cipherAlgorithm: 'AES', // Cipher algorithm to use. Excel uses AES.                    cipherChaining: 'ChainingModeCBC', // Cipher chaining mode to use. Excel uses CBC.                    saltValue: crypto.randomBytes(16), // Random value to use as encryption salt. Excel uses 16 bytes.                    hashAlgorithm: 'SHA512', // Hash algorithm to use. Excel uses SHA512.                    hashSize: 64, // The size of the hash in bytes. SHA512 results in 64-byte hashes                    blockSize: 16, // The number of bytes used to encrypt one block of data. It MUST be at least 2, no greater than 4096, and a multiple of 2. Excel uses 16                    keyBits: packageKey.length * 8 // The number of bits in the package key.                },                key: { // Info on the encryption of the package key.                    cipherAlgorithm: 'AES', // Cipher algorithm to use. Excel uses AES.                    cipherChaining: 'ChainingModeCBC', // Cipher chaining mode to use. Excel uses CBC.                    saltValue: crypto.randomBytes(16), // Random value to use as encryption salt. Excel uses 16 bytes.                    hashAlgorithm: 'SHA512', // Hash algorithm to use. Excel uses SHA512.                    hashSize: 64, // The size of the hash in bytes. SHA512 results in 64-byte hashes                    blockSize: 16, // The number of bytes used to encrypt one block of data. It MUST be at least 2, no greater than 4096, and a multiple of 2. Excel uses 16                    spinCount: 100000, // The number of times to iterate on a hash of a password. It MUST NOT be greater than 10,000,000. Excel uses 100,000.                    keyBits: 256 // The length of the key to generate from the password. Must be a multiple of 8. Excel uses 256.                }            };            /* Package Encryption */            // Encrypt package using the package key.            var encryptedPackage = this._cryptPackage(true, encryptionInfo.package.cipherAlgorithm, encryptionInfo.package.cipherChaining, encryptionInfo.package.hashAlgorithm, encryptionInfo.package.blockSize, encryptionInfo.package.saltValue, packageKey, data);            /* Data Integrity */            // Create the data integrity fields used by clients for integrity checks.            // First generate a random array of bytes to use in HMAC. The docs say to use the same length as the key salt, but Excel seems to use 64.            var hmacKey = crypto.randomBytes(64);            // Then create an initialization vector using the package encryption info and the appropriate block key.            var hmacKeyIV = this._createIV(encryptionInfo.package.hashAlgorithm, encryptionInfo.package.saltValue, encryptionInfo.package.blockSize, BLOCK_KEYS.dataIntegrity.hmacKey);            // Use the package key and the IV to encrypt the HMAC key            var encryptedHmacKey = this._crypt(true, encryptionInfo.package.cipherAlgorithm, encryptionInfo.package.cipherChaining, packageKey, hmacKeyIV, hmacKey);            // Now create the HMAC            var hmacValue = this._hmac(encryptionInfo.package.hashAlgorithm, hmacKey, encryptedPackage);            // Next generate an initialization vector for encrypting the resulting HMAC value.            var hmacValueIV = this._createIV(encryptionInfo.package.hashAlgorithm, encryptionInfo.package.saltValue, encryptionInfo.package.blockSize, BLOCK_KEYS.dataIntegrity.hmacValue);            // Now encrypt the value            var encryptedHmacValue = this._crypt(true, encryptionInfo.package.cipherAlgorithm, encryptionInfo.package.cipherChaining, packageKey, hmacValueIV, hmacValue);            // Put the encrypted key and value on the encryption info            encryptionInfo.dataIntegrity = {                encryptedHmacKey: encryptedHmacKey,                encryptedHmacValue: encryptedHmacValue            };            /* Key Encryption */            // Convert the password to an encryption key            var key = this._convertPasswordToKey(password, encryptionInfo.key.hashAlgorithm, encryptionInfo.key.saltValue, encryptionInfo.key.spinCount, encryptionInfo.key.keyBits, BLOCK_KEYS.key);            // Encrypt the package key with the            encryptionInfo.key.encryptedKeyValue = this._crypt(true, encryptionInfo.key.cipherAlgorithm, encryptionInfo.key.cipherChaining, key, encryptionInfo.key.saltValue, packageKey);            /* Verifier hash */            // Create a random byte array for hashing            var verifierHashInput = crypto.randomBytes(16);            // Create an encryption key from the password for the input            var verifierHashInputKey = this._convertPasswordToKey(password, encryptionInfo.key.hashAlgorithm, encryptionInfo.key.saltValue, encryptionInfo.key.spinCount, encryptionInfo.key.keyBits, BLOCK_KEYS.verifierHash.input);            // Use the key to encrypt the verifier input            encryptionInfo.key.encryptedVerifierHashInput = this._crypt(true, encryptionInfo.key.cipherAlgorithm, encryptionInfo.key.cipherChaining, verifierHashInputKey, encryptionInfo.key.saltValue, verifierHashInput);            // Create a hash of the input            var verifierHashValue = this._hash(encryptionInfo.key.hashAlgorithm, verifierHashInput);            // Create an encryption key from the password for the hash            var verifierHashValueKey = this._convertPasswordToKey(password, encryptionInfo.key.hashAlgorithm, encryptionInfo.key.saltValue, encryptionInfo.key.spinCount, encryptionInfo.key.keyBits, BLOCK_KEYS.verifierHash.value);            // Use the key to encrypt the hash value            encryptionInfo.key.encryptedVerifierHashValue = this._crypt(true, encryptionInfo.key.cipherAlgorithm, encryptionInfo.key.cipherChaining, verifierHashValueKey, encryptionInfo.key.saltValue, verifierHashValue);            // Build the encryption info buffer            var encryptionInfoBuffer = this._buildEncryptionInfo(encryptionInfo);            // Create a new CFB            var output = cfb.utils.cfb_new();            // Add the encryption info and encrypted package            cfb.utils.cfb_add(output, "EncryptionInfo", encryptionInfoBuffer);            cfb.utils.cfb_add(output, "EncryptedPackage", encryptedPackage);            // Delete the SheetJS entry that is added at initialization            cfb.utils.cfb_del(output, "\x01Sh33tJ5");            // Write to a buffer and return            output = cfb.write(output);            // The cfb library writes to a Uint8array in the browser. Convert to a Buffer.            if (!Buffer.isBuffer(output)) output = Buffer.from(output);            return output;        }        /**         * Decrypt the data with the given password         * @param {Buffer} data - The data to decrypt         * @param {string} password - The password         * @returns {Promise.<Buffer>} The decrypted data         */    }, {        key: "decryptAsync",        value: function decryptAsync(data, password) {            var _this = this;            // Parse the CFB input and pull out the encryption info and encrypted package entries.            var parsed = cfb.parse(data);            var encryptionInfoBuffer = _.find(parsed.FileIndex, { name: "EncryptionInfo" }).content;            var encryptedPackageBuffer = _.find(parsed.FileIndex, { name: "EncryptedPackage" }).content;            // In the browser the CFB content is an array. Convert to a Buffer.            if (!Buffer.isBuffer(encryptionInfoBuffer)) encryptionInfoBuffer = Buffer.from(encryptionInfoBuffer);            if (!Buffer.isBuffer(encryptedPackageBuffer)) encryptedPackageBuffer = Buffer.from(encryptedPackageBuffer);            return externals.Promise.resolve().then(function () {                return _this._parseEncryptionInfoAsync(encryptionInfoBuffer);            }) // Parse the encryption info XML into an object            .then(function (encryptionInfo) {                // Convert the password into an encryption key                var key = _this._convertPasswordToKey(password, encryptionInfo.key.hashAlgorithm, encryptionInfo.key.saltValue, encryptionInfo.key.spinCount, encryptionInfo.key.keyBits, BLOCK_KEYS.key);                // Use the key to decrypt the package key                var packageKey = _this._crypt(false, encryptionInfo.key.cipherAlgorithm, encryptionInfo.key.cipherChaining, key, encryptionInfo.key.saltValue, encryptionInfo.key.encryptedKeyValue);                // Use the package key to decrypt the package                return _this._cryptPackage(false, encryptionInfo.package.cipherAlgorithm, encryptionInfo.package.cipherChaining, encryptionInfo.package.hashAlgorithm, encryptionInfo.package.blockSize, encryptionInfo.package.saltValue, packageKey, encryptedPackageBuffer);            });        }        /**         * Build the encryption info XML/buffer         * @param {{}} encryptionInfo - The encryption info object         * @returns {Buffer} The buffer         * @private         */    }, {        key: "_buildEncryptionInfo",        value: function _buildEncryptionInfo(encryptionInfo) {            // Map the object into the appropriate XML structure. Buffers are encoded in base 64.            var encryptionInfoNode = {                name: "encryption",                attributes: {                    xmlns: "http://schemas.microsoft.com/office/2006/encryption",                    'xmlns:p': "http://schemas.microsoft.com/office/2006/keyEncryptor/password",                    'xmlns:c': "http://schemas.microsoft.com/office/2006/keyEncryptor/certificate"                },                children: [{                    name: "keyData",                    attributes: {                        saltSize: encryptionInfo.package.saltValue.length,                        blockSize: encryptionInfo.package.blockSize,                        keyBits: encryptionInfo.package.keyBits,                        hashSize: encryptionInfo.package.hashSize,                        cipherAlgorithm: encryptionInfo.package.cipherAlgorithm,                        cipherChaining: encryptionInfo.package.cipherChaining,                        hashAlgorithm: encryptionInfo.package.hashAlgorithm,                        saltValue: encryptionInfo.package.saltValue.toString("base64")                    }                }, {                    name: "dataIntegrity",                    attributes: {                        encryptedHmacKey: encryptionInfo.dataIntegrity.encryptedHmacKey.toString("base64"),                        encryptedHmacValue: encryptionInfo.dataIntegrity.encryptedHmacValue.toString("base64")                    }                }, {                    name: "keyEncryptors",                    children: [{                        name: "keyEncryptor",                        attributes: {                            uri: "http://schemas.microsoft.com/office/2006/keyEncryptor/password"                        },                        children: [{                            name: "p:encryptedKey",                            attributes: {                                spinCount: encryptionInfo.key.spinCount,                                saltSize: encryptionInfo.key.saltValue.length,                                blockSize: encryptionInfo.key.blockSize,                                keyBits: encryptionInfo.key.keyBits,                                hashSize: encryptionInfo.key.hashSize,                                cipherAlgorithm: encryptionInfo.key.cipherAlgorithm,                                cipherChaining: encryptionInfo.key.cipherChaining,                                hashAlgorithm: encryptionInfo.key.hashAlgorithm,                                saltValue: encryptionInfo.key.saltValue.toString("base64"),                                encryptedVerifierHashInput: encryptionInfo.key.encryptedVerifierHashInput.toString("base64"),                                encryptedVerifierHashValue: encryptionInfo.key.encryptedVerifierHashValue.toString("base64"),                                encryptedKeyValue: encryptionInfo.key.encryptedKeyValue.toString("base64")                            }                        }]                    }]                }]            };            // Convert to an XML string            var xmlBuilder = new XmlBuilder();            var encryptionInfoXml = xmlBuilder.build(encryptionInfoNode);            // Convert to a buffer and prefix with the appropriate bytes            return Buffer.concat([ENCRYPTION_INFO_PREFIX, Buffer.from(encryptionInfoXml, "utf8")]);        }        /**         * Parse the encryption info from the XML/buffer         * @param {Buffer} buffer - The buffer         * @returns {Promise.<{}>} The parsed encryption info object         * @private         */    }, {        key: "_parseEncryptionInfoAsync",        value: function _parseEncryptionInfoAsync(buffer) {            // Pull off the prefix and convert to string            var xml = buffer.slice(ENCRYPTION_INFO_PREFIX.length).toString("utf8");            // Parse the XML            var xmlParser = new XmlParser();            return xmlParser.parseAsync(xml).then(function (doc) {                // Pull out the relevant values for decryption and return                var keyDataNode = xmlq.findChild(doc, "keyData");                var keyEncryptorsNode = xmlq.findChild(doc, "keyEncryptors");                var keyEncryptorNode = xmlq.findChild(keyEncryptorsNode, "keyEncryptor");                var encryptedKeyNode = xmlq.findChild(keyEncryptorNode, "p:encryptedKey");                return {                    package: {                        cipherAlgorithm: keyDataNode.attributes.cipherAlgorithm,                        cipherChaining: keyDataNode.attributes.cipherChaining,                        saltValue: Buffer.from(keyDataNode.attributes.saltValue, "base64"),                        hashAlgorithm: keyDataNode.attributes.hashAlgorithm,                        blockSize: keyDataNode.attributes.blockSize                    },                    key: {                        encryptedKeyValue: Buffer.from(encryptedKeyNode.attributes.encryptedKeyValue, "base64"),                        cipherAlgorithm: encryptedKeyNode.attributes.cipherAlgorithm,                        cipherChaining: encryptedKeyNode.attributes.cipherChaining,                        saltValue: Buffer.from(encryptedKeyNode.attributes.saltValue, "base64"),                        hashAlgorithm: encryptedKeyNode.attributes.hashAlgorithm,                        spinCount: encryptedKeyNode.attributes.spinCount,                        keyBits: encryptedKeyNode.attributes.keyBits                    }                };            });        }        /**         * Calculate a hash of the concatenated buffers with the given algorithm.         * @param {string} algorithm - The hash algorithm.         * @param {Array.<Buffer>} buffers - The buffers to concat and hash         * @returns {Buffer} The hash         * @private         */    }, {        key: "_hash",        value: function _hash(algorithm) {            algorithm = algorithm.toLowerCase();            var hashes = crypto.getHashes();            if (hashes.indexOf(algorithm) < 0) throw new Error("Hash algorithm '" + algorithm + "' not supported!");            var hash = crypto.createHash(algorithm);            for (var _len = arguments.length, buffers = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {                buffers[_key - 1] = arguments[_key];            }            hash.update(Buffer.concat(buffers));            return hash.digest();        }        /**         * Calculate an HMAC of the concatenated buffers with the given algorithm and key         * @param {string} algorithm - The algorithm.         * @param {string} key - The key         * @param {Array.<Buffer>} buffers - The buffer to concat and HMAC         * @returns {Buffer} The HMAC         * @private         */    }, {        key: "_hmac",        value: function _hmac(algorithm, key) {            algorithm = algorithm.toLowerCase();            var hashes = crypto.getHashes();            if (hashes.indexOf(algorithm) < 0) throw new Error("HMAC algorithm '" + algorithm + "' not supported!");            var hmac = crypto.createHmac(algorithm, key);            for (var _len2 = arguments.length, buffers = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {                buffers[_key2 - 2] = arguments[_key2];            }            hmac.update(Buffer.concat(buffers));            return hmac.digest();        }        /**         * Encrypt/decrypt input         * @param {boolean} encrypt - True to encrypt, false to decrypt         * @param {string} cipherAlgorithm - The cipher algorithm         * @param {sring} cipherChaining - The cipher chaining mode         * @param {Buffer} key - The encryption key         * @param {Buffer} iv - The initialization vector         * @param {Buffer} input - The input         * @returns {Buffer} The output         * @private         */    }, {        key: "_crypt",        value: function _crypt(encrypt, cipherAlgorithm, cipherChaining, key, iv, input) {            var algorithm = cipherAlgorithm.toLowerCase() + "-" + key.length * 8;            if (cipherChaining === 'ChainingModeCBC') algorithm += '-cbc';else throw new Error("Unknown cipher chaining: " + cipherChaining);            var cipher = crypto[encrypt ? 'createCipheriv' : 'createDecipheriv'](algorithm, key, iv);            cipher.setAutoPadding(false);            var output = cipher.update(input);            output = Buffer.concat([output, cipher.final()]);            return output;        }        /**         * Encrypt/decrypt the package         * @param {boolean} encrypt - True to encrypt, false to decrypt         * @param {string} cipherAlgorithm - The cipher algorithm         * @param {string} cipherChaining - The cipher chaining mode         * @param {string} hashAlgorithm - The hash algorithm         * @param {number} blockSize - The IV block size         * @param {Buffer} saltValue - The salt         * @param {Buffer} key - The encryption key         * @param {Buffer} input - The package input         * @returns {Buffer} The output         * @private         */    }, {        key: "_cryptPackage",        value: function _cryptPackage(encrypt, cipherAlgorithm, cipherChaining, hashAlgorithm, blockSize, saltValue, key, input) {            // The first 8 bytes is supposed to be the length, but it seems like it is really the length - 4..            var outputChunks = [];            var offset = encrypt ? 0 : PACKAGE_OFFSET;            // The package is encoded in chunks. Encrypt/decrypt each and concat.            var i = 0,                start = 0,                end = 0;            while (end < input.length) {                start = end;                end = start + PACKAGE_ENCRYPTION_CHUNK_SIZE;                if (end > input.length) end = input.length;                // Grab the next chunk                var inputChunk = input.slice(start + offset, end + offset);                // Pad the chunk if it is not an integer multiple of the block size                var remainder = inputChunk.length % blockSize;                if (remainder) inputChunk = Buffer.concat([inputChunk, Buffer.alloc(blockSize - remainder)]);                // Create the initialization vector                var iv = this._createIV(hashAlgorithm, saltValue, blockSize, i);                // Encrypt/decrypt the chunk and add it to the array                var outputChunk = this._crypt(encrypt, cipherAlgorithm, cipherChaining, key, iv, inputChunk);                outputChunks.push(outputChunk);                i++;            }            // Concat all of the output chunks.            var output = Buffer.concat(outputChunks);            if (encrypt) {                // Put the length of the package in the first 8 bytes                output = Buffer.concat([this._createUInt32LEBuffer(input.length, PACKAGE_OFFSET), output]);            } else {                // Truncate the buffer to the size in the prefix                var length = input.readUInt32LE(0);                output = output.slice(0, length);            }            return output;        }        /**         * Create a buffer of an integer encoded as a uint32le         * @param {number} value - The integer to encode         * @param {number} [bufferSize=4] The output buffer size in bytes         * @returns {Buffer} The buffer         * @private         */    }, {        key: "_createUInt32LEBuffer",        value: function _createUInt32LEBuffer(value) {            var bufferSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4;            var buffer = Buffer.alloc(bufferSize);            buffer.writeUInt32LE(value, 0);            return buffer;        }        /**         * Convert a password into an encryption key         * @param {string} password - The password         * @param {string} hashAlgorithm - The hash algoritm         * @param {Buffer} saltValue - The salt value         * @param {number} spinCount - The spin count         * @param {number} keyBits - The length of the key in bits         * @param {Buffer} blockKey - The block key         * @returns {Buffer} The encryption key         * @private         */    }, {        key: "_convertPasswordToKey",        value: function _convertPasswordToKey(password, hashAlgorithm, saltValue, spinCount, keyBits, blockKey) {            // Password must be in unicode buffer            var passwordBuffer = Buffer.from(password, 'utf16le');            // Generate the initial hash            var key = this._hash(hashAlgorithm, saltValue, passwordBuffer);            // Now regenerate until spin count            for (var i = 0; i < spinCount; i++) {                var iterator = this._createUInt32LEBuffer(i);                key = this._hash(hashAlgorithm, iterator, key);            }            // Now generate the final hash            key = this._hash(hashAlgorithm, key, blockKey);            // Truncate or pad as needed to get to length of keyBits            var keyBytes = keyBits / 8;            if (key.length < keyBytes) {                var tmp = Buffer.alloc(keyBytes, 0x36);                key.copy(tmp);                key = tmp;            } else if (key.length > keyBytes) {                key = key.slice(0, keyBytes);            }            return key;        }        /**         * Create an initialization vector (IV)         * @param {string} hashAlgorithm - The hash algorithm         * @param {Buffer} saltValue - The salt value         * @param {number} blockSize - The size of the IV         * @param {Buffer|number} blockKey - The block key or an int to convert to a buffer         * @returns {Buffer} The IV         * @private         */    }, {        key: "_createIV",        value: function _createIV(hashAlgorithm, saltValue, blockSize, blockKey) {            // Create the block key from the current index            if (typeof blockKey === "number") blockKey = this._createUInt32LEBuffer(blockKey);            // Create the initialization vector by hashing the salt with the block key.            // Truncate or pad as needed to meet the block size.            var iv = this._hash(hashAlgorithm, saltValue, blockKey);            if (iv.length < blockSize) {                var tmp = Buffer.alloc(blockSize, 0x36);                iv.copy(tmp);                iv = tmp;            } else if (iv.length > blockSize) {                iv = iv.slice(0, blockSize);            }            return iv;        }    }]);    return Encryptor;}();module.exports = Encryptor;}).call(this,require("buffer").Buffer)},{"./XmlBuilder":21,"./XmlParser":22,"./externals":27,"./xmlq":29,"buffer":79,"cfb":80,"crypto":109,"lodash":193}],8:[function(require,module,exports){"use strict";var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var _ = require("lodash");/** * A formula error (e.g. #DIV/0!). */var FormulaError = function () {  // /**  //  * Creates a new instance of Formula Error.  //  * @param {string} error - The error code.  //  */  function FormulaError(error) {    _classCallCheck(this, FormulaError);    this._error = error;  }  /**   * Get the error code.   * @returns {string} The error code.   */  _createClass(FormulaError, [{    key: "error",    value: function error() {      return this._error;    }  }]);  return FormulaError;}();/** * \#DIV/0! error. * @type {FormulaError} */FormulaError.DIV0 = new FormulaError("#DIV/0!");/** * \#N/A error. * @type {FormulaError} */FormulaError.NA = new FormulaError("#N/A");/** * \#NAME? error. * @type {FormulaError} */FormulaError.NAME = new FormulaError("#NAME?");/** * \#NULL! error. * @type {FormulaError} */FormulaError.NULL = new FormulaError("#NULL!");/** * \#NUM! error. * @type {FormulaError} */FormulaError.NUM = new FormulaError("#NUM!");/** * \#REF! error. * @type {FormulaError} */FormulaError.REF = new FormulaError("#REF!");/** * \#VALUE! error. * @type {FormulaError} */FormulaError.VALUE = new FormulaError("#VALUE!");/** * Get the matching FormulaError object. * @param {string} error - The error code. * @returns {FormulaError} The matching FormulaError or a new object if no match. * @ignore */FormulaError.getError = function (error) {  return _.find(FormulaError, function (value) {    return value instanceof FormulaError && value.error() === error;  }) || new FormulaError(error);};module.exports = FormulaError;},{"lodash":193}],9:[function(require,module,exports){"use strict";/** * PageBreaks */var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var PageBreaks = function () {    function PageBreaks(node) {        _classCallCheck(this, PageBreaks);        this._node = node;    }    /**     * add page-breaks by row/column id     * @param {number} id - row/column id (rowNumber/colNumber)     * @return {PageBreaks} the page-breaks     */    _createClass(PageBreaks, [{        key: "add",        value: function add(id) {            this._node.children.push({                name: "brk",                children: [],                attributes: {                    id: id,                    max: 16383,                    man: 1                }            });            this._node.attributes.count++;            this._node.attributes.manualBreakCount++;            return this;        }        /**         * remove page-breaks by index         * @param {number} index - index of list         * @return {PageBreaks} the page-breaks         */    }, {        key: "remove",        value: function remove(index) {            var brk = this._node.children[index];            if (brk) {                this._node.children.splice(index, 1);                this._node.attributes.count--;                if (brk.man) {                    this._node.attributes.manualBreakCount--;                }            }            return this;        }        /**         * get count of the page-breaks         * @return {number} the page-breaks' count         */    }, {        key: "count",        get: function get() {            return this._node.attributes.count;        }        /**         * get list of page-breaks         * @return {Array} list of the page-breaks         */    }, {        key: "list",        get: function get() {            return this._node.children.map(function (brk) {                return {                    id: brk.id,                    isManual: !!brk.man                };            });        }    }]);    return PageBreaks;}();module.exports = PageBreaks;},{}],10:[function(require,module,exports){"use strict";var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var ArgHandler = require("./ArgHandler");var addressConverter = require("./addressConverter");/** * A range of cells. */var Range = function () {    // /**    //  * Creates a new instance of Range.    //  * @param {Cell} startCell - The start cell.    //  * @param {Cell} endCell - The end cell.    //  */    function Range(startCell, endCell) {        _classCallCheck(this, Range);        this._startCell = startCell;        this._endCell = endCell;        this._findRangeExtent(startCell, endCell);    }    /**     * Get the address of the range.     * @param {{}} [opts] - Options     * @param {boolean} [opts.includeSheetName] - Include the sheet name in the address.     * @param {boolean} [opts.startRowAnchored] - Anchor the start row.     * @param {boolean} [opts.startColumnAnchored] - Anchor the start column.     * @param {boolean} [opts.endRowAnchored] - Anchor the end row.     * @param {boolean} [opts.endColumnAnchored] - Anchor the end column.     * @param {boolean} [opts.anchored] - Anchor all row and columns.     * @returns {string} The address.     */    _createClass(Range, [{        key: "address",        value: function address(opts) {            return addressConverter.toAddress({                type: 'range',                startRowNumber: this.startCell().rowNumber(),                startRowAnchored: opts && (opts.startRowAnchored || opts.anchored),                startColumnName: this.startCell().columnName(),                startColumnAnchored: opts && (opts.startColumnAnchored || opts.anchored),                endRowNumber: this.endCell().rowNumber(),                endRowAnchored: opts && (opts.endRowAnchored || opts.anchored),                endColumnName: this.endCell().columnName(),                endColumnAnchored: opts && (opts.endColumnAnchored || opts.anchored),                sheetName: opts && opts.includeSheetName && this.sheet().name()            });        }        /**         * Gets a cell within the range.         * @param {number} ri - Row index relative to the top-left corner of the range (0-based).         * @param {number} ci - Column index relative to the top-left corner of the range (0-based).         * @returns {Cell} The cell.         */    }, {        key: "cell",        value: function cell(ri, ci) {            return this.sheet().cell(this._minRowNumber + ri, this._minColumnNumber + ci);        }        /**         * Sets sheet autoFilter to this range.         * @returns {Range} This range.         */    }, {        key: "autoFilter",        value: function autoFilter() {            this.sheet().autoFilter(this);            return this;        }        /**         * Get the cells in the range as a 2D array.         * @returns {Array.<Array.<Cell>>} The cells.         */    }, {        key: "cells",        value: function cells() {            return this.map(function (cell) {                return cell;            });        }        /**         * Clear the contents of all the cells in the range.         * @returns {Range} The range.         */    }, {        key: "clear",        value: function clear() {            return this.value(undefined);        }        /**         * Get the end cell of the range.         * @returns {Cell} The end cell.         */    }, {        key: "endCell",        value: function endCell() {            return this._endCell;        }        /**         * Callback used by forEach.         * @callback Range~forEachCallback         * @param {Cell} cell - The cell.         * @param {number} ri - The relative row index.         * @param {number} ci - The relative column index.         * @param {Range} range - The range.         * @returns {undefined}         */        /**         * Call a function for each cell in the range. Goes by row then column.         * @param {Range~forEachCallback} callback - Function called for each cell in the range.         * @returns {Range} The range.         */    }, {        key: "forEach",        value: function forEach(callback) {            for (var ri = 0; ri < this._numRows; ri++) {                for (var ci = 0; ci < this._numColumns; ci++) {                    callback(this.cell(ri, ci), ri, ci, this);                }            }            return this;        }        /**         * Gets the shared formula in the start cell (assuming it's the source of the shared formula).         * @returns {string|undefined} The shared formula.         */ /**            * Sets the shared formula in the range. The formula will be translated for each cell.            * @param {string} formula - The formula to set.            * @returns {Range} The range.            */    }, {        key: "formula",        value: function formula() {            var _this = this;            return new ArgHandler("Range.formula").case(function () {                return _this.startCell().getSharedRefFormula();            }).case('string', function (formula) {                var sharedFormulaId = _this.sheet().incrementMaxSharedFormulaId();                _this.forEach(function (cell, ri, ci) {                    if (ri === 0 && ci === 0) {                        cell.setSharedFormula(sharedFormulaId, formula, _this.address());                    } else {                        cell.setSharedFormula(sharedFormulaId);                    }                });                return _this;            }).handle(arguments);        }        /**         * Callback used by map.         * @callback Range~mapCallback         * @param {Cell} cell - The cell.         * @param {number} ri - The relative row index.         * @param {number} ci - The relative column index.         * @param {Range} range - The range.         * @returns {*} The value to map to.         */        /**         * Creates a 2D array of values by running each cell through a callback.         * @param {Range~mapCallback} callback - Function called for each cell in the range.         * @returns {Array.<Array.<*>>} The 2D array of return values.         */    }, {        key: "map",        value: function map(callback) {            var _this2 = this;            var result = [];            this.forEach(function (cell, ri, ci) {                if (!result[ri]) result[ri] = [];                result[ri][ci] = callback(cell, ri, ci, _this2);            });            return result;        }        /**         * Gets a value indicating whether the cells in the range are merged.         * @returns {boolean} The value.         */ /**            * Sets a value indicating whether the cells in the range should be merged.            * @param {boolean} merged - True to merge, false to unmerge.            * @returns {Range} The range.            */    }, {        key: "merged",        value: function merged(_merged) {            var _this3 = this;            return new ArgHandler('Range.merged').case(function () {                return _this3.sheet().merged(_this3.address());            }).case('*', function (merged) {                _this3.sheet().merged(_this3.address(), merged);                return _this3;            }).handle(arguments);        }        /**         * Gets the data validation object attached to the Range.         * @returns {object|undefined} The data validation object or undefined if not set.         */ /**            * Set or clear the data validation object of the entire range.            * @param {object|undefined} dataValidation - Object or null to clear.            * @returns {Range} The range.            */    }, {        key: "dataValidation",        value: function dataValidation() {            var _this4 = this;            return new ArgHandler('Range.dataValidation').case(function () {                return _this4.sheet().dataValidation(_this4.address());            }).case('boolean', function (obj) {                return _this4.sheet().dataValidation(_this4.address(), obj);            }).case('*', function (obj) {                _this4.sheet().dataValidation(_this4.address(), obj);                return _this4;            }).handle(arguments);        }        /**         * Callback used by reduce.         * @callback Range~reduceCallback         * @param {*} accumulator - The accumulated value.         * @param {Cell} cell - The cell.         * @param {number} ri - The relative row index.         * @param {number} ci - The relative column index.         * @param {Range} range - The range.         * @returns {*} The value to map to.         */        /**         * Reduces the range to a single value accumulated from the result of a function called for each cell.         * @param {Range~reduceCallback} callback - Function called for each cell in the range.         * @param {*} [initialValue] - The initial value.         * @returns {*} The accumulated value.         */    }, {        key: "reduce",        value: function reduce(callback, initialValue) {            var _this5 = this;            var accumulator = initialValue;            this.forEach(function (cell, ri, ci) {                accumulator = callback(accumulator, cell, ri, ci, _this5);            });            return accumulator;        }        /**         * Gets the parent sheet of the range.         * @returns {Sheet} The parent sheet.         */    }, {        key: "sheet",        value: function sheet() {            return this.startCell().sheet();        }        /**         * Gets the start cell of the range.         * @returns {Cell} The start cell.         */    }, {        key: "startCell",        value: function startCell() {            return this._startCell;        }        /**         * Gets a single style for each cell.         * @param {string} name - The name of the style.         * @returns {Array.<Array.<*>>} 2D array of style values.         */ /**            * Gets multiple styles for each cell.            * @param {Array.<string>} names - The names of the styles.            * @returns {Object.<string, Array.<Array.<*>>>} Object whose keys are style names and values are 2D arrays of style values.            */ /**               * Set the style in each cell to the result of a function called for each.               * @param {string} name - The name of the style.               * @param {Range~mapCallback} callback - The callback to provide value for the cell.               * @returns {Range} The range.               */ /**                  * Sets the style in each cell to the corresponding value in the given 2D array of values.                  * @param {string} name - The name of the style.                  * @param {Array.<Array.<*>>} values - The style values to set.                  * @returns {Range} The range.                  */ /**                     * Set the style of all cells in the range to a single style value.                     * @param {string} name - The name of the style.                     * @param {*} value - The value to set.                     * @returns {Range} The range.                     */ /**                        * Set multiple styles for the cells in the range.                        * @param {object.<string,Range~mapCallback|Array.<Array.<*>>|*>} styles - Object whose keys are style names and values are either function callbacks, 2D arrays of style values, or a single value for all the cells.                        * @returns {Range} The range.                        */ /**                           * Sets to a specific style                           * @param {Style} style - Style object given from stylesheet.createStyle                           * @returns {Range} The range.                           */    }, {        key: "style",        value: function style() {            var _this6 = this;            return new ArgHandler("Range.style").case('string', function (name) {                // Get single value                return _this6.map(function (cell) {                    return cell.style(name);                });            }).case('array', function (names) {                // Get list of values                var values = {};                names.forEach(function (name) {                    values[name] = _this6.style(name);                });                return values;            }).case(['string', 'function'], function (name, callback) {                // Set a single value for the cells to the result of a function                return _this6.forEach(function (cell, ri, ci) {                    cell.style(name, callback(cell, ri, ci, _this6));                });            }).case(['string', 'array'], function (name, values) {                // Set a single value for the cells using an array of matching dimension                return _this6.forEach(function (cell, ri, ci) {                    if (values[ri] && values[ri][ci] !== undefined) {                        cell.style(name, values[ri][ci]);                    }                });            }).case(['string', '*'], function (name, value) {                // Set a single value for all cells to a single value                return _this6.forEach(function (cell) {                    return cell.style(name, value);                });            }).case('object', function (nameValues) {                // Object of key value pairs to set                for (var name in nameValues) {                    if (!nameValues.hasOwnProperty(name)) continue;                    var value = nameValues[name];                    _this6.style(name, value);                }                return _this6;            }).case('Style', function (style) {                _this6._style = style;                return _this6.forEach(function (cell) {                    return cell.style(style);                });            }).handle(arguments);        }        /**         * Callback used by tap.         * @callback Range~tapCallback         * @param {Range} range - The range.         * @returns {undefined}         */        /**         * Invoke a callback on the range and return the range. Useful for method chaining.         * @param {Range~tapCallback} callback - The callback function.         * @returns {Range} The range.         */    }, {        key: "tap",        value: function tap(callback) {            callback(this);            return this;        }        /**         * Callback used by thru.         * @callback Range~thruCallback         * @param {Range} range - The range.         * @returns {*} The value to return from thru.         */        /**         * Invoke a callback on the range and return the value provided by the callback. Useful for method chaining.         * @param {Range~thruCallback} callback - The callback function.         * @returns {*} The return value of the callback.         */    }, {        key: "thru",        value: function thru(callback) {            return callback(this);        }        /**         * Get the values of each cell in the range as a 2D array.         * @returns {Array.<Array.<*>>} The values.         */ /**            * Set the values in each cell to the result of a function called for each.            * @param {Range~mapCallback} callback - The callback to provide value for the cell.            * @returns {Range} The range.            */ /**               * Sets the value in each cell to the corresponding value in the given 2D array of values.               * @param {Array.<Array.<*>>} values - The values to set.               * @returns {Range} The range.               */ /**                  * Set the value of all cells in the range to a single value.                  * @param {*} value - The value to set.                  * @returns {Range} The range.                  */    }, {        key: "value",        value: function value() {            var _this7 = this;            return new ArgHandler("Range.value").case(function () {                // Get values                return _this7.map(function (cell) {                    return cell.value();                });            }).case('function', function (callback) {                // Set a value for the cells to the result of a function                return _this7.forEach(function (cell, ri, ci) {                    cell.value(callback(cell, ri, ci, _this7));                });            }).case('array', function (values) {                // Set value for the cells using an array of matching dimension                return _this7.forEach(function (cell, ri, ci) {                    if (values[ri] && values[ri][ci] !== undefined) {                        cell.value(values[ri][ci]);                    }                });            }).case('*', function (value) {                // Set the value for all cells to a single value                return _this7.forEach(function (cell) {                    return cell.value(value);                });            }).handle(arguments);        }        /**         * Gets the parent workbook.         * @returns {Workbook} The parent workbook.         */    }, {        key: "workbook",        value: function workbook() {            return this.sheet().workbook();        }        /**         * Find the extent of the range.         * @returns {undefined}         * @private         */    }, {        key: "_findRangeExtent",        value: function _findRangeExtent() {            this._minRowNumber = Math.min(this._startCell.rowNumber(), this._endCell.rowNumber());            this._maxRowNumber = Math.max(this._startCell.rowNumber(), this._endCell.rowNumber());            this._minColumnNumber = Math.min(this._startCell.columnNumber(), this._endCell.columnNumber());            this._maxColumnNumber = Math.max(this._startCell.columnNumber(), this._endCell.columnNumber());            this._numRows = this._maxRowNumber - this._minRowNumber + 1;            this._numColumns = this._maxColumnNumber - this._minColumnNumber + 1;        }    }]);    return Range;}();module.exports = Range;},{"./ArgHandler":2,"./addressConverter":23}],11:[function(require,module,exports){"use strict";var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var _ = require("lodash");var RELATIONSHIP_SCHEMA_PREFIX = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/";/** * A relationship collection. * @ignore */var Relationships = function () {    /**     * Creates a new instance of _Relationships.     * @param {{}} node - The node.     */    function Relationships(node) {        _classCallCheck(this, Relationships);        this._init(node);        this._getStartingId();    }    /**     * Add a new relationship.     * @param {string} type - The type of relationship.     * @param {string} target - The target of the relationship.     * @param {string} [targetMode] - The target mode of the relationship.     * @returns {{}} The new relationship.     */    _createClass(Relationships, [{        key: "add",        value: function add(type, target, targetMode) {            var node = {                name: "Relationship",                attributes: {                    Id: "rId" + this._nextId++,                    Type: "" + RELATIONSHIP_SCHEMA_PREFIX + type,                    Target: target                }            };            if (targetMode) {                node.attributes.TargetMode = targetMode;            }            this._node.children.push(node);            return node;        }        /**         * Find a relationship by ID.         * @param {string} id - The relationship ID.         * @returns {{}|undefined} The matching relationship or undefined if not found.         */    }, {        key: "findById",        value: function findById(id) {            return _.find(this._node.children, function (node) {                return node.attributes.Id === id;            });        }        /**         * Find a relationship by type.         * @param {string} type - The type to search for.         * @returns {{}|undefined} The matching relationship or undefined if not found.         */    }, {        key: "findByType",        value: function findByType(type) {            return _.find(this._node.children, function (node) {                return node.attributes.Type === "" + RELATIONSHIP_SCHEMA_PREFIX + type;            });        }        /**         * Convert the collection to an XML object.         * @returns {{}|undefined} The XML or undefined if empty.         */    }, {        key: "toXml",        value: function toXml() {            if (!this._node.children.length) return;            return this._node;        }        /**         * Get the starting relationship ID to use for new relationships.         * @private         * @returns {undefined}         */    }, {        key: "_getStartingId",        value: function _getStartingId() {            var _this = this;            this._nextId = 1;            this._node.children.forEach(function (node) {                var id = parseInt(node.attributes.Id.substr(3));                if (id >= _this._nextId) _this._nextId = id + 1;            });        }        /**         * Initialize the node.         * @param {{}} [node] - The relationships node.         * @private         * @returns {undefined}         */    }, {        key: "_init",        value: function _init(node) {            if (!node) node = {                name: "Relationships",                attributes: {                    xmlns: "http://schemas.openxmlformats.org/package/2006/relationships"                },                children: []            };            this._node = node;        }    }]);    return Relationships;}();module.exports = Relationships;/*xl/_rels/workbook.xml.rels<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">    <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>    <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/>    <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/>    <Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/calcChain" Target="calcChain.xml"/>    <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="sharedStrings.xml"/></Relationships>*/},{"lodash":193}],12:[function(require,module,exports){"use strict";var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var _ = require("lodash");var RichTextFragment = require("./RichTextFragment");/** * A RichText class that contains many {@link RichTextFragment}. */var RichText = function () {    /**     * Creates a new instance of RichText. If you get the instance by calling `Cell.value()`,     * adding a text contains line separator will trigger {@link Cell.style}('wrapText', true), which     * will make MS Excel show the new line. i.e. In MS Excel, Tap "alt+Enter" in a cell, the cell     * will set wrap text to true automatically.     *     * @param {undefined|null|Object} [node] - The node stored in the shared string     */    function RichText(node) {        _classCallCheck(this, RichText);        this._node = [];        this._cell = null;        this._remainingNodes = [];        if (node) {            for (var i = 0; i < node.length; i++) {                var fragment = node[i];                if (fragment.name === 'r') {                    this._node.push(new RichTextFragment(fragment, null, this));                } else {                    // special node, e.g. rPh, phoneticPr in Japanese language.                    this._remainingNodes.push(fragment);                }            }        }    }    /**     * Gets which cell this {@link RichText} instance belongs to.     * @return {Cell|undefined} The cell this instance belongs to.     */    _createClass(RichText, [{        key: "text",        /**         * Gets concatenated text without styles.         * @return {string} concatenated text         */        value: function text() {            var text = '';            for (var i = 0; i < this._node.length; i++) {                text += this.get(i).value();            }            return text;        }        /**         * Gets the instance with cell reference defined.         * @param {Cell} cell - Cell reference.         * @return {RichText} The instance with cell reference defined.         */    }, {        key: "getInstanceWithCellRef",        value: function getInstanceWithCellRef(cell) {            this._cell = cell;            return this;        }        /**         * Returns a deep copy of this instance.         * If cell reference is provided, it checks line separators and calls         * `cell.style('wrapText', true)` when needed.         * @param {Cell|undefined} [cell] - The cell reference.         * @return {RichText} A deep copied instance         */    }, {        key: "copy",        value: function copy(cell) {            var newRichText = new RichText(_.cloneDeep(this.toXml()));            if (cell && _.includes(this.text(), '\n')) {                cell.style('wrapText', true);            }            return newRichText;        }        /**         * Gets the ith fragment of this {@link RichText} instance.         * @param {number} index - The index         * @return {RichTextFragment} A rich text fragment         */    }, {        key: "get",        value: function get(index) {            return this._node[index];        }        /**         * Removes a rich text fragment. This instance will be mutated.         * @param {number} index - the index of the fragment to remove         * @return {RichText} the rich text instance         */    }, {        key: "remove",        value: function remove(index) {            this._node.splice(index, 1);            this.removeUnsupportedNodes();            return this;        }        /**         * Adds a rich text fragment to the last or after the given index. This instance will be mutated.         * @param {string} text - the text         * @param {{}} [styles] - the styles js object, i.e. {fontSize: 12}         * @param {number|undefined|null} [index] - the index of the fragment to add         * @return {RichText} the rich text instance         */    }, {        key: "add",        value: function add(text, styles, index) {            if (index === undefined || index === null) {                this._node.push(new RichTextFragment(text, styles, this));            } else {                this._node.splice(index, 0, new RichTextFragment(text, styles, this));            }            this.removeUnsupportedNodes();            return this;        }        /**         * Clears this rich text         * @return {RichText} the rich text instance         */    }, {        key: "clear",        value: function clear() {            this._node = [];            this._remainingNodes = [];            this._cell = undefined;            return this;        }        /**         * Remove all unsupported nodes (phoneticPr, rPh for Japanese language).         * @return {undefined}         */    }, {        key: "removeUnsupportedNodes",        value: function removeUnsupportedNodes() {            this._remainingNodes = [];        }        /**         * Convert the rich text to an XML object.         * @returns {Array.<{}>} The XML form.         * @ignore         */    }, {        key: "toXml",        value: function toXml() {            var node = [];            for (var i = 0; i < this._node.length; i++) {                node.push(this._node[i].toXml());            }            return node.concat(this._remainingNodes);        }    }, {        key: "cell",        get: function get() {            return this._cell;        }        /**         * Gets the how many rich text fragment this {@link RichText} instance contains         * @return {number} The number of fragments this {@link RichText} instance has.         */    }, {        key: "length",        get: function get() {            return this._node.length;        }    }]);    return RichText;}();// IE doesn't support function names so explicitly set it.if (!RichText.name) RichText.name = "RichText";module.exports = RichText;},{"./RichTextFragment":13,"lodash":193}],13:[function(require,module,exports){"use strict";/* eslint camelcase:off */var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var ArgHandler = require("./ArgHandler");var _ = require("lodash");var xmlq = require("./xmlq");var colorIndexes = require("./colorIndexes");/** * A Rich text fragment. */var RichTextFragment = function () {    /**     * Creates a new instance of RichTextFragment.     * @constructor     * @param {string|Object} value - Text value or XML node     * @param {object|undefined|null} [styles] - Multiple styles.     * @param {RichText} richText - The rich text instance where this fragment belongs to.     */    function RichTextFragment(value, styles, richText) {        _classCallCheck(this, RichTextFragment);        this._richText = richText;        if (value.name === 'r') {            this._node = value;            this._fontNode = xmlq.findChild(this._node, 'rPr');            if (!this._fontNode) {                this._fontNode = { name: 'rPr', attributes: {}, children: [] };                this._node.children.unshift(this._fontNode);            }            this._valueNode = xmlq.findChild(this._node, 't');        } else {            this._node = {                name: 'r',                attributes: {},                children: [{ name: 'rPr', attributes: {}, children: [] }, { name: 't', attributes: {}, children: [] }]            };            this._fontNode = xmlq.findChild(this._node, 'rPr');            this._valueNode = xmlq.findChild(this._node, 't');            this.value(value);            if (styles) {                this.style(styles);            }        }    }    /**     * Gets the value of this part of rich text     * @return {string} text     */ /**        * Sets the value of this part of rich text        * @param {string} text - the text to set        * @return {RichTextFragment} - RichTextFragment        */    _createClass(RichTextFragment, [{        key: "value",        value: function value() {            var _this = this;            return new ArgHandler("_RichText.value").case(function () {                return _this._valueNode.children[0];            }).case('string', function (value) {                value = value.replace(/(?:\r\n|\r|\n)/g, '\r\n');                var hasLineSeparator = value.indexOf('\r\n') !== -1;                _this._valueNode.children[0] = value;                if (value.charAt(0) === ' ') xmlq.setAttributes(_this._valueNode, { 'xml:space': 'preserve' });                if (_this._richText) _this._richText.removeUnsupportedNodes();                if (hasLineSeparator) {                    // set wrapText = true if it contains line separator, excel will only display new lines if it sets.                    if (_this._richText.cell) {                        _this._richText.cell.style('wrapText', true);                    }                    xmlq.setAttributes(_this._valueNode, { 'xml:space': 'preserve' });                }                return _this;            }).handle(arguments);        }        /**         * Convert the rich text to an XML object.         * @returns {{}} The XML form.         * @ignore         */    }, {        key: "toXml",        value: function toXml() {            return this._node;        }        /**         * Gets an individual style.         * @param {string} name - The name of the style.         * @returns {*} The style.         */ /**            * Gets multiple styles.            * @param {Array.<string>} names - The names of the style.            * @returns {object.<string, *>} Object whose keys are the style names and values are the styles.            */ /**               * Sets an individual style.               * @param {string} name - The name of the style.               * @param {*} value - The value to set.               * @returns {RichTextFragment} This RichTextFragment.               */ /**                  * Sets multiple styles.                  * @param {object.<string, *>} styles - Object whose keys are the style names and values are the styles to set.                  * @returns {RichTextFragment} This RichTextFragment.                  */    }, {        key: "style",        value: function style() {            var _this2 = this;            return new ArgHandler("_RichText.style").case('string', function (name) {                // Get single value                var getterName = "_get_" + name;                if (!_this2[getterName]) throw new Error("_RichText.style: '" + name + "' is not a valid style");                return _this2[getterName]();            }).case('array', function (names) {                // Get list of values                var values = {};                names.forEach(function (name) {                    values[name] = _this2.style(name);                });                return values;            }).case(['string', '*'], function (name, value) {                // Set a single value                var setterName = "_set_" + name;                if (!_this2[setterName]) throw new Error("_RichText.style: '" + name + "' is not a valid style");                return _this2[setterName](value);            }).case('object', function (nameValues) {                // Object of key value pairs to set                for (var name in nameValues) {                    if (!nameValues.hasOwnProperty(name)) continue;                    var value = nameValues[name];                    _this2.style(name, value);                }                return _this2;            }).handle(arguments);        }    }, {        key: "_getColor",        value: function _getColor(node, name) {            var child = xmlq.findChild(node, name);            if (!child || !child.attributes) return;            var color = {};            if (child.attributes.hasOwnProperty('rgb')) color.rgb = child.attributes.rgb;else if (child.attributes.hasOwnProperty('theme')) color.theme = child.attributes.theme;else if (child.attributes.hasOwnProperty('indexed')) color.rgb = colorIndexes[child.attributes.indexed];            if (child.attributes.hasOwnProperty('tint')) color.tint = child.attributes.tint;            if (_.isEmpty(color)) return;            return color;        }    }, {        key: "_setColor",        value: function _setColor(node, name, color) {            if (typeof color === "string") color = { rgb: color };else if (typeof color === "number") color = { theme: color };            xmlq.setChildAttributes(node, name, {                rgb: color && color.rgb && color.rgb.toUpperCase(),                indexed: null,                theme: color && color.theme,                tint: color && color.tint            });            xmlq.removeChildIfEmpty(node, 'color');        }    }, {        key: "_get_bold",        value: function _get_bold() {            return xmlq.hasChild(this._fontNode, 'b');        }    }, {        key: "_set_bold",        value: function _set_bold(bold) {            if (bold) xmlq.appendChildIfNotFound(this._fontNode, "b");else xmlq.removeChild(this._fontNode, 'b');        }    }, {        key: "_get_italic",        value: function _get_italic() {            return xmlq.hasChild(this._fontNode, 'i');        }    }, {        key: "_set_italic",        value: function _set_italic(italic) {            if (italic) xmlq.appendChildIfNotFound(this._fontNode, "i");else xmlq.removeChild(this._fontNode, 'i');        }    }, {        key: "_get_underline",        value: function _get_underline() {            var uNode = xmlq.findChild(this._fontNode, 'u');            return uNode ? uNode.attributes.val || true : false;        }    }, {        key: "_set_underline",        value: function _set_underline(underline) {            if (underline) {                var uNode = xmlq.appendChildIfNotFound(this._fontNode, "u");                var val = typeof underline === 'string' ? underline : null;                xmlq.setAttributes(uNode, { val: val });            } else {                xmlq.removeChild(this._fontNode, 'u');            }        }    }, {        key: "_get_strikethrough",        value: function _get_strikethrough() {            return xmlq.hasChild(this._fontNode, 'strike');        }    }, {        key: "_set_strikethrough",        value: function _set_strikethrough(strikethrough) {            if (strikethrough) xmlq.appendChildIfNotFound(this._fontNode, "strike");else xmlq.removeChild(this._fontNode, 'strike');        }    }, {        key: "_getFontVerticalAlignment",        value: function _getFontVerticalAlignment() {            return xmlq.getChildAttribute(this._fontNode, 'vertAlign', "val");        }    }, {        key: "_setFontVerticalAlignment",        value: function _setFontVerticalAlignment(alignment) {            xmlq.setChildAttributes(this._fontNode, 'vertAlign', { val: alignment });            xmlq.removeChildIfEmpty(this._fontNode, 'vertAlign');        }    }, {        key: "_get_subscript",        value: function _get_subscript() {            return this._getFontVerticalAlignment() === "subscript";        }    }, {        key: "_set_subscript",        value: function _set_subscript(subscript) {            this._setFontVerticalAlignment(subscript ? "subscript" : null);        }    }, {        key: "_get_superscript",        value: function _get_superscript() {            return this._getFontVerticalAlignment() === "superscript";        }    }, {        key: "_set_superscript",        value: function _set_superscript(superscript) {            this._setFontVerticalAlignment(superscript ? "superscript" : null);        }    }, {        key: "_get_fontSize",        value: function _get_fontSize() {            return xmlq.getChildAttribute(this._fontNode, 'sz', "val");        }    }, {        key: "_set_fontSize",        value: function _set_fontSize(size) {            xmlq.setChildAttributes(this._fontNode, 'sz', { val: size });            xmlq.removeChildIfEmpty(this._fontNode, 'sz');        }    }, {        key: "_get_fontFamily",        value: function _get_fontFamily() {            return xmlq.getChildAttribute(this._fontNode, 'rFont', "val");        }    }, {        key: "_set_fontFamily",        value: function _set_fontFamily(family) {            xmlq.setChildAttributes(this._fontNode, 'rFont', { val: family });            xmlq.removeChildIfEmpty(this._fontNode, 'rFont');        }    }, {        key: "_get_fontGenericFamily",        value: function _get_fontGenericFamily() {            return xmlq.getChildAttribute(this._fontNode, 'family', "val");        }        /**         * @param {number} genericFamily - 1: Serif, 2: Sans Serif, 3: Monospace,         * @private         * @return {undefined}         */    }, {        key: "_set_fontGenericFamily",        value: function _set_fontGenericFamily(genericFamily) {            xmlq.setChildAttributes(this._fontNode, 'family', { val: genericFamily });            xmlq.removeChildIfEmpty(this._fontNode, 'family');        }    }, {        key: "_get_fontColor",        value: function _get_fontColor() {            return this._getColor(this._fontNode, "color");        }    }, {        key: "_set_fontColor",        value: function _set_fontColor(color) {            this._setColor(this._fontNode, "color", color);        }    }, {        key: "_get_fontScheme",        value: function _get_fontScheme() {            // can be 'minor', 'major', 'none'            return xmlq.getChildAttribute(this._fontNode, 'scheme', "val");        }        /**         * @param {string} scheme - 'minor'|'major'|'none'         * @private         * @return {undefined}         */    }, {        key: "_set_fontScheme",        value: function _set_fontScheme(scheme) {            xmlq.setChildAttributes(this._fontNode, 'scheme', { val: scheme });            xmlq.removeChildIfEmpty(this._fontNode, 'scheme');        }    }]);    return RichTextFragment;}();// IE doesn't support function names so explicitly set it.if (!RichTextFragment.name) RichTextFragment.name = "RichTextFragment";module.exports = RichTextFragment;},{"./ArgHandler":2,"./colorIndexes":25,"./xmlq":29,"lodash":193}],14:[function(require,module,exports){"use strict";var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var _ = require("lodash");var Cell = require("./Cell");var regexify = require("./regexify");var ArgHandler = require("./ArgHandler");var addressConverter = require('./addressConverter');/** * A row. */var Row = function () {    // /**    //  * Creates a new instance of Row.    //  * @param {Sheet} sheet - The parent sheet.    //  * @param {{}} node - The row node.    //  */    function Row(sheet, node) {        _classCallCheck(this, Row);        this._sheet = sheet;        this._init(node);    }    /* PUBLIC */    /**     * Get the address of the row.     * @param {{}} [opts] - Options     * @param {boolean} [opts.includeSheetName] - Include the sheet name in the address.     * @param {boolean} [opts.anchored] - Anchor the address.     * @returns {string} The address     */    _createClass(Row, [{        key: "address",        value: function address(opts) {            return addressConverter.toAddress({                type: 'row',                rowNumber: this.rowNumber(),                sheetName: opts && opts.includeSheetName && this.sheet().name(),                rowAnchored: opts && opts.anchored            });        }        /**         * Get a cell in the row.         * @param {string|number} columnNameOrNumber - The name or number of the column.         * @returns {Cell} The cell.         */    }, {        key: "cell",        value: function cell(columnNameOrNumber) {            var columnNumber = columnNameOrNumber;            if (typeof columnNameOrNumber === 'string') {                columnNumber = addressConverter.columnNameToNumber(columnNameOrNumber);            }            if (columnNumber < 1) throw new RangeError("Invalid column number " + columnNumber + ". Remember that spreadsheets use 1-based indexing.");            // Return an existing cell.            if (this._cells[columnNumber]) return this._cells[columnNumber];            // No cell exists for this.            // Check if there is an existing row/column style for the new cell.            var styleId = void 0;            var rowStyleId = this._node.attributes.s;            var columnStyleId = this.sheet().existingColumnStyleId(columnNumber);            // Row style takes priority. If a cell has both row and column styles it should have created a cell entry with a cell-specific style.            if (!_.isNil(rowStyleId)) styleId = rowStyleId;else if (!_.isNil(columnStyleId)) styleId = columnStyleId;            // Create the new cell.            var cell = new Cell(this, columnNumber, styleId);            this._cells[columnNumber] = cell;            return cell;        }        /**         * Gets the row height.         * @returns {undefined|number} The height (or undefined).         */ /**            * Sets the row height.            * @param {number} height - The height of the row.            * @returns {Row} The row.            */    }, {        key: "height",        value: function height() {            var _this = this;            return new ArgHandler('Row.height').case(function () {                return _this._node.attributes.customHeight ? _this._node.attributes.ht : undefined;            }).case('number', function (height) {                _this._node.attributes.ht = height;                _this._node.attributes.customHeight = 1;                return _this;            }).case('nil', function () {                delete _this._node.attributes.ht;                delete _this._node.attributes.customHeight;                return _this;            }).handle(arguments);        }        /**         * Gets a value indicating whether the row is hidden.         * @returns {boolean} A flag indicating whether the row is hidden.         */ /**            * Sets whether the row is hidden.            * @param {boolean} hidden - A flag indicating whether to hide the row.            * @returns {Row} The row.            */    }, {        key: "hidden",        value: function hidden() {            var _this2 = this;            return new ArgHandler("Row.hidden").case(function () {                return _this2._node.attributes.hidden === 1;            }).case('boolean', function (hidden) {                if (hidden) _this2._node.attributes.hidden = 1;else delete _this2._node.attributes.hidden;                return _this2;            }).handle(arguments);        }        /**         * Gets the row number.         * @returns {number} The row number.         */    }, {        key: "rowNumber",        value: function rowNumber() {            return this._node.attributes.r;        }        /**         * Gets the parent sheet of the row.         * @returns {Sheet} The parent sheet.         */    }, {        key: "sheet",        value: function sheet() {            return this._sheet;        }        /**         * Gets an individual style.         * @param {string} name - The name of the style.         * @returns {*} The style.         */ /**            * Gets multiple styles.            * @param {Array.<string>} names - The names of the style.            * @returns {object.<string, *>} Object whose keys are the style names and values are the styles.            */ /**               * Sets an individual style.               * @param {string} name - The name of the style.               * @param {*} value - The value to set.               * @returns {Cell} The cell.               */ /**                  * Sets multiple styles.                  * @param {object.<string, *>} styles - Object whose keys are the style names and values are the styles to set.                  * @returns {Cell} The cell.                  */ /**                     * Sets to a specific style                     * @param {Style} style - Style object given from stylesheet.createStyle                     * @returns {Cell} The cell.                     */    }, {        key: "style",        value: function style() {            var _this3 = this;            return new ArgHandler("Row.style").case('string', function (name) {                // Get single value                _this3._createStyleIfNeeded();                return _this3._style.style(name);            }).case('array', function (names) {                // Get list of values                var values = {};                names.forEach(function (name) {                    values[name] = _this3.style(name);                });                return values;            }).case(['string', '*'], function (name, value) {                _this3._createCellStylesIfNeeded();                // Style each existing cell within this row. (Cells don't inherit ow/column styles.)                _.forEach(_this3._cells, function (cell) {                    if (cell) cell.style(name, value);                });                // Set the style on the row.                _this3._createStyleIfNeeded();                _this3._style.style(name, value);                return _this3;            }).case('object', function (nameValues) {                // Object of key value pairs to set                for (var name in nameValues) {                    if (!nameValues.hasOwnProperty(name)) continue;                    var value = nameValues[name];                    _this3.style(name, value);                }                return _this3;            }).case('Style', function (style) {                _this3._createCellStylesIfNeeded();                // Style each existing cell within this row. (Cells don't inherit ow/column styles.)                _.forEach(_this3._cells, function (cell) {                    if (cell) cell.style(style);                });                _this3._style = style;                _this3._node.attributes.s = style.id();                _this3._node.attributes.customFormat = 1;                return _this3;            }).handle(arguments);        }        /**         * Get the parent workbook.         * @returns {Workbook} The parent workbook.         */    }, {        key: "workbook",        value: function workbook() {            return this.sheet().workbook();        }        /**         * Append horizontal page break after the row.         * @returns {Row} the row.         */    }, {        key: "addPageBreak",        value: function addPageBreak() {            this.sheet().horizontalPageBreaks().add(this.rowNumber());            return this;        }        /* INTERNAL */        /**         * Clear cells that are using a given shared formula ID.         * @param {number} sharedFormulaId - The shared formula ID.         * @returns {undefined}         * @ignore         */    }, {        key: "clearCellsUsingSharedFormula",        value: function clearCellsUsingSharedFormula(sharedFormulaId) {            this._cells.forEach(function (cell) {                if (!cell) return;                if (cell.sharesFormula(sharedFormulaId)) cell.clear();            });        }        /**         * Find a pattern in the row and optionally replace it.         * @param {string|RegExp} pattern - The search pattern.         * @param {string} [replacement] - The replacement text.         * @returns {Array.<Cell>} The matched cells.         * @ignore         */    }, {        key: "find",        value: function find(pattern, replacement) {            pattern = regexify(pattern);            var matches = [];            this._cells.forEach(function (cell) {                if (!cell) return;                if (cell.find(pattern, replacement)) matches.push(cell);            });            return matches;        }        /**         * Check if the row has a cell at the given column number.         * @param {number} columnNumber - The column number.         * @returns {boolean} True if a cell exists, false otherwise.         * @ignore         */    }, {        key: "hasCell",        value: function hasCell(columnNumber) {            if (columnNumber < 1) throw new RangeError("Invalid column number " + columnNumber + ". Remember that spreadsheets use 1-based indexing.");            return !!this._cells[columnNumber];        }        /**         * Check if the column has a style defined.         * @returns {boolean} True if a style exists, false otherwise.         * @ignore         */    }, {        key: "hasStyle",        value: function hasStyle() {            return !_.isNil(this._node.attributes.s);        }        /**         * Returns the nax used column number.         * @returns {number} The max used column number.         * @ignore         */    }, {        key: "minUsedColumnNumber",        value: function minUsedColumnNumber() {            return _.findIndex(this._cells);        }        /**         * Returns the nax used column number.         * @returns {number} The max used column number.         * @ignore         */    }, {        key: "maxUsedColumnNumber",        value: function maxUsedColumnNumber() {            return this._cells.length - 1;        }        /**         * Convert the row to an object.         * @returns {{}} The object form.         * @ignore         */    }, {        key: "toXml",        value: function toXml() {            return this._node;        }        /* PRIVATE */        /**         * If a column node is already defined that intersects with this row and that column has a style set, we         * need to make sure that a cell node exists at the intersection so we can style it appropriately.         * Fetching the cell will force a new cell node to be created with a style matching the column.         * @returns {undefined}         * @private         */    }, {        key: "_createCellStylesIfNeeded",        value: function _createCellStylesIfNeeded() {            var _this4 = this;            this.sheet().forEachExistingColumnNumber(function (columnNumber) {                if (!_.isNil(_this4.sheet().existingColumnStyleId(columnNumber))) _this4.cell(columnNumber);            });        }        /**         * Create a style for this row if it doesn't already exist.         * @returns {undefined}         * @private         */    }, {        key: "_createStyleIfNeeded",        value: function _createStyleIfNeeded() {            if (!this._style) {                var styleId = this._node.attributes.s;                this._style = this.workbook().styleSheet().createStyle(styleId);                this._node.attributes.s = this._style.id();                this._node.attributes.customFormat = 1;            }        }        /**         * Initialize the row node.         * @param {{}} node - The row node.         * @returns {undefined}         * @private         */    }, {        key: "_init",        value: function _init(node) {            var _this5 = this;            this._node = node;            this._cells = [];            this._node.children.forEach(function (cellNode) {                var cell = new Cell(_this5, cellNode);                _this5._cells[cell.columnNumber()] = cell;            });            this._node.children = this._cells;        }    }]);    return Row;}();module.exports = Row;/*<row r="6" spans="1:9" x14ac:dyDescent="0.25">    <c r="A6" s="1" t="s">        <v>2</v>    </c>    <c r="B6" s="1"/>    <c r="C6" s="1"/></row>*/},{"./ArgHandler":2,"./Cell":3,"./addressConverter":23,"./regexify":28,"lodash":193}],15:[function(require,module,exports){"use strict";var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var _ = require("lodash");/** * The shared strings table. * @ignore */var SharedStrings = function () {    /**     * Constructs a new instance of _SharedStrings.     * @param {{}} node - The node.     */    function SharedStrings(node) {        _classCallCheck(this, SharedStrings);        this._stringArray = [];        this._indexMap = {};        this._init(node);        this._cacheExistingSharedStrings();    }    /**     * Gets the index for a string     * @param {string|Array.<{}>} string - The string or rich text array.     * @returns {number} The index     */    _createClass(SharedStrings, [{        key: "getIndexForString",        value: function getIndexForString(string) {            // If the string is found in the cache, return the index.            var key = _.isArray(string) ? JSON.stringify(string) : string;            var index = this._indexMap[key];            if (index >= 0) return index;            // Otherwise, add it to the caches.            index = this._stringArray.length;            this._stringArray.push(string);            this._indexMap[key] = index;            // Append a new si node.            this._node.children.push({                name: "si",                children: _.isArray(string) ? string : [{                    name: "t",                    attributes: { 'xml:space': "preserve" },                    children: [string]                }]            });            return index;        }        /**         * Get the string for a given index         * @param {number} index - The index         * @returns {string} The string         */    }, {        key: "getStringByIndex",        value: function getStringByIndex(index) {            return this._stringArray[index];        }        /**         * Convert the collection to an XML object.         * @returns {{}} The XML object.         */    }, {        key: "toXml",        value: function toXml() {            return this._node;        }        /**         * Store any existing values in the caches.         * @private         * @returns {undefined}         */    }, {        key: "_cacheExistingSharedStrings",        value: function _cacheExistingSharedStrings() {            var _this = this;            this._node.children.forEach(function (node, i) {                var content = node.children[0];                if (content.name === "t") {                    var string = content.children[0];                    _this._stringArray.push(string);                    _this._indexMap[string] = i;                } else {                    // TODO: Properly support rich text nodes in the future. For now just store the object as a placeholder.                    _this._stringArray.push(node.children);                    _this._indexMap[JSON.stringify(node.children)] = i;                }            });        }        /**         * Initialize the node.         * @param {{}} [node] - The shared strings node.         * @private         * @returns {undefined}         */    }, {        key: "_init",        value: function _init(node) {            if (!node) node = {                name: "sst",                attributes: {                    xmlns: "http://schemas.openxmlformats.org/spreadsheetml/2006/main"                },                children: []            };            this._node = node;            delete this._node.attributes.count;            delete this._node.attributes.uniqueCount;        }    }]);    return SharedStrings;}();module.exports = SharedStrings;/*xl/sharedStrings.xml<?xml version="1.0" encoding="UTF-8" standalone="yes"?><sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="13" uniqueCount="4">	<si>		<t>Foo</t>	</si>	<si>		<t>Bar</t>	</si>	<si>		<t>Goo</t>	</si>	<si>		<r>			<t>s</t>		</r><r>			<rPr>				<b/>				<sz val="11"/>				<color theme="1"/>				<rFont val="Calibri"/>				<family val="2"/>				<scheme val="minor"/>			</rPr><t>d;</t>		</r><r>			<rPr>				<sz val="11"/>				<color theme="1"/>				<rFont val="Calibri"/>				<family val="2"/>				<scheme val="minor"/>			</rPr><t>lfk;l</t>		</r>	</si></sst>*/},{"lodash":193}],16:[function(require,module,exports){"use strict";var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var _ = require("lodash");var Cell = require("./Cell");var Row = require("./Row");var Column = require("./Column");var Range = require("./Range");var Relationships = require("./Relationships");var xmlq = require("./xmlq");var regexify = require("./regexify");var addressConverter = require("./addressConverter");var ArgHandler = require("./ArgHandler");var colorIndexes = require("./colorIndexes");var PageBreaks = require("./PageBreaks");// Order of the nodes as defined by the spec.var nodeOrder = ["sheetPr", "dimension", "sheetViews", "sheetFormatPr", "cols", "sheetData", "sheetCalcPr", "sheetProtection", "autoFilter", "protectedRanges", "scenarios", "autoFilter", "sortState", "dataConsolidate", "customSheetViews", "mergeCells", "phoneticPr", "conditionalFormatting", "dataValidations", "hyperlinks", "printOptions", "pageMargins", "pageSetup", "headerFooter", "rowBreaks", "colBreaks", "customProperties", "cellWatches", "ignoredErrors", "smartTags", "drawing", "drawingHF", "legacyDrawing", "legacyDrawingHF", "picture", "oleObjects", "controls", "webPublishItems", "tableParts", "extLst"];/** * A worksheet. */var Sheet = function () {    // /**    //  * Creates a new instance of Sheet.    //  * @param {Workbook} workbook - The parent workbook.    //  * @param {{}} idNode - The sheet ID node (from the parent workbook).    //  * @param {{}} node - The sheet node.    //  * @param {{}} [relationshipsNode] - The optional sheet relationships node.    //  */    function Sheet(workbook, idNode, node, relationshipsNode) {        _classCallCheck(this, Sheet);        this._init(workbook, idNode, node, relationshipsNode);    }    /* PUBLIC */    /**     * Gets a value indicating whether the sheet is the active sheet in the workbook.     * @returns {boolean} True if active, false otherwise.     */ /**        * Make the sheet the active sheet in the workkbok.        * @param {boolean} active - Must be set to `true`. Deactivating directly is not supported. To deactivate, you should activate a different sheet instead.        * @returns {Sheet} The sheet.        */    _createClass(Sheet, [{        key: "active",        value: function active() {            var _this = this;            return new ArgHandler('Sheet.active').case(function () {                return _this.workbook().activeSheet() === _this;            }).case('boolean', function (active) {                if (!active) throw new Error("Deactivating sheet directly not supported. Activate a different sheet instead.");                _this.workbook().activeSheet(_this);                return _this;            }).handle(arguments);        }        /**         * Get the active cell in the sheet.         * @returns {Cell} The active cell.         */ /**            * Set the active cell in the workbook.            * @param {string|Cell} cell - The cell or address of cell to activate.            * @returns {Sheet} The sheet.            */ /**               * Set the active cell in the workbook by row and column.               * @param {number} rowNumber - The row number of the cell.               * @param {string|number} columnNameOrNumber - The column name or number of the cell.               * @returns {Sheet} The sheet.               */    }, {        key: "activeCell",        value: function activeCell() {            var _this2 = this;            var sheetViewNode = this._getOrCreateSheetViewNode();            var selectionNode = xmlq.findChild(sheetViewNode, "selection");            return new ArgHandler('Sheet.activeCell').case(function () {                var cellAddress = selectionNode ? selectionNode.attributes.activeCell : "A1";                return _this2.cell(cellAddress);            }).case(['number', '*'], function (rowNumber, columnNameOrNumber) {                var cell = _this2.cell(rowNumber, columnNameOrNumber);                return _this2.activeCell(cell);            }).case('*', function (cell) {                if (!selectionNode) {                    selectionNode = {                        name: "selection",                        attributes: {},                        children: []                    };                    xmlq.appendChild(sheetViewNode, selectionNode);                }                if (!(cell instanceof Cell)) cell = _this2.cell(cell);                selectionNode.attributes.activeCell = selectionNode.attributes.sqref = cell.address();                return _this2;            }).handle(arguments);        }        /**         * Gets the cell with the given address.         * @param {string} address - The address of the cell.         * @returns {Cell} The cell.         */ /**            * Gets the cell with the given row and column numbers.            * @param {number} rowNumber - The row number of the cell.            * @param {string|number} columnNameOrNumber - The column name or number of the cell.            * @returns {Cell} The cell.            */    }, {        key: "cell",        value: function cell() {            var _this3 = this;            return new ArgHandler('Sheet.cell').case('string', function (address) {                var ref = addressConverter.fromAddress(address);                if (ref.type !== 'cell') throw new Error('Sheet.cell: Invalid address.');                return _this3.row(ref.rowNumber).cell(ref.columnNumber);            }).case(['number', '*'], function (rowNumber, columnNameOrNumber) {                return _this3.row(rowNumber).cell(columnNameOrNumber);            }).handle(arguments);        }        /**         * Gets a column in the sheet.         * @param {string|number} columnNameOrNumber - The name or number of the column.         * @returns {Column} The column.         */    }, {        key: "column",        value: function column(columnNameOrNumber) {            var columnNumber = typeof columnNameOrNumber === "string" ? addressConverter.columnNameToNumber(columnNameOrNumber) : columnNameOrNumber;            // If we're already created a column for this column number, return it.            if (this._columns[columnNumber]) return this._columns[columnNumber];            // We need to create a new column, which requires a backing col node. There may already exist a node whose min/max cover our column.            // First, see if there is an existing col node.            var existingColNode = this._colNodes[columnNumber];            var colNode = void 0;            if (existingColNode) {                // If the existing node covered earlier columns than the new one, we need to have a col node to cover the min up to our new node.                if (existingColNode.attributes.min < columnNumber) {                    // Clone the node and set the max to the column before our new col.                    var beforeColNode = _.cloneDeep(existingColNode);                    beforeColNode.attributes.max = columnNumber - 1;                    // Update the col nodes cache.                    for (var i = beforeColNode.attributes.min; i <= beforeColNode.attributes.max; i++) {                        this._colNodes[i] = beforeColNode;                    }                }                // Make a clone for the new column. Set the min/max to the column number and cache it.                colNode = _.cloneDeep(existingColNode);                colNode.attributes.min = columnNumber;                colNode.attributes.max = columnNumber;                this._colNodes[columnNumber] = colNode;                // If the max of the existing node is greater than the nre one, create a col node for that too.                if (existingColNode.attributes.max > columnNumber) {                    var afterColNode = _.cloneDeep(existingColNode);                    afterColNode.attributes.min = columnNumber + 1;                    for (var _i = afterColNode.attributes.min; _i <= afterColNode.attributes.max; _i++) {                        this._colNodes[_i] = afterColNode;                    }                }            } else {                // The was no existing node so create a new one.                colNode = {                    name: 'col',                    attributes: {                        min: columnNumber,                        max: columnNumber                    },                    children: []                };                this._colNodes[columnNumber] = colNode;            }            // Create the new column and cache it.            var column = new Column(this, colNode);            this._columns[columnNumber] = column;            return column;        }        /**         * Gets a defined name scoped to the sheet.         * @param {string} name - The defined name.         * @returns {undefined|string|Cell|Range|Row|Column} What the defined name refers to or undefined if not found. Will return the string formula if not a Row, Column, Cell, or Range.         */ /**            * Set a defined name scoped to the sheet.            * @param {string} name - The defined name.            * @param {string|Cell|Range|Row|Column} refersTo - What the name refers to.            * @returns {Workbook} The workbook.            */    }, {        key: "definedName",        value: function definedName() {            var _this4 = this;            return new ArgHandler("Workbook.definedName").case('string', function (name) {                return _this4.workbook().scopedDefinedName(_this4, name);            }).case(['string', '*'], function (name, refersTo) {                _this4.workbook().scopedDefinedName(_this4, name, refersTo);                return _this4;            }).handle(arguments);        }        /**         * Deletes the sheet and returns the parent workbook.         * @returns {Workbook} The workbook.         */    }, {        key: "delete",        value: function _delete() {            this.workbook().deleteSheet(this);            return this.workbook();        }        /**         * Find the given pattern in the sheet and optionally replace it.         * @param {string|RegExp} pattern - The pattern to look for. Providing a string will result in a case-insensitive substring search. Use a RegExp for more sophisticated searches.         * @param {string|function} [replacement] - The text to replace or a String.replace callback function. If pattern is a string, all occurrences of the pattern in each cell will be replaced.         * @returns {Array.<Cell>} The matching cells.         */    }, {        key: "find",        value: function find(pattern, replacement) {            pattern = regexify(pattern);            var matches = [];            this._rows.forEach(function (row) {                if (!row) return;                matches = matches.concat(row.find(pattern, replacement));            });            return matches;        }        /**         * Gets a value indicating whether this sheet's grid lines are visible.         * @returns {boolean} True if selected, false if not.         */ /**            * Sets whether this sheet's grid lines are visible.            * @param {boolean} selected - True to make visible, false to hide.            * @returns {Sheet} The sheet.            */    }, {        key: "gridLinesVisible",        value: function gridLinesVisible() {            var _this5 = this;            var sheetViewNode = this._getOrCreateSheetViewNode();            return new ArgHandler('Sheet.gridLinesVisible').case(function () {                return sheetViewNode.attributes.showGridLines === 1 || sheetViewNode.attributes.showGridLines === undefined;            }).case('boolean', function (visible) {                sheetViewNode.attributes.showGridLines = visible ? 1 : 0;                return _this5;            }).handle(arguments);        }        /**         * Gets a value indicating if the sheet is hidden or not.         * @returns {boolean|string} True if hidden, false if visible, and 'very' if very hidden.         */ /**            * Set whether the sheet is hidden or not.            * @param {boolean|string} hidden - True to hide, false to show, and 'very' to make very hidden.            * @returns {Sheet} The sheet.            */    }, {        key: "hidden",        value: function hidden() {            var _this6 = this;            return new ArgHandler('Sheet.hidden').case(function () {                if (_this6._idNode.attributes.state === 'hidden') return true;                if (_this6._idNode.attributes.state === 'veryHidden') return "very";                return false;            }).case('*', function (hidden) {                if (hidden) {                    var visibleSheets = _.filter(_this6.workbook().sheets(), function (sheet) {                        return !sheet.hidden();                    });                    if (visibleSheets.length === 1 && visibleSheets[0] === _this6) {                        throw new Error("This sheet may not be hidden as a workbook must contain at least one visible sheet.");                    }                    // If activate, activate the first other visible sheet.                    if (_this6.active()) {                        var activeIndex = visibleSheets[0] === _this6 ? 1 : 0;                        visibleSheets[activeIndex].active(true);                    }                }                if (hidden === 'very') _this6._idNode.attributes.state = 'veryHidden';else if (hidden) _this6._idNode.attributes.state = 'hidden';else delete _this6._idNode.attributes.state;                return _this6;            }).handle(arguments);        }        /**         * Move the sheet.         * @param {number|string|Sheet} [indexOrBeforeSheet] The index to move the sheet to or the sheet (or name of sheet) to move this sheet before. Omit this argument to move to the end of the workbook.         * @returns {Sheet} The sheet.         */    }, {        key: "move",        value: function move(indexOrBeforeSheet) {            this.workbook().moveSheet(this, indexOrBeforeSheet);            return this;        }        /**         * Get the name of the sheet.         * @returns {string} The sheet name.         */ /**            * Set the name of the sheet. *Note: this method does not rename references to the sheet so formulas, etc. can be broken. Use with caution!*            * @param {string} name - The name to set to the sheet.            * @returns {Sheet} The sheet.            */    }, {        key: "name",        value: function name() {            var _this7 = this;            return new ArgHandler('Sheet.name').case(function () {                return "" + _this7._idNode.attributes.name;            }).case('string', function (name) {                _this7._idNode.attributes.name = name;                return _this7;            }).handle(arguments);        }        /**         * Gets a range from the given range address.         * @param {string} address - The range address (e.g. 'A1:B3').         * @returns {Range} The range.         */ /**            * Gets a range from the given cells or cell addresses.            * @param {string|Cell} startCell - The starting cell or cell address (e.g. 'A1').            * @param {string|Cell} endCell - The ending cell or cell address (e.g. 'B3').            * @returns {Range} The range.            */ /**               * Gets a range from the given row numbers and column names or numbers.               * @param {number} startRowNumber - The starting cell row number.               * @param {string|number} startColumnNameOrNumber - The starting cell column name or number.               * @param {number} endRowNumber - The ending cell row number.               * @param {string|number} endColumnNameOrNumber - The ending cell column name or number.               * @returns {Range} The range.               */    }, {        key: "range",        value: function range() {            var _this8 = this;            return new ArgHandler('Sheet.range').case('string', function (address) {                var ref = addressConverter.fromAddress(address);                if (ref.type !== 'range') throw new Error('Sheet.range: Invalid address');                return _this8.range(ref.startRowNumber, ref.startColumnNumber, ref.endRowNumber, ref.endColumnNumber);            }).case(['*', '*'], function (startCell, endCell) {                if (typeof startCell === "string") startCell = _this8.cell(startCell);                if (typeof endCell === "string") endCell = _this8.cell(endCell);                return new Range(startCell, endCell);            }).case(['number', '*', 'number', '*'], function (startRowNumber, startColumnNameOrNumber, endRowNumber, endColumnNameOrNumber) {                return _this8.range(_this8.cell(startRowNumber, startColumnNameOrNumber), _this8.cell(endRowNumber, endColumnNameOrNumber));            }).handle(arguments);        }        /**         * Unsets sheet autoFilter.         * @returns {Sheet} This sheet.         */ /**            * Sets sheet autoFilter to a Range.            * @param {Range} range - The autoFilter range.            * @returns {Sheet} This sheet.            */    }, {        key: "autoFilter",        value: function autoFilter(range) {            this._autoFilter = range;            return this;        }        /**         * Gets the row with the given number.         * @param {number} rowNumber - The row number.         * @returns {Row} The row with the given number.         */    }, {        key: "row",        value: function row(rowNumber) {            if (rowNumber < 1) throw new RangeError("Invalid row number " + rowNumber + ". Remember that spreadsheets use 1-based indexing.");            if (this._rows[rowNumber]) return this._rows[rowNumber];            var rowNode = {                name: 'row',                attributes: {                    r: rowNumber                },                children: []            };            var row = new Row(this, rowNode);            this._rows[rowNumber] = row;            return row;        }        /**         * Get the tab color. (See style [Color](#color).)         * @returns {undefined|Color} The color or undefined if not set.         */ /**            * Sets the tab color. (See style [Color](#color).)            * @returns {Color|string|number} color - Color of the tab. If string, will set an RGB color. If number, will set a theme color.            */    }, {        key: "tabColor",        value: function tabColor() {            var _this9 = this;            return new ArgHandler("Sheet.tabColor").case(function () {                var tabColorNode = xmlq.findChild(_this9._sheetPrNode, "tabColor");                if (!tabColorNode) return;                var color = {};                if (tabColorNode.attributes.hasOwnProperty('rgb')) color.rgb = tabColorNode.attributes.rgb;else if (tabColorNode.attributes.hasOwnProperty('theme')) color.theme = tabColorNode.attributes.theme;else if (tabColorNode.attributes.hasOwnProperty('indexed')) color.rgb = colorIndexes[tabColorNode.attributes.indexed];                if (tabColorNode.attributes.hasOwnProperty('tint')) color.tint = tabColorNode.attributes.tint;                return color;            }).case("string", function (rgb) {                return _this9.tabColor({ rgb: rgb });            }).case("integer", function (theme) {                return _this9.tabColor({ theme: theme });            }).case("nil", function () {                xmlq.removeChild(_this9._sheetPrNode, "tabColor");                return _this9;            }).case("object", function (color) {                var tabColorNode = xmlq.appendChildIfNotFound(_this9._sheetPrNode, "tabColor");                xmlq.setAttributes(tabColorNode, {                    rgb: color.rgb && color.rgb.toUpperCase(),                    indexed: null,                    theme: color.theme,                    tint: color.tint                });                return _this9;            }).handle(arguments);        }        /**         * Gets a value indicating whether this sheet is selected.         * @returns {boolean} True if selected, false if not.         */ /**            * Sets whether this sheet is selected.            * @param {boolean} selected - True to select, false to deselected.            * @returns {Sheet} The sheet.            */    }, {        key: "tabSelected",        value: function tabSelected() {            var _this10 = this;            var sheetViewNode = this._getOrCreateSheetViewNode();            return new ArgHandler('Sheet.tabSelected').case(function () {                return sheetViewNode.attributes.tabSelected === 1;            }).case('boolean', function (selected) {                if (selected) sheetViewNode.attributes.tabSelected = 1;else delete sheetViewNode.attributes.tabSelected;                return _this10;            }).handle(arguments);        }        /**         * Get the range of cells in the sheet that have contained a value or style at any point. Useful for extracting the entire sheet contents.         * @returns {Range|undefined} The used range or undefined if no cells in the sheet are used.         */    }, {        key: "usedRange",        value: function usedRange() {            var minRowNumber = _.findIndex(this._rows);            var maxRowNumber = this._rows.length - 1;            var minColumnNumber = 0;            var maxColumnNumber = 0;            for (var i = 0; i < this._rows.length; i++) {                var row = this._rows[i];                if (!row) continue;                var minUsedColumnNumber = row.minUsedColumnNumber();                var maxUsedColumnNumber = row.maxUsedColumnNumber();                if (minUsedColumnNumber > 0 && (!minColumnNumber || minUsedColumnNumber < minColumnNumber)) minColumnNumber = minUsedColumnNumber;                if (maxUsedColumnNumber > 0 && (!maxColumnNumber || maxUsedColumnNumber > maxColumnNumber)) maxColumnNumber = maxUsedColumnNumber;            }            // Return undefined if nothing in the sheet is used.            if (minRowNumber <= 0 || minColumnNumber <= 0 || maxRowNumber <= 0 || maxColumnNumber <= 0) return;            return this.range(minRowNumber, minColumnNumber, maxRowNumber, maxColumnNumber);        }        /**         * Gets the parent workbook.         * @returns {Workbook} The parent workbook.         */    }, {        key: "workbook",        value: function workbook() {            return this._workbook;        }        /**         * Gets all page breaks.         * @returns {{}} the object holds both vertical and horizontal PageBreaks.         */    }, {        key: "pageBreaks",        value: function pageBreaks() {            return this._pageBreaks;        }        /**         * Gets the vertical page breaks.         * @returns {PageBreaks} vertical PageBreaks.         */    }, {        key: "verticalPageBreaks",        value: function verticalPageBreaks() {            return this._pageBreaks.colBreaks;        }        /**         * Gets the horizontal page breaks.         * @returns {PageBreaks} horizontal PageBreaks.         */    }, {        key: "horizontalPageBreaks",        value: function horizontalPageBreaks() {            return this._pageBreaks.rowBreaks;        }        /* INTERNAL */        /**         * Clear cells that are using a given shared formula ID.         * @param {number} sharedFormulaId - The shared formula ID.         * @returns {undefined}         * @ignore         */    }, {        key: "clearCellsUsingSharedFormula",        value: function clearCellsUsingSharedFormula(sharedFormulaId) {            this._rows.forEach(function (row) {                if (!row) return;                row.clearCellsUsingSharedFormula(sharedFormulaId);            });        }        /**         * Get an existing column style ID.         * @param {number} columnNumber - The column number.         * @returns {undefined|number} The style ID.         * @ignore         */    }, {        key: "existingColumnStyleId",        value: function existingColumnStyleId(columnNumber) {            // This will work after setting Column.style because Column updates the attributes live.            var colNode = this._colNodes[columnNumber];            return colNode && colNode.attributes.style;        }        /**         * Call a callback for each column number that has a node defined for it.         * @param {Function} callback - The callback.         * @returns {undefined}         * @ignore         */    }, {        key: "forEachExistingColumnNumber",        value: function forEachExistingColumnNumber(callback) {            _.forEach(this._colNodes, function (node, columnNumber) {                if (!node) return;                callback(columnNumber);            });        }        /**         * Call a callback for each existing row.         * @param {Function} callback - The callback.         * @returns {undefined}         * @ignore         */    }, {        key: "forEachExistingRow",        value: function forEachExistingRow(callback) {            _.forEach(this._rows, function (row, rowNumber) {                if (row) callback(row, rowNumber);            });            return this;        }        /**         * Get the hyperlink attached to the cell with the given address.         * @param {string} address - The address of the hyperlinked cell.         * @returns {string|undefined} The hyperlink or undefined if not set.         */ /**            * Set the hyperlink on the cell with the given address.            * @param {string} address - The address of the hyperlinked cell.            * @param {string} hyperlink - The hyperlink to set or undefined to clear.            * @param {boolean} [internal] - The flag to force hyperlink to be internal. If true, then autodetect is skipped.            * @returns {Sheet} The sheet.            */ /**               * Set the hyperlink on the cell with the given address. If opts is a Cell an internal hyperlink is added.               * @param {string} address - The address of the hyperlinked cell.               * @param {object|Cell} opts - Options.               * @returns {Sheet} The sheet.               * @ignore               */ /**                  * Set the hyperlink on the cell with the given address and options.                  * @param {string} address - The address of the hyperlinked cell.                  * @param {{}|Cell} opts - Options or Cell. If opts is a Cell then an internal hyperlink is added.                  * @param {string|Cell} [opts.hyperlink] - The hyperlink to set, can be a Cell or an internal/external string.                  * @param {string} [opts.tooltip] - Additional text to help the user understand more about the hyperlink.                  * @param {string} [opts.email] - Email address, ignored if opts.hyperlink is set.                  * @param {string} [opts.emailSubject] - Email subject, ignored if opts.hyperlink is set.                  * @returns {Sheet} The sheet.                  */    }, {        key: "hyperlink",        value: function hyperlink() {            var _this11 = this;            return new ArgHandler('Sheet.hyperlink').case('string', function (address) {                var hyperlinkNode = _this11._hyperlinks[address];                if (!hyperlinkNode) return;                var relationship = _this11._relationships.findById(hyperlinkNode.attributes['r:id']);                return relationship && relationship.attributes.Target;            }).case(['string', 'nil'], function (address) {                // TODO: delete relationship                delete _this11._hyperlinks[address];                return _this11;            }).case(['string', 'string'], function (address, hyperlink) {                return _this11.hyperlink(address, hyperlink, false);            }).case(['string', 'string', 'boolean'], function (address, hyperlink, internal) {                var isHyperlinkInternalAddress = internal || addressConverter.fromAddress(hyperlink);                var nodeAttributes = void 0;                if (isHyperlinkInternalAddress) {                    nodeAttributes = {                        ref: address,                        location: hyperlink,                        display: hyperlink                    };                } else {                    var relationship = _this11._relationships.add("hyperlink", hyperlink, "External");                    nodeAttributes = {                        ref: address,                        'r:id': relationship.attributes.Id                    };                }                _this11._hyperlinks[address] = {                    name: 'hyperlink',                    attributes: nodeAttributes,                    children: []                };                return _this11;            }).case(['string', 'object'], function (address, opts) {                if (opts instanceof Cell) {                    var cell = opts;                    var hyperlink = cell.address({ includeSheetName: true });                    _this11.hyperlink(address, hyperlink, true);                } else if (opts.hyperlink) {                    _this11.hyperlink(address, opts.hyperlink);                } else if (opts.email) {                    var email = opts.email;                    var subject = opts.emailSubject || '';                    _this11.hyperlink(address, encodeURI("mailto:" + email + "?subject=" + subject));                }                var hyperlinkNode = _this11._hyperlinks[address];                if (hyperlinkNode) {                    if (opts.tooltip) {                        hyperlinkNode.attributes.tooltip = opts.tooltip;                    }                }                return _this11;            }).handle(arguments);        }        /**         * Increment and return the max shared formula ID.         * @returns {number} The new max shared formula ID.         * @ignore         */    }, {        key: "incrementMaxSharedFormulaId",        value: function incrementMaxSharedFormulaId() {            return ++this._maxSharedFormulaId;        }        /**         * Get a value indicating whether the cells in the given address are merged.         * @param {string} address - The address to check.         * @returns {boolean} True if merged, false if not merged.         * @ignore         */ /**            * Merge/unmerge cells by adding/removing a mergeCell entry.            * @param {string} address - The address to merge.            * @param {boolean} merged - True to merge, false to unmerge.            * @returns {Sheet} The sheet.            * @ignore            */    }, {        key: "merged",        value: function merged() {            var _this12 = this;            return new ArgHandler('Sheet.merge').case('string', function (address) {                return _this12._mergeCells.hasOwnProperty(address);            }).case(['string', '*'], function (address, merge) {                if (merge) {                    _this12._mergeCells[address] = {                        name: 'mergeCell',                        attributes: { ref: address },                        children: []                    };                } else {                    delete _this12._mergeCells[address];                }                return _this12;            }).handle(arguments);        }        /**         * Gets a Object or undefined of the cells in the given address.         * @param {string} address - The address to check.         * @returns {object|boolean} Object or false if not set         * @ignore         */ /**            * Removes dataValidation at the given address            * @param {string} address - The address to remove.            * @param {boolean} obj - false to delete.            * @returns {boolean} true if removed.            * @ignore            */ /**               * Add dataValidation to cells at the given address if object or string               * @param {string} address - The address to set.               * @param {object|string} obj - Object or String to set               * @returns {Sheet} The sheet.               * @ignore               */    }, {        key: "dataValidation",        value: function dataValidation() {            var _this13 = this;            return new ArgHandler('Sheet.dataValidation').case('string', function (address) {                if (_this13._dataValidations[address]) {                    return {                        type: _this13._dataValidations[address].attributes.type,                        allowBlank: _this13._dataValidations[address].attributes.allowBlank,                        showInputMessage: _this13._dataValidations[address].attributes.showInputMessage,                        prompt: _this13._dataValidations[address].attributes.prompt,                        promptTitle: _this13._dataValidations[address].attributes.promptTitle,                        showErrorMessage: _this13._dataValidations[address].attributes.showErrorMessage,                        error: _this13._dataValidations[address].attributes.error,                        errorTitle: _this13._dataValidations[address].attributes.errorTitle,                        operator: _this13._dataValidations[address].attributes.operator,                        formula1: _this13._dataValidations[address].children[0].children[0],                        formula2: _this13._dataValidations[address].children[1] ? _this13._dataValidations[address].children[1].children[0] : undefined                    };                } else {                    return false;                }            }).case(['string', 'boolean'], function (address, obj) {                if (_this13._dataValidations[address]) {                    if (obj === false) return delete _this13._dataValidations[address];                } else {                    return false;                }            }).case(['string', '*'], function (address, obj) {                if (typeof obj === 'string') {                    _this13._dataValidations[address] = {                        name: 'dataValidation',                        attributes: {                            type: 'list',                            allowBlank: false,                            showInputMessage: false,                            prompt: '',                            promptTitle: '',                            showErrorMessage: false,                            error: '',                            errorTitle: '',                            operator: '',                            sqref: address                        },                        children: [{                            name: 'formula1',                            atrributes: {},                            children: [obj]                        }, {                            name: 'formula2',                            atrributes: {},                            children: ['']                        }]                    };                } else if ((typeof obj === "undefined" ? "undefined" : _typeof(obj)) === 'object') {                    _this13._dataValidations[address] = {                        name: 'dataValidation',                        attributes: {                            type: obj.type ? obj.type : 'list',                            allowBlank: obj.allowBlank,                            showInputMessage: obj.showInputMessage,                            prompt: obj.prompt,                            promptTitle: obj.promptTitle,                            showErrorMessage: obj.showErrorMessage,                            error: obj.error,                            errorTitle: obj.errorTitle,                            operator: obj.operator,                            sqref: address                        },                        children: [{                            name: 'formula1',                            atrributes: {},                            children: [obj.formula1]                        }, {                            name: 'formula2',                            atrributes: {},                            children: [obj.formula2]                        }]                    };                }                return _this13;            }).handle(arguments);        }        /**         * Convert the sheet to a collection of XML objects.         * @returns {{}} The XML forms.         * @ignore         */    }, {        key: "toXmls",        value: function toXmls() {            var _this14 = this;            // Shallow clone the node so we don't have to remove these children later if they don't belong.            var node = _.clone(this._node);            node.children = node.children.slice();            // Add the columns if needed.            this._colsNode.children = _.filter(this._colNodes, function (colNode, i) {                // Columns should only be present if they have attributes other than min/max.                return colNode && i === colNode.attributes.min && Object.keys(colNode.attributes).length > 2;            });            if (this._colsNode.children.length) {                xmlq.insertInOrder(node, this._colsNode, nodeOrder);            }            // Add the hyperlinks if needed.            this._hyperlinksNode.children = _.values(this._hyperlinks);            if (this._hyperlinksNode.children.length) {                xmlq.insertInOrder(node, this._hyperlinksNode, nodeOrder);            }            // Add the printOptions if needed.            if (this._printOptionsNode) {                if (Object.keys(this._printOptionsNode.attributes).length) {                    xmlq.insertInOrder(node, this._printOptionsNode, nodeOrder);                }            }            // Add the pageMargins if needed.            if (this._pageMarginsNode && this._pageMarginsPresetName) {                // Clone to preserve the current state of this sheet.                var childNode = _.clone(this._pageMarginsNode);                if (Object.keys(this._pageMarginsNode.attributes).length) {                    // Fill in any missing attribute values with presets.                    childNode.attributes = _.assign(this._pageMarginsPresets[this._pageMarginsPresetName], this._pageMarginsNode.attributes);                } else {                    // No need to fill in, all attributes is currently empty, simply replace.                    childNode.attributes = this._pageMarginsPresets[this._pageMarginsPresetName];                }                xmlq.insertInOrder(node, childNode, nodeOrder);            }            // Add the merge cells if needed.            this._mergeCellsNode.children = _.values(this._mergeCells);            if (this._mergeCellsNode.children.length) {                xmlq.insertInOrder(node, this._mergeCellsNode, nodeOrder);            }            // Add the DataValidation cells if needed.            this._dataValidationsNode.children = _.values(this._dataValidations);            if (this._dataValidationsNode.children.length) {                xmlq.insertInOrder(node, this._dataValidationsNode, nodeOrder);            }            if (this._autoFilter) {                xmlq.insertInOrder(node, {                    name: "autoFilter",                    children: [],                    attributes: {                        ref: this._autoFilter.address()                    }                }, nodeOrder);            }            // Add the PageBreaks nodes if needed.            ['colBreaks', 'rowBreaks'].forEach(function (name) {                var breaks = _this14["_" + name + "Node"];                if (breaks.attributes.count) {                    xmlq.insertInOrder(node, breaks, nodeOrder);                }            });            return {                id: this._idNode,                sheet: node,                relationships: this._relationships            };        }        /**         * Update the max shared formula ID to the given value if greater than current.         * @param {number} sharedFormulaId - The new shared formula ID.         * @returns {undefined}         * @ignore         */    }, {        key: "updateMaxSharedFormulaId",        value: function updateMaxSharedFormulaId(sharedFormulaId) {            if (sharedFormulaId > this._maxSharedFormulaId) {                this._maxSharedFormulaId = sharedFormulaId;            }        }        /**         * Get the print option given a valid print option attribute.         * @param {string} attributeName - Attribute name of the printOptions.         *   gridLines - Used in conjunction with gridLinesSet. If both gridLines and gridlinesSet are true, then grid lines shall print. Otherwise, they shall not (i.e., one or both have false values).         *   gridLinesSet - Used in conjunction with gridLines. If both gridLines and gridLinesSet are true, then grid lines shall print. Otherwise, they shall not (i.e., one or both have false values).         *   headings - Print row and column headings.         *   horizontalCentered - Center on page horizontally when printing.         *   verticalCentered - Center on page vertically when printing.         * @returns {boolean}         */ /**            * Set the print option given a valid print option attribute and a value.            * @param {string} attributeName - Attribute name of the printOptions. See get print option for list of valid attributes.            * @param {undefined|boolean} attributeEnabled - If `undefined` or `false` then the attribute is removed, otherwise the print option is enabled.            * @returns {Sheet} The sheet.            */    }, {        key: "printOptions",        value: function printOptions() {            var _this15 = this;            var supportedAttributeNames = ['gridLines', 'gridLinesSet', 'headings', 'horizontalCentered', 'verticalCentered'];            var checkAttributeName = this._getCheckAttributeNameHelper('printOptions', supportedAttributeNames);            return new ArgHandler('Sheet.printOptions').case(['string'], function (attributeName) {                checkAttributeName(attributeName);                return _this15._printOptionsNode.attributes[attributeName] === 1;            }).case(['string', 'nil'], function (attributeName) {                checkAttributeName(attributeName);                delete _this15._printOptionsNode.attributes[attributeName];                return _this15;            }).case(['string', 'boolean'], function (attributeName, attributeEnabled) {                checkAttributeName(attributeName);                if (attributeEnabled) {                    _this15._printOptionsNode.attributes[attributeName] = 1;                    return _this15;                } else {                    return _this15.printOptions(attributeName, undefined);                }            }).handle(arguments);        }        /**         * Get the print option for the gridLines attribute value.         * @returns {boolean}         */ /**            * Set the print option for the gridLines attribute value.            * @param {undefined|boolean} enabled - If `undefined` or `false` then attribute is removed, otherwise gridLines is enabled.            * @returns {Sheet} The sheet.            */    }, {        key: "printGridLines",        value: function printGridLines() {            var _this16 = this;            return new ArgHandler('Sheet.gridLines').case(function () {                return _this16.printOptions('gridLines') && _this16.printOptions('gridLinesSet');            }).case(['nil'], function () {                _this16.printOptions('gridLines', undefined);                _this16.printOptions('gridLinesSet', undefined);                return _this16;            }).case(['boolean'], function (enabled) {                _this16.printOptions('gridLines', enabled);                _this16.printOptions('gridLinesSet', enabled);                return _this16;            }).handle(arguments);        }        /**         * Get the page margin given a valid attribute name.         * If the value is not yet defined, then it will return the current preset value.         * @param {string} attributeName - Attribute name of the pageMargins.         *     left - Left Page Margin in inches.         *     right - Right page margin in inches.         *     top - Top Page Margin in inches.         *     buttom - Bottom Page Margin in inches.         *     footer - Footer Page Margin in inches.         *     header - Header Page Margin in inches.         * @returns {number} the attribute value.         */ /**            * Set the page margin (or override the preset) given an attribute name and a value.            * @param {string} attributeName - Attribute name of the pageMargins. See get page margin for list of valid attributes.            * @param {undefined|number|string} attributeStringValue - If `undefined` then set back to preset value, otherwise, set the given attribute value.            * @returns {Sheet} The sheet.            */    }, {        key: "pageMargins",        value: function pageMargins() {            var _this17 = this;            if (this.pageMarginsPreset() === undefined) {                throw new Error('Sheet.pageMargins: preset is undefined.');            }            var supportedAttributeNames = ['left', 'right', 'top', 'bottom', 'header', 'footer'];            var checkAttributeName = this._getCheckAttributeNameHelper('pageMargins', supportedAttributeNames);            var checkRange = this._getCheckRangeHelper('pageMargins', 0, undefined);            return new ArgHandler('Sheet.pageMargins').case(['string'], function (attributeName) {                checkAttributeName(attributeName);                var attributeValue = _this17._pageMarginsNode.attributes[attributeName];                if (attributeValue !== undefined) {                    return parseFloat(attributeValue);                } else if (_this17._pageMarginsPresetName) {                    return parseFloat(_this17._pageMarginsPresets[_this17._pageMarginsPresetName][attributeName]);                } else {                    return undefined;                }            }).case(['string', 'nil'], function (attributeName) {                checkAttributeName(attributeName);                delete _this17._pageMarginsNode.attributes[attributeName];                return _this17;            }).case(['string', 'number'], function (attributeName, attributeNumberValue) {                checkAttributeName(attributeName);                checkRange(attributeNumberValue);                _this17._pageMarginsNode.attributes[attributeName] = attributeNumberValue;                return _this17;            }).case(['string', 'string'], function (attributeName, attributeStringValue) {                return _this17.pageMargins(attributeName, parseFloat(attributeStringValue));            }).handle(arguments);        }        /**         * Page margins preset is a set of page margins associated with a name.         * The page margin preset acts as a fallback when not explicitly defined by `Sheet.pageMargins`.         * If a sheet already contains page margins, it attempts to auto-detect, otherwise they are defined as the template preset.         * If no page margins exist, then the preset is undefined and will not be included in the output of `Sheet.toXmls`.         * Available presets include: normal, wide, narrow, template.         *         * Get the page margins preset name. The registered name of a predefined set of attributes.         * @returns {string} The preset name.         */ /**            * Set the page margins preset by name, clearing any existing/temporary attribute values.            * @param {undefined|string} presetName - The preset name. If `undefined`, page margins will not be included in the output of `Sheet.toXmls`.            * @returns {Sheet} The sheet.            */ /**               * Set a new page margins preset by name and attributes object.               * @param {string} presetName - The preset name.               * @param {object} presetAttributes - The preset attributes.               * @returns {Sheet} The sheet.               */    }, {        key: "pageMarginsPreset",        value: function pageMarginsPreset() {            var _this18 = this;            return new ArgHandler('Sheet.pageMarginsPreset').case(function () {                return _this18._pageMarginsPresetName;            }).case(['nil'], function () {                // Remove all preset overrides and exclude from sheet                _this18._pageMarginsPresetName = undefined;                // Remove all preset overrides                _this18._pageMarginsNode.attributes = {};                return _this18;            }).case(['string'], function (presetName) {                var checkPresetName = _this18._getCheckAttributeNameHelper('pageMarginsPreset', Object.keys(_this18._pageMarginsPresets));                checkPresetName(presetName);                // Change to new preset                _this18._pageMarginsPresetName = presetName;                // Remove all preset overrides                _this18._pageMarginsNode.attributes = {};                return _this18;            }).case(['string', 'object'], function (presetName, presetAttributes) {                if (_this18._pageMarginsPresets.hasOwnProperty(presetName)) {                    throw new Error("Sheet.pageMarginsPreset: The preset " + presetName + " already exists!");                }                // Validate preset attribute keys.                var pageMarginsAttributeNames = ['left', 'right', 'top', 'bottom', 'header', 'footer'];                var isValidPresetAttributeKeys = _.isEqual(_.sortBy(pageMarginsAttributeNames), _.sortBy(Object.keys(presetAttributes)));                if (isValidPresetAttributeKeys === false) {                    throw new Error("Sheet.pageMarginsPreset: Invalid preset attributes for one or key(s)! - \"" + Object.keys(presetAttributes) + "\"");                }                // Validate preset attribute values.                _.forEach(function (attributeValue, attributeName) {                    var attributeNumberValue = parseFloat(attributeValue);                    if (_.isNaN(attributeNumberValue) || _.isNumber(attributeNumberValue) === false) {                        throw new Error("Sheet.pageMarginsPreset: Invalid preset attribute value! - \"" + attributeValue + "\"");                    }                });                // Change to new preset                _this18._pageMarginsPresetName = presetName;                // Remove all preset overrides                _this18._pageMarginsNode.attributes = {};                // Register the preset                _this18._pageMarginsPresets[presetName] = presetAttributes;                return _this18;            }).handle(arguments);        }        /**         * https://docs.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.pane?view=openxml-2.8.1         * @typedef {Object} PaneOptions         * @property {string} activePane=bottomRight Active Pane. The pane that is active.         * @property {string} state Split State. Indicates whether the pane has horizontal / vertical splits,         * and whether those splits are frozen.         * @property {string} topLeftCell Top Left Visible Cell. Location of the top left visible cell in the bottom         * right pane (when in Left-To-Right mode).         * @property {number} xSplit (Horizontal Split Position) Horizontal position of the split, in 1/20th of a point;         * 0 (zero) if none. If the pane is frozen, this value indicates the number of columns visible in the top pane.         * @property {number} ySplit (Vertical Split Position) Vertical position of the split, in 1/20th of a point; 0         * (zero) if none. If the pane is frozen, this value indicates the number of rows visible in the left pane.         */ /**            * Gets sheet view pane options            * @return {PaneOptions} sheet view pane options            */ /**               * Sets sheet view pane options               * @param {PaneOptions|null|undefined} paneOptions sheet view pane options               * @return {Sheet} The sheet               */    }, {        key: "panes",        value: function panes() {            var _this19 = this;            var supportedStates = ['split', 'frozen', 'frozenSplit'];            var supportedActivePanes = ['bottomLeft', 'bottomRight', 'topLeft', 'topRight'];            var checkStateName = this._getCheckAttributeNameHelper('pane.state', supportedStates);            var checkActivePane = this._getCheckAttributeNameHelper('pane.activePane', supportedActivePanes);            var sheetViewNode = this._getOrCreateSheetViewNode();            var paneNode = xmlq.findChild(sheetViewNode, 'pane');            return new ArgHandler('Sheet.pane').case(function () {                if (paneNode) {                    var result = _.cloneDeep(paneNode.attributes);                    if (!result.state) result.state = 'split';                    return result;                }            }).case(['nil'], function () {                xmlq.removeChild(sheetViewNode, 'pane');                return _this19;            }).case(['object'], function (paneAttributes) {                var attributes = _.assign({ activePane: 'bottomRight' }, paneAttributes);                checkStateName(attributes.state);                checkActivePane(attributes.activePane);                if (paneNode) {                    paneNode.attributes = attributes;                } else {                    paneNode = {                        name: "pane",                        attributes: attributes,                        children: []                    };                    xmlq.appendChild(sheetViewNode, paneNode);                }                return _this19;            }).handle(arguments);        }        /**         * Freezes Panes for this sheet.         * @param {number} xSplit the number of columns visible in the top pane. 0 (zero) if none.         * @param {number} ySplit the number of rows visible in the left pane. 0 (zero) if none.         * @return {Sheet} The sheet         */ /**            * freezes Panes for this sheet.            * @param {string} topLeftCell Top Left Visible Cell. Location of the top left visible cell in the bottom            * right pane (when in Left-To-Right mode).            * @return {Sheet} The sheet            */    }, {        key: "freezePanes",        value: function freezePanes() {            var _this20 = this;            return new ArgHandler('Sheet.feezePanes').case(['integer', 'integer'], function (xSplit, ySplit) {                var topLeftCell = addressConverter.columnNumberToName(xSplit + 1) + (ySplit + 1);                var activePane = xSplit === 0 ? 'bottomLeft' : 'bottomRight';                activePane = ySplit === 0 ? 'topRight' : activePane;                return _this20.panes({ state: 'frozen', topLeftCell: topLeftCell, xSplit: xSplit, ySplit: ySplit, activePane: activePane });            }).case(['string'], function (topLeftCell) {                var ref = addressConverter.fromAddress(topLeftCell);                var xSplit = ref.columnNumber - 1,                    ySplit = ref.rowNumber - 1;                var activePane = xSplit === 0 ? 'bottomLeft' : 'bottomRight';                activePane = ySplit === 0 ? 'topRight' : activePane;                return _this20.panes({ state: 'frozen', topLeftCell: topLeftCell, xSplit: xSplit, ySplit: ySplit, activePane: activePane });            }).handle(arguments);        }        /**         * Splits Panes for this sheet.         * @param {number} xSplit (Horizontal Split Position) Horizontal position of the split,         * in 1/20th of a point; 0 (zero) if none.         * @param {number} ySplit (Vertical Split Position) VVertical position of the split,         * in 1/20th of a point; 0 (zero) if none.         * @return {Sheet} The sheet         */    }, {        key: "splitPanes",        value: function splitPanes(xSplit, ySplit) {            return this.panes({ state: 'split', xSplit: xSplit, ySplit: ySplit });        }        /**         * resets to default sheet view panes.         * @return {Sheet} The sheet         */    }, {        key: "resetPanes",        value: function resetPanes() {            return this.panes(null);        }        /* PRIVATE */        /**         * Get a helper function to check that the attribute name provided is supported.         * @param {string} functionName - Name of the parent function.         * @param {array} supportedAttributeNames - Array of supported attribute name strings.         * @returns {function} The helper function, which takes an attribute name. If the array of supported attribute names does not contain the given attribute name, then an Error is thrown.         * @ignore         */    }, {        key: "_getCheckAttributeNameHelper",        value: function _getCheckAttributeNameHelper(functionName, supportedAttributeNames) {            return function (attributeName) {                if (!_.includes(supportedAttributeNames, attributeName)) {                    throw new Error("Sheet." + functionName + ": \"" + attributeName + "\" is not supported.");                }            };        }        /**         * Get a helper function to check that the value is of the expected type.         * @param {string} functionName - Name of the parent function.         * @param {string} valueType - A string produced by typeof.         * @returns {function} The helper function, which takes a value. If the value type is not expected, a TypeError is thrown.         * @ignore         */    }, {        key: "_getCheckTypeHelper",        value: function _getCheckTypeHelper(functionName, valueType) {            return function (value) {                if ((typeof value === "undefined" ? "undefined" : _typeof(value)) !== valueType) {                    throw new TypeError("Sheet." + functionName + ": invalid type - value must be of type " + valueType + ".");                }            };        }        /**         * Get a helper function to check that the value is within the expected range.         * @param {string} functionName - Name of the parent function.         * @param {undefined|number} valueMin - The minimum value of the range. This value is range-inclusive.         * @param {undefined|number} valueMax - The maximum value of the range. This value is range-exclusive.         * @returns {function} The helper function, which takes a value. If the value type is not 'number', a TypeError is thrown. If the value is not within the range, a RangeError is thrown.         * @ignore         */    }, {        key: "_getCheckRangeHelper",        value: function _getCheckRangeHelper(functionName, valueMin, valueMax) {            var checkType = this._getCheckTypeHelper(functionName, 'number');            return function (value) {                checkType(value);                if (valueMin !== undefined) {                    if (value < valueMin) {                        throw new RangeError("Sheet." + functionName + ": value too small - value must be greater than or equal to " + valueMin + ".");                    }                }                if (valueMax !== undefined) {                    if (valueMax <= value) {                        throw new RangeError("Sheet." + functionName + ": value too large - value must be less than " + valueMax + ".");                    }                }            };        }        /**         * Get the sheet view node if it exists or create it if it doesn't.         * @returns {{}} The sheet view node.         * @private         */    }, {        key: "_getOrCreateSheetViewNode",        value: function _getOrCreateSheetViewNode() {            var sheetViewsNode = xmlq.findChild(this._node, "sheetViews");            if (!sheetViewsNode) {                sheetViewsNode = {                    name: "sheetViews",                    attributes: {},                    children: [{                        name: "sheetView",                        attributes: {                            workbookViewId: 0                        },                        children: []                    }]                };                xmlq.insertInOrder(this._node, sheetViewsNode, nodeOrder);            }            return xmlq.findChild(sheetViewsNode, "sheetView");        }        /**         * Initializes the sheet.         * @param {Workbook} workbook - The parent workbook.         * @param {{}} idNode - The sheet ID node (from the parent workbook).         * @param {{}} node - The sheet node.         * @param {{}} [relationshipsNode] - The optional sheet relationships node.         * @returns {undefined}         * @private         */    }, {        key: "_init",        value: function _init(workbook, idNode, node, relationshipsNode) {            var _this21 = this;            if (!node) {                node = {                    name: "worksheet",                    attributes: {                        xmlns: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",                        'xmlns:r': "http://schemas.openxmlformats.org/officeDocument/2006/relationships",                        'xmlns:mc': "http://schemas.openxmlformats.org/markup-compatibility/2006",                        'mc:Ignorable': "x14ac",                        'xmlns:x14ac': "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac"                    },                    children: [{                        name: "sheetData",                        attributes: {},                        children: []                    }]                };            }            this._workbook = workbook;            this._idNode = idNode;            this._node = node;            this._maxSharedFormulaId = -1;            this._mergeCells = {};            this._dataValidations = {};            this._hyperlinks = {};            this._autoFilter = null;            // Create the relationships.            this._relationships = new Relationships(relationshipsNode);            // Delete the optional dimension node            xmlq.removeChild(this._node, "dimension");            // Create the rows.            this._rows = [];            this._sheetDataNode = xmlq.findChild(this._node, "sheetData");            this._sheetDataNode.children.forEach(function (rowNode) {                var row = new Row(_this21, rowNode);                _this21._rows[row.rowNumber()] = row;            });            this._sheetDataNode.children = this._rows;            // Create the columns node.            this._columns = [];            this._colsNode = xmlq.findChild(this._node, "cols");            if (this._colsNode) {                xmlq.removeChild(this._node, this._colsNode);            } else {                this._colsNode = { name: 'cols', attributes: {}, children: [] };            }            // Cache the col nodes.            this._colNodes = [];            _.forEach(this._colsNode.children, function (colNode) {                var min = colNode.attributes.min;                var max = colNode.attributes.max;                for (var i = min; i <= max; i++) {                    _this21._colNodes[i] = colNode;                }            });            // Create the sheet properties node.            this._sheetPrNode = xmlq.findChild(this._node, "sheetPr");            if (!this._sheetPrNode) {                this._sheetPrNode = { name: 'sheetPr', attributes: {}, children: [] };                xmlq.insertInOrder(this._node, this._sheetPrNode, nodeOrder);            }            // Create the merge cells.            this._mergeCellsNode = xmlq.findChild(this._node, "mergeCells");            if (this._mergeCellsNode) {                xmlq.removeChild(this._node, this._mergeCellsNode);            } else {                this._mergeCellsNode = { name: 'mergeCells', attributes: {}, children: [] };            }            var mergeCellNodes = this._mergeCellsNode.children;            this._mergeCellsNode.children = [];            mergeCellNodes.forEach(function (mergeCellNode) {                _this21._mergeCells[mergeCellNode.attributes.ref] = mergeCellNode;            });            // Create the DataValidations.            this._dataValidationsNode = xmlq.findChild(this._node, "dataValidations");            if (this._dataValidationsNode) {                xmlq.removeChild(this._node, this._dataValidationsNode);            } else {                this._dataValidationsNode = { name: 'dataValidations', attributes: {}, children: [] };            }            var dataValidationNodes = this._dataValidationsNode.children;            this._dataValidationsNode.children = [];            dataValidationNodes.forEach(function (dataValidationNode) {                _this21._dataValidations[dataValidationNode.attributes.sqref] = dataValidationNode;            });            // Create the hyperlinks.            this._hyperlinksNode = xmlq.findChild(this._node, "hyperlinks");            if (this._hyperlinksNode) {                xmlq.removeChild(this._node, this._hyperlinksNode);            } else {                this._hyperlinksNode = { name: 'hyperlinks', attributes: {}, children: [] };            }            var hyperlinkNodes = this._hyperlinksNode.children;            this._hyperlinksNode.children = [];            hyperlinkNodes.forEach(function (hyperlinkNode) {                _this21._hyperlinks[hyperlinkNode.attributes.ref] = hyperlinkNode;            });            // Create the printOptions.            this._printOptionsNode = xmlq.findChild(this._node, "printOptions");            if (this._printOptionsNode) {                xmlq.removeChild(this._node, this._printOptionsNode);            } else {                this._printOptionsNode = { name: 'printOptions', attributes: {}, children: [] };            }            // Create the pageMargins.            this._pageMarginsPresets = {                normal: {                    left: 0.7,                    right: 0.7,                    top: 0.75,                    bottom: 0.75,                    header: 0.3,                    footer: 0.3                },                wide: {                    left: 1,                    right: 1,                    top: 1,                    bottom: 1,                    header: 0.5,                    footer: 0.5                },                narrow: {                    left: 0.25,                    right: 0.25,                    top: 0.75,                    bottom: 0.75,                    header: 0.3,                    footer: 0.3                }            };            this._pageMarginsNode = xmlq.findChild(this._node, "pageMargins");            if (this._pageMarginsNode) {                // Sheet has page margins, assume preset is template.                this._pageMarginsPresetName = 'template';                // Search for a preset that matches existing attributes.                for (var presetName in this._pageMarginsPresets) {                    if (_.isEqual(this._pageMarginsNode.attributes, this._pageMarginsPresets[presetName])) {                        this._pageMarginsPresetName = presetName;                        break;                    }                }                // If template preset, then register as template preset, and clear attributes.                if (this._pageMarginsPresetName === 'template') {                    this._pageMarginsPresets.template = this._pageMarginsNode.attributes;                    this._pageMarginsNode.attributes = {};                }                xmlq.removeChild(this._node, this._pageMarginsNode);            } else {                // Sheet has no page margins, the preset assignment is therefore undefined.                this._pageMarginsPresetName = undefined;                this._pageMarginsNode = { name: 'pageMargins', attributes: {}, children: [] };            }            // Create the pageBreaks            ['colBreaks', 'rowBreaks'].forEach(function (name) {                _this21["_" + name + "Node"] = xmlq.findChild(_this21._node, name);                if (_this21["_" + name + "Node"]) {                    xmlq.removeChild(_this21._node, _this21["_" + name + "Node"]);                } else {                    _this21["_" + name + "Node"] = {                        name: name,                        children: [],                        attributes: {                            count: 0,                            manualBreakCount: 0                        }                    };                }            });            this._pageBreaks = {                colBreaks: new PageBreaks(this._colBreaksNode),                rowBreaks: new PageBreaks(this._rowBreaksNode)            };        }    }]);    return Sheet;}();module.exports = Sheet;/*xl/workbook.xml<?xml version="1.0" encoding="UTF-8" standalone="yes"?><worksheet ...>    ...    <printOptions headings="1" gridLines="1" />    <pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3" />    <pageSetup orientation="portrait" horizontalDpi="0" verticalDpi="0" /></worksheet>// */},{"./ArgHandler":2,"./Cell":3,"./Column":4,"./PageBreaks":9,"./Range":10,"./Relationships":11,"./Row":14,"./addressConverter":23,"./colorIndexes":25,"./regexify":28,"./xmlq":29,"lodash":193}],17:[function(require,module,exports){"use strict";/* eslint camelcase:off */var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var ArgHandler = require("./ArgHandler");var _ = require("lodash");var xmlq = require("./xmlq");var colorIndexes = require("./colorIndexes");/** * A style. * @ignore */var Style = function () {    /**     * Creates a new instance of _Style.     * @constructor     * @param {StyleSheet} styleSheet - The styleSheet.     * @param {number} id - The style ID.     * @param {{}} xfNode - The xf node.     * @param {{}} fontNode - The font node.     * @param {{}} fillNode - The fill node.     * @param {{}} borderNode - The border node.     */    function Style(styleSheet, id, xfNode, fontNode, fillNode, borderNode) {        _classCallCheck(this, Style);        this._styleSheet = styleSheet;        this._id = id;        this._xfNode = xfNode;        this._fontNode = fontNode;        this._fillNode = fillNode;        this._borderNode = borderNode;    }    /**     * Gets the style ID.     * @returns {number} The ID.     */    _createClass(Style, [{        key: "id",        value: function id() {            return this._id;        }        /**         * Gets or sets a style.         * @param {string} name - The style name.         * @param {*} [value] - The value to set.         * @returns {*|Style} The value if getting or the style if setting.         */    }, {        key: "style",        value: function style() {            var _this = this;            return new ArgHandler("_Style.style").case('string', function (name) {                var getterName = "_get_" + name;                if (!_this[getterName]) throw new Error("_Style.style: '" + name + "' is not a valid style");                return _this[getterName]();            }).case(['string', '*'], function (name, value) {                var setterName = "_set_" + name;                if (!_this[setterName]) throw new Error("_Style.style: '" + name + "' is not a valid style");                _this[setterName](value);                return _this;            }).handle(arguments);        }    }, {        key: "_getColor",        value: function _getColor(node, name) {            var child = xmlq.findChild(node, name);            if (!child || !child.attributes) return;            var color = {};            if (child.attributes.hasOwnProperty('rgb')) color.rgb = child.attributes.rgb;else if (child.attributes.hasOwnProperty('theme')) color.theme = child.attributes.theme;else if (child.attributes.hasOwnProperty('indexed')) color.rgb = colorIndexes[child.attributes.indexed];            if (child.attributes.hasOwnProperty('tint')) color.tint = child.attributes.tint;            if (_.isEmpty(color)) return;            return color;        }    }, {        key: "_setColor",        value: function _setColor(node, name, color) {            if (typeof color === "string") color = { rgb: color };else if (typeof color === "number") color = { theme: color };            xmlq.setChildAttributes(node, name, {                rgb: color && color.rgb && color.rgb.toUpperCase(),                indexed: null,                theme: color && color.theme,                tint: color && color.tint            });            xmlq.removeChildIfEmpty(node, 'color');        }    }, {        key: "_get_bold",        value: function _get_bold() {            return xmlq.hasChild(this._fontNode, 'b');        }    }, {        key: "_set_bold",        value: function _set_bold(bold) {            if (bold) xmlq.appendChildIfNotFound(this._fontNode, "b");else xmlq.removeChild(this._fontNode, 'b');        }    }, {        key: "_get_italic",        value: function _get_italic() {            return xmlq.hasChild(this._fontNode, 'i');        }    }, {        key: "_set_italic",        value: function _set_italic(italic) {            if (italic) xmlq.appendChildIfNotFound(this._fontNode, "i");else xmlq.removeChild(this._fontNode, 'i');        }    }, {        key: "_get_underline",        value: function _get_underline() {            var uNode = xmlq.findChild(this._fontNode, 'u');            return uNode ? uNode.attributes.val || true : false;        }    }, {        key: "_set_underline",        value: function _set_underline(underline) {            if (underline) {                var uNode = xmlq.appendChildIfNotFound(this._fontNode, "u");                var val = typeof underline === 'string' ? underline : null;                xmlq.setAttributes(uNode, { val: val });            } else {                xmlq.removeChild(this._fontNode, 'u');            }        }    }, {        key: "_get_strikethrough",        value: function _get_strikethrough() {            return xmlq.hasChild(this._fontNode, 'strike');        }    }, {        key: "_set_strikethrough",        value: function _set_strikethrough(strikethrough) {            if (strikethrough) xmlq.appendChildIfNotFound(this._fontNode, "strike");else xmlq.removeChild(this._fontNode, 'strike');        }    }, {        key: "_getFontVerticalAlignment",        value: function _getFontVerticalAlignment() {            return xmlq.getChildAttribute(this._fontNode, 'vertAlign', "val");        }    }, {        key: "_setFontVerticalAlignment",        value: function _setFontVerticalAlignment(alignment) {            xmlq.setChildAttributes(this._fontNode, 'vertAlign', { val: alignment });            xmlq.removeChildIfEmpty(this._fontNode, 'vertAlign');        }    }, {        key: "_get_subscript",        value: function _get_subscript() {            return this._getFontVerticalAlignment() === "subscript";        }    }, {        key: "_set_subscript",        value: function _set_subscript(subscript) {            this._setFontVerticalAlignment(subscript ? "subscript" : null);        }    }, {        key: "_get_superscript",        value: function _get_superscript() {            return this._getFontVerticalAlignment() === "superscript";        }    }, {        key: "_set_superscript",        value: function _set_superscript(superscript) {            this._setFontVerticalAlignment(superscript ? "superscript" : null);        }    }, {        key: "_get_fontSize",        value: function _get_fontSize() {            return xmlq.getChildAttribute(this._fontNode, 'sz', "val");        }    }, {        key: "_set_fontSize",        value: function _set_fontSize(size) {            xmlq.setChildAttributes(this._fontNode, 'sz', { val: size });            xmlq.removeChildIfEmpty(this._fontNode, 'sz');        }    }, {        key: "_get_fontFamily",        value: function _get_fontFamily() {            return xmlq.getChildAttribute(this._fontNode, 'name', "val");        }    }, {        key: "_set_fontFamily",        value: function _set_fontFamily(family) {            xmlq.setChildAttributes(this._fontNode, 'name', { val: family });            xmlq.removeChildIfEmpty(this._fontNode, 'name');        }    }, {        key: "_get_fontGenericFamily",        value: function _get_fontGenericFamily() {            return xmlq.getChildAttribute(this._fontNode, 'family', "val");        }    }, {        key: "_set_fontGenericFamily",        value: function _set_fontGenericFamily(genericFamily) {            xmlq.setChildAttributes(this._fontNode, 'family', { val: genericFamily });            xmlq.removeChildIfEmpty(this._fontNode, 'family');        }    }, {        key: "_get_fontColor",        value: function _get_fontColor() {            return this._getColor(this._fontNode, "color");        }    }, {        key: "_set_fontColor",        value: function _set_fontColor(color) {            this._setColor(this._fontNode, "color", color);        }    }, {        key: "_get_fontScheme",        value: function _get_fontScheme() {            // can be 'minor', 'major', 'none'            return xmlq.getChildAttribute(this._fontNode, 'scheme', "val");        }    }, {        key: "_set_fontScheme",        value: function _set_fontScheme(scheme) {            xmlq.setChildAttributes(this._fontNode, 'scheme', { val: scheme });            xmlq.removeChildIfEmpty(this._fontNode, 'scheme');        }    }, {        key: "_get_horizontalAlignment",        value: function _get_horizontalAlignment() {            return xmlq.getChildAttribute(this._xfNode, 'alignment', "horizontal");        }    }, {        key: "_set_horizontalAlignment",        value: function _set_horizontalAlignment(alignment) {            xmlq.setChildAttributes(this._xfNode, 'alignment', { horizontal: alignment });            xmlq.removeChildIfEmpty(this._xfNode, 'alignment');        }    }, {        key: "_get_justifyLastLine",        value: function _get_justifyLastLine() {            return xmlq.getChildAttribute(this._xfNode, 'alignment', "justifyLastLine") === 1;        }    }, {        key: "_set_justifyLastLine",        value: function _set_justifyLastLine(justifyLastLine) {            xmlq.setChildAttributes(this._xfNode, 'alignment', { justifyLastLine: justifyLastLine ? 1 : null });            xmlq.removeChildIfEmpty(this._xfNode, 'alignment');        }    }, {        key: "_get_indent",        value: function _get_indent() {            return xmlq.getChildAttribute(this._xfNode, 'alignment', "indent");        }    }, {        key: "_set_indent",        value: function _set_indent(indent) {            xmlq.setChildAttributes(this._xfNode, 'alignment', { indent: indent });            xmlq.removeChildIfEmpty(this._xfNode, 'alignment');        }    }, {        key: "_get_verticalAlignment",        value: function _get_verticalAlignment() {            return xmlq.getChildAttribute(this._xfNode, 'alignment', "vertical");        }    }, {        key: "_set_verticalAlignment",        value: function _set_verticalAlignment(alignment) {            xmlq.setChildAttributes(this._xfNode, 'alignment', { vertical: alignment });            xmlq.removeChildIfEmpty(this._xfNode, 'alignment');        }    }, {        key: "_get_wrapText",        value: function _get_wrapText() {            return xmlq.getChildAttribute(this._xfNode, 'alignment', "wrapText") === 1;        }    }, {        key: "_set_wrapText",        value: function _set_wrapText(wrapText) {            xmlq.setChildAttributes(this._xfNode, 'alignment', { wrapText: wrapText ? 1 : null });            xmlq.removeChildIfEmpty(this._xfNode, 'alignment');        }    }, {        key: "_get_shrinkToFit",        value: function _get_shrinkToFit() {            return xmlq.getChildAttribute(this._xfNode, 'alignment', "shrinkToFit") === 1;        }    }, {        key: "_set_shrinkToFit",        value: function _set_shrinkToFit(shrinkToFit) {            xmlq.setChildAttributes(this._xfNode, 'alignment', { shrinkToFit: shrinkToFit ? 1 : null });            xmlq.removeChildIfEmpty(this._xfNode, 'alignment');        }    }, {        key: "_get_textDirection",        value: function _get_textDirection() {            var readingOrder = xmlq.getChildAttribute(this._xfNode, 'alignment', "readingOrder");            if (readingOrder === 1) return "left-to-right";            if (readingOrder === 2) return "right-to-left";            return readingOrder;        }    }, {        key: "_set_textDirection",        value: function _set_textDirection(textDirection) {            var readingOrder = void 0;            if (textDirection === "left-to-right") readingOrder = 1;else if (textDirection === "right-to-left") readingOrder = 2;            xmlq.setChildAttributes(this._xfNode, 'alignment', { readingOrder: readingOrder });            xmlq.removeChildIfEmpty(this._xfNode, 'alignment');        }    }, {        key: "_getTextRotation",        value: function _getTextRotation() {            return xmlq.getChildAttribute(this._xfNode, 'alignment', "textRotation");        }    }, {        key: "_setTextRotation",        value: function _setTextRotation(textRotation) {            xmlq.setChildAttributes(this._xfNode, 'alignment', { textRotation: textRotation });            xmlq.removeChildIfEmpty(this._xfNode, 'alignment');        }    }, {        key: "_get_textRotation",        value: function _get_textRotation() {            var textRotation = this._getTextRotation();            // Negative angles in Excel correspond to values > 90 in OOXML.            if (textRotation > 90) textRotation = 90 - textRotation;            return textRotation;        }    }, {        key: "_set_textRotation",        value: function _set_textRotation(textRotation) {            // Negative angles in Excel correspond to values > 90 in OOXML.            if (textRotation < 0) textRotation = 90 - textRotation;            this._setTextRotation(textRotation);        }    }, {        key: "_get_angleTextCounterclockwise",        value: function _get_angleTextCounterclockwise() {            return this._getTextRotation() === 45;        }    }, {        key: "_set_angleTextCounterclockwise",        value: function _set_angleTextCounterclockwise(value) {            this._setTextRotation(value ? 45 : null);        }    }, {        key: "_get_angleTextClockwise",        value: function _get_angleTextClockwise() {            return this._getTextRotation() === 135;        }    }, {        key: "_set_angleTextClockwise",        value: function _set_angleTextClockwise(value) {            this._setTextRotation(value ? 135 : null);        }    }, {        key: "_get_rotateTextUp",        value: function _get_rotateTextUp() {            return this._getTextRotation() === 90;        }    }, {        key: "_set_rotateTextUp",        value: function _set_rotateTextUp(value) {            this._setTextRotation(value ? 90 : null);        }    }, {        key: "_get_rotateTextDown",        value: function _get_rotateTextDown() {            return this._getTextRotation() === 180;        }    }, {        key: "_set_rotateTextDown",        value: function _set_rotateTextDown(value) {            this._setTextRotation(value ? 180 : null);        }    }, {        key: "_get_verticalText",        value: function _get_verticalText() {            return this._getTextRotation() === 255;        }    }, {        key: "_set_verticalText",        value: function _set_verticalText(value) {            this._setTextRotation(value ? 255 : null);        }    }, {        key: "_get_fill",        value: function _get_fill() {            var _this2 = this;            var patternFillNode = xmlq.findChild(this._fillNode, 'patternFill'); // jq.get(this._fillNode, "patternFill[0]");            var gradientFillNode = xmlq.findChild(this._fillNode, 'gradientFill'); // jq.get(this._fillNode, "gradientFill[0]");            var patternType = patternFillNode && patternFillNode.attributes.patternType; // jq.get(patternFillNode, "$.patternType");            if (patternType === "solid") {                return {                    type: "solid",                    color: this._getColor(patternFillNode, "fgColor")                };            }            if (patternType) {                return {                    type: "pattern",                    pattern: patternType,                    foreground: this._getColor(patternFillNode, "fgColor"),                    background: this._getColor(patternFillNode, "bgColor")                };            }            if (gradientFillNode) {                var gradientType = gradientFillNode.attributes.type || "linear";                var fill = {                    type: "gradient",                    gradientType: gradientType,                    stops: _.map(gradientFillNode.children, function (stop) {                        return {                            position: stop.attributes.position,                            color: _this2._getColor(stop, "color")                        };                    })                };                if (gradientType === "linear") {                    fill.angle = gradientFillNode.attributes.degree;                } else {                    fill.left = gradientFillNode.attributes.left;                    fill.right = gradientFillNode.attributes.right;                    fill.top = gradientFillNode.attributes.top;                    fill.bottom = gradientFillNode.attributes.bottom;                }                return fill;            }        }    }, {        key: "_set_fill",        value: function _set_fill(fill) {            var _this3 = this;            this._fillNode.children = [];            // No fill            if (_.isNil(fill)) return;            // Pattern fill            if (fill.type === "pattern") {                var _patternFill = {                    name: 'patternFill',                    attributes: { patternType: fill.pattern },                    children: []                };                this._fillNode.children.push(_patternFill);                this._setColor(_patternFill, "fgColor", fill.foreground);                this._setColor(_patternFill, "bgColor", fill.background);                return;            }            // Gradient fill            if (fill.type === "gradient") {                var gradientFill = { name: 'gradientFill', attributes: {}, children: [] };                this._fillNode.children.push(gradientFill);                xmlq.setAttributes(gradientFill, {                    type: fill.gradientType === "path" ? "path" : undefined,                    left: fill.left,                    right: fill.right,                    top: fill.top,                    bottom: fill.bottom,                    degree: fill.angle                });                _.forEach(fill.stops, function (fillStop, i) {                    var stop = {                        name: 'stop',                        attributes: { position: fillStop.position },                        children: []                    };                    gradientFill.children.push(stop);                    _this3._setColor(stop, 'color', fillStop.color);                });                return;            }            // Solid fill (really a pattern fill with a solid pattern type).            if (!_.isObject(fill)) fill = { type: "solid", color: fill };else if (fill.hasOwnProperty('rgb') || fill.hasOwnProperty("theme")) fill = { color: fill };            var patternFill = {                name: 'patternFill',                attributes: { patternType: 'solid' }            };            this._fillNode.children.push(patternFill);            this._setColor(patternFill, "fgColor", fill.color);        }    }, {        key: "_getBorder",        value: function _getBorder() {            var _this4 = this;            var result = {};            ["left", "right", "top", "bottom", "diagonal"].forEach(function (side) {                var sideNode = xmlq.findChild(_this4._borderNode, side);                var sideResult = {};                var style = xmlq.getChildAttribute(_this4._borderNode, side, 'style');                if (style) sideResult.style = style;                var color = _this4._getColor(sideNode, 'color');                if (color) sideResult.color = color;                if (side === "diagonal") {                    var up = _this4._borderNode.attributes.diagonalUp;                    var down = _this4._borderNode.attributes.diagonalDown;                    var direction = void 0;                    if (up && down) direction = "both";else if (up) direction = "up";else if (down) direction = "down";                    if (direction) sideResult.direction = direction;                }                if (!_.isEmpty(sideResult)) result[side] = sideResult;            });            return result;        }    }, {        key: "_setBorder",        value: function _setBorder(settings) {            var _this5 = this;            _.forOwn(settings, function (setting, side) {                if (typeof setting === "boolean") {                    setting = { style: setting ? "thin" : null };                } else if (typeof setting === "string") {                    setting = { style: setting };                } else if (setting === null || setting === undefined) {                    setting = { style: null, color: null, direction: null };                }                if (setting.hasOwnProperty("style")) {                    xmlq.setChildAttributes(_this5._borderNode, side, { style: setting.style });                }                if (setting.hasOwnProperty("color")) {                    var sideNode = xmlq.findChild(_this5._borderNode, side);                    _this5._setColor(sideNode, "color", setting.color);                }                if (side === "diagonal") {                    xmlq.setAttributes(_this5._borderNode, {                        diagonalUp: setting.direction === "up" || setting.direction === "both" ? 1 : null,                        diagonalDown: setting.direction === "down" || setting.direction === "both" ? 1 : null                    });                }            });        }    }, {        key: "_get_border",        value: function _get_border() {            return this._getBorder();        }    }, {        key: "_set_border",        value: function _set_border(settings) {            if (_.isObject(settings) && !settings.hasOwnProperty("style") && !settings.hasOwnProperty("color")) {                settings = _.defaults(settings, {                    left: null,                    right: null,                    top: null,                    bottom: null,                    diagonal: null                });                this._setBorder(settings);            } else {                this._setBorder({                    left: settings,                    right: settings,                    top: settings,                    bottom: settings                });            }        }    }, {        key: "_get_borderColor",        value: function _get_borderColor() {            return _.mapValues(this._getBorder(), function (value) {                return value.color;            });        }    }, {        key: "_set_borderColor",        value: function _set_borderColor(color) {            if (_.isObject(color)) {                this._setBorder(_.mapValues(color, function (color) {                    return { color: color };                }));            } else {                this._setBorder({                    left: { color: color },                    right: { color: color },                    top: { color: color },                    bottom: { color: color },                    diagonal: { color: color }                });            }        }    }, {        key: "_get_borderStyle",        value: function _get_borderStyle() {            return _.mapValues(this._getBorder(), function (value) {                return value.style;            });        }    }, {        key: "_set_borderStyle",        value: function _set_borderStyle(style) {            if (_.isObject(style)) {                this._setBorder(_.mapValues(style, function (style) {                    return { style: style };                }));            } else {                this._setBorder({                    left: { style: style },                    right: { style: style },                    top: { style: style },                    bottom: { style: style }                });            }        }    }, {        key: "_get_diagonalBorderDirection",        value: function _get_diagonalBorderDirection() {            var border = this._getBorder().diagonal;            return border && border.direction;        }    }, {        key: "_set_diagonalBorderDirection",        value: function _set_diagonalBorderDirection(direction) {            this._setBorder({ diagonal: { direction: direction } });        }    }, {        key: "_get_numberFormat",        value: function _get_numberFormat() {            var numFmtId = this._xfNode.attributes.numFmtId || 0;            return this._styleSheet.getNumberFormatCode(numFmtId);        }    }, {        key: "_set_numberFormat",        value: function _set_numberFormat(formatCode) {            this._xfNode.attributes.numFmtId = this._styleSheet.getNumberFormatId(formatCode);        }    }]);    return Style;}();["left", "right", "top", "bottom", "diagonal"].forEach(function (side) {    Style.prototype["_get_" + side + "Border"] = function () {        return this._getBorder()[side];    };    Style.prototype["_set_" + side + "Border"] = function (settings) {        this._setBorder(_defineProperty({}, side, settings));    };    Style.prototype["_get_" + side + "BorderColor"] = function () {        var border = this._getBorder()[side];        return border && border.color;    };    Style.prototype["_set_" + side + "BorderColor"] = function (color) {        this._setBorder(_defineProperty({}, side, { color: color }));    };    Style.prototype["_get_" + side + "BorderStyle"] = function () {        var border = this._getBorder()[side];        return border && border.style;    };    Style.prototype["_set_" + side + "BorderStyle"] = function (style) {        this._setBorder(_defineProperty({}, side, { style: style }));    };});// IE doesn't support function names so explicitly set it.if (!Style.name) Style.name = "Style";module.exports = Style;},{"./ArgHandler":2,"./colorIndexes":25,"./xmlq":29,"lodash":193}],18:[function(require,module,exports){"use strict";var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var _ = require("lodash");var xmlq = require("./xmlq");var Style = require("./Style");/** * Standard number format codes * Taken from http://polymathprogrammer.com/2011/02/15/built-in-styles-for-excel-open-xml/ * @private */var STANDARD_CODES = {    0: 'General',    1: '0',    2: '0.00',    3: '#,##0',    4: '#,##0.00',    9: '0%',    10: '0.00%',    11: '0.00E+00',    12: '# ?/?',    13: '# ??/??',    14: 'mm-dd-yy',    15: 'd-mmm-yy',    16: 'd-mmm',    17: 'mmm-yy',    18: 'h:mm AM/PM',    19: 'h:mm:ss AM/PM',    20: 'h:mm',    21: 'h:mm:ss',    22: 'm/d/yy h:mm',    37: '#,##0 ;(#,##0)',    38: '#,##0 ;[Red](#,##0)',    39: '#,##0.00;(#,##0.00)',    40: '#,##0.00;[Red](#,##0.00)',    45: 'mm:ss',    46: '[h]:mm:ss',    47: 'mmss.0',    48: '##0.0E+0',    49: '@'};/** * The starting ID for custom number formats. The first 163 indexes are reserved. * @private */var STARTING_CUSTOM_NUMBER_FORMAT_ID = 164;/** * A style sheet. * @ignore */var StyleSheet = function () {    /**     * Creates an instance of _StyleSheet.     * @param {string} node - The style sheet node     */    function StyleSheet(node) {        _classCallCheck(this, StyleSheet);        this._init(node);        this._cacheNumberFormats();    }    /**     * Create a style.     * @param {number} [sourceId] - The source style ID to copy, if provided.     * @returns {Style} The style.     */    _createClass(StyleSheet, [{        key: "createStyle",        value: function createStyle(sourceId) {            var fontNode = void 0,                fillNode = void 0,                borderNode = void 0,                xfNode = void 0;            if (sourceId >= 0) {                var sourceXfNode = this._cellXfsNode.children[sourceId];                xfNode = _.cloneDeep(sourceXfNode);                if (sourceXfNode.attributes.applyFont) {                    var fontId = sourceXfNode.attributes.fontId;                    fontNode = _.cloneDeep(this._fontsNode.children[fontId]);                }                if (sourceXfNode.attributes.applyFill) {                    var fillId = sourceXfNode.attributes.fillId;                    fillNode = _.cloneDeep(this._fillsNode.children[fillId]);                }                if (sourceXfNode.attributes.applyBorder) {                    var borderId = sourceXfNode.attributes.borderId;                    borderNode = _.cloneDeep(this._bordersNode.children[borderId]);                }            }            if (!fontNode) fontNode = { name: "font", attributes: {}, children: [] };            this._fontsNode.children.push(fontNode);            if (!fillNode) fillNode = { name: "fill", attributes: {}, children: [] };            this._fillsNode.children.push(fillNode);            // The border sides must be in order            if (!borderNode) borderNode = { name: "border", attributes: {}, children: [] };            borderNode.children = [xmlq.findChild(borderNode, "left") || { name: "left", attributes: {}, children: [] }, xmlq.findChild(borderNode, "right") || { name: "right", attributes: {}, children: [] }, xmlq.findChild(borderNode, "top") || { name: "top", attributes: {}, children: [] }, xmlq.findChild(borderNode, "bottom") || { name: "bottom", attributes: {}, children: [] }, xmlq.findChild(borderNode, "diagonal") || { name: "diagonal", attributes: {}, children: [] }];            this._bordersNode.children.push(borderNode);            if (!xfNode) xfNode = { name: "xf", attributes: {}, children: [] };            _.assign(xfNode.attributes, {                fontId: this._fontsNode.children.length - 1,                fillId: this._fillsNode.children.length - 1,                borderId: this._bordersNode.children.length - 1,                applyFont: 1,                applyFill: 1,                applyBorder: 1            });            this._cellXfsNode.children.push(xfNode);            return new Style(this, this._cellXfsNode.children.length - 1, xfNode, fontNode, fillNode, borderNode);        }        /**         * Get the number format code for a given ID.         * @param {number} id - The number format ID.         * @returns {string} The format code.         */    }, {        key: "getNumberFormatCode",        value: function getNumberFormatCode(id) {            return this._numberFormatCodesById[id];        }        /**         * Get the nuumber format ID for a given code.         * @param {string} code - The format code.         * @returns {number} The number format ID.         */    }, {        key: "getNumberFormatId",        value: function getNumberFormatId(code) {            var id = this._numberFormatIdsByCode[code];            if (id === undefined) {                id = this._nextNumFormatId++;                this._numberFormatCodesById[id] = code;                this._numberFormatIdsByCode[code] = id;                this._numFmtsNode.children.push({                    name: 'numFmt',                    attributes: {                        numFmtId: id,                        formatCode: code                    }                });            }            return id;        }        /**         * Convert the style sheet to an XML object.         * @returns {{}} The XML form.         * @ignore         */    }, {        key: "toXml",        value: function toXml() {            return this._node;        }        /**         * Cache the number format codes         * @returns {undefined}         * @private         */    }, {        key: "_cacheNumberFormats",        value: function _cacheNumberFormats() {            var _this = this;            // Load the standard number format codes into the caches.            this._numberFormatCodesById = {};            this._numberFormatIdsByCode = {};            for (var id in STANDARD_CODES) {                if (!STANDARD_CODES.hasOwnProperty(id)) continue;                var code = STANDARD_CODES[id];                this._numberFormatCodesById[id] = code;                this._numberFormatIdsByCode[code] = parseInt(id);            }            // Set the next number format code.            this._nextNumFormatId = STARTING_CUSTOM_NUMBER_FORMAT_ID;            // If there are custom number formats, cache them all and update the next num as needed.            this._numFmtsNode.children.forEach(function (node) {                var id = node.attributes.numFmtId;                var code = node.attributes.formatCode;                _this._numberFormatCodesById[id] = code;                _this._numberFormatIdsByCode[code] = id;                if (id >= _this._nextNumFormatId) _this._nextNumFormatId = id + 1;            });        }        /**         * Initialize the style sheet node.         * @param {{}} [node] - The node         * @returns {undefined}         * @private         */    }, {        key: "_init",        value: function _init(node) {            this._node = node;            // Cache the refs to the collections.            this._numFmtsNode = xmlq.findChild(this._node, "numFmts");            this._fontsNode = xmlq.findChild(this._node, "fonts");            this._fillsNode = xmlq.findChild(this._node, "fills");            this._bordersNode = xmlq.findChild(this._node, "borders");            this._cellXfsNode = xmlq.findChild(this._node, "cellXfs");            if (!this._numFmtsNode) {                this._numFmtsNode = {                    name: "numFmts",                    attributes: {},                    children: []                };                // Number formats need to be before the others.                xmlq.insertBefore(this._node, this._numFmtsNode, this._fontsNode);            }            // Remove the optional counts so we don't have to keep them up to date.            delete this._numFmtsNode.attributes.count;            delete this._fontsNode.attributes.count;            delete this._fillsNode.attributes.count;            delete this._bordersNode.attributes.count;            delete this._cellXfsNode.attributes.count;        }    }]);    return StyleSheet;}();module.exports = StyleSheet;/*xl/styles.xml<?xml version="1.0" encoding="UTF-8" standalone="yes"?><styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac x16r2" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac" xmlns:x16r2="http://schemas.microsoft.com/office/spreadsheetml/2015/02/main">    <numFmts count="1">        <numFmt numFmtId="164" formatCode="#,##0_);[Red]\(#,##0\)\)"/>    </numFmts>    <fonts count="1" x14ac:knownFonts="1">        <font>            <sz val="11"/>            <color theme="1"/>            <name val="Calibri"/>            <family val="2"/>            <scheme val="minor"/>        </font>    </fonts>    <fills count="11">        <fill>            <patternFill patternType="none"/>        </fill>        <fill>            <patternFill patternType="gray125"/>        </fill>        <fill>            <patternFill patternType="solid">                <fgColor rgb="FFC00000"/>                <bgColor indexed="64"/>            </patternFill>        </fill>        <fill>            <patternFill patternType="lightDown">                <fgColor theme="4"/>                <bgColor rgb="FFC00000"/>            </patternFill>        </fill>        <fill>            <gradientFill degree="90">                <stop position="0">                    <color theme="0"/>                </stop>                <stop position="1">                    <color theme="4"/>                </stop>            </gradientFill>        </fill>        <fill>            <gradientFill>                <stop position="0">                    <color theme="0"/>                </stop>                <stop position="1">                    <color theme="4"/>                </stop>            </gradientFill>        </fill>        <fill>            <gradientFill degree="45">                <stop position="0">                    <color theme="0"/>                </stop>                <stop position="1">                    <color theme="4"/>                </stop>            </gradientFill>        </fill>        <fill>            <gradientFill degree="135">                <stop position="0">                    <color theme="0"/>                </stop>                <stop position="1">                    <color theme="4"/>                </stop>            </gradientFill>        </fill>        <fill>            <gradientFill type="path">                <stop position="0">                    <color theme="0"/>                </stop>                <stop position="1">                    <color theme="4"/>                </stop>            </gradientFill>        </fill>        <fill>            <gradientFill type="path" left="0.5" right="0.5" top="0.5" bottom="0.5">                <stop position="0">                    <color theme="0"/>                </stop>                <stop position="1">                    <color theme="4"/>                </stop>            </gradientFill>        </fill>        <fill>            <gradientFill degree="270">                <stop position="0">                    <color theme="0"/>                </stop>                <stop position="1">                    <color theme="4"/>                </stop>            </gradientFill>        </fill>    </fills>    <borders count="10">        <border>            <left/>            <right/>            <top/>            <bottom/>            <diagonal/>        </border>        <border diagonalDown="1">            <left/>            <right/>            <top/>            <bottom/>            <diagonal style="hair">                <color auto="1"/>            </diagonal>        </border>        <border diagonalDown="1">            <left/>            <right/>            <top/>            <bottom/>            <diagonal style="dotted">                <color auto="1"/>            </diagonal>        </border>        <border diagonalDown="1">            <left/>            <right/>            <top/>            <bottom/>            <diagonal style="dashDotDot">                <color auto="1"/>            </diagonal>        </border>        <border diagonalDown="1">            <left/>            <right/>            <top/>            <bottom/>            <diagonal style="dashDot">                <color auto="1"/>            </diagonal>        </border>        <border diagonalDown="1">            <left/>            <right/>            <top/>            <bottom/>            <diagonal style="dashed">                <color auto="1"/>            </diagonal>        </border>        <border diagonalUp="1">            <left/>            <right/>            <top/>            <bottom/>            <diagonal style="mediumDashDotDot">                <color auto="1"/>            </diagonal>        </border>        <border diagonalUp="1">            <left/>            <right/>            <top/>            <bottom/>            <diagonal style="slantDashDot">                <color auto="1"/>            </diagonal>        </border>        <border diagonalUp="1">            <left/>            <right/>            <top/>            <bottom/>            <diagonal style="mediumDashDot">                <color auto="1"/>            </diagonal>        </border>        <border diagonalUp="1">            <left/>            <right/>            <top/>            <bottom/>            <diagonal style="mediumDashed">                <color auto="1"/>            </diagonal>        </border>    </borders>    <cellStyleXfs count="1">        <xf numFmtId="0" fontId="0" fillId="0" borderId="0"/>    </cellStyleXfs>    <cellXfs count="19">        <xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/>        <xf numFmtId="0" fontId="0" fillId="0" borderId="1" xfId="0" applyBorder="1"/>        <xf numFmtId="0" fontId="0" fillId="0" borderId="2" xfId="0" applyBorder="1"/>        <xf numFmtId="0" fontId="0" fillId="0" borderId="3" xfId="0" applyBorder="1"/>        <xf numFmtId="0" fontId="0" fillId="0" borderId="4" xfId="0" applyBorder="1"/>        <xf numFmtId="0" fontId="0" fillId="0" borderId="5" xfId="0" applyBorder="1"/>        <xf numFmtId="0" fontId="0" fillId="0" borderId="6" xfId="0" applyBorder="1"/>        <xf numFmtId="0" fontId="0" fillId="0" borderId="7" xfId="0" applyBorder="1"/>        <xf numFmtId="0" fontId="0" fillId="0" borderId="8" xfId="0" applyBorder="1"/>        <xf numFmtId="0" fontId="0" fillId="0" borderId="9" xfId="0" applyBorder="1"/>        <xf numFmtId="0" fontId="0" fillId="2" borderId="0" xfId="0" applyFill="1" applyBorder="1"/>        <xf numFmtId="0" fontId="0" fillId="3" borderId="0" xfId="0" applyFill="1"/>        <xf numFmtId="0" fontId="0" fillId="4" borderId="0" xfId="0" applyFill="1"/>        <xf numFmtId="0" fontId="0" fillId="5" borderId="0" xfId="0" applyFill="1"/>        <xf numFmtId="0" fontId="0" fillId="6" borderId="0" xfId="0" applyFill="1"/>        <xf numFmtId="0" fontId="0" fillId="7" borderId="0" xfId="0" applyFill="1"/>        <xf numFmtId="0" fontId="0" fillId="8" borderId="0" xfId="0" applyFill="1"/>        <xf numFmtId="0" fontId="0" fillId="9" borderId="0" xfId="0" applyFill="1"/>        <xf numFmtId="0" fontId="0" fillId="10" borderId="0" xfId="0" applyFill="1"/>    </cellXfs>    <cellStyles count="1">        <cellStyle name="Normal" xfId="0" builtinId="0"/>    </cellStyles>    <dxfs count="0"/>    <tableStyles count="0" defaultTableStyle="TableStyleMedium2" defaultPivotStyle="PivotStyleLight16"/>    <extLst>        <ext uri="{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}" xmlns:x14="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main">            <x14:slicerStyles defaultSlicerStyle="SlicerStyleLight1"/>        </ext>        <ext uri="{9260A510-F301-46a8-8635-F512D64BE5F5}" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main">            <x15:timelineStyles defaultTimelineStyle="TimeSlicerStyleLight1"/>        </ext>    </extLst></styleSheet>*/},{"./Style":17,"./xmlq":29,"lodash":193}],19:[function(require,module,exports){(function (process,Buffer){"use strict";var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var _ = require("lodash");var fs = require("fs");var JSZip = require('jszip');var externals = require("./externals");var regexify = require("./regexify");var blank = require("./blank")();var xmlq = require("./xmlq");var Sheet = require("./Sheet");var ContentTypes = require("./ContentTypes");var AppProperties = require("./AppProperties");var CoreProperties = require("./CoreProperties");var Relationships = require("./Relationships");var SharedStrings = require("./SharedStrings");var StyleSheet = require("./StyleSheet");var Encryptor = require("./Encryptor");var XmlParser = require("./XmlParser");var XmlBuilder = require("./XmlBuilder");var ArgHandler = require("./ArgHandler");var addressConverter = require("./addressConverter");// Options for adding files to zip. Do not create folders and use a fixed time at epoch.// The default JSZip behavior uses current time, which causes idential workbooks to be different each time.var zipFileOpts = {    date: new Date(0),    createFolders: false};// Initialize the parser and builder.var xmlParser = new XmlParser();var xmlBuilder = new XmlBuilder();// Initialize the encryptor if present (can be excluded in browser build).var encryptor = typeof Encryptor === "function" && new Encryptor();// Characters not allowed in sheet names.var badSheetNameChars = ['\\', '/', '*', '[', ']', ':', '?'];// Excel limits sheet names to 31 chars.var maxSheetNameLength = 31;// Order of the nodes as defined by the spec.var nodeOrder = ["fileVersion", "fileSharing", "workbookPr", "workbookProtection", "bookViews", "sheets", "functionGroups", "externalReferences", "definedNames", "calcPr", "oleSize", "customWorkbookViews", "pivotCaches", "smartTagPr", "smartTagTypes", "webPublishing", "fileRecoveryPr", "webPublishObjects", "extLst"];/** * A workbook. */var Workbook = function () {    function Workbook() {        _classCallCheck(this, Workbook);    }    _createClass(Workbook, [{        key: "activeSheet",        /**         * Get the active sheet in the workbook.         * @returns {Sheet} The active sheet.         */ /**            * Set the active sheet in the workbook.            * @param {Sheet|string|number} sheet - The sheet or name of sheet or index of sheet to activate. The sheet must not be hidden.            * @returns {Workbook} The workbook.            */        value: function activeSheet() {            var _this = this;            return new ArgHandler('Workbook.activeSheet').case(function () {                return _this._activeSheet;            }).case('*', function (sheet) {                // Get the sheet from name/index if needed.                if (!(sheet instanceof Sheet)) sheet = _this.sheet(sheet);                // Check if the sheet is hidden.                if (sheet.hidden()) throw new Error("You may not activate a hidden sheet.");                // Deselect all sheets except the active one (mirroring ying Excel behavior).                _.forEach(_this._sheets, function (current) {                    current.tabSelected(current === sheet);                });                _this._activeSheet = sheet;                return _this;            }).handle(arguments);        }        /**         * Add a new sheet to the workbook.         * @param {string} name - The name of the sheet. Must be unique, less than 31 characters, and may not contain the following characters: \ / * [ ] : ?         * @param {number|string|Sheet} [indexOrBeforeSheet] The index to move the sheet to or the sheet (or name of sheet) to move this sheet before. Omit this argument to move to the end of the workbook.         * @returns {Sheet} The new sheet.         */    }, {        key: "addSheet",        value: function addSheet(name, indexOrBeforeSheet) {            return this._addSheet(name, indexOrBeforeSheet);        }        /**         * Gets a defined name scoped to the workbook.         * @param {string} name - The defined name.         * @returns {undefined|string|Cell|Range|Row|Column} What the defined name refers to or undefined if not found. Will return the string formula if not a Row, Column, Cell, or Range.         */ /**            * Set a defined name scoped to the workbook.            * @param {string} name - The defined name.            * @param {string|Cell|Range|Row|Column} refersTo - What the name refers to.            * @returns {Workbook} The workbook.            */    }, {        key: "definedName",        value: function definedName() {            var _this2 = this;            return new ArgHandler("Workbook.definedName").case('string', function (name) {                return _this2.scopedDefinedName(undefined, name);            }).case(['string', '*'], function (name, refersTo) {                _this2.scopedDefinedName(undefined, name, refersTo);                return _this2;            }).handle(arguments);        }        /**         * Delete a sheet from the workbook.         * @param {Sheet|string|number} sheet - The sheet or name of sheet or index of sheet to move.         * @returns {Workbook} The workbook.         */    }, {        key: "deleteSheet",        value: function deleteSheet(sheet) {            // Get the sheet to move.            if (!(sheet instanceof Sheet)) {                sheet = this.sheet(sheet);                if (!sheet) throw new Error("Invalid move sheet reference.");            }            // Make sure we are not deleting the only visible sheet.            var visibleSheets = _.filter(this._sheets, function (sheet) {                return !sheet.hidden();            });            if (visibleSheets.length === 1 && visibleSheets[0] === sheet) {                throw new Error("This sheet may not be deleted as a workbook must contain at least one visible sheet.");            }            // Remove the sheet.            var index = this._sheets.indexOf(sheet);            this._sheets.splice(index, 1);            // Set the new active sheet.            if (sheet === this.activeSheet()) {                if (index >= this._sheets.length) index--;                this.activeSheet(index);            }            return this;        }        /**         * Find the given pattern in the workbook and optionally replace it.         * @param {string|RegExp} pattern - The pattern to look for. Providing a string will result in a case-insensitive substring search. Use a RegExp for more sophisticated searches.         * @param {string|function} [replacement] - The text to replace or a String.replace callback function. If pattern is a string, all occurrences of the pattern in each cell will be replaced.         * @returns {boolean} A flag indicating if the pattern was found.         */    }, {        key: "find",        value: function find(pattern, replacement) {            pattern = regexify(pattern);            var matches = [];            this._sheets.forEach(function (sheet) {                matches = matches.concat(sheet.find(pattern, replacement));            });            return matches;        }        /**         * Move a sheet to a new position.         * @param {Sheet|string|number} sheet - The sheet or name of sheet or index of sheet to move.         * @param {number|string|Sheet} [indexOrBeforeSheet] The index to move the sheet to or the sheet (or name of sheet) to move this sheet before. Omit this argument to move to the end of the workbook.         * @returns {Workbook} The workbook.         */    }, {        key: "moveSheet",        value: function moveSheet(sheet, indexOrBeforeSheet) {            // Get the sheet to move.            if (!(sheet instanceof Sheet)) {                sheet = this.sheet(sheet);                if (!sheet) throw new Error("Invalid move sheet reference.");            }            // Get the to/from indexes.            var from = this._sheets.indexOf(sheet);            var to = void 0;            if (_.isNil(indexOrBeforeSheet)) {                to = this._sheets.length - 1;            } else if (_.isInteger(indexOrBeforeSheet)) {                to = indexOrBeforeSheet;            } else {                if (!(indexOrBeforeSheet instanceof Sheet)) {                    indexOrBeforeSheet = this.sheet(indexOrBeforeSheet);                    if (!indexOrBeforeSheet) throw new Error("Invalid before sheet reference.");                }                to = this._sheets.indexOf(indexOrBeforeSheet);            }            // Insert the sheet at the appropriate place.            this._sheets.splice(to, 0, this._sheets.splice(from, 1)[0]);            return this;        }        /**         * Generates the workbook output.         * @param {string} [type] - The type of the data to return: base64, binarystring, uint8array, arraybuffer, blob, nodebuffer. Defaults to 'nodebuffer' in Node.js and 'blob' in browsers.         * @returns {string|Uint8Array|ArrayBuffer|Blob|Buffer} The data.         */ /**            * Generates the workbook output.            * @param {{}} [opts] Options            * @param {string} [opts.type] - The type of the data to return: base64, binarystring, uint8array, arraybuffer, blob, nodebuffer. Defaults to 'nodebuffer' in Node.js and 'blob' in browsers.            * @param {string} [opts.password] - The password to use to encrypt the workbook.            * @returns {string|Uint8Array|ArrayBuffer|Blob|Buffer} The data.            */    }, {        key: "outputAsync",        value: function outputAsync(opts) {            var _this3 = this;            opts = opts || {};            if (typeof opts === 'string') opts = { type: opts };            this._setSheetRefs();            var definedNamesNode = xmlq.findChild(this._node, "definedNames");            this._sheets.forEach(function (sheet, i) {                if (!sheet._autoFilter) return;                if (!definedNamesNode) {                    definedNamesNode = {                        name: "definedNames",                        attributes: {},                        children: []                    };                    xmlq.insertInOrder(_this3._node, definedNamesNode, nodeOrder);                }                xmlq.appendChild(definedNamesNode, {                    name: "definedName",                    attributes: {                        name: "_xlnm._FilterDatabase",                        localSheetId: i,                        hidden: "1"                    },                    children: [sheet._autoFilter.address({ includeSheetName: true, anchored: true })]                });            });            this._sheetsNode.children = [];            this._sheets.forEach(function (sheet, i) {                var sheetPath = "xl/worksheets/sheet" + (i + 1) + ".xml";                var sheetRelsPath = "xl/worksheets/_rels/sheet" + (i + 1) + ".xml.rels";                var sheetXmls = sheet.toXmls();                var relationship = _this3._relationships.findById(sheetXmls.id.attributes['r:id']);                relationship.attributes.Target = "worksheets/sheet" + (i + 1) + ".xml";                _this3._sheetsNode.children.push(sheetXmls.id);                _this3._zip.file(sheetPath, xmlBuilder.build(sheetXmls.sheet), zipFileOpts);                var relationshipsXml = xmlBuilder.build(sheetXmls.relationships);                if (relationshipsXml) {                    _this3._zip.file(sheetRelsPath, relationshipsXml, zipFileOpts);                } else {                    _this3._zip.remove(sheetRelsPath);                }            });            // Set the app security to true if a password is set, false if not.            // this._appProperties.isSecure(!!opts.password);            // Convert the various components to XML strings and add them to the zip.            this._zip.file("[Content_Types].xml", xmlBuilder.build(this._contentTypes), zipFileOpts);            this._zip.file("docProps/app.xml", xmlBuilder.build(this._appProperties), zipFileOpts);            this._zip.file("docProps/core.xml", xmlBuilder.build(this._coreProperties), zipFileOpts);            this._zip.file("xl/_rels/workbook.xml.rels", xmlBuilder.build(this._relationships), zipFileOpts);            this._zip.file("xl/sharedStrings.xml", xmlBuilder.build(this._sharedStrings), zipFileOpts);            this._zip.file("xl/styles.xml", xmlBuilder.build(this._styleSheet), zipFileOpts);            this._zip.file("xl/workbook.xml", xmlBuilder.build(this._node), zipFileOpts);            // Generate the zip.            return this._zip.generateAsync({                type: "nodebuffer",                compression: "DEFLATE"            }).then(function (output) {                // If a password is set, encrypt the workbook.                if (opts.password) output = encryptor.encrypt(output, opts.password);                // Convert and return                return _this3._convertBufferToOutput(output, opts.type);            });        }        /**         * Gets the sheet with the provided name or index (0-based).         * @param {string|number} sheetNameOrIndex - The sheet name or index.         * @returns {Sheet|undefined} The sheet or undefined if not found.         */    }, {        key: "sheet",        value: function sheet(sheetNameOrIndex) {            if (_.isInteger(sheetNameOrIndex)) return this._sheets[sheetNameOrIndex];            return _.find(this._sheets, function (sheet) {                return sheet.name() === sheetNameOrIndex;            });        }        /**         * Get an array of all the sheets in the workbook.         * @returns {Array.<Sheet>} The sheets.         */    }, {        key: "sheets",        value: function sheets() {            return this._sheets.slice();        }        /**         * Gets an individual property.         * @param {string} name - The name of the property.         * @returns {*} The property.         */ /**            * Gets multiple properties.            * @param {Array.<string>} names - The names of the properties.            * @returns {object.<string, *>} Object whose keys are the property names and values are the properties.            */ /**               * Sets an individual property.               * @param {string} name - The name of the property.               * @param {*} value - The value to set.               * @returns {Workbook} The workbook.               */ /**                  * Sets multiple properties.                  * @param {object.<string, *>} properties - Object whose keys are the property names and values are the values to set.                  * @returns {Workbook} The workbook.                  */    }, {        key: "property",        value: function property() {            var _this4 = this;            return new ArgHandler("Workbook.property").case('string', function (name) {                // Get single value                return _this4._coreProperties.get(name);            }).case('array', function (names) {                // Get list of values                var values = {};                names.forEach(function (name) {                    values[name] = _this4._coreProperties.get(name);                });                return values;            }).case(['string', '*'], function (name, value) {                // Set a single value for all cells to a single value                _this4._coreProperties.set(name, value);                return _this4;            }).case('object', function (nameValues) {                // Object of key value pairs to set                for (var name in nameValues) {                    if (!nameValues.hasOwnProperty(name)) continue;                    var value = nameValues[name];                    _this4._coreProperties.set(name, value);                }                return _this4;            }).handle(arguments);        }        /**         * Get access to core properties object         * @returns {CoreProperties} The core properties.         */    }, {        key: "properties",        value: function properties() {            return this._coreProperties;        }        /**         * Write the workbook to file. (Not supported in browsers.)         * @param {string} path - The path of the file to write.         * @param {{}} [opts] - Options         * @param {string} [opts.password] - The password to encrypt the workbook.         * @returns {Promise.<undefined>} A promise.         */    }, {        key: "toFileAsync",        value: function toFileAsync(path, opts) {            if (process.browser) throw new Error("Workbook.toFileAsync is not supported in the browser.");            return this.outputAsync(opts).then(function (data) {                return new externals.Promise(function (resolve, reject) {                    fs.writeFile(path, data, function (err) {                        if (err) return reject(err);                        resolve();                    });                });            });        }        /**         * Gets a scoped defined name.         * @param {Sheet} sheetScope - The sheet the name is scoped to. Use undefined for workbook scope.         * @param {string} name - The defined name.         * @returns {undefined|Cell|Range|Row|Column} What the defined name refers to.         * @ignore         */ /**            * Sets a scoped defined name.            * @param {Sheet} sheetScope - The sheet the name is scoped to. Use undefined for workbook scope.            * @param {string} name - The defined name.            * @param {undefined|Cell|Range|Row|Column} refersTo - What the defined name refers to.            * @returns {Workbook} The workbook.            * @ignore            */    }, {        key: "scopedDefinedName",        value: function scopedDefinedName(sheetScope, name, refersTo) {            var _this5 = this;            var definedNamesNode = xmlq.findChild(this._node, "definedNames");            var definedNameNode = definedNamesNode && _.find(definedNamesNode.children, function (node) {                return node.attributes.name === name && node.localSheet === sheetScope;            });            return new ArgHandler('Workbook.scopedDefinedName').case(['*', 'string'], function () {                // Get the address from the definedNames node.                var refersTo = definedNameNode && definedNameNode.children[0];                if (!refersTo) return undefined;                // Try to parse the address.                var ref = addressConverter.fromAddress(refersTo);                if (!ref) return refersTo;                // Load the appropriate selection type.                var sheet = _this5.sheet(ref.sheetName);                if (ref.type === 'cell') return sheet.cell(ref.rowNumber, ref.columnNumber);                if (ref.type === 'range') return sheet.range(ref.startRowNumber, ref.startColumnNumber, ref.endRowNumber, ref.endColumnNumber);                if (ref.type === 'row') return sheet.row(ref.rowNumber);                if (ref.type === 'column') return sheet.column(ref.columnNumber);                return refersTo;            }).case(['*', 'string', 'nil'], function () {                if (definedNameNode) xmlq.removeChild(definedNamesNode, definedNameNode);                if (definedNamesNode && !definedNamesNode.children.length) xmlq.removeChild(_this5._node, definedNamesNode);                return _this5;            }).case(['*', 'string', '*'], function () {                if (typeof refersTo !== 'string') {                    refersTo = refersTo.address({                        includeSheetName: true,                        anchored: true                    });                }                if (!definedNamesNode) {                    definedNamesNode = {                        name: "definedNames",                        attributes: {},                        children: []                    };                    xmlq.insertInOrder(_this5._node, definedNamesNode, nodeOrder);                }                if (!definedNameNode) {                    definedNameNode = {                        name: "definedName",                        attributes: { name: name },                        children: [refersTo]                    };                    if (sheetScope) definedNameNode.localSheet = sheetScope;                    xmlq.appendChild(definedNamesNode, definedNameNode);                }                definedNameNode.children = [refersTo];                return _this5;            }).handle(arguments);        }        /**         * Get the shared strings table.         * @returns {SharedStrings} The shared strings table.         * @ignore         */    }, {        key: "sharedStrings",        value: function sharedStrings() {            return this._sharedStrings;        }        /**         * Get the style sheet.         * @returns {StyleSheet} The style sheet.         * @ignore         */    }, {        key: "styleSheet",        value: function styleSheet() {            return this._styleSheet;        }        /**         * Add a new sheet to the workbook.         *          * **WARN:** this function has limits:  if you clone a sheet with some images or other things link outside the Sheet object, these things in the cloned sheet will be locked when you open in MS Excel app.         * @param {Sheet} from - The sheet to be cloned.         * @param {string} name - The name of the new sheet. Must be unique, less than 31 characters, and may not contain the following characters: \ / * [ ] : ?         * @param {number|string|Sheet} [indexOrBeforeSheet] The index to move the sheet to or the sheet (or name of sheet) to move this sheet before. Omit this argument to move to the end of the workbook.         * @returns {Sheet} The new sheet.         */    }, {        key: "cloneSheet",        value: function cloneSheet(from, name, indexOrBeforeSheet) {            if (!from || !(from instanceof Sheet)) throw new Error("Invalid clone from.");            return this._addSheet(name, indexOrBeforeSheet, function () {                var cloneXml = function cloneXml(node) {                    // If the node has a toXml method, call it.                    if (node && _.isFunction(node.toXml)) node = node.toXml();                    if ((typeof node === "undefined" ? "undefined" : _typeof(node)) === 'object') {                        if (node.name) {                            var result = {                                name: node.name,                                attributes: {},                                children: []                            };                            _.forOwn(node.attributes, function (value, name) {                                result.attributes[name] = value;                            });                            var chld = void 0;                            if (node.children) {                                node.children.forEach(function (child) {                                    chld = cloneXml(child);                                    if (child !== null) {                                        result.children.push(chld);                                    }                                });                            }                            return result;                        }                    } else if (node !== null) {                        return node;                    }                    return null;                };                // clone SheetNode & relationshipNode from source                var fromXml = from.toXmls();                var sheetNode = cloneXml(fromXml.sheet);                var relationshipNode = cloneXml(fromXml.relationships);                return { sheetNode: sheetNode, relationshipNode: relationshipNode };            });        }        /**         * Add a new sheet to the workbook.         * @param {string} name - The name of the sheet. Must be unique, less than 31 characters, and may not contain the following characters: \ / * [ ] : ?         * @param {number|string|Sheet} [indexOrBeforeSheet] The index to move the sheet to or the sheet (or name of sheet) to move this sheet before. Omit this argument to move to the end of the workbook.         * @param {callback} [getTemplateNodes] optional callback function for template nodes         * @returns {Sheet} The new sheet.         * @private         */    }, {        key: "_addSheet",        value: function _addSheet(name, indexOrBeforeSheet, getTemplateNodes) {            // Validate the sheet name.            if (!name || typeof name !== "string") throw new Error("Invalid sheet name.");            if (_.some(badSheetNameChars, function (char) {                return name.indexOf(char) >= 0;            })) throw new Error("Sheet name may not contain any of the following characters: " + badSheetNameChars.join(" "));            if (name.length > maxSheetNameLength) throw new Error("Sheet name may not be greater than " + maxSheetNameLength + " characters.");            if (this.sheet(name)) throw new Error("Sheet with name \"" + name + "\" already exists.");            // Get the destination index of new sheet.            var index = void 0;            if (_.isNil(indexOrBeforeSheet)) {                index = this._sheets.length;            } else if (_.isInteger(indexOrBeforeSheet)) {                index = indexOrBeforeSheet;            } else {                if (!(indexOrBeforeSheet instanceof Sheet)) {                    indexOrBeforeSheet = this.sheet(indexOrBeforeSheet);                    if (!indexOrBeforeSheet) throw new Error("Invalid before sheet reference.");                }                index = this._sheets.indexOf(indexOrBeforeSheet);            }            // Add a new relationship for the new sheet and create the new sheet ID node.            var relationship = this._relationships.add("worksheet"); // Leave target blank as it will be filled later.            var sheetIdNode = {                name: "sheet",                attributes: {                    name: name,                    sheetId: ++this._maxSheetId,                    'r:id': relationship.attributes.Id                },                children: []            };            // Create the new sheet.            var sheet = void 0;            if (getTemplateNodes) {                var _getTemplateNodes = getTemplateNodes(),                    sheetNode = _getTemplateNodes.sheetNode,                    relationshipNode = _getTemplateNodes.relationshipNode;                sheet = new Sheet(this, sheetIdNode, sheetNode, relationshipNode);            } else {                sheet = new Sheet(this, sheetIdNode);            }            // Insert the sheet at the appropriate index.            this._sheets.splice(index, 0, sheet);            return sheet;        }        /**         * Initialize the workbook. (This is separated from the constructor to ease testing.)         * @param {string|ArrayBuffer|Uint8Array|Buffer|Blob} data - The data to load.         * @param {{}} [opts] - Options         * @param {boolean} [opts.base64=false] - No used unless input is a string. True if the input string is base64 encoded, false for binary.         * @returns {Promise.<Workbook>} The workbook.         * @private         */    }, {        key: "_initAsync",        value: function _initAsync(data, opts) {            var _this6 = this;            opts = opts || {};            this._maxSheetId = 0;            this._sheets = [];            return externals.Promise.resolve().then(function () {                // Make sure the input is a Buffer                return _this6._convertInputToBufferAsync(data, opts.base64).then(function (buffer) {                    data = buffer;                });            }).then(function () {                if (!opts.password) return;                return encryptor.decryptAsync(data, opts.password).then(function (decrypted) {                    data = decrypted;                });            }).then(function () {                return JSZip.loadAsync(data);            }).then(function (zip) {                _this6._zip = zip;                return _this6._parseNodesAsync(["[Content_Types].xml", "docProps/app.xml", "docProps/core.xml", "xl/_rels/workbook.xml.rels", "xl/sharedStrings.xml", "xl/styles.xml", "xl/workbook.xml"]);            }).then(function (nodes) {                var contentTypesNode = nodes[0];                var appPropertiesNode = nodes[1];                var corePropertiesNode = nodes[2];                var relationshipsNode = nodes[3];                var sharedStringsNode = nodes[4];                var styleSheetNode = nodes[5];                var workbookNode = nodes[6];                // Load the various components.                _this6._contentTypes = new ContentTypes(contentTypesNode);                _this6._appProperties = new AppProperties(appPropertiesNode);                _this6._coreProperties = new CoreProperties(corePropertiesNode);                _this6._relationships = new Relationships(relationshipsNode);                _this6._sharedStrings = new SharedStrings(sharedStringsNode);                _this6._styleSheet = new StyleSheet(styleSheetNode);                _this6._node = workbookNode;                // Add the shared strings relationship if it doesn't exist.                if (!_this6._relationships.findByType("sharedStrings")) {                    _this6._relationships.add("sharedStrings", "sharedStrings.xml");                }                // Add the shared string content type if it doesn't exist.                if (!_this6._contentTypes.findByPartName("/xl/sharedStrings.xml")) {                    _this6._contentTypes.add("/xl/sharedStrings.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml");                }                // Kill the calc chain. It's not required and the workbook will corrupt unless we keep it up to date.                _this6._zip.remove("xl/calcChain.xml");                // Load each sheet.                _this6._sheetsNode = xmlq.findChild(_this6._node, "sheets");                return externals.Promise.all(_.map(_this6._sheetsNode.children, function (sheetIdNode, i) {                    if (sheetIdNode.attributes.sheetId > _this6._maxSheetId) _this6._maxSheetId = sheetIdNode.attributes.sheetId;                    return _this6._parseNodesAsync(["xl/worksheets/sheet" + (i + 1) + ".xml", "xl/worksheets/_rels/sheet" + (i + 1) + ".xml.rels"]).then(function (nodes) {                        var sheetNode = nodes[0];                        var sheetRelationshipsNode = nodes[1];                        // Insert at position i as the promises will resolve at different times.                        _this6._sheets[i] = new Sheet(_this6, sheetIdNode, sheetNode, sheetRelationshipsNode);                    });                }));            }).then(function () {                return _this6._parseSheetRefs();            }).then(function () {                return _this6;            });        }        /**         * Parse files out of zip into XML node objects.         * @param {Array.<string>} names - The file names to parse.         * @returns {Promise.<Array.<{}>>} An array of the parsed objects.         * @private         */    }, {        key: "_parseNodesAsync",        value: function _parseNodesAsync(names) {            var _this7 = this;            return externals.Promise.all(_.map(names, function (name) {                return _this7._zip.file(name);            })).then(function (files) {                return externals.Promise.all(_.map(files, function (file) {                    return file && file.async("string");                }));            }).then(function (texts) {                return externals.Promise.all(_.map(texts, function (text) {                    return text && xmlParser.parseAsync(text);                }));            });        }        /**         * Parse the sheet references out so we can reorder freely.         * @returns {undefined}         * @private         */    }, {        key: "_parseSheetRefs",        value: function _parseSheetRefs() {            var _this8 = this;            // Parse the active sheet.            var bookViewsNode = xmlq.findChild(this._node, "bookViews");            var workbookViewNode = bookViewsNode && xmlq.findChild(bookViewsNode, "workbookView");            var activeTabId = workbookViewNode && workbookViewNode.attributes.activeTab || 0;            this._activeSheet = this._sheets[activeTabId];            // Set the location sheet on the defined name nodes. The defined name should point to the index of the sheet            // but reordering sheets messes this up. So store it on the node and we'll update the index on XML build.            var definedNamesNode = xmlq.findChild(this._node, "definedNames");            if (definedNamesNode) {                _.forEach(definedNamesNode.children, function (definedNameNode) {                    if (definedNameNode.attributes.hasOwnProperty("localSheetId")) {                        definedNameNode.localSheet = _this8._sheets[definedNameNode.attributes.localSheetId];                    }                });            }        }        /**         * Set the proper sheet references in the XML.         * @returns {undefined}         * @private         */    }, {        key: "_setSheetRefs",        value: function _setSheetRefs() {            var _this9 = this;            // Set the active sheet.            var bookViewsNode = xmlq.findChild(this._node, "bookViews");            if (!bookViewsNode) {                bookViewsNode = { name: 'bookViews', attributes: {}, children: [] };                xmlq.insertInOrder(this._node, bookViewsNode, nodeOrder);            }            var workbookViewNode = xmlq.findChild(bookViewsNode, "workbookView");            if (!workbookViewNode) {                workbookViewNode = { name: 'workbookView', attributes: {}, children: [] };                xmlq.appendChild(bookViewsNode, workbookViewNode);            }            workbookViewNode.attributes.activeTab = this._sheets.indexOf(this._activeSheet);            // Set the defined names local sheet indexes.            var definedNamesNode = xmlq.findChild(this._node, "definedNames");            if (definedNamesNode) {                _.forEach(definedNamesNode.children, function (definedNameNode) {                    if (definedNameNode.localSheet) {                        definedNameNode.attributes.localSheetId = _this9._sheets.indexOf(definedNameNode.localSheet);                    }                });            }        }        /**         * Convert buffer to desired output format         * @param {Buffer} buffer - The buffer         * @param {string} type - The type to convert to: buffer/nodebuffer, blob, base64, binarystring, uint8array, arraybuffer         * @returns {Buffer|Blob|string|Uint8Array|ArrayBuffer} The output         * @private         */    }, {        key: "_convertBufferToOutput",        value: function _convertBufferToOutput(buffer, type) {            if (!type) type = process.browser ? "blob" : "nodebuffer";            if (type === "buffer" || type === "nodebuffer") return buffer;            if (process.browser && type === "blob") return new Blob([buffer], { type: Workbook.MIME_TYPE });            if (type === "base64") return buffer.toString("base64");            if (type === "binarystring") return buffer.toString("utf8");            if (type === "uint8array") return new Uint8Array(buffer);            if (type === "arraybuffer") return new Uint8Array(buffer).buffer;            throw new Error("Output type '" + type + "' not supported.");        }        /**         * Convert input to buffer         * @param {Buffer|Blob|string|Uint8Array|ArrayBuffer} input - The input         * @param {boolean} [base64=false] - Only applies if input is a string. If true, the string is base64 encoded, false for binary         * @returns {Promise.<Buffer>} The buffer.         * @private         */    }, {        key: "_convertInputToBufferAsync",        value: function _convertInputToBufferAsync(input, base64) {            return externals.Promise.resolve().then(function () {                if (Buffer.isBuffer(input)) return input;                if (process.browser && input instanceof Blob) {                    return new externals.Promise(function (resolve) {                        var fileReader = new FileReader();                        fileReader.onload = function (event) {                            resolve(Buffer.from(event.target.result));                        };                        fileReader.readAsArrayBuffer(input);                    });                }                if (typeof input === "string" && base64) return Buffer.from(input, "base64");                if (typeof input === "string" && !base64) return Buffer.from(input, "utf8");                if (input instanceof Uint8Array || input instanceof ArrayBuffer) return Buffer.from(input);                throw new Error("Input type unknown.");            });        }    }], [{        key: "fromBlankAsync",        /**         * Create a new blank workbook.         * @returns {Promise.<Workbook>} The workbook.         * @ignore         */        value: function fromBlankAsync() {            return Workbook.fromDataAsync(blank);        }        /**         * Loads a workbook from a data object. (Supports any supported [JSZip data types]{@link https://stuk.github.io/jszip/documentation/api_jszip/load_async.html}.)         * @param {string|Array.<number>|ArrayBuffer|Uint8Array|Buffer|Blob|Promise.<*>} data - The data to load.         * @param {{}} [opts] - Options         * @returns {Promise.<Workbook>} The workbook.         * @ignore         */    }, {        key: "fromDataAsync",        value: function fromDataAsync(data, opts) {            return new Workbook()._initAsync(data, opts);        }        /**         * Loads a workbook from file.         * @param {string} path - The path to the workbook.         * @param {{}} [opts] - Options         * @returns {Promise.<Workbook>} The workbook.         * @ignore         */    }, {        key: "fromFileAsync",        value: function fromFileAsync(path, opts) {            if (process.browser) throw new Error("Workbook.fromFileAsync is not supported in the browser");            return new externals.Promise(function (resolve, reject) {                fs.readFile(path, function (err, data) {                    if (err) return reject(err);                    resolve(data);                });            }).then(function (data) {                return Workbook.fromDataAsync(data, opts);            });        }    }]);    return Workbook;}();/** * The XLSX mime type. * @type {string} * @ignore */Workbook.MIME_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";module.exports = Workbook;/*xl/workbook.xml<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x15" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main">	<fileVersion appName="xl" lastEdited="7" lowestEdited="7" rupBuild="16925"/>	<workbookPr defaultThemeVersion="164011"/>	<mc:AlternateContent xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">		<mc:Choice Requires="x15">			<x15ac:absPath url="\path\to\file" xmlns:x15ac="http://schemas.microsoft.com/office/spreadsheetml/2010/11/ac"/>		</mc:Choice>	</mc:AlternateContent>	<bookViews>		<workbookView xWindow="3720" yWindow="0" windowWidth="27870" windowHeight="12795"/>	</bookViews>	<sheets>		<sheet name="Sheet1" sheetId="1" r:id="rId1"/>	</sheets>	<calcPr calcId="171027"/>	<extLst>		<ext uri="{140A7094-0E35-4892-8432-C4D2E57EDEB5}" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main">			<x15:workbookPr chartTrackingRefBase="1"/>		</ext>	</extLst></workbook>// */}).call(this,require('_process'),require("buffer").Buffer)},{"./AppProperties":1,"./ArgHandler":2,"./ContentTypes":5,"./CoreProperties":6,"./Encryptor":7,"./Relationships":11,"./SharedStrings":15,"./Sheet":16,"./StyleSheet":18,"./XmlBuilder":21,"./XmlParser":22,"./addressConverter":23,"./blank":24,"./externals":27,"./regexify":28,"./xmlq":29,"_process":226,"buffer":79,"fs":76,"jszip":166,"lodash":193}],20:[function(require,module,exports){"use strict";var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var externals = require("./externals");var Workbook = require("./Workbook");var FormulaError = require("./FormulaError");var dateConverter = require("./dateConverter");var RichText = require("./RichText");/** * xlsx-poulate namespace. * @namespace */var XlsxPopulate = function () {    function XlsxPopulate() {        _classCallCheck(this, XlsxPopulate);    }    _createClass(XlsxPopulate, null, [{        key: "dateToNumber",        /**         * Convert a date to a number for Excel.         * @param {Date} date - The date.         * @returns {number} The number.         */        value: function dateToNumber(date) {            return dateConverter.dateToNumber(date);        }        /**         * Create a new blank workbook.         * @returns {Promise.<Workbook>} The workbook.         */    }, {        key: "fromBlankAsync",        value: function fromBlankAsync() {            return Workbook.fromBlankAsync();        }        /**         * Loads a workbook from a data object. (Supports any supported [JSZip data types]{@link https://stuk.github.io/jszip/documentation/api_jszip/load_async.html}.)         * @param {string|Array.<number>|ArrayBuffer|Uint8Array|Buffer|Blob|Promise.<*>} data - The data to load.         * @param {{}} [opts] - Options         * @param {string} [opts.password] - The password to decrypt the workbook.         * @returns {Promise.<Workbook>} The workbook.         */    }, {        key: "fromDataAsync",        value: function fromDataAsync(data, opts) {            return Workbook.fromDataAsync(data, opts);        }        /**         * Loads a workbook from file.         * @param {string} path - The path to the workbook.         * @param {{}} [opts] - Options         * @param {string} [opts.password] - The password to decrypt the workbook.         * @returns {Promise.<Workbook>} The workbook.         */    }, {        key: "fromFileAsync",        value: function fromFileAsync(path, opts) {            return Workbook.fromFileAsync(path, opts);        }        /**         * Convert an Excel number to a date.         * @param {number} number - The number.         * @returns {Date} The date.         */    }, {        key: "numberToDate",        value: function numberToDate(number) {            return dateConverter.numberToDate(number);        }        /**         * The Promise library.         * @type {Promise}         */    }, {        key: "Promise",        get: function get() {            return externals.Promise;        },        set: function set(Promise) {            externals.Promise = Promise;        }    }]);    return XlsxPopulate;}();/** * The XLSX mime type. * @type {string} */XlsxPopulate.MIME_TYPE = Workbook.MIME_TYPE;/** * Formula error class. * @type {FormulaError} */XlsxPopulate.FormulaError = FormulaError;/** * RichTexts class * @type {RichText} */XlsxPopulate.RichText = RichText;module.exports = XlsxPopulate;},{"./FormulaError":8,"./RichText":12,"./Workbook":19,"./dateConverter":26,"./externals":27}],21:[function(require,module,exports){"use strict";var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var _ = require("lodash");var XML_DECLARATION = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";/** * XML document builder. * @private */var XmlBuilder = function () {    function XmlBuilder() {        _classCallCheck(this, XmlBuilder);    }    _createClass(XmlBuilder, [{        key: "build",        /**         * Build an XML string from the JSON object.         * @param {{}} node - The node.         * @returns {string} The XML text.         */        value: function build(node) {            this._i = 0;            var xml = this._build(node, '');            if (xml === '') return;            return XML_DECLARATION + xml;        }        /**         * Build the XML string. (This is the internal recursive method.)         * @param {{}} node - The node.         * @param {string} xml - The initial XML doc string.         * @returns {string} The generated XML element.         * @private         */    }, {        key: "_build",        value: function _build(node, xml) {            var _this = this;            // For CPU performance, JS engines don't truly concatenate strings; they create a tree of pointers to            // the various concatenated strings. The downside of this is that it consumes a lot of memory, which            // will cause problems with large workbooks. So periodically, we grab a character from the xml, which            // causes the JS engine to flatten the tree into a single string. Do this too often and CPU takes a hit.            // Too frequently and memory takes a hit. Every 100k nodes seems to be a good balance.            if (this._i++ % 1000000 === 0) {                this._c = xml[0];            }            // If the node has a toXml method, call it.            if (node && _.isFunction(node.toXml)) node = node.toXml();            if (_.isObject(node)) {                // If the node is an object, then it maps to an element. Check if it has a name.                if (!node.name) throw new Error("XML node does not have name: " + JSON.stringify(node));                // Add the opening tag.                xml += "<" + node.name;                // Add any node attributes                _.forOwn(node.attributes, function (value, name) {                    xml += " " + name + "=\"" + _this._escapeString(value, true) + "\"";                });                if (_.isEmpty(node.children)) {                    // Self-close the tag if no children.                    xml += "/>";                } else {                    xml += ">";                    // Recursively add any children.                    _.forEach(node.children, function (child) {                        // Add the children to the XML.                        xml = _this._build(child, xml);                    });                    // Close the tag.                    xml += "</" + node.name + ">";                }            } else if (!_.isNil(node)) {                // It not an object, this should be a text node. Just add it.                xml += this._escapeString(node);            }            // Return the updated XML element.            return xml;        }        /**         * Escape a string for use in XML by replacing &, ", ', <, and >.         * @param {*} value - The value to escape.         * @param {boolean} [isAttribute] - A flag indicating if this is an attribute.         * @returns {string} The escaped string.         * @private         */    }, {        key: "_escapeString",        value: function _escapeString(value, isAttribute) {            if (_.isNil(value)) return value;            value = value.toString().replace(/&/g, "&") // Escape '&' first as the other escapes add them.            .replace(/</g, "<").replace(/>/g, ">");            if (isAttribute) {                value = value.replace(/"/g, """);            }            return value;        }    }]);    return XmlBuilder;}();module.exports = XmlBuilder;},{"lodash":193}],22:[function(require,module,exports){"use strict";var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var sax = require("sax");var externals = require("./externals");// Regex to check if string is all whitespace.var allWhitespaceRegex = /^\s+$/;/** * XML parser. * @private */var XmlParser = function () {    function XmlParser() {        _classCallCheck(this, XmlParser);    }    _createClass(XmlParser, [{        key: "parseAsync",        /**         * Parse the XML text into a JSON object.         * @param {string} xmlText - The XML text.         * @returns {{}} The JSON object.         */        value: function parseAsync(xmlText) {            var _this = this;            return new externals.Promise(function (resolve, reject) {                // Create the SAX parser.                var parser = sax.parser(true);                // Parsed is the full parsed object. Current is the current node being parsed. Stack is the current stack of                // nodes leading to the current one.                var parsed = void 0,                    current = void 0;                var stack = [];                // On error: Reject the promise.                parser.onerror = reject;                // On text nodes: If it is all whitespace, do nothing. Otherwise, try to convert to a number and add as a child.                parser.ontext = function (text) {                    if (allWhitespaceRegex.test(text)) {                        if (current && current.attributes['xml:space'] === 'preserve') {                            current.children.push(text);                        }                    } else {                        current.children.push(_this._covertToNumberIfNumber(text));                    }                };                // On open tag start: Create a child element. If this is the root element, set it as parsed. Otherwise, add                // it as a child to the current node.                parser.onopentagstart = function (node) {                    var child = { name: node.name, attributes: {}, children: [] };                    if (current) {                        current.children.push(child);                    } else {                        parsed = child;                    }                    stack.push(child);                    current = child;                };                // On close tag: Pop the stack.                parser.onclosetag = function (node) {                    stack.pop();                    current = stack[stack.length - 1];                };                // On attribute: Try to convert the value to a number and add to the current node.                parser.onattribute = function (attribute) {                    current.attributes[attribute.name] = _this._covertToNumberIfNumber(attribute.value);                };                // On end: Resolve the promise.                parser.onend = function () {                    return resolve(parsed);                };                // Start parsing the text.                parser.write(xmlText).close();            });        }        /**         * Convert the string to a number if it looks like one.         * @param {string} str - The string to convert.         * @returns {string|number} The number if converted or the string if not.         * @private         */    }, {        key: "_covertToNumberIfNumber",        value: function _covertToNumberIfNumber(str) {            var num = Number(str);            return num.toString() === str ? num : str;        }    }]);    return XmlParser;}();module.exports = XmlParser;},{"./externals":27,"sax":248}],23:[function(require,module,exports){"use strict";// V8 doesn't support optimization for compound assignment of let variables.// These methods get called a lot so disable the rule to allow V8 opmtimization./* eslint-disable operator-assignment */var _ = require("lodash");var ADDRESS_REGEX = /^(?:'?(.+?)'?!)?(?:(\$)?([A-Z]+)(\$)?(\d+)(?::(\$)?([A-Z]+)(\$)?(\d+))?|(\$)?([A-Z]+):(\$)?([A-Z]+)|(\$)?(\d+):(\$)?(\d+))$/;/** * Address converter. * @private */module.exports = {    /**     * Convert a column name to a number.     * @param {string} name - The column name.     * @returns {number} The number.     */    columnNameToNumber: function columnNameToNumber(name) {        if (!name || typeof name !== "string") return;        name = name.toUpperCase();        var sum = 0;        for (var i = 0; i < name.length; i++) {            sum = sum * 26;            sum = sum + (name[i].charCodeAt(0) - 'A'.charCodeAt(0) + 1);        }        return sum;    },    /**     * Convert a column number to a name.     * @param {number} number - The column number.     * @returns {string} The name.     */    columnNumberToName: function columnNumberToName(number) {        var dividend = number;        var name = '';        var modulo = 0;        while (dividend > 0) {            modulo = (dividend - 1) % 26;            name = String.fromCharCode('A'.charCodeAt(0) + modulo) + name;            dividend = Math.floor((dividend - modulo) / 26);        }        return name;    },    /**     * Convert an address to a reference object.     * @param {string} address - The address.     * @returns {{}} The reference object.     */    fromAddress: function fromAddress(address) {        var match = address.match(ADDRESS_REGEX);        if (!match) return;        var ref = {};        if (match[1]) ref.sheetName = match[1].replace(/''/g, "'");        if (match[3] && match[7]) {            ref.type = 'range';            ref.startColumnAnchored = !!match[2];            ref.startColumnName = match[3];            ref.startColumnNumber = this.columnNameToNumber(ref.startColumnName);            ref.startRowAnchored = !!match[4];            ref.startRowNumber = parseInt(match[5]);            ref.endColumnAnchored = !!match[6];            ref.endColumnName = match[7];            ref.endColumnNumber = this.columnNameToNumber(ref.endColumnName);            ref.endRowAnchored = !!match[8];            ref.endRowNumber = parseInt(match[9]);        } else if (match[3]) {            ref.type = 'cell';            ref.columnAnchored = !!match[2];            ref.columnName = match[3];            ref.columnNumber = this.columnNameToNumber(ref.columnName);            ref.rowAnchored = !!match[4];            ref.rowNumber = parseInt(match[5]);        } else if (match[11] && match[11] !== match[13]) {            ref.type = 'columnRange';            ref.startColumnAnchored = !!match[10];            ref.startColumnName = match[11];            ref.startColumnNumber = this.columnNameToNumber(ref.startColumnName);            ref.endColumnAnchored = !!match[12];            ref.endColumnName = match[13];            ref.endColumnNumber = this.columnNameToNumber(ref.endColumnName);        } else if (match[11]) {            ref.type = 'column';            ref.columnAnchored = !!match[10];            ref.columnName = match[11];            ref.columnNumber = this.columnNameToNumber(ref.columnName);        } else if (match[15] && match[15] !== match[17]) {            ref.type = 'rowRange';            ref.startRowAnchored = !!match[14];            ref.startRowNumber = parseInt(match[15]);            ref.endRowAnchored = !!match[16];            ref.endRowNumber = parseInt(match[17]);        } else if (match[15]) {            ref.type = 'row';            ref.rowAnchored = !!match[14];            ref.rowNumber = parseInt(match[15]);        }        return ref;    },    /**     * Convert a reference object to an address.     * @param {{}} ref - The reference object.     * @returns {string} The address.     */    toAddress: function toAddress(ref) {        var a = void 0,            b = void 0;        var sheetName = ref.sheetName;        if (ref.type === 'cell') {            a = {                columnName: ref.columnName,                columnNumber: ref.columnNumber,                columnAnchored: ref.columnAnchored,                rowNumber: ref.rowNumber,                rowAnchored: ref.rowAnchored            };        } else if (ref.type === 'range') {            a = {                columnName: ref.startColumnName,                columnNumber: ref.startColumnNumber,                columnAnchored: ref.startColumnAnchored,                rowNumber: ref.startRowNumber,                rowAnchored: ref.startRowAnchored            };            b = {                columnName: ref.endColumnName,                columnNumber: ref.endColumnNumber,                columnAnchored: ref.endColumnAnchored,                rowNumber: ref.endRowNumber,                rowAnchored: ref.endRowAnchored            };        } else if (ref.type === 'column') {            a = b = {                columnName: ref.columnName,                columnNumber: ref.columnNumber,                columnAnchored: ref.columnAnchored            };        } else if (ref.type === 'row') {            a = b = {                rowNumber: ref.rowNumber,                rowAnchored: ref.rowAnchored            };        } else if (ref.type === 'columnRange') {            a = {                columnName: ref.startColumnName,                columnNumber: ref.startColumnNumber,                columnAnchored: ref.startColumnAnchored            };            b = {                columnName: ref.endColumnName,                columnNumber: ref.endColumnNumber,                columnAnchored: ref.endColumnAnchored            };        } else if (ref.type === 'rowRange') {            a = {                rowNumber: ref.startRowNumber,                rowAnchored: ref.startRowAnchored            };            b = {                rowNumber: ref.endRowNumber,                rowAnchored: ref.endRowAnchored            };        }        var address = '';        if (sheetName) address = address + "'" + sheetName.replace(/'/g, "''") + "'!";        if (a.columnAnchored) address = address + "$";        if (a.columnName) address = address + a.columnName;else if (a.columnNumber) address = address + this.columnNumberToName(a.columnNumber);        if (a.rowAnchored) address = address + "$";        if (a.rowNumber) address = address + a.rowNumber;        if (b) {            address = address + ":";            if (b.columnAnchored) address = address + "$";            if (b.columnName) address = address + b.columnName;else if (b.columnNumber) address = address + this.columnNumberToName(b.columnNumber);            if (b.rowAnchored) address = address + "$";            if (b.rowNumber) address = address + b.rowNumber;        }        return address;    }};},{"lodash":193}],24:[function(require,module,exports){(function (Buffer){"use strict";// Export as a function as proxyquireify has trouble with constant exports.module.exports = function () {  return Buffer.from("UEsDBBQAAAAIAAAAIQC1VTAj7AAAAEwCAAALAAAAX3JlbHMvLnJlbHONks1OwzAMgO9IvEPk++puSAihpbsgpN0QKg9gEvdHbeMoCdC9PeGAoNIYPcaxP3+2vD/M06jeOcRenIZtUYJiZ8T2rtXwUj9u7kDFRM7SKI41nDjCobq+2j/zSCkXxa73UWWKixq6lPw9YjQdTxQL8ezyTyNhopSfoUVPZqCWcVeWtxh+M6BaMNXRaghHewOqPnlew5am6Q0/iHmb2KUzLZDnxM6y3fiQ60Pq8zSqptBy0mDFPOVwRPK+yGjA80a79UZ/T4sTJ7KUCI0EvuzzlXFJaLte6P8VLTN+bOYRPyQMryLDtwsubqD6BFBLAwQUAAAACAAAACEA3kEW2XsBAAARAwAAEAAAAGRvY1Byb3BzL2FwcC54bWydkkFP4zAQhe9I/IfId+oElhWqHCNUQBwWbaUWOBtn0lg4tuUZopZfj5OqIV32xO3NzNPLlxmL621rsw4iGu9KVsxyloHTvjJuU7Kn9f3ZFcuQlKuU9Q5KtgNk1/L0RCyjDxDJAGYpwmHJGqIw5xx1A63CWRq7NKl9bBWlMm64r2uj4dbr9xYc8fM8/81hS+AqqM7CGMj2ifOOfhpaed3z4fN6F1KeFDchWKMVpb+Uj0ZHj76m7G6rwQo+HYoUtAL9Hg3tZC74tBQrrSwsUrCslUUQ/KshHkD1S1sqE1GKjuYdaPIxQ/OR1nbOsleF0OOUrFPRKEdsb9sXg7YBKcoXH9+wASAUfGwOcuqdavNLFoMhiWMjH0GSPkZcG7KAf+ulivQf4mJKPDCwCeOq5yu+8R2+9E/2wrdBubRAPqo/xr3hU1j7W0VwWOdxU6waFaFKFxjXPTbEQ+KKtvcvGuU2UB083wf98Z/3L1wWl7P8Is+Hmx96gn+9ZfkJUEsDBBQAAAAIAOehdkc+qGWw1QAAAG0BAAARAAAAZG9jUHJvcHMvY29yZS54bWxtkE1Lw0AQhu9C/0PYezKJBZGQpDdPCkIVvA67Y7qY/WBnNO2/7zZoFOxxeJ95mHm73dFNxRcltsH3qqlqVZDXwVg/9ur15aG8VwULeoNT8NSrE7HaDZubTsdWh0TPKURKYomLbPLc6tirg0hsAVgfyCFXmfA5fA/JoeQxjRBRf+BIcFvXd+BI0KAgXIRlXI3qW2n0qoyfaVoERgNN5MgLQ1M18MsKJcdXF5bkD+msnCJdRX/ClT6yXcF5nqt5u6D5/gbenh73y6ul9ZeuNKmhg38FDWdQSwMEFAAAAAAA2aF2RwAAAAAAAAAAAAAAAAkAAAB4bC9fcmVscy9QSwMEFAAAAAgAAAAhAI2H2nDaAAAALQIAABoAAAB4bC9fcmVscy93b3JrYm9vay54bWwucmVsc62R3YrCMBCF7xf2HcLcb9NWWGQx9UYWeiv1AUI6/cE2CZlZtW9vXMEfEPHCq+FMmO+cySyWh3EQOwzUO6sgS1IQaI2re9sq2FS/X3MQxNrWenAWFUxIsCw+PxZrHDTHIep6TyJSLCnomP2PlGQ6HDUlzqONL40Lo+YoQyu9NlvdoszT9FuGWwYUd0xR1gpCWc9AVJPHV9iuaXqDK2f+RrT8wEIST0NcQFQ6tMgKzjqJHJCP7fN32nOcxav7vzw3s2cZsndm2LuwpQ6RrzkurfhBp3IJI++OXBwBUEsDBBQAAAAIAAAAIQDeI/LTbgIAALEFAAANAAAAeGwvc3R5bGVzLnhtbKWUXWvbMBSG7wf7D0L3rmw3zpJguyxNDYVuDJrBbhVbTkT1YSSlSzb233tkO7FDxzbWK53z6ug5rz7s9OYgBXpmxnKtMhxdhRgxVeqKq22Gv66LYIaRdVRVVGjFMnxkFt/k79+l1h0Fe9wx5hAglM3wzrlmQYgtd0xSe6UbpmCm1kZSB6nZEtsYRivrF0lB4jCcEkm5wh1hIct/gUhqnvZNUGrZUMc3XHB3bFkYyXJxv1Xa0I0Aq4doQssTu01e4SUvjba6dleAI7quecleu5yTOQFSntZaOYtKvVcOzgrQHrp4Uvq7KvyUF7uqPLU/0DMVoESY5GmphTbIQVfmi0BRVLKu4pYKvjHcizWVXBw7OfZCa7Svkxy25kXSdWgHC4u4EGdXMe6EPIXTccyoAhLUx+tjA+0VXGSHaev+Ur019BjFyWhBO0DfjTYVPJzhPE5SngpWO1hg+HbnR6cb4iedg1PO04rTrVZUeORpRR8AtmRCPPrH9a2+YB9qpPaykO6+yjA8U7/7UwiG+rDDdInnj2kd+81YdKgv+Wd02+iCflaRv+8Mf/YPWQwItNlz4bj6jWFgVofBazvr/Mu+7AKMitV0L9z6PJnhIf7EKr6X8bnqC3/Wrq8a4gd/U9HU92AH92BdO6K94Rn+ebf8MF/dFXEwC5ezYHLNkmCeLFdBMrldrlbFPIzD21+jD+0Nn1n7O4BLiSYLK6DK9JvtzT8OWoZHSWe/PT+wPfY+j6fhxyQKg+I6jILJlM6C2fQ6CYokilfTyfIuKZKR9+T/vEchiaLBfLJwXDLBFbu0vx6rcEmQ/mET5HQTZPjX5i9QSwMEFAAAAAAA2aF2RwAAAAAAAAAAAAAAAAkAAAB4bC90aGVtZS9QSwMEFAAAAAgAAAAhAIuCblj1BQAAjhoAABMAAAB4bC90aGVtZS90aGVtZTEueG1s7VlPjxs1FL8j8R2suafzfyZZNVslk6SF7rZVd1vUozNxMm4842js7G5UVULtEQkJURAXJG4cEFCplbiUT7NQBEXqV8DjyR9P4tCFbqWCmkjJ+Pn3nn9+7/nZM3Px0klKwBHKGaZZ07AvWAZAWUwHOBs1jVuHvVrdAIzDbAAJzVDTmCFmXNp9/72LcIcnKEVA6GdsBzaNhPPJjmmyWIghu0AnKBN9Q5qnkItmPjIHOTwWdlNiOpYVmCnEmQEymAqz14dDHCNwWJg0dhfGu0T8ZJwVgpjkB7EcUdWQ2MHYLv7YjEUkB0eQNA0xzoAeH6ITbgACGRcdTcOSH8PcvWgulQjfoqvo9eRnrjdXGIwdqZeP+ktFz/O9oLW075T2N3HdsBt0g6U9CYBxLGZqb2D9dqPd8edYBVReamx3wo5rV/CKfXcD3/KLbwXvrvDeBr7Xi1Y+VEDlpa/xSehEXgXvr/DBBj60Wh0vrOAlKCE4G2+gLT9wo8Vsl5AhJVe08Ibv9UJnDl+hTCW7Sv2Mb8u1FN6leU8AZHAhxxngswkawljgIkhwP8dgD48SkXgTmFEmxJZj9SxX/BZfT15Jj8AdBBXtUhSzDVHBB7A4xxPeND4UVg0F8vLZ9y+fPQEvnz0+ffD09MFPpw8fnj74UaN4BWYjVfHFt5/9+fXH4I8n37x49IUez1T8rz988svPn+uBXAU+//Lxb08fP//q09+/e6SBt3LYV+GHOEUMXEPH4CZNxdw0A6B+/s80DhOIKxowEUgNsMuTCvDaDBIdro2qzrudiyKhA16e3q1wPUjyKcca4NUkrQD3KSVtmmunc7UYS53ONBvpB8+nKu4mhEe6saO10HanE5HtWGcySlCF5g0iog1HKEMcFH10jJBG7Q7GFb/u4zinjA45uINBG2KtSw5xn+uVruBUxGWmIyhCXfHN/m3QpkRnvoOOqkixICDRmUSk4sbLcMphqmUMU6Ii9yBPdCQPZnlccTjjItIjRCjoDhBjOp3r+axC96ooLvqw75NZWkXmHI91yD1IqYrs0HGUwHSi5YyzRMV+wMYiRSG4QbmWBK2ukKIt4gCzreG+jVEl3K9e1rdEXdUnSNEzzXVLAtHqepyRIUTSuLlWzVOcvbK0rxV1/11R1xf1Vo61S2u9lG/D/QcLeAdOsxtIrBkN9F39fle///f1e9taPv+qvSrUZqmonN3TrUf3ISbkgM8I2mOyxDMxvUFPCGVDKi3vFCaJuJwPV8GNciivQU75R5gnBwmciGFsOcKIzU2PGJhQJjYJY6vtooNM0306KKW2vbg5FQqQr+Rik1nIxZbES2kQru7CluZla8RUAr40enYSymBVEq6GROiejYRtnReLhoZF3f47FqYSFbH+ACyea/heyUjkGyRoUMSp1F9E99wjvc2Z1Wk7muk1vLM5+QyRrpBQ0q1KQknDBA7QuvicY91YhbRCz9HSCOtvItbmZm0gWbUFjsWac31hJoaTpjEUx0NxmU6EPVbUTUhGWdOI+dzR/6ayTHLGO5AlJUx2lfNPMUc5IDgVua6GgWQrbrYTWm8vuYb19nnOXA8yGg5RzLdIVk3RVxrR9r4muGjQqSB9kAyOQZ9M85tQOMoP7cKBA8z40psDnCvJvfLiWrmaL8XKQ7PVEoVkksD5jqIW8xIur5d0lHlIpuuzqrbnk+mPeuex675aqehQiuaWDSTcWsXe3CavsHL1rHxtrWvUl1L9LvH6G4JCra6n5uqpWVuoneOBQBku2OK35R5x3rvBetaayrlStjbeTtD+XZH5HXFcnRLOJFV0Iu4RosVz5bISSOmiupxwMM1x07hn+S0vcvyoZtX9bs1zPatW91tureX7rt31bavTdu4Lp/Aktf1y7J64nyGz+csXKd94AZMujtkXYpqaVJ6DTaksX8DYzvYXMAALz9wLnF7DbbSDWsNt9Wpep12vNaKgXesEUdjpdSK/3ujdN8CRBHstN/KCbr0W2FFU8wKroF9v1ELPcVpe2Kp3vdb9ua/FzBf/C/dKXrt/AVBLAwQUAAAACAAAACEAfDzuwy4CAACbBAAADwAAAHhsL3dvcmtib29rLnhtbK2UTY+bMBCG75X6H5DvhI9AN0Ehq81H1UjVarXN7l5yccwQ3Bib2qZJVPW/d4CSps1lK+0Fj8344Z13bCa3x1I430EbrmRKgoFPHJBMZVzuUvK0/uiOiGMslRkVSkJKTmDI7fT9u8lB6f1Wqb2DAGlSUlhbJZ5nWAElNQNVgcQ3udIltTjVO89UGmhmCgBbCi/0/Q9eSbkkHSHRr2GoPOcMForVJUjbQTQIalG+KXhlelrJXoMrqd7XlctUWSFiywW3pxZKnJIlq51Umm4Fln0M4p6M4RW65Ewro3I7QNRvkVf1Br4XBF3J00nOBTx3tju0qu5p2XxFEEdQY5cZt5ClBGUIdYC/FnRdzWoucBJEUegTb3puxYN2MshpLewaZfV4TIyHYRg2mVjUnbCgJbUwV9Kih2/kV8ueFwoLdx7hW801mM626QSflCV0ax6oLZxai5TMk82TQX2b7KsqpFFyM1cZbI7CHN1KVTV2FDaCbzcXrtNrif/hO2WNAd5ZZRf/68Z00hj5zOFg/vjaTJ3jC5eZOqRkPMQ7cupnGB/a8IVntkhJOPRvzmufgO8Kiw3wh12nvAt6K7AfHdkegC9NHOCNa8ZV02NseMIx0KssaAn9NkYFw4Y3Q5sYh3HQZsDRfja2HdFrnpIfQeTf3fjjyPWXw9iNRuPQHUXD0J1Hi3AZ3ywXy1n8822PN1KSi2PJCqrtWlO2x//KI+QzaqAprikIdXbPVrXX75r+AlBLAwQUAAAAAADZoXZHAAAAAAAAAAAAAAAADgAAAHhsL3dvcmtzaGVldHMvUEsDBBQAAAAIAAAAIQDmVajjXQEAAIQCAAAYAAAAeGwvd29ya3NoZWV0cy9zaGVldDEueG1sjZJPawIxEMXvhX6HkLtGbW2ruEpBpB4Kpf/u2ezsbjDJLMlY9dt3dq1S8OJtXibz471JZou9d+IHYrIYMjnsD6SAYLCwocrk1+eq9yRFIh0K7TBAJg+Q5GJ+ezPbYdykGoAEE0LKZE3UTJVKpgavUx8bCNwpMXpNLGOlUhNBF92Qd2o0GDwor22QR8I0XsPAsrQGlmi2HgIdIRGcJvafatukE82ba3Bex8226Rn0DSNy6ywdOqgU3kzXVcCoc8e598N7bU7sTlzgvTURE5bUZ9yf0cvMEzVRTJrPCssJ2rWLCGUmn4dSzWfdxW8Lu/SvFqTzD3BgCAp+Iyna3eeIm7a55qNBO6ouZldd0LcoCij11tE77l7AVjUxZMxZ2hTT4rCEZHiXjOmPxmcTS02a60ZX8KpjZUMSDsru1qMU8YjpasKmqxiZIxH6k6o5OcRW3UlRItJJtG7P/2f+C1BLAwQUAAAACAAAACEApFPFz0EBAAAIBAAAEwAAAFtDb250ZW50X1R5cGVzXS54bWytk89OAjEQxu8mvkPTK9kWPBhjWDj456gc8AFqO8s2dNumUxDe3tmCHgiKBC/b7M583+/bdjqebjrH1pDQBl/zkRhyBl4HY/2i5m/z5+qOM8zKG+WCh5pvAfl0cn01nm8jICO1x5q3Ocd7KVG30CkUIYKnShNSpzK9poWMSi/VAuTNcHgrdfAZfK5y78En40do1Mpl9rShz7skCRxy9rBr7Fk1VzE6q1Wmulx7c0Cp9gRBytKDrY04oAYujxL6ys+Ave6VtiZZA2ymUn5RHXXJjZMfIS3fQ1iK302OpAxNYzWYoFcdSQTGBMpgC5A7J8oqOmX94DS/NKMsy+ifg3z7n8iR6bxh97w8QrE5AcS8dYAXow62vZj+RibhLIWINLkJzqd/jWavriIZQcr2j0SyPh948LvQT70Bc4Qtyz2efAJQSwECFAAUAAAACAAAACEAtVUwI+wAAABMAgAACwAAAAAAAAABAAAAAAAAAAAAX3JlbHMvLnJlbHNQSwECFAAUAAAACAAAACEA3kEW2XsBAAARAwAAEAAAAAAAAAABAAAAAAAVAQAAZG9jUHJvcHMvYXBwLnhtbFBLAQIUABQAAAAIAOehdkc+qGWw1QAAAG0BAAARAAAAAAAAAAEAIAAAAL4CAABkb2NQcm9wcy9jb3JlLnhtbFBLAQIUABQAAAAAANmhdkcAAAAAAAAAAAAAAAAJAAAAAAAAAAAAEAAAAMIDAAB4bC9fcmVscy9QSwECFAAUAAAACAAAACEAjYfacNoAAAAtAgAAGgAAAAAAAAABAAAAAADpAwAAeGwvX3JlbHMvd29ya2Jvb2sueG1sLnJlbHNQSwECFAAUAAAACAAAACEA3iPy024CAACxBQAADQAAAAAAAAABAAAAAAD7BAAAeGwvc3R5bGVzLnhtbFBLAQIUABQAAAAAANmhdkcAAAAAAAAAAAAAAAAJAAAAAAAAAAAAEAAAAJQHAAB4bC90aGVtZS9QSwECFAAUAAAACAAAACEAi4JuWPUFAACOGgAAEwAAAAAAAAABAAAAAAC7BwAAeGwvdGhlbWUvdGhlbWUxLnhtbFBLAQIUABQAAAAIAAAAIQB8PO7DLgIAAJsEAAAPAAAAAAAAAAEAAAAAAOENAAB4bC93b3JrYm9vay54bWxQSwECFAAUAAAAAADZoXZHAAAAAAAAAAAAAAAADgAAAAAAAAAAABAAAAA8EAAAeGwvd29ya3NoZWV0cy9QSwECFAAUAAAACAAAACEA5lWo410BAACEAgAAGAAAAAAAAAABAAAAAABoEAAAeGwvd29ya3NoZWV0cy9zaGVldDEueG1sUEsBAhQAFAAAAAgAAAAhAKRTxc9BAQAACAQAABMAAAAAAAAAAQAAAAAA+xEAAFtDb250ZW50X1R5cGVzXS54bWxQSwUGAAAAAAwADADoAgAAbRMAAAAA", "base64");};}).call(this,require("buffer").Buffer)},{"buffer":79}],25:[function(require,module,exports){"use strict";/** * Legacy color indexes. * https://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.indexedcolors(v=office.15).aspx */module.exports = ["000000", "FFFFFF", "FF0000", "00FF00", "0000FF", "FFFF00", "FF00FF", "00FFFF", "000000", "FFFFFF", "FF0000", "00FF00", "0000FF", "FFFF00", "FF00FF", "00FFFF", "800000", "008000", "000080", "808000", "800080", "008080", "C0C0C0", "808080", "9999FF", "993366", "FFFFCC", "CCFFFF", "660066", "FF8080", "0066CC", "CCCCFF", "000080", "FF00FF", "FFFF00", "00FFFF", "800080", "800000", "008080", "0000FF", "00CCFF", "CCFFFF", "CCFFCC", "FFFF99", "99CCFF", "FF99CC", "CC99FF", "FFCC99", "3366FF", "33CCCC", "99CC00", "FFCC00", "FF9900", "FF6600", "666699", "969696", "003366", "339966", "003300", "333300", "993300", "993366", "333399", "333333", "System Foreground", "System Background"];},{}],26:[function(require,module,exports){"use strict";// The base date = 0.var dateBase = new Date(1900, 0, 0);// The date conversion has a bug that assumes 1900 was a leap year. So we need to add one for dates after this.var incorrectLeapDate = new Date(1900, 1, 28);// Number of milliseconds in a day.var millisecondsInDay = 1000 * 60 * 60 * 24;/** * Date converter. * @private */module.exports = {        /**         * Convert a date to a number for Excel.         * @param {Date} date - The date.         * @returns {number} The number.         */        dateToNumber: function dateToNumber(date) {                // Clone the date and strip the time off.                var dateOnly = new Date(date.getTime());                dateOnly.setHours(0, 0, 0, 0);                // Set the number to be the number of days between the date and the base date.                // We need to round as daylight savings will cause fractional days, which we don't want.                var number = Math.round((dateOnly - dateBase) / millisecondsInDay);                // Add the true fractional days from just the milliseconds left in the current day.                number += (date - dateOnly) / millisecondsInDay;                // Adjust for the "bug" in Excel that treats 1900 as a leap year.                if (date > incorrectLeapDate) number += 1;                return number;        },        /**         * Convert a number to a date.         * @param {number} number - The number.         * @returns {Date} The date.         */        numberToDate: function numberToDate(number) {                // If the number is greater than the incorrect leap date, we should subtract one.                if (number > this.dateToNumber(incorrectLeapDate)) number--;                // Break the number of full days and the remaining milliseconds in the current day.                var fullDays = Math.floor(number);                var partialMilliseconds = Math.round((number - fullDays) * millisecondsInDay);                // Create a new date from the base date plus the time in the current day.                var date = new Date(dateBase.getTime() + partialMilliseconds);                // Now add the number of full days. JS will properly handle the month/year changes.                date.setDate(date.getDate() + fullDays);                return date;        }};},{}],27:[function(require,module,exports){"use strict";var JSZip = require("jszip");/** * External modules. * @private */module.exports = {    /**     * The Promise library.     * @type {Promise}     */    get Promise() {        return JSZip.external.Promise;    },    set Promise(Promise) {        JSZip.external.Promise = Promise;    }};},{"jszip":166}],28:[function(require,module,exports){"use strict";var _ = require("lodash");/** * Convert a pattern to a RegExp. * @param {RegExp|string} pattern - The pattern to convert. * @returns {RegExp} The regex. * @private */module.exports = function (pattern) {    if (typeof pattern === "string") {        pattern = new RegExp(_.escapeRegExp(pattern), "igm");    }    pattern.lastIndex = 0;    return pattern;};},{"lodash":193}],29:[function(require,module,exports){"use strict";var _ = require("lodash");/** * XML query methods. * @private */module.exports = {    /**     * Append a child to the node.     * @param {{}} node - The parent node.     * @param {{}} child - The child node.     * @returns {undefined}     */    appendChild: function appendChild(node, child) {        if (!node.children) node.children = [];        node.children.push(child);    },    /**     * Append a child if one with the given name is not found.     * @param {{}} node - The parent node.     * @param {string} name - The child node name.     * @returns {{}} The child.     */    appendChildIfNotFound: function appendChildIfNotFound(node, name) {        var child = this.findChild(node, name);        if (!child) {            child = { name: name, attributes: {}, children: [] };            this.appendChild(node, child);        }        return child;    },    /**     * Find a child with the given name.     * @param {{}} node - The parent node.     * @param {string} name - The name to find.     * @returns {undefined|{}} The child if found.     */    findChild: function findChild(node, name) {        return _.find(node.children, { name: name });    },    /**     * Get an attribute from a child node.     * @param {{}} node - The parent node.     * @param {string} name - The name of the child node.     * @param {string} attribute - The name of the attribute.     * @returns {undefined|*} The value of the attribute if found.     */    getChildAttribute: function getChildAttribute(node, name, attribute) {        var child = this.findChild(node, name);        if (child) return child.attributes && child.attributes[attribute];    },    /**     * Returns a value indicating whether the node has a child with the given name.     * @param {{}} node - The parent node.     * @param {string} name - The name of the child node.     * @returns {boolean} True if found, false otherwise.     */    hasChild: function hasChild(node, name) {        return _.some(node.children, { name: name });    },    /**     * Insert the child after the specified node.     * @param {{}} node - The parent node.     * @param {{}} child - The child node.     * @param {{}} after - The node to insert after.     * @returns {undefined}     */    insertAfter: function insertAfter(node, child, after) {        if (!node.children) node.children = [];        var index = node.children.indexOf(after);        node.children.splice(index + 1, 0, child);    },    /**     * Insert the child before the specified node.     * @param {{}} node - The parent node.     * @param {{}} child - The child node.     * @param {{}} before - The node to insert before.     * @returns {undefined}     */    insertBefore: function insertBefore(node, child, before) {        if (!node.children) node.children = [];        var index = node.children.indexOf(before);        node.children.splice(index, 0, child);    },    /**     * Insert a child node in the correct order.     * @param {{}} node - The parent node.     * @param {{}} child - The child node.     * @param {Array.<string>} nodeOrder - The order of the node names.     * @returns {undefined}     */    insertInOrder: function insertInOrder(node, child, nodeOrder) {        var childIndex = nodeOrder.indexOf(child.name);        if (node.children && childIndex >= 0) {            for (var i = childIndex + 1; i < nodeOrder.length; i++) {                var sibling = this.findChild(node, nodeOrder[i]);                if (sibling) {                    this.insertBefore(node, child, sibling);                    return;                }            }        }        this.appendChild(node, child);    },    /**     * Check if the node is empty (no attributes and no children).     * @param {{}} node - The node.     * @returns {boolean} True if empty, false otherwise.     */    isEmpty: function isEmpty(node) {        return _.isEmpty(node.children) && _.isEmpty(node.attributes);    },    /**     * Remove a child node.     * @param {{}} node - The parent node.     * @param {string|{}} child - The child node or name of node.     * @returns {undefined}     */    removeChild: function removeChild(node, child) {        if (!node.children) return;        if (typeof child === 'string') {            _.remove(node.children, { name: child });        } else {            var index = node.children.indexOf(child);            if (index >= 0) node.children.splice(index, 1);        }    },    /**     * Set/unset the attributes on the node.     * @param {{}} node - The node.     * @param {{}} attributes - The attributes to set.     * @returns {undefined}     */    setAttributes: function setAttributes(node, attributes) {        _.forOwn(attributes, function (value, attribute) {            if (_.isNil(value)) {                if (node.attributes) delete node.attributes[attribute];            } else {                if (!node.attributes) node.attributes = {};                node.attributes[attribute] = value;            }        });    },    /**     * Set attributes on a child node, creating the child if necessary.     * @param {{}} node - The parent node.     * @param {string} name - The name of the child node.     * @param {{}} attributes - The attributes to set.     * @returns {{}} The child.     */    setChildAttributes: function setChildAttributes(node, name, attributes) {        var _this = this;        var child = this.findChild(node, name);        _.forOwn(attributes, function (value, attribute) {            if (_.isNil(value)) {                if (child && child.attributes) delete child.attributes[attribute];            } else {                if (!child) {                    child = { name: name, attributes: {}, children: [] };                    _this.appendChild(node, child);                }                if (!child.attributes) child.attributes = {};                child.attributes[attribute] = value;            }        });        return child;    },    /**     * Remove the child node if empty.     * @param {{}} node - The parent node.     * @param {string|{}} child - The child or name of child node.     * @returns {undefined}     */    removeChildIfEmpty: function removeChildIfEmpty(node, child) {        if (typeof child === 'string') child = this.findChild(node, child);        if (child && this.isEmpty(child)) this.removeChild(node, child);    }};},{"lodash":193}],30:[function(require,module,exports){var asn1 = exports;asn1.bignum = require('bn.js');asn1.define = require('./asn1/api').define;asn1.base = require('./asn1/base');asn1.constants = require('./asn1/constants');asn1.decoders = require('./asn1/decoders');asn1.encoders = require('./asn1/encoders');},{"./asn1/api":31,"./asn1/base":33,"./asn1/constants":37,"./asn1/decoders":39,"./asn1/encoders":42,"bn.js":45}],31:[function(require,module,exports){var asn1 = require('../asn1');var inherits = require('inherits');var api = exports;api.define = function define(name, body) {  return new Entity(name, body);};function Entity(name, body) {  this.name = name;  this.body = body;  this.decoders = {};  this.encoders = {};};Entity.prototype._createNamed = function createNamed(base) {  var named;  try {    named = require('vm').runInThisContext(      '(function ' + this.name + '(entity) {\n' +      '  this._initNamed(entity);\n' +      '})'    );  } catch (e) {    named = function (entity) {      this._initNamed(entity);    };  }  inherits(named, base);  named.prototype._initNamed = function initnamed(entity) {    base.call(this, entity);  };  return new named(this);};Entity.prototype._getDecoder = function _getDecoder(enc) {  enc = enc || 'der';  // Lazily create decoder  if (!this.decoders.hasOwnProperty(enc))    this.decoders[enc] = this._createNamed(asn1.decoders[enc]);  return this.decoders[enc];};Entity.prototype.decode = function decode(data, enc, options) {  return this._getDecoder(enc).decode(data, options);};Entity.prototype._getEncoder = function _getEncoder(enc) {  enc = enc || 'der';  // Lazily create encoder  if (!this.encoders.hasOwnProperty(enc))    this.encoders[enc] = this._createNamed(asn1.encoders[enc]);  return this.encoders[enc];};Entity.prototype.encode = function encode(data, enc, /* internal */ reporter) {  return this._getEncoder(enc).encode(data, reporter);};},{"../asn1":30,"inherits":154,"vm":261}],32:[function(require,module,exports){var inherits = require('inherits');var Reporter = require('../base').Reporter;var Buffer = require('buffer').Buffer;function DecoderBuffer(base, options) {  Reporter.call(this, options);  if (!Buffer.isBuffer(base)) {    this.error('Input not Buffer');    return;  }  this.base = base;  this.offset = 0;  this.length = base.length;}inherits(DecoderBuffer, Reporter);exports.DecoderBuffer = DecoderBuffer;DecoderBuffer.prototype.save = function save() {  return { offset: this.offset, reporter: Reporter.prototype.save.call(this) };};DecoderBuffer.prototype.restore = function restore(save) {  // Return skipped data  var res = new DecoderBuffer(this.base);  res.offset = save.offset;  res.length = this.offset;  this.offset = save.offset;  Reporter.prototype.restore.call(this, save.reporter);  return res;};DecoderBuffer.prototype.isEmpty = function isEmpty() {  return this.offset === this.length;};DecoderBuffer.prototype.readUInt8 = function readUInt8(fail) {  if (this.offset + 1 <= this.length)    return this.base.readUInt8(this.offset++, true);  else    return this.error(fail || 'DecoderBuffer overrun');}DecoderBuffer.prototype.skip = function skip(bytes, fail) {  if (!(this.offset + bytes <= this.length))    return this.error(fail || 'DecoderBuffer overrun');  var res = new DecoderBuffer(this.base);  // Share reporter state  res._reporterState = this._reporterState;  res.offset = this.offset;  res.length = this.offset + bytes;  this.offset += bytes;  return res;}DecoderBuffer.prototype.raw = function raw(save) {  return this.base.slice(save ? save.offset : this.offset, this.length);}function EncoderBuffer(value, reporter) {  if (Array.isArray(value)) {    this.length = 0;    this.value = value.map(function(item) {      if (!(item instanceof EncoderBuffer))        item = new EncoderBuffer(item, reporter);      this.length += item.length;      return item;    }, this);  } else if (typeof value === 'number') {    if (!(0 <= value && value <= 0xff))      return reporter.error('non-byte EncoderBuffer value');    this.value = value;    this.length = 1;  } else if (typeof value === 'string') {    this.value = value;    this.length = Buffer.byteLength(value);  } else if (Buffer.isBuffer(value)) {    this.value = value;    this.length = value.length;  } else {    return reporter.error('Unsupported type: ' + typeof value);  }}exports.EncoderBuffer = EncoderBuffer;EncoderBuffer.prototype.join = function join(out, offset) {  if (!out)    out = new Buffer(this.length);  if (!offset)    offset = 0;  if (this.length === 0)    return out;  if (Array.isArray(this.value)) {    this.value.forEach(function(item) {      item.join(out, offset);      offset += item.length;    });  } else {    if (typeof this.value === 'number')      out[offset] = this.value;    else if (typeof this.value === 'string')      out.write(this.value, offset);    else if (Buffer.isBuffer(this.value))      this.value.copy(out, offset);    offset += this.length;  }  return out;};},{"../base":33,"buffer":79,"inherits":154}],33:[function(require,module,exports){var base = exports;base.Reporter = require('./reporter').Reporter;base.DecoderBuffer = require('./buffer').DecoderBuffer;base.EncoderBuffer = require('./buffer').EncoderBuffer;base.Node = require('./node');},{"./buffer":32,"./node":34,"./reporter":35}],34:[function(require,module,exports){var Reporter = require('../base').Reporter;var EncoderBuffer = require('../base').EncoderBuffer;var DecoderBuffer = require('../base').DecoderBuffer;var assert = require('minimalistic-assert');// Supported tagsvar tags = [  'seq', 'seqof', 'set', 'setof', 'objid', 'bool',  'gentime', 'utctime', 'null_', 'enum', 'int', 'objDesc',  'bitstr', 'bmpstr', 'charstr', 'genstr', 'graphstr', 'ia5str', 'iso646str',  'numstr', 'octstr', 'printstr', 't61str', 'unistr', 'utf8str', 'videostr'];// Public methods listvar methods = [  'key', 'obj', 'use', 'optional', 'explicit', 'implicit', 'def', 'choice',  'any', 'contains'].concat(tags);// Overrided methods listvar overrided = [  '_peekTag', '_decodeTag', '_use',  '_decodeStr', '_decodeObjid', '_decodeTime',  '_decodeNull', '_decodeInt', '_decodeBool', '_decodeList',  '_encodeComposite', '_encodeStr', '_encodeObjid', '_encodeTime',  '_encodeNull', '_encodeInt', '_encodeBool'];function Node(enc, parent) {  var state = {};  this._baseState = state;  state.enc = enc;  state.parent = parent || null;  state.children = null;  // State  state.tag = null;  state.args = null;  state.reverseArgs = null;  state.choice = null;  state.optional = false;  state.any = false;  state.obj = false;  state.use = null;  state.useDecoder = null;  state.key = null;  state['default'] = null;  state.explicit = null;  state.implicit = null;  state.contains = null;  // Should create new instance on each method  if (!state.parent) {    state.children = [];    this._wrap();  }}module.exports = Node;var stateProps = [  'enc', 'parent', 'children', 'tag', 'args', 'reverseArgs', 'choice',  'optional', 'any', 'obj', 'use', 'alteredUse', 'key', 'default', 'explicit',  'implicit', 'contains'];Node.prototype.clone = function clone() {  var state = this._baseState;  var cstate = {};  stateProps.forEach(function(prop) {    cstate[prop] = state[prop];  });  var res = new this.constructor(cstate.parent);  res._baseState = cstate;  return res;};Node.prototype._wrap = function wrap() {  var state = this._baseState;  methods.forEach(function(method) {    this[method] = function _wrappedMethod() {      var clone = new this.constructor(this);      state.children.push(clone);      return clone[method].apply(clone, arguments);    };  }, this);};Node.prototype._init = function init(body) {  var state = this._baseState;  assert(state.parent === null);  body.call(this);  // Filter children  state.children = state.children.filter(function(child) {    return child._baseState.parent === this;  }, this);  assert.equal(state.children.length, 1, 'Root node can have only one child');};Node.prototype._useArgs = function useArgs(args) {  var state = this._baseState;  // Filter children and args  var children = args.filter(function(arg) {    return arg instanceof this.constructor;  }, this);  args = args.filter(function(arg) {    return !(arg instanceof this.constructor);  }, this);  if (children.length !== 0) {    assert(state.children === null);    state.children = children;    // Replace parent to maintain backward link    children.forEach(function(child) {      child._baseState.parent = this;    }, this);  }  if (args.length !== 0) {    assert(state.args === null);    state.args = args;    state.reverseArgs = args.map(function(arg) {      if (typeof arg !== 'object' || arg.constructor !== Object)        return arg;      var res = {};      Object.keys(arg).forEach(function(key) {        if (key == (key | 0))          key |= 0;        var value = arg[key];        res[value] = key;      });      return res;    });  }};//// Overrided methods//overrided.forEach(function(method) {  Node.prototype[method] = function _overrided() {    var state = this._baseState;    throw new Error(method + ' not implemented for encoding: ' + state.enc);  };});//// Public methods//tags.forEach(function(tag) {  Node.prototype[tag] = function _tagMethod() {    var state = this._baseState;    var args = Array.prototype.slice.call(arguments);    assert(state.tag === null);    state.tag = tag;    this._useArgs(args);    return this;  };});Node.prototype.use = function use(item) {  assert(item);  var state = this._baseState;  assert(state.use === null);  state.use = item;  return this;};Node.prototype.optional = function optional() {  var state = this._baseState;  state.optional = true;  return this;};Node.prototype.def = function def(val) {  var state = this._baseState;  assert(state['default'] === null);  state['default'] = val;  state.optional = true;  return this;};Node.prototype.explicit = function explicit(num) {  var state = this._baseState;  assert(state.explicit === null && state.implicit === null);  state.explicit = num;  return this;};Node.prototype.implicit = function implicit(num) {  var state = this._baseState;  assert(state.explicit === null && state.implicit === null);  state.implicit = num;  return this;};Node.prototype.obj = function obj() {  var state = this._baseState;  var args = Array.prototype.slice.call(arguments);  state.obj = true;  if (args.length !== 0)    this._useArgs(args);  return this;};Node.prototype.key = function key(newKey) {  var state = this._baseState;  assert(state.key === null);  state.key = newKey;  return this;};Node.prototype.any = function any() {  var state = this._baseState;  state.any = true;  return this;};Node.prototype.choice = function choice(obj) {  var state = this._baseState;  assert(state.choice === null);  state.choice = obj;  this._useArgs(Object.keys(obj).map(function(key) {    return obj[key];  }));  return this;};Node.prototype.contains = function contains(item) {  var state = this._baseState;  assert(state.use === null);  state.contains = item;  return this;};//// Decoding//Node.prototype._decode = function decode(input, options) {  var state = this._baseState;  // Decode root node  if (state.parent === null)    return input.wrapResult(state.children[0]._decode(input, options));  var result = state['default'];  var present = true;  var prevKey = null;  if (state.key !== null)    prevKey = input.enterKey(state.key);  // Check if tag is there  if (state.optional) {    var tag = null;    if (state.explicit !== null)      tag = state.explicit;    else if (state.implicit !== null)      tag = state.implicit;    else if (state.tag !== null)      tag = state.tag;    if (tag === null && !state.any) {      // Trial and Error      var save = input.save();      try {        if (state.choice === null)          this._decodeGeneric(state.tag, input, options);        else          this._decodeChoice(input, options);        present = true;      } catch (e) {        present = false;      }      input.restore(save);    } else {      present = this._peekTag(input, tag, state.any);      if (input.isError(present))        return present;    }  }  // Push object on stack  var prevObj;  if (state.obj && present)    prevObj = input.enterObject();  if (present) {    // Unwrap explicit values    if (state.explicit !== null) {      var explicit = this._decodeTag(input, state.explicit);      if (input.isError(explicit))        return explicit;      input = explicit;    }    var start = input.offset;    // Unwrap implicit and normal values    if (state.use === null && state.choice === null) {      if (state.any)        var save = input.save();      var body = this._decodeTag(        input,        state.implicit !== null ? state.implicit : state.tag,        state.any      );      if (input.isError(body))        return body;      if (state.any)        result = input.raw(save);      else        input = body;    }    if (options && options.track && state.tag !== null)      options.track(input.path(), start, input.length, 'tagged');    if (options && options.track && state.tag !== null)      options.track(input.path(), input.offset, input.length, 'content');    // Select proper method for tag    if (state.any)      result = result;    else if (state.choice === null)      result = this._decodeGeneric(state.tag, input, options);    else      result = this._decodeChoice(input, options);    if (input.isError(result))      return result;    // Decode children    if (!state.any && state.choice === null && state.children !== null) {      state.children.forEach(function decodeChildren(child) {        // NOTE: We are ignoring errors here, to let parser continue with other        // parts of encoded data        child._decode(input, options);      });    }    // Decode contained/encoded by schema, only in bit or octet strings    if (state.contains && (state.tag === 'octstr' || state.tag === 'bitstr')) {      var data = new DecoderBuffer(result);      result = this._getUse(state.contains, input._reporterState.obj)          ._decode(data, options);    }  }  // Pop object  if (state.obj && present)    result = input.leaveObject(prevObj);  // Set key  if (state.key !== null && (result !== null || present === true))    input.leaveKey(prevKey, state.key, result);  else if (prevKey !== null)    input.exitKey(prevKey);  return result;};Node.prototype._decodeGeneric = function decodeGeneric(tag, input, options) {  var state = this._baseState;  if (tag === 'seq' || tag === 'set')    return null;  if (tag === 'seqof' || tag === 'setof')    return this._decodeList(input, tag, state.args[0], options);  else if (/str$/.test(tag))    return this._decodeStr(input, tag, options);  else if (tag === 'objid' && state.args)    return this._decodeObjid(input, state.args[0], state.args[1], options);  else if (tag === 'objid')    return this._decodeObjid(input, null, null, options);  else if (tag === 'gentime' || tag === 'utctime')    return this._decodeTime(input, tag, options);  else if (tag === 'null_')    return this._decodeNull(input, options);  else if (tag === 'bool')    return this._decodeBool(input, options);  else if (tag === 'objDesc')    return this._decodeStr(input, tag, options);  else if (tag === 'int' || tag === 'enum')    return this._decodeInt(input, state.args && state.args[0], options);  if (state.use !== null) {    return this._getUse(state.use, input._reporterState.obj)        ._decode(input, options);  } else {    return input.error('unknown tag: ' + tag);  }};Node.prototype._getUse = function _getUse(entity, obj) {  var state = this._baseState;  // Create altered use decoder if implicit is set  state.useDecoder = this._use(entity, obj);  assert(state.useDecoder._baseState.parent === null);  state.useDecoder = state.useDecoder._baseState.children[0];  if (state.implicit !== state.useDecoder._baseState.implicit) {    state.useDecoder = state.useDecoder.clone();    state.useDecoder._baseState.implicit = state.implicit;  }  return state.useDecoder;};Node.prototype._decodeChoice = function decodeChoice(input, options) {  var state = this._baseState;  var result = null;  var match = false;  Object.keys(state.choice).some(function(key) {    var save = input.save();    var node = state.choice[key];    try {      var value = node._decode(input, options);      if (input.isError(value))        return false;      result = { type: key, value: value };      match = true;    } catch (e) {      input.restore(save);      return false;    }    return true;  }, this);  if (!match)    return input.error('Choice not matched');  return result;};//// Encoding//Node.prototype._createEncoderBuffer = function createEncoderBuffer(data) {  return new EncoderBuffer(data, this.reporter);};Node.prototype._encode = function encode(data, reporter, parent) {  var state = this._baseState;  if (state['default'] !== null && state['default'] === data)    return;  var result = this._encodeValue(data, reporter, parent);  if (result === undefined)    return;  if (this._skipDefault(result, reporter, parent))    return;  return result;};Node.prototype._encodeValue = function encode(data, reporter, parent) {  var state = this._baseState;  // Decode root node  if (state.parent === null)    return state.children[0]._encode(data, reporter || new Reporter());  var result = null;  // Set reporter to share it with a child class  this.reporter = reporter;  // Check if data is there  if (state.optional && data === undefined) {    if (state['default'] !== null)      data = state['default']    else      return;  }  // Encode children first  var content = null;  var primitive = false;  if (state.any) {    // Anything that was given is translated to buffer    result = this._createEncoderBuffer(data);  } else if (state.choice) {    result = this._encodeChoice(data, reporter);  } else if (state.contains) {    content = this._getUse(state.contains, parent)._encode(data, reporter);    primitive = true;  } else if (state.children) {    content = state.children.map(function(child) {      if (child._baseState.tag === 'null_')        return child._encode(null, reporter, data);      if (child._baseState.key === null)        return reporter.error('Child should have a key');      var prevKey = reporter.enterKey(child._baseState.key);      if (typeof data !== 'object')        return reporter.error('Child expected, but input is not object');      var res = child._encode(data[child._baseState.key], reporter, data);      reporter.leaveKey(prevKey);      return res;    }, this).filter(function(child) {      return child;    });    content = this._createEncoderBuffer(content);  } else {    if (state.tag === 'seqof' || state.tag === 'setof') {      // TODO(indutny): this should be thrown on DSL level      if (!(state.args && state.args.length === 1))        return reporter.error('Too many args for : ' + state.tag);      if (!Array.isArray(data))        return reporter.error('seqof/setof, but data is not Array');      var child = this.clone();      child._baseState.implicit = null;      content = this._createEncoderBuffer(data.map(function(item) {        var state = this._baseState;        return this._getUse(state.args[0], data)._encode(item, reporter);      }, child));    } else if (state.use !== null) {      result = this._getUse(state.use, parent)._encode(data, reporter);    } else {      content = this._encodePrimitive(state.tag, data);      primitive = true;    }  }  // Encode data itself  var result;  if (!state.any && state.choice === null) {    var tag = state.implicit !== null ? state.implicit : state.tag;    var cls = state.implicit === null ? 'universal' : 'context';    if (tag === null) {      if (state.use === null)        reporter.error('Tag could be omitted only for .use()');    } else {      if (state.use === null)        result = this._encodeComposite(tag, primitive, cls, content);    }  }  // Wrap in explicit  if (state.explicit !== null)    result = this._encodeComposite(state.explicit, false, 'context', result);  return result;};Node.prototype._encodeChoice = function encodeChoice(data, reporter) {  var state = this._baseState;  var node = state.choice[data.type];  if (!node) {    assert(        false,        data.type + ' not found in ' +            JSON.stringify(Object.keys(state.choice)));  }  return node._encode(data.value, reporter);};Node.prototype._encodePrimitive = function encodePrimitive(tag, data) {  var state = this._baseState;  if (/str$/.test(tag))    return this._encodeStr(data, tag);  else if (tag === 'objid' && state.args)    return this._encodeObjid(data, state.reverseArgs[0], state.args[1]);  else if (tag === 'objid')    return this._encodeObjid(data, null, null);  else if (tag === 'gentime' || tag === 'utctime')    return this._encodeTime(data, tag);  else if (tag === 'null_')    return this._encodeNull();  else if (tag === 'int' || tag === 'enum')    return this._encodeInt(data, state.args && state.reverseArgs[0]);  else if (tag === 'bool')    return this._encodeBool(data);  else if (tag === 'objDesc')    return this._encodeStr(data, tag);  else    throw new Error('Unsupported tag: ' + tag);};Node.prototype._isNumstr = function isNumstr(str) {  return /^[0-9 ]*$/.test(str);};Node.prototype._isPrintstr = function isPrintstr(str) {  return /^[A-Za-z0-9 '\(\)\+,\-\.\/:=\?]*$/.test(str);};},{"../base":33,"minimalistic-assert":197}],35:[function(require,module,exports){var inherits = require('inherits');function Reporter(options) {  this._reporterState = {    obj: null,    path: [],    options: options || {},    errors: []  };}exports.Reporter = Reporter;Reporter.prototype.isError = function isError(obj) {  return obj instanceof ReporterError;};Reporter.prototype.save = function save() {  var state = this._reporterState;  return { obj: state.obj, pathLen: state.path.length };};Reporter.prototype.restore = function restore(data) {  var state = this._reporterState;  state.obj = data.obj;  state.path = state.path.slice(0, data.pathLen);};Reporter.prototype.enterKey = function enterKey(key) {  return this._reporterState.path.push(key);};Reporter.prototype.exitKey = function exitKey(index) {  var state = this._reporterState;  state.path = state.path.slice(0, index - 1);};Reporter.prototype.leaveKey = function leaveKey(index, key, value) {  var state = this._reporterState;  this.exitKey(index);  if (state.obj !== null)    state.obj[key] = value;};Reporter.prototype.path = function path() {  return this._reporterState.path.join('/');};Reporter.prototype.enterObject = function enterObject() {  var state = this._reporterState;  var prev = state.obj;  state.obj = {};  return prev;};Reporter.prototype.leaveObject = function leaveObject(prev) {  var state = this._reporterState;  var now = state.obj;  state.obj = prev;  return now;};Reporter.prototype.error = function error(msg) {  var err;  var state = this._reporterState;  var inherited = msg instanceof ReporterError;  if (inherited) {    err = msg;  } else {    err = new ReporterError(state.path.map(function(elem) {      return '[' + JSON.stringify(elem) + ']';    }).join(''), msg.message || msg, msg.stack);  }  if (!state.options.partial)    throw err;  if (!inherited)    state.errors.push(err);  return err;};Reporter.prototype.wrapResult = function wrapResult(result) {  var state = this._reporterState;  if (!state.options.partial)    return result;  return {    result: this.isError(result) ? null : result,    errors: state.errors  };};function ReporterError(path, msg) {  this.path = path;  this.rethrow(msg);};inherits(ReporterError, Error);ReporterError.prototype.rethrow = function rethrow(msg) {  this.message = msg + ' at: ' + (this.path || '(shallow)');  if (Error.captureStackTrace)    Error.captureStackTrace(this, ReporterError);  if (!this.stack) {    try {      // IE only adds stack when thrown      throw new Error(this.message);    } catch (e) {      this.stack = e.stack;    }  }  return this;};},{"inherits":154}],36:[function(require,module,exports){var constants = require('../constants');exports.tagClass = {  0: 'universal',  1: 'application',  2: 'context',  3: 'private'};exports.tagClassByName = constants._reverse(exports.tagClass);exports.tag = {  0x00: 'end',  0x01: 'bool',  0x02: 'int',  0x03: 'bitstr',  0x04: 'octstr',  0x05: 'null_',  0x06: 'objid',  0x07: 'objDesc',  0x08: 'external',  0x09: 'real',  0x0a: 'enum',  0x0b: 'embed',  0x0c: 'utf8str',  0x0d: 'relativeOid',  0x10: 'seq',  0x11: 'set',  0x12: 'numstr',  0x13: 'printstr',  0x14: 't61str',  0x15: 'videostr',  0x16: 'ia5str',  0x17: 'utctime',  0x18: 'gentime',  0x19: 'graphstr',  0x1a: 'iso646str',  0x1b: 'genstr',  0x1c: 'unistr',  0x1d: 'charstr',  0x1e: 'bmpstr'};exports.tagByName = constants._reverse(exports.tag);},{"../constants":37}],37:[function(require,module,exports){var constants = exports;// Helperconstants._reverse = function reverse(map) {  var res = {};  Object.keys(map).forEach(function(key) {    // Convert key to integer if it is stringified    if ((key | 0) == key)      key = key | 0;    var value = map[key];    res[value] = key;  });  return res;};constants.der = require('./der');},{"./der":36}],38:[function(require,module,exports){var inherits = require('inherits');var asn1 = require('../../asn1');var base = asn1.base;var bignum = asn1.bignum;// Import DER constantsvar der = asn1.constants.der;function DERDecoder(entity) {  this.enc = 'der';  this.name = entity.name;  this.entity = entity;  // Construct base tree  this.tree = new DERNode();  this.tree._init(entity.body);};module.exports = DERDecoder;DERDecoder.prototype.decode = function decode(data, options) {  if (!(data instanceof base.DecoderBuffer))    data = new base.DecoderBuffer(data, options);  return this.tree._decode(data, options);};// Tree methodsfunction DERNode(parent) {  base.Node.call(this, 'der', parent);}inherits(DERNode, base.Node);DERNode.prototype._peekTag = function peekTag(buffer, tag, any) {  if (buffer.isEmpty())    return false;  var state = buffer.save();  var decodedTag = derDecodeTag(buffer, 'Failed to peek tag: "' + tag + '"');  if (buffer.isError(decodedTag))    return decodedTag;  buffer.restore(state);  return decodedTag.tag === tag || decodedTag.tagStr === tag ||    (decodedTag.tagStr + 'of') === tag || any;};DERNode.prototype._decodeTag = function decodeTag(buffer, tag, any) {  var decodedTag = derDecodeTag(buffer,                                'Failed to decode tag of "' + tag + '"');  if (buffer.isError(decodedTag))    return decodedTag;  var len = derDecodeLen(buffer,                         decodedTag.primitive,                         'Failed to get length of "' + tag + '"');  // Failure  if (buffer.isError(len))    return len;  if (!any &&      decodedTag.tag !== tag &&      decodedTag.tagStr !== tag &&      decodedTag.tagStr + 'of' !== tag) {    return buffer.error('Failed to match tag: "' + tag + '"');  }  if (decodedTag.primitive || len !== null)    return buffer.skip(len, 'Failed to match body of: "' + tag + '"');  // Indefinite length... find END tag  var state = buffer.save();  var res = this._skipUntilEnd(      buffer,      'Failed to skip indefinite length body: "' + this.tag + '"');  if (buffer.isError(res))    return res;  len = buffer.offset - state.offset;  buffer.restore(state);  return buffer.skip(len, 'Failed to match body of: "' + tag + '"');};DERNode.prototype._skipUntilEnd = function skipUntilEnd(buffer, fail) {  while (true) {    var tag = derDecodeTag(buffer, fail);    if (buffer.isError(tag))      return tag;    var len = derDecodeLen(buffer, tag.primitive, fail);    if (buffer.isError(len))      return len;    var res;    if (tag.primitive || len !== null)      res = buffer.skip(len)    else      res = this._skipUntilEnd(buffer, fail);    // Failure    if (buffer.isError(res))      return res;    if (tag.tagStr === 'end')      break;  }};DERNode.prototype._decodeList = function decodeList(buffer, tag, decoder,                                                    options) {  var result = [];  while (!buffer.isEmpty()) {    var possibleEnd = this._peekTag(buffer, 'end');    if (buffer.isError(possibleEnd))      return possibleEnd;    var res = decoder.decode(buffer, 'der', options);    if (buffer.isError(res) && possibleEnd)      break;    result.push(res);  }  return result;};DERNode.prototype._decodeStr = function decodeStr(buffer, tag) {  if (tag === 'bitstr') {    var unused = buffer.readUInt8();    if (buffer.isError(unused))      return unused;    return { unused: unused, data: buffer.raw() };  } else if (tag === 'bmpstr') {    var raw = buffer.raw();    if (raw.length % 2 === 1)      return buffer.error('Decoding of string type: bmpstr length mismatch');    var str = '';    for (var i = 0; i < raw.length / 2; i++) {      str += String.fromCharCode(raw.readUInt16BE(i * 2));    }    return str;  } else if (tag === 'numstr') {    var numstr = buffer.raw().toString('ascii');    if (!this._isNumstr(numstr)) {      return buffer.error('Decoding of string type: ' +                          'numstr unsupported characters');    }    return numstr;  } else if (tag === 'octstr') {    return buffer.raw();  } else if (tag === 'objDesc') {    return buffer.raw();  } else if (tag === 'printstr') {    var printstr = buffer.raw().toString('ascii');    if (!this._isPrintstr(printstr)) {      return buffer.error('Decoding of string type: ' +                          'printstr unsupported characters');    }    return printstr;  } else if (/str$/.test(tag)) {    return buffer.raw().toString();  } else {    return buffer.error('Decoding of string type: ' + tag + ' unsupported');  }};DERNode.prototype._decodeObjid = function decodeObjid(buffer, values, relative) {  var result;  var identifiers = [];  var ident = 0;  while (!buffer.isEmpty()) {    var subident = buffer.readUInt8();    ident <<= 7;    ident |= subident & 0x7f;    if ((subident & 0x80) === 0) {      identifiers.push(ident);      ident = 0;    }  }  if (subident & 0x80)    identifiers.push(ident);  var first = (identifiers[0] / 40) | 0;  var second = identifiers[0] % 40;  if (relative)    result = identifiers;  else    result = [first, second].concat(identifiers.slice(1));  if (values) {    var tmp = values[result.join(' ')];    if (tmp === undefined)      tmp = values[result.join('.')];    if (tmp !== undefined)      result = tmp;  }  return result;};DERNode.prototype._decodeTime = function decodeTime(buffer, tag) {  var str = buffer.raw().toString();  if (tag === 'gentime') {    var year = str.slice(0, 4) | 0;    var mon = str.slice(4, 6) | 0;    var day = str.slice(6, 8) | 0;    var hour = str.slice(8, 10) | 0;    var min = str.slice(10, 12) | 0;    var sec = str.slice(12, 14) | 0;  } else if (tag === 'utctime') {    var year = str.slice(0, 2) | 0;    var mon = str.slice(2, 4) | 0;    var day = str.slice(4, 6) | 0;    var hour = str.slice(6, 8) | 0;    var min = str.slice(8, 10) | 0;    var sec = str.slice(10, 12) | 0;    if (year < 70)      year = 2000 + year;    else      year = 1900 + year;  } else {    return buffer.error('Decoding ' + tag + ' time is not supported yet');  }  return Date.UTC(year, mon - 1, day, hour, min, sec, 0);};DERNode.prototype._decodeNull = function decodeNull(buffer) {  return null;};DERNode.prototype._decodeBool = function decodeBool(buffer) {  var res = buffer.readUInt8();  if (buffer.isError(res))    return res;  else    return res !== 0;};DERNode.prototype._decodeInt = function decodeInt(buffer, values) {  // Bigint, return as it is (assume big endian)  var raw = buffer.raw();  var res = new bignum(raw);  if (values)    res = values[res.toString(10)] || res;  return res;};DERNode.prototype._use = function use(entity, obj) {  if (typeof entity === 'function')    entity = entity(obj);  return entity._getDecoder('der').tree;};// Utility methodsfunction derDecodeTag(buf, fail) {  var tag = buf.readUInt8(fail);  if (buf.isError(tag))    return tag;  var cls = der.tagClass[tag >> 6];  var primitive = (tag & 0x20) === 0;  // Multi-octet tag - load  if ((tag & 0x1f) === 0x1f) {    var oct = tag;    tag = 0;    while ((oct & 0x80) === 0x80) {      oct = buf.readUInt8(fail);      if (buf.isError(oct))        return oct;      tag <<= 7;      tag |= oct & 0x7f;    }  } else {    tag &= 0x1f;  }  var tagStr = der.tag[tag];  return {    cls: cls,    primitive: primitive,    tag: tag,    tagStr: tagStr  };}function derDecodeLen(buf, primitive, fail) {  var len = buf.readUInt8(fail);  if (buf.isError(len))    return len;  // Indefinite form  if (!primitive && len === 0x80)    return null;  // Definite form  if ((len & 0x80) === 0) {    // Short form    return len;  }  // Long form  var num = len & 0x7f;  if (num > 4)    return buf.error('length octect is too long');  len = 0;  for (var i = 0; i < num; i++) {    len <<= 8;    var j = buf.readUInt8(fail);    if (buf.isError(j))      return j;    len |= j;  }  return len;}},{"../../asn1":30,"inherits":154}],39:[function(require,module,exports){var decoders = exports;decoders.der = require('./der');decoders.pem = require('./pem');},{"./der":38,"./pem":40}],40:[function(require,module,exports){var inherits = require('inherits');var Buffer = require('buffer').Buffer;var DERDecoder = require('./der');function PEMDecoder(entity) {  DERDecoder.call(this, entity);  this.enc = 'pem';};inherits(PEMDecoder, DERDecoder);module.exports = PEMDecoder;PEMDecoder.prototype.decode = function decode(data, options) {  var lines = data.toString().split(/[\r\n]+/g);  var label = options.label.toUpperCase();  var re = /^-----(BEGIN|END) ([^-]+)-----$/;  var start = -1;  var end = -1;  for (var i = 0; i < lines.length; i++) {    var match = lines[i].match(re);    if (match === null)      continue;    if (match[2] !== label)      continue;    if (start === -1) {      if (match[1] !== 'BEGIN')        break;      start = i;    } else {      if (match[1] !== 'END')        break;      end = i;      break;    }  }  if (start === -1 || end === -1)    throw new Error('PEM section not found for: ' + label);  var base64 = lines.slice(start + 1, end).join('');  // Remove excessive symbols  base64.replace(/[^a-z0-9\+\/=]+/gi, '');  var input = new Buffer(base64, 'base64');  return DERDecoder.prototype.decode.call(this, input, options);};},{"./der":38,"buffer":79,"inherits":154}],41:[function(require,module,exports){var inherits = require('inherits');var Buffer = require('buffer').Buffer;var asn1 = require('../../asn1');var base = asn1.base;// Import DER constantsvar der = asn1.constants.der;function DEREncoder(entity) {  this.enc = 'der';  this.name = entity.name;  this.entity = entity;  // Construct base tree  this.tree = new DERNode();  this.tree._init(entity.body);};module.exports = DEREncoder;DEREncoder.prototype.encode = function encode(data, reporter) {  return this.tree._encode(data, reporter).join();};// Tree methodsfunction DERNode(parent) {  base.Node.call(this, 'der', parent);}inherits(DERNode, base.Node);DERNode.prototype._encodeComposite = function encodeComposite(tag,                                                              primitive,                                                              cls,                                                              content) {  var encodedTag = encodeTag(tag, primitive, cls, this.reporter);  // Short form  if (content.length < 0x80) {    var header = new Buffer(2);    header[0] = encodedTag;    header[1] = content.length;    return this._createEncoderBuffer([ header, content ]);  }  // Long form  // Count octets required to store length  var lenOctets = 1;  for (var i = content.length; i >= 0x100; i >>= 8)    lenOctets++;  var header = new Buffer(1 + 1 + lenOctets);  header[0] = encodedTag;  header[1] = 0x80 | lenOctets;  for (var i = 1 + lenOctets, j = content.length; j > 0; i--, j >>= 8)    header[i] = j & 0xff;  return this._createEncoderBuffer([ header, content ]);};DERNode.prototype._encodeStr = function encodeStr(str, tag) {  if (tag === 'bitstr') {    return this._createEncoderBuffer([ str.unused | 0, str.data ]);  } else if (tag === 'bmpstr') {    var buf = new Buffer(str.length * 2);    for (var i = 0; i < str.length; i++) {      buf.writeUInt16BE(str.charCodeAt(i), i * 2);    }    return this._createEncoderBuffer(buf);  } else if (tag === 'numstr') {    if (!this._isNumstr(str)) {      return this.reporter.error('Encoding of string type: numstr supports ' +                                 'only digits and space');    }    return this._createEncoderBuffer(str);  } else if (tag === 'printstr') {    if (!this._isPrintstr(str)) {      return this.reporter.error('Encoding of string type: printstr supports ' +                                 'only latin upper and lower case letters, ' +                                 'digits, space, apostrophe, left and rigth ' +                                 'parenthesis, plus sign, comma, hyphen, ' +                                 'dot, slash, colon, equal sign, ' +                                 'question mark');    }    return this._createEncoderBuffer(str);  } else if (/str$/.test(tag)) {    return this._createEncoderBuffer(str);  } else if (tag === 'objDesc') {    return this._createEncoderBuffer(str);  } else {    return this.reporter.error('Encoding of string type: ' + tag +                               ' unsupported');  }};DERNode.prototype._encodeObjid = function encodeObjid(id, values, relative) {  if (typeof id === 'string') {    if (!values)      return this.reporter.error('string objid given, but no values map found');    if (!values.hasOwnProperty(id))      return this.reporter.error('objid not found in values map');    id = values[id].split(/[\s\.]+/g);    for (var i = 0; i < id.length; i++)      id[i] |= 0;  } else if (Array.isArray(id)) {    id = id.slice();    for (var i = 0; i < id.length; i++)      id[i] |= 0;  }  if (!Array.isArray(id)) {    return this.reporter.error('objid() should be either array or string, ' +                               'got: ' + JSON.stringify(id));  }  if (!relative) {    if (id[1] >= 40)      return this.reporter.error('Second objid identifier OOB');    id.splice(0, 2, id[0] * 40 + id[1]);  }  // Count number of octets  var size = 0;  for (var i = 0; i < id.length; i++) {    var ident = id[i];    for (size++; ident >= 0x80; ident >>= 7)      size++;  }  var objid = new Buffer(size);  var offset = objid.length - 1;  for (var i = id.length - 1; i >= 0; i--) {    var ident = id[i];    objid[offset--] = ident & 0x7f;    while ((ident >>= 7) > 0)      objid[offset--] = 0x80 | (ident & 0x7f);  }  return this._createEncoderBuffer(objid);};function two(num) {  if (num < 10)    return '0' + num;  else    return num;}DERNode.prototype._encodeTime = function encodeTime(time, tag) {  var str;  var date = new Date(time);  if (tag === 'gentime') {    str = [      two(date.getFullYear()),      two(date.getUTCMonth() + 1),      two(date.getUTCDate()),      two(date.getUTCHours()),      two(date.getUTCMinutes()),      two(date.getUTCSeconds()),      'Z'    ].join('');  } else if (tag === 'utctime') {    str = [      two(date.getFullYear() % 100),      two(date.getUTCMonth() + 1),      two(date.getUTCDate()),      two(date.getUTCHours()),      two(date.getUTCMinutes()),      two(date.getUTCSeconds()),      'Z'    ].join('');  } else {    this.reporter.error('Encoding ' + tag + ' time is not supported yet');  }  return this._encodeStr(str, 'octstr');};DERNode.prototype._encodeNull = function encodeNull() {  return this._createEncoderBuffer('');};DERNode.prototype._encodeInt = function encodeInt(num, values) {  if (typeof num === 'string') {    if (!values)      return this.reporter.error('String int or enum given, but no values map');    if (!values.hasOwnProperty(num)) {      return this.reporter.error('Values map doesn\'t contain: ' +                                 JSON.stringify(num));    }    num = values[num];  }  // Bignum, assume big endian  if (typeof num !== 'number' && !Buffer.isBuffer(num)) {    var numArray = num.toArray();    if (!num.sign && numArray[0] & 0x80) {      numArray.unshift(0);    }    num = new Buffer(numArray);  }  if (Buffer.isBuffer(num)) {    var size = num.length;    if (num.length === 0)      size++;    var out = new Buffer(size);    num.copy(out);    if (num.length === 0)      out[0] = 0    return this._createEncoderBuffer(out);  }  if (num < 0x80)    return this._createEncoderBuffer(num);  if (num < 0x100)    return this._createEncoderBuffer([0, num]);  var size = 1;  for (var i = num; i >= 0x100; i >>= 8)    size++;  var out = new Array(size);  for (var i = out.length - 1; i >= 0; i--) {    out[i] = num & 0xff;    num >>= 8;  }  if(out[0] & 0x80) {    out.unshift(0);  }  return this._createEncoderBuffer(new Buffer(out));};DERNode.prototype._encodeBool = function encodeBool(value) {  return this._createEncoderBuffer(value ? 0xff : 0);};DERNode.prototype._use = function use(entity, obj) {  if (typeof entity === 'function')    entity = entity(obj);  return entity._getEncoder('der').tree;};DERNode.prototype._skipDefault = function skipDefault(dataBuffer, reporter, parent) {  var state = this._baseState;  var i;  if (state['default'] === null)    return false;  var data = dataBuffer.join();  if (state.defaultBuffer === undefined)    state.defaultBuffer = this._encodeValue(state['default'], reporter, parent).join();  if (data.length !== state.defaultBuffer.length)    return false;  for (i=0; i < data.length; i++)    if (data[i] !== state.defaultBuffer[i])      return false;  return true;};// Utility methodsfunction encodeTag(tag, primitive, cls, reporter) {  var res;  if (tag === 'seqof')    tag = 'seq';  else if (tag === 'setof')    tag = 'set';  if (der.tagByName.hasOwnProperty(tag))    res = der.tagByName[tag];  else if (typeof tag === 'number' && (tag | 0) === tag)    res = tag;  else    return reporter.error('Unknown tag: ' + tag);  if (res >= 0x1f)    return reporter.error('Multi-octet tag encoding unsupported');  if (!primitive)    res |= 0x20;  res |= (der.tagClassByName[cls || 'universal'] << 6);  return res;}},{"../../asn1":30,"buffer":79,"inherits":154}],42:[function(require,module,exports){var encoders = exports;encoders.der = require('./der');encoders.pem = require('./pem');},{"./der":41,"./pem":43}],43:[function(require,module,exports){var inherits = require('inherits');var DEREncoder = require('./der');function PEMEncoder(entity) {  DEREncoder.call(this, entity);  this.enc = 'pem';};inherits(PEMEncoder, DEREncoder);module.exports = PEMEncoder;PEMEncoder.prototype.encode = function encode(data, options) {  var buf = DEREncoder.prototype.encode.call(this, data);  var p = buf.toString('base64');  var out = [ '-----BEGIN ' + options.label + '-----' ];  for (var i = 0; i < p.length; i += 64)    out.push(p.slice(i, i + 64));  out.push('-----END ' + options.label + '-----');  return out.join('\n');};},{"./der":41,"inherits":154}],44:[function(require,module,exports){'use strict'exports.byteLength = byteLengthexports.toByteArray = toByteArrayexports.fromByteArray = fromByteArrayvar lookup = []var revLookup = []var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Arrayvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'for (var i = 0, len = code.length; i < len; ++i) {  lookup[i] = code[i]  revLookup[code.charCodeAt(i)] = i}// Support decoding URL-safe base64 strings, as Node.js does.// See: https://en.wikipedia.org/wiki/Base64#URL_applicationsrevLookup['-'.charCodeAt(0)] = 62revLookup['_'.charCodeAt(0)] = 63function getLens (b64) {  var len = b64.length  if (len % 4 > 0) {    throw new Error('Invalid string. Length must be a multiple of 4')  }  // Trim off extra bytes after placeholder bytes are found  // See: https://github.com/beatgammit/base64-js/issues/42  var validLen = b64.indexOf('=')  if (validLen === -1) validLen = len  var placeHoldersLen = validLen === len    ? 0    : 4 - (validLen % 4)  return [validLen, placeHoldersLen]}// base64 is 4/3 + up to two characters of the original datafunction byteLength (b64) {  var lens = getLens(b64)  var validLen = lens[0]  var placeHoldersLen = lens[1]  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen}function _byteLength (b64, validLen, placeHoldersLen) {  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen}function toByteArray (b64) {  var tmp  var lens = getLens(b64)  var validLen = lens[0]  var placeHoldersLen = lens[1]  var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))  var curByte = 0  // if there are placeholders, only get up to the last complete 4 chars  var len = placeHoldersLen > 0    ? validLen - 4    : validLen  for (var i = 0; i < len; i += 4) {    tmp =      (revLookup[b64.charCodeAt(i)] << 18) |      (revLookup[b64.charCodeAt(i + 1)] << 12) |      (revLookup[b64.charCodeAt(i + 2)] << 6) |      revLookup[b64.charCodeAt(i + 3)]    arr[curByte++] = (tmp >> 16) & 0xFF    arr[curByte++] = (tmp >> 8) & 0xFF    arr[curByte++] = tmp & 0xFF  }  if (placeHoldersLen === 2) {    tmp =      (revLookup[b64.charCodeAt(i)] << 2) |      (revLookup[b64.charCodeAt(i + 1)] >> 4)    arr[curByte++] = tmp & 0xFF  }  if (placeHoldersLen === 1) {    tmp =      (revLookup[b64.charCodeAt(i)] << 10) |      (revLookup[b64.charCodeAt(i + 1)] << 4) |      (revLookup[b64.charCodeAt(i + 2)] >> 2)    arr[curByte++] = (tmp >> 8) & 0xFF    arr[curByte++] = tmp & 0xFF  }  return arr}function tripletToBase64 (num) {  return lookup[num >> 18 & 0x3F] +    lookup[num >> 12 & 0x3F] +    lookup[num >> 6 & 0x3F] +    lookup[num & 0x3F]}function encodeChunk (uint8, start, end) {  var tmp  var output = []  for (var i = start; i < end; i += 3) {    tmp =      ((uint8[i] << 16) & 0xFF0000) +      ((uint8[i + 1] << 8) & 0xFF00) +      (uint8[i + 2] & 0xFF)    output.push(tripletToBase64(tmp))  }  return output.join('')}function fromByteArray (uint8) {  var tmp  var len = uint8.length  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes  var parts = []  var maxChunkLength = 16383 // must be multiple of 3  // go through the array every three bytes, we'll deal with trailing stuff later  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {    parts.push(encodeChunk(      uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)    ))  }  // pad the end with zeros, but make sure to not forget the extra bytes  if (extraBytes === 1) {    tmp = uint8[len - 1]    parts.push(      lookup[tmp >> 2] +      lookup[(tmp << 4) & 0x3F] +      '=='    )  } else if (extraBytes === 2) {    tmp = (uint8[len - 2] << 8) + uint8[len - 1]    parts.push(      lookup[tmp >> 10] +      lookup[(tmp >> 4) & 0x3F] +      lookup[(tmp << 2) & 0x3F] +      '='    )  }  return parts.join('')}},{}],45:[function(require,module,exports){(function (module, exports) {  'use strict';  // Utils  function assert (val, msg) {    if (!val) throw new Error(msg || 'Assertion failed');  }  // Could use `inherits` module, but don't want to move from single file  // architecture yet.  function inherits (ctor, superCtor) {    ctor.super_ = superCtor;    var TempCtor = function () {};    TempCtor.prototype = superCtor.prototype;    ctor.prototype = new TempCtor();    ctor.prototype.constructor = ctor;  }  // BN  function BN (number, base, endian) {    if (BN.isBN(number)) {      return number;    }    this.negative = 0;    this.words = null;    this.length = 0;    // Reduction context    this.red = null;    if (number !== null) {      if (base === 'le' || base === 'be') {        endian = base;        base = 10;      }      this._init(number || 0, base || 10, endian || 'be');    }  }  if (typeof module === 'object') {    module.exports = BN;  } else {    exports.BN = BN;  }  BN.BN = BN;  BN.wordSize = 26;  var Buffer;  try {    Buffer = require('buffer').Buffer;  } catch (e) {  }  BN.isBN = function isBN (num) {    if (num instanceof BN) {      return true;    }    return num !== null && typeof num === 'object' &&      num.constructor.wordSize === BN.wordSize && Array.isArray(num.words);  };  BN.max = function max (left, right) {    if (left.cmp(right) > 0) return left;    return right;  };  BN.min = function min (left, right) {    if (left.cmp(right) < 0) return left;    return right;  };  BN.prototype._init = function init (number, base, endian) {    if (typeof number === 'number') {      return this._initNumber(number, base, endian);    }    if (typeof number === 'object') {      return this._initArray(number, base, endian);    }    if (base === 'hex') {      base = 16;    }    assert(base === (base | 0) && base >= 2 && base <= 36);    number = number.toString().replace(/\s+/g, '');    var start = 0;    if (number[0] === '-') {      start++;    }    if (base === 16) {      this._parseHex(number, start);    } else {      this._parseBase(number, base, start);    }    if (number[0] === '-') {      this.negative = 1;    }    this.strip();    if (endian !== 'le') return;    this._initArray(this.toArray(), base, endian);  };  BN.prototype._initNumber = function _initNumber (number, base, endian) {    if (number < 0) {      this.negative = 1;      number = -number;    }    if (number < 0x4000000) {      this.words = [ number & 0x3ffffff ];      this.length = 1;    } else if (number < 0x10000000000000) {      this.words = [        number & 0x3ffffff,        (number / 0x4000000) & 0x3ffffff      ];      this.length = 2;    } else {      assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)      this.words = [        number & 0x3ffffff,        (number / 0x4000000) & 0x3ffffff,        1      ];      this.length = 3;    }    if (endian !== 'le') return;    // Reverse the bytes    this._initArray(this.toArray(), base, endian);  };  BN.prototype._initArray = function _initArray (number, base, endian) {    // Perhaps a Uint8Array    assert(typeof number.length === 'number');    if (number.length <= 0) {      this.words = [ 0 ];      this.length = 1;      return this;    }    this.length = Math.ceil(number.length / 3);    this.words = new Array(this.length);    for (var i = 0; i < this.length; i++) {      this.words[i] = 0;    }    var j, w;    var off = 0;    if (endian === 'be') {      for (i = number.length - 1, j = 0; i >= 0; i -= 3) {        w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);        this.words[j] |= (w << off) & 0x3ffffff;        this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;        off += 24;        if (off >= 26) {          off -= 26;          j++;        }      }    } else if (endian === 'le') {      for (i = 0, j = 0; i < number.length; i += 3) {        w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);        this.words[j] |= (w << off) & 0x3ffffff;        this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;        off += 24;        if (off >= 26) {          off -= 26;          j++;        }      }    }    return this.strip();  };  function parseHex (str, start, end) {    var r = 0;    var len = Math.min(str.length, end);    for (var i = start; i < len; i++) {      var c = str.charCodeAt(i) - 48;      r <<= 4;      // 'a' - 'f'      if (c >= 49 && c <= 54) {        r |= c - 49 + 0xa;      // 'A' - 'F'      } else if (c >= 17 && c <= 22) {        r |= c - 17 + 0xa;      // '0' - '9'      } else {        r |= c & 0xf;      }    }    return r;  }  BN.prototype._parseHex = function _parseHex (number, start) {    // Create possibly bigger array to ensure that it fits the number    this.length = Math.ceil((number.length - start) / 6);    this.words = new Array(this.length);    for (var i = 0; i < this.length; i++) {      this.words[i] = 0;    }    var j, w;    // Scan 24-bit chunks and add them to the number    var off = 0;    for (i = number.length - 6, j = 0; i >= start; i -= 6) {      w = parseHex(number, i, i + 6);      this.words[j] |= (w << off) & 0x3ffffff;      // NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb      this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;      off += 24;      if (off >= 26) {        off -= 26;        j++;      }    }    if (i + 6 !== start) {      w = parseHex(number, start, i + 6);      this.words[j] |= (w << off) & 0x3ffffff;      this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;    }    this.strip();  };  function parseBase (str, start, end, mul) {    var r = 0;    var len = Math.min(str.length, end);    for (var i = start; i < len; i++) {      var c = str.charCodeAt(i) - 48;      r *= mul;      // 'a'      if (c >= 49) {        r += c - 49 + 0xa;      // 'A'      } else if (c >= 17) {        r += c - 17 + 0xa;      // '0' - '9'      } else {        r += c;      }    }    return r;  }  BN.prototype._parseBase = function _parseBase (number, base, start) {    // Initialize as zero    this.words = [ 0 ];    this.length = 1;    // Find length of limb in base    for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) {      limbLen++;    }    limbLen--;    limbPow = (limbPow / base) | 0;    var total = number.length - start;    var mod = total % limbLen;    var end = Math.min(total, total - mod) + start;    var word = 0;    for (var i = start; i < end; i += limbLen) {      word = parseBase(number, i, i + limbLen, base);      this.imuln(limbPow);      if (this.words[0] + word < 0x4000000) {        this.words[0] += word;      } else {        this._iaddn(word);      }    }    if (mod !== 0) {      var pow = 1;      word = parseBase(number, i, number.length, base);      for (i = 0; i < mod; i++) {        pow *= base;      }      this.imuln(pow);      if (this.words[0] + word < 0x4000000) {        this.words[0] += word;      } else {        this._iaddn(word);      }    }  };  BN.prototype.copy = function copy (dest) {    dest.words = new Array(this.length);    for (var i = 0; i < this.length; i++) {      dest.words[i] = this.words[i];    }    dest.length = this.length;    dest.negative = this.negative;    dest.red = this.red;  };  BN.prototype.clone = function clone () {    var r = new BN(null);    this.copy(r);    return r;  };  BN.prototype._expand = function _expand (size) {    while (this.length < size) {      this.words[this.length++] = 0;    }    return this;  };  // Remove leading `0` from `this`  BN.prototype.strip = function strip () {    while (this.length > 1 && this.words[this.length - 1] === 0) {      this.length--;    }    return this._normSign();  };  BN.prototype._normSign = function _normSign () {    // -0 = 0    if (this.length === 1 && this.words[0] === 0) {      this.negative = 0;    }    return this;  };  BN.prototype.inspect = function inspect () {    return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>';  };  /*  var zeros = [];  var groupSizes = [];  var groupBases = [];  var s = '';  var i = -1;  while (++i < BN.wordSize) {    zeros[i] = s;    s += '0';  }  groupSizes[0] = 0;  groupSizes[1] = 0;  groupBases[0] = 0;  groupBases[1] = 0;  var base = 2 - 1;  while (++base < 36 + 1) {    var groupSize = 0;    var groupBase = 1;    while (groupBase < (1 << BN.wordSize) / base) {      groupBase *= base;      groupSize += 1;    }    groupSizes[base] = groupSize;    groupBases[base] = groupBase;  }  */  var zeros = [    '',    '0',    '00',    '000',    '0000',    '00000',    '000000',    '0000000',    '00000000',    '000000000',    '0000000000',    '00000000000',    '000000000000',    '0000000000000',    '00000000000000',    '000000000000000',    '0000000000000000',    '00000000000000000',    '000000000000000000',    '0000000000000000000',    '00000000000000000000',    '000000000000000000000',    '0000000000000000000000',    '00000000000000000000000',    '000000000000000000000000',    '0000000000000000000000000'  ];  var groupSizes = [    0, 0,    25, 16, 12, 11, 10, 9, 8,    8, 7, 7, 7, 7, 6, 6,    6, 6, 6, 6, 6, 5, 5,    5, 5, 5, 5, 5, 5, 5,    5, 5, 5, 5, 5, 5, 5  ];  var groupBases = [    0, 0,    33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,    43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,    16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,    6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,    24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176  ];  BN.prototype.toString = function toString (base, padding) {    base = base || 10;    padding = padding | 0 || 1;    var out;    if (base === 16 || base === 'hex') {      out = '';      var off = 0;      var carry = 0;      for (var i = 0; i < this.length; i++) {        var w = this.words[i];        var word = (((w << off) | carry) & 0xffffff).toString(16);        carry = (w >>> (24 - off)) & 0xffffff;        if (carry !== 0 || i !== this.length - 1) {          out = zeros[6 - word.length] + word + out;        } else {          out = word + out;        }        off += 2;        if (off >= 26) {          off -= 26;          i--;        }      }      if (carry !== 0) {        out = carry.toString(16) + out;      }      while (out.length % padding !== 0) {        out = '0' + out;      }      if (this.negative !== 0) {        out = '-' + out;      }      return out;    }    if (base === (base | 0) && base >= 2 && base <= 36) {      // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));      var groupSize = groupSizes[base];      // var groupBase = Math.pow(base, groupSize);      var groupBase = groupBases[base];      out = '';      var c = this.clone();      c.negative = 0;      while (!c.isZero()) {        var r = c.modn(groupBase).toString(base);        c = c.idivn(groupBase);        if (!c.isZero()) {          out = zeros[groupSize - r.length] + r + out;        } else {          out = r + out;        }      }      if (this.isZero()) {        out = '0' + out;      }      while (out.length % padding !== 0) {        out = '0' + out;      }      if (this.negative !== 0) {        out = '-' + out;      }      return out;    }    assert(false, 'Base should be between 2 and 36');  };  BN.prototype.toNumber = function toNumber () {    var ret = this.words[0];    if (this.length === 2) {      ret += this.words[1] * 0x4000000;    } else if (this.length === 3 && this.words[2] === 0x01) {      // NOTE: at this stage it is known that the top bit is set      ret += 0x10000000000000 + (this.words[1] * 0x4000000);    } else if (this.length > 2) {      assert(false, 'Number can only safely store up to 53 bits');    }    return (this.negative !== 0) ? -ret : ret;  };  BN.prototype.toJSON = function toJSON () {    return this.toString(16);  };  BN.prototype.toBuffer = function toBuffer (endian, length) {    assert(typeof Buffer !== 'undefined');    return this.toArrayLike(Buffer, endian, length);  };  BN.prototype.toArray = function toArray (endian, length) {    return this.toArrayLike(Array, endian, length);  };  BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) {    var byteLength = this.byteLength();    var reqLength = length || Math.max(1, byteLength);    assert(byteLength <= reqLength, 'byte array longer than desired length');    assert(reqLength > 0, 'Requested array length <= 0');    this.strip();    var littleEndian = endian === 'le';    var res = new ArrayType(reqLength);    var b, i;    var q = this.clone();    if (!littleEndian) {      // Assume big-endian      for (i = 0; i < reqLength - byteLength; i++) {        res[i] = 0;      }      for (i = 0; !q.isZero(); i++) {        b = q.andln(0xff);        q.iushrn(8);        res[reqLength - i - 1] = b;      }    } else {      for (i = 0; !q.isZero(); i++) {        b = q.andln(0xff);        q.iushrn(8);        res[i] = b;      }      for (; i < reqLength; i++) {        res[i] = 0;      }    }    return res;  };  if (Math.clz32) {    BN.prototype._countBits = function _countBits (w) {      return 32 - Math.clz32(w);    };  } else {    BN.prototype._countBits = function _countBits (w) {      var t = w;      var r = 0;      if (t >= 0x1000) {        r += 13;        t >>>= 13;      }      if (t >= 0x40) {        r += 7;        t >>>= 7;      }      if (t >= 0x8) {        r += 4;        t >>>= 4;      }      if (t >= 0x02) {        r += 2;        t >>>= 2;      }      return r + t;    };  }  BN.prototype._zeroBits = function _zeroBits (w) {    // Short-cut    if (w === 0) return 26;    var t = w;    var r = 0;    if ((t & 0x1fff) === 0) {      r += 13;      t >>>= 13;    }    if ((t & 0x7f) === 0) {      r += 7;      t >>>= 7;    }    if ((t & 0xf) === 0) {      r += 4;      t >>>= 4;    }    if ((t & 0x3) === 0) {      r += 2;      t >>>= 2;    }    if ((t & 0x1) === 0) {      r++;    }    return r;  };  // Return number of used bits in a BN  BN.prototype.bitLength = function bitLength () {    var w = this.words[this.length - 1];    var hi = this._countBits(w);    return (this.length - 1) * 26 + hi;  };  function toBitArray (num) {    var w = new Array(num.bitLength());    for (var bit = 0; bit < w.length; bit++) {      var off = (bit / 26) | 0;      var wbit = bit % 26;      w[bit] = (num.words[off] & (1 << wbit)) >>> wbit;    }    return w;  }  // Number of trailing zero bits  BN.prototype.zeroBits = function zeroBits () {    if (this.isZero()) return 0;    var r = 0;    for (var i = 0; i < this.length; i++) {      var b = this._zeroBits(this.words[i]);      r += b;      if (b !== 26) break;    }    return r;  };  BN.prototype.byteLength = function byteLength () {    return Math.ceil(this.bitLength() / 8);  };  BN.prototype.toTwos = function toTwos (width) {    if (this.negative !== 0) {      return this.abs().inotn(width).iaddn(1);    }    return this.clone();  };  BN.prototype.fromTwos = function fromTwos (width) {    if (this.testn(width - 1)) {      return this.notn(width).iaddn(1).ineg();    }    return this.clone();  };  BN.prototype.isNeg = function isNeg () {    return this.negative !== 0;  };  // Return negative clone of `this`  BN.prototype.neg = function neg () {    return this.clone().ineg();  };  BN.prototype.ineg = function ineg () {    if (!this.isZero()) {      this.negative ^= 1;    }    return this;  };  // Or `num` with `this` in-place  BN.prototype.iuor = function iuor (num) {    while (this.length < num.length) {      this.words[this.length++] = 0;    }    for (var i = 0; i < num.length; i++) {      this.words[i] = this.words[i] | num.words[i];    }    return this.strip();  };  BN.prototype.ior = function ior (num) {    assert((this.negative | num.negative) === 0);    return this.iuor(num);  };  // Or `num` with `this`  BN.prototype.or = function or (num) {    if (this.length > num.length) return this.clone().ior(num);    return num.clone().ior(this);  };  BN.prototype.uor = function uor (num) {    if (this.length > num.length) return this.clone().iuor(num);    return num.clone().iuor(this);  };  // And `num` with `this` in-place  BN.prototype.iuand = function iuand (num) {    // b = min-length(num, this)    var b;    if (this.length > num.length) {      b = num;    } else {      b = this;    }    for (var i = 0; i < b.length; i++) {      this.words[i] = this.words[i] & num.words[i];    }    this.length = b.length;    return this.strip();  };  BN.prototype.iand = function iand (num) {    assert((this.negative | num.negative) === 0);    return this.iuand(num);  };  // And `num` with `this`  BN.prototype.and = function and (num) {    if (this.length > num.length) return this.clone().iand(num);    return num.clone().iand(this);  };  BN.prototype.uand = function uand (num) {    if (this.length > num.length) return this.clone().iuand(num);    return num.clone().iuand(this);  };  // Xor `num` with `this` in-place  BN.prototype.iuxor = function iuxor (num) {    // a.length > b.length    var a;    var b;    if (this.length > num.length) {      a = this;      b = num;    } else {      a = num;      b = this;    }    for (var i = 0; i < b.length; i++) {      this.words[i] = a.words[i] ^ b.words[i];    }    if (this !== a) {      for (; i < a.length; i++) {        this.words[i] = a.words[i];      }    }    this.length = a.length;    return this.strip();  };  BN.prototype.ixor = function ixor (num) {    assert((this.negative | num.negative) === 0);    return this.iuxor(num);  };  // Xor `num` with `this`  BN.prototype.xor = function xor (num) {    if (this.length > num.length) return this.clone().ixor(num);    return num.clone().ixor(this);  };  BN.prototype.uxor = function uxor (num) {    if (this.length > num.length) return this.clone().iuxor(num);    return num.clone().iuxor(this);  };  // Not ``this`` with ``width`` bitwidth  BN.prototype.inotn = function inotn (width) {    assert(typeof width === 'number' && width >= 0);    var bytesNeeded = Math.ceil(width / 26) | 0;    var bitsLeft = width % 26;    // Extend the buffer with leading zeroes    this._expand(bytesNeeded);    if (bitsLeft > 0) {      bytesNeeded--;    }    // Handle complete words    for (var i = 0; i < bytesNeeded; i++) {      this.words[i] = ~this.words[i] & 0x3ffffff;    }    // Handle the residue    if (bitsLeft > 0) {      this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft));    }    // And remove leading zeroes    return this.strip();  };  BN.prototype.notn = function notn (width) {    return this.clone().inotn(width);  };  // Set `bit` of `this`  BN.prototype.setn = function setn (bit, val) {    assert(typeof bit === 'number' && bit >= 0);    var off = (bit / 26) | 0;    var wbit = bit % 26;    this._expand(off + 1);    if (val) {      this.words[off] = this.words[off] | (1 << wbit);    } else {      this.words[off] = this.words[off] & ~(1 << wbit);    }    return this.strip();  };  // Add `num` to `this` in-place  BN.prototype.iadd = function iadd (num) {    var r;    // negative + positive    if (this.negative !== 0 && num.negative === 0) {      this.negative = 0;      r = this.isub(num);      this.negative ^= 1;      return this._normSign();    // positive + negative    } else if (this.negative === 0 && num.negative !== 0) {      num.negative = 0;      r = this.isub(num);      num.negative = 1;      return r._normSign();    }    // a.length > b.length    var a, b;    if (this.length > num.length) {      a = this;      b = num;    } else {      a = num;      b = this;    }    var carry = 0;    for (var i = 0; i < b.length; i++) {      r = (a.words[i] | 0) + (b.words[i] | 0) + carry;      this.words[i] = r & 0x3ffffff;      carry = r >>> 26;    }    for (; carry !== 0 && i < a.length; i++) {      r = (a.words[i] | 0) + carry;      this.words[i] = r & 0x3ffffff;      carry = r >>> 26;    }    this.length = a.length;    if (carry !== 0) {      this.words[this.length] = carry;      this.length++;    // Copy the rest of the words    } else if (a !== this) {      for (; i < a.length; i++) {        this.words[i] = a.words[i];      }    }    return this;  };  // Add `num` to `this`  BN.prototype.add = function add (num) {    var res;    if (num.negative !== 0 && this.negative === 0) {      num.negative = 0;      res = this.sub(num);      num.negative ^= 1;      return res;    } else if (num.negative === 0 && this.negative !== 0) {      this.negative = 0;      res = num.sub(this);      this.negative = 1;      return res;    }    if (this.length > num.length) return this.clone().iadd(num);    return num.clone().iadd(this);  };  // Subtract `num` from `this` in-place  BN.prototype.isub = function isub (num) {    // this - (-num) = this + num    if (num.negative !== 0) {      num.negative = 0;      var r = this.iadd(num);      num.negative = 1;      return r._normSign();    // -this - num = -(this + num)    } else if (this.negative !== 0) {      this.negative = 0;      this.iadd(num);      this.negative = 1;      return this._normSign();    }    // At this point both numbers are positive    var cmp = this.cmp(num);    // Optimization - zeroify    if (cmp === 0) {      this.negative = 0;      this.length = 1;      this.words[0] = 0;      return this;    }    // a > b    var a, b;    if (cmp > 0) {      a = this;      b = num;    } else {      a = num;      b = this;    }    var carry = 0;    for (var i = 0; i < b.length; i++) {      r = (a.words[i] | 0) - (b.words[i] | 0) + carry;      carry = r >> 26;      this.words[i] = r & 0x3ffffff;    }    for (; carry !== 0 && i < a.length; i++) {      r = (a.words[i] | 0) + carry;      carry = r >> 26;      this.words[i] = r & 0x3ffffff;    }    // Copy rest of the words    if (carry === 0 && i < a.length && a !== this) {      for (; i < a.length; i++) {        this.words[i] = a.words[i];      }    }    this.length = Math.max(this.length, i);    if (a !== this) {      this.negative = 1;    }    return this.strip();  };  // Subtract `num` from `this`  BN.prototype.sub = function sub (num) {    return this.clone().isub(num);  };  function smallMulTo (self, num, out) {    out.negative = num.negative ^ self.negative;    var len = (self.length + num.length) | 0;    out.length = len;    len = (len - 1) | 0;    // Peel one iteration (compiler can't do it, because of code complexity)    var a = self.words[0] | 0;    var b = num.words[0] | 0;    var r = a * b;    var lo = r & 0x3ffffff;    var carry = (r / 0x4000000) | 0;    out.words[0] = lo;    for (var k = 1; k < len; k++) {      // Sum all words with the same `i + j = k` and accumulate `ncarry`,      // note that ncarry could be >= 0x3ffffff      var ncarry = carry >>> 26;      var rword = carry & 0x3ffffff;      var maxJ = Math.min(k, num.length - 1);      for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {        var i = (k - j) | 0;        a = self.words[i] | 0;        b = num.words[j] | 0;        r = a * b + rword;        ncarry += (r / 0x4000000) | 0;        rword = r & 0x3ffffff;      }      out.words[k] = rword | 0;      carry = ncarry | 0;    }    if (carry !== 0) {      out.words[k] = carry | 0;    } else {      out.length--;    }    return out.strip();  }  // TODO(indutny): it may be reasonable to omit it for users who don't need  // to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit  // multiplication (like elliptic secp256k1).  var comb10MulTo = function comb10MulTo (self, num, out) {    var a = self.words;    var b = num.words;    var o = out.words;    var c = 0;    var lo;    var mid;    var hi;    var a0 = a[0] | 0;    var al0 = a0 & 0x1fff;    var ah0 = a0 >>> 13;    var a1 = a[1] | 0;    var al1 = a1 & 0x1fff;    var ah1 = a1 >>> 13;    var a2 = a[2] | 0;    var al2 = a2 & 0x1fff;    var ah2 = a2 >>> 13;    var a3 = a[3] | 0;    var al3 = a3 & 0x1fff;    var ah3 = a3 >>> 13;    var a4 = a[4] | 0;    var al4 = a4 & 0x1fff;    var ah4 = a4 >>> 13;    var a5 = a[5] | 0;    var al5 = a5 & 0x1fff;    var ah5 = a5 >>> 13;    var a6 = a[6] | 0;    var al6 = a6 & 0x1fff;    var ah6 = a6 >>> 13;    var a7 = a[7] | 0;    var al7 = a7 & 0x1fff;    var ah7 = a7 >>> 13;    var a8 = a[8] | 0;    var al8 = a8 & 0x1fff;    var ah8 = a8 >>> 13;    var a9 = a[9] | 0;    var al9 = a9 & 0x1fff;    var ah9 = a9 >>> 13;    var b0 = b[0] | 0;    var bl0 = b0 & 0x1fff;    var bh0 = b0 >>> 13;    var b1 = b[1] | 0;    var bl1 = b1 & 0x1fff;    var bh1 = b1 >>> 13;    var b2 = b[2] | 0;    var bl2 = b2 & 0x1fff;    var bh2 = b2 >>> 13;    var b3 = b[3] | 0;    var bl3 = b3 & 0x1fff;    var bh3 = b3 >>> 13;    var b4 = b[4] | 0;    var bl4 = b4 & 0x1fff;    var bh4 = b4 >>> 13;    var b5 = b[5] | 0;    var bl5 = b5 & 0x1fff;    var bh5 = b5 >>> 13;    var b6 = b[6] | 0;    var bl6 = b6 & 0x1fff;    var bh6 = b6 >>> 13;    var b7 = b[7] | 0;    var bl7 = b7 & 0x1fff;    var bh7 = b7 >>> 13;    var b8 = b[8] | 0;    var bl8 = b8 & 0x1fff;    var bh8 = b8 >>> 13;    var b9 = b[9] | 0;    var bl9 = b9 & 0x1fff;    var bh9 = b9 >>> 13;    out.negative = self.negative ^ num.negative;    out.length = 19;    /* k = 0 */    lo = Math.imul(al0, bl0);    mid = Math.imul(al0, bh0);    mid = (mid + Math.imul(ah0, bl0)) | 0;    hi = Math.imul(ah0, bh0);    var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;    c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0;    w0 &= 0x3ffffff;    /* k = 1 */    lo = Math.imul(al1, bl0);    mid = Math.imul(al1, bh0);    mid = (mid + Math.imul(ah1, bl0)) | 0;    hi = Math.imul(ah1, bh0);    lo = (lo + Math.imul(al0, bl1)) | 0;    mid = (mid + Math.imul(al0, bh1)) | 0;    mid = (mid + Math.imul(ah0, bl1)) | 0;    hi = (hi + Math.imul(ah0, bh1)) | 0;    var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;    c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0;    w1 &= 0x3ffffff;    /* k = 2 */    lo = Math.imul(al2, bl0);    mid = Math.imul(al2, bh0);    mid = (mid + Math.imul(ah2, bl0)) | 0;    hi = Math.imul(ah2, bh0);    lo = (lo + Math.imul(al1, bl1)) | 0;    mid = (mid + Math.imul(al1, bh1)) | 0;    mid = (mid + Math.imul(ah1, bl1)) | 0;    hi = (hi + Math.imul(ah1, bh1)) | 0;    lo = (lo + Math.imul(al0, bl2)) | 0;    mid = (mid + Math.imul(al0, bh2)) | 0;    mid = (mid + Math.imul(ah0, bl2)) | 0;    hi = (hi + Math.imul(ah0, bh2)) | 0;    var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;    c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0;    w2 &= 0x3ffffff;    /* k = 3 */    lo = Math.imul(al3, bl0);    mid = Math.imul(al3, bh0);    mid = (mid + Math.imul(ah3, bl0)) | 0;    hi = Math.imul(ah3, bh0);    lo = (lo + Math.imul(al2, bl1)) | 0;    mid = (mid + Math.imul(al2, bh1)) | 0;    mid = (mid + Math.imul(ah2, bl1)) | 0;    hi = (hi + Math.imul(ah2, bh1)) | 0;    lo = (lo + Math.imul(al1, bl2)) | 0;    mid = (mid + Math.imul(al1, bh2)) | 0;    mid = (mid + Math.imul(ah1, bl2)) | 0;    hi = (hi + Math.imul(ah1, bh2)) | 0;    lo = (lo + Math.imul(al0, bl3)) | 0;    mid = (mid + Math.imul(al0, bh3)) | 0;    mid = (mid + Math.imul(ah0, bl3)) | 0;    hi = (hi + Math.imul(ah0, bh3)) | 0;    var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;    c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0;    w3 &= 0x3ffffff;    /* k = 4 */    lo = Math.imul(al4, bl0);    mid = Math.imul(al4, bh0);    mid = (mid + Math.imul(ah4, bl0)) | 0;    hi = Math.imul(ah4, bh0);    lo = (lo + Math.imul(al3, bl1)) | 0;    mid = (mid + Math.imul(al3, bh1)) | 0;    mid = (mid + Math.imul(ah3, bl1)) | 0;    hi = (hi + Math.imul(ah3, bh1)) | 0;    lo = (lo + Math.imul(al2, bl2)) | 0;    mid = (mid + Math.imul(al2, bh2)) | 0;    mid = (mid + Math.imul(ah2, bl2)) | 0;    hi = (hi + Math.imul(ah2, bh2)) | 0;    lo = (lo + Math.imul(al1, bl3)) | 0;    mid = (mid + Math.imul(al1, bh3)) | 0;    mid = (mid + Math.imul(ah1, bl3)) | 0;    hi = (hi + Math.imul(ah1, bh3)) | 0;    lo = (lo + Math.imul(al0, bl4)) | 0;    mid = (mid + Math.imul(al0, bh4)) | 0;    mid = (mid + Math.imul(ah0, bl4)) | 0;    hi = (hi + Math.imul(ah0, bh4)) | 0;    var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;    c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0;    w4 &= 0x3ffffff;    /* k = 5 */    lo = Math.imul(al5, bl0);    mid = Math.imul(al5, bh0);    mid = (mid + Math.imul(ah5, bl0)) | 0;    hi = Math.imul(ah5, bh0);    lo = (lo + Math.imul(al4, bl1)) | 0;    mid = (mid + Math.imul(al4, bh1)) | 0;    mid = (mid + Math.imul(ah4, bl1)) | 0;    hi = (hi + Math.imul(ah4, bh1)) | 0;    lo = (lo + Math.imul(al3, bl2)) | 0;    mid = (mid + Math.imul(al3, bh2)) | 0;    mid = (mid + Math.imul(ah3, bl2)) | 0;    hi = (hi + Math.imul(ah3, bh2)) | 0;    lo = (lo + Math.imul(al2, bl3)) | 0;    mid = (mid + Math.imul(al2, bh3)) | 0;    mid = (mid + Math.imul(ah2, bl3)) | 0;    hi = (hi + Math.imul(ah2, bh3)) | 0;    lo = (lo + Math.imul(al1, bl4)) | 0;    mid = (mid + Math.imul(al1, bh4)) | 0;    mid = (mid + Math.imul(ah1, bl4)) | 0;    hi = (hi + Math.imul(ah1, bh4)) | 0;    lo = (lo + Math.imul(al0, bl5)) | 0;    mid = (mid + Math.imul(al0, bh5)) | 0;    mid = (mid + Math.imul(ah0, bl5)) | 0;    hi = (hi + Math.imul(ah0, bh5)) | 0;    var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;    c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0;    w5 &= 0x3ffffff;    /* k = 6 */    lo = Math.imul(al6, bl0);    mid = Math.imul(al6, bh0);    mid = (mid + Math.imul(ah6, bl0)) | 0;    hi = Math.imul(ah6, bh0);    lo = (lo + Math.imul(al5, bl1)) | 0;    mid = (mid + Math.imul(al5, bh1)) | 0;    mid = (mid + Math.imul(ah5, bl1)) | 0;    hi = (hi + Math.imul(ah5, bh1)) | 0;    lo = (lo + Math.imul(al4, bl2)) | 0;    mid = (mid + Math.imul(al4, bh2)) | 0;    mid = (mid + Math.imul(ah4, bl2)) | 0;    hi = (hi + Math.imul(ah4, bh2)) | 0;    lo = (lo + Math.imul(al3, bl3)) | 0;    mid = (mid + Math.imul(al3, bh3)) | 0;    mid = (mid + Math.imul(ah3, bl3)) | 0;    hi = (hi + Math.imul(ah3, bh3)) | 0;    lo = (lo + Math.imul(al2, bl4)) | 0;    mid = (mid + Math.imul(al2, bh4)) | 0;    mid = (mid + Math.imul(ah2, bl4)) | 0;    hi = (hi + Math.imul(ah2, bh4)) | 0;    lo = (lo + Math.imul(al1, bl5)) | 0;    mid = (mid + Math.imul(al1, bh5)) | 0;    mid = (mid + Math.imul(ah1, bl5)) | 0;    hi = (hi + Math.imul(ah1, bh5)) | 0;    lo = (lo + Math.imul(al0, bl6)) | 0;    mid = (mid + Math.imul(al0, bh6)) | 0;    mid = (mid + Math.imul(ah0, bl6)) | 0;    hi = (hi + Math.imul(ah0, bh6)) | 0;    var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;    c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0;    w6 &= 0x3ffffff;    /* k = 7 */    lo = Math.imul(al7, bl0);    mid = Math.imul(al7, bh0);    mid = (mid + Math.imul(ah7, bl0)) | 0;    hi = Math.imul(ah7, bh0);    lo = (lo + Math.imul(al6, bl1)) | 0;    mid = (mid + Math.imul(al6, bh1)) | 0;    mid = (mid + Math.imul(ah6, bl1)) | 0;    hi = (hi + Math.imul(ah6, bh1)) | 0;    lo = (lo + Math.imul(al5, bl2)) | 0;    mid = (mid + Math.imul(al5, bh2)) | 0;    mid = (mid + Math.imul(ah5, bl2)) | 0;    hi = (hi + Math.imul(ah5, bh2)) | 0;    lo = (lo + Math.imul(al4, bl3)) | 0;    mid = (mid + Math.imul(al4, bh3)) | 0;    mid = (mid + Math.imul(ah4, bl3)) | 0;    hi = (hi + Math.imul(ah4, bh3)) | 0;    lo = (lo + Math.imul(al3, bl4)) | 0;    mid = (mid + Math.imul(al3, bh4)) | 0;    mid = (mid + Math.imul(ah3, bl4)) | 0;    hi = (hi + Math.imul(ah3, bh4)) | 0;    lo = (lo + Math.imul(al2, bl5)) | 0;    mid = (mid + Math.imul(al2, bh5)) | 0;    mid = (mid + Math.imul(ah2, bl5)) | 0;    hi = (hi + Math.imul(ah2, bh5)) | 0;    lo = (lo + Math.imul(al1, bl6)) | 0;    mid = (mid + Math.imul(al1, bh6)) | 0;    mid = (mid + Math.imul(ah1, bl6)) | 0;    hi = (hi + Math.imul(ah1, bh6)) | 0;    lo = (lo + Math.imul(al0, bl7)) | 0;    mid = (mid + Math.imul(al0, bh7)) | 0;    mid = (mid + Math.imul(ah0, bl7)) | 0;    hi = (hi + Math.imul(ah0, bh7)) | 0;    var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;    c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0;    w7 &= 0x3ffffff;    /* k = 8 */    lo = Math.imul(al8, bl0);    mid = Math.imul(al8, bh0);    mid = (mid + Math.imul(ah8, bl0)) | 0;    hi = Math.imul(ah8, bh0);    lo = (lo + Math.imul(al7, bl1)) | 0;    mid = (mid + Math.imul(al7, bh1)) | 0;    mid = (mid + Math.imul(ah7, bl1)) | 0;    hi = (hi + Math.imul(ah7, bh1)) | 0;    lo = (lo + Math.imul(al6, bl2)) | 0;    mid = (mid + Math.imul(al6, bh2)) | 0;    mid = (mid + Math.imul(ah6, bl2)) | 0;    hi = (hi + Math.imul(ah6, bh2)) | 0;    lo = (lo + Math.imul(al5, bl3)) | 0;    mid = (mid + Math.imul(al5, bh3)) | 0;    mid = (mid + Math.imul(ah5, bl3)) | 0;    hi = (hi + Math.imul(ah5, bh3)) | 0;    lo = (lo + Math.imul(al4, bl4)) | 0;    mid = (mid + Math.imul(al4, bh4)) | 0;    mid = (mid + Math.imul(ah4, bl4)) | 0;    hi = (hi + Math.imul(ah4, bh4)) | 0;    lo = (lo + Math.imul(al3, bl5)) | 0;    mid = (mid + Math.imul(al3, bh5)) | 0;    mid = (mid + Math.imul(ah3, bl5)) | 0;    hi = (hi + Math.imul(ah3, bh5)) | 0;    lo = (lo + Math.imul(al2, bl6)) | 0;    mid = (mid + Math.imul(al2, bh6)) | 0;    mid = (mid + Math.imul(ah2, bl6)) | 0;    hi = (hi + Math.imul(ah2, bh6)) | 0;    lo = (lo + Math.imul(al1, bl7)) | 0;    mid = (mid + Math.imul(al1, bh7)) | 0;    mid = (mid + Math.imul(ah1, bl7)) | 0;    hi = (hi + Math.imul(ah1, bh7)) | 0;    lo = (lo + Math.imul(al0, bl8)) | 0;    mid = (mid + Math.imul(al0, bh8)) | 0;    mid = (mid + Math.imul(ah0, bl8)) | 0;    hi = (hi + Math.imul(ah0, bh8)) | 0;    var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;    c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0;    w8 &= 0x3ffffff;    /* k = 9 */    lo = Math.imul(al9, bl0);    mid = Math.imul(al9, bh0);    mid = (mid + Math.imul(ah9, bl0)) | 0;    hi = Math.imul(ah9, bh0);    lo = (lo + Math.imul(al8, bl1)) | 0;    mid = (mid + Math.imul(al8, bh1)) | 0;    mid = (mid + Math.imul(ah8, bl1)) | 0;    hi = (hi + Math.imul(ah8, bh1)) | 0;    lo = (lo + Math.imul(al7, bl2)) | 0;    mid = (mid + Math.imul(al7, bh2)) | 0;    mid = (mid + Math.imul(ah7, bl2)) | 0;    hi = (hi + Math.imul(ah7, bh2)) | 0;    lo = (lo + Math.imul(al6, bl3)) | 0;    mid = (mid + Math.imul(al6, bh3)) | 0;    mid = (mid + Math.imul(ah6, bl3)) | 0;    hi = (hi + Math.imul(ah6, bh3)) | 0;    lo = (lo + Math.imul(al5, bl4)) | 0;    mid = (mid + Math.imul(al5, bh4)) | 0;    mid = (mid + Math.imul(ah5, bl4)) | 0;    hi = (hi + Math.imul(ah5, bh4)) | 0;    lo = (lo + Math.imul(al4, bl5)) | 0;    mid = (mid + Math.imul(al4, bh5)) | 0;    mid = (mid + Math.imul(ah4, bl5)) | 0;    hi = (hi + Math.imul(ah4, bh5)) | 0;    lo = (lo + Math.imul(al3, bl6)) | 0;    mid = (mid + Math.imul(al3, bh6)) | 0;    mid = (mid + Math.imul(ah3, bl6)) | 0;    hi = (hi + Math.imul(ah3, bh6)) | 0;    lo = (lo + Math.imul(al2, bl7)) | 0;    mid = (mid + Math.imul(al2, bh7)) | 0;    mid = (mid + Math.imul(ah2, bl7)) | 0;    hi = (hi + Math.imul(ah2, bh7)) | 0;    lo = (lo + Math.imul(al1, bl8)) | 0;    mid = (mid + Math.imul(al1, bh8)) | 0;    mid = (mid + Math.imul(ah1, bl8)) | 0;    hi = (hi + Math.imul(ah1, bh8)) | 0;    lo = (lo + Math.imul(al0, bl9)) | 0;    mid = (mid + Math.imul(al0, bh9)) | 0;    mid = (mid + Math.imul(ah0, bl9)) | 0;    hi = (hi + Math.imul(ah0, bh9)) | 0;    var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;    c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0;    w9 &= 0x3ffffff;    /* k = 10 */    lo = Math.imul(al9, bl1);    mid = Math.imul(al9, bh1);    mid = (mid + Math.imul(ah9, bl1)) | 0;    hi = Math.imul(ah9, bh1);    lo = (lo + Math.imul(al8, bl2)) | 0;    mid = (mid + Math.imul(al8, bh2)) | 0;    mid = (mid + Math.imul(ah8, bl2)) | 0;    hi = (hi + Math.imul(ah8, bh2)) | 0;    lo = (lo + Math.imul(al7, bl3)) | 0;    mid = (mid + Math.imul(al7, bh3)) | 0;    mid = (mid + Math.imul(ah7, bl3)) | 0;    hi = (hi + Math.imul(ah7, bh3)) | 0;    lo = (lo + Math.imul(al6, bl4)) | 0;    mid = (mid + Math.imul(al6, bh4)) | 0;    mid = (mid + Math.imul(ah6, bl4)) | 0;    hi = (hi + Math.imul(ah6, bh4)) | 0;    lo = (lo + Math.imul(al5, bl5)) | 0;    mid = (mid + Math.imul(al5, bh5)) | 0;    mid = (mid + Math.imul(ah5, bl5)) | 0;    hi = (hi + Math.imul(ah5, bh5)) | 0;    lo = (lo + Math.imul(al4, bl6)) | 0;    mid = (mid + Math.imul(al4, bh6)) | 0;    mid = (mid + Math.imul(ah4, bl6)) | 0;    hi = (hi + Math.imul(ah4, bh6)) | 0;    lo = (lo + Math.imul(al3, bl7)) | 0;    mid = (mid + Math.imul(al3, bh7)) | 0;    mid = (mid + Math.imul(ah3, bl7)) | 0;    hi = (hi + Math.imul(ah3, bh7)) | 0;    lo = (lo + Math.imul(al2, bl8)) | 0;    mid = (mid + Math.imul(al2, bh8)) | 0;    mid = (mid + Math.imul(ah2, bl8)) | 0;    hi = (hi + Math.imul(ah2, bh8)) | 0;    lo = (lo + Math.imul(al1, bl9)) | 0;    mid = (mid + Math.imul(al1, bh9)) | 0;    mid = (mid + Math.imul(ah1, bl9)) | 0;    hi = (hi + Math.imul(ah1, bh9)) | 0;    var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;    c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0;    w10 &= 0x3ffffff;    /* k = 11 */    lo = Math.imul(al9, bl2);    mid = Math.imul(al9, bh2);    mid = (mid + Math.imul(ah9, bl2)) | 0;    hi = Math.imul(ah9, bh2);    lo = (lo + Math.imul(al8, bl3)) | 0;    mid = (mid + Math.imul(al8, bh3)) | 0;    mid = (mid + Math.imul(ah8, bl3)) | 0;    hi = (hi + Math.imul(ah8, bh3)) | 0;    lo = (lo + Math.imul(al7, bl4)) | 0;    mid = (mid + Math.imul(al7, bh4)) | 0;    mid = (mid + Math.imul(ah7, bl4)) | 0;    hi = (hi + Math.imul(ah7, bh4)) | 0;    lo = (lo + Math.imul(al6, bl5)) | 0;    mid = (mid + Math.imul(al6, bh5)) | 0;    mid = (mid + Math.imul(ah6, bl5)) | 0;    hi = (hi + Math.imul(ah6, bh5)) | 0;    lo = (lo + Math.imul(al5, bl6)) | 0;    mid = (mid + Math.imul(al5, bh6)) | 0;    mid = (mid + Math.imul(ah5, bl6)) | 0;    hi = (hi + Math.imul(ah5, bh6)) | 0;    lo = (lo + Math.imul(al4, bl7)) | 0;    mid = (mid + Math.imul(al4, bh7)) | 0;    mid = (mid + Math.imul(ah4, bl7)) | 0;    hi = (hi + Math.imul(ah4, bh7)) | 0;    lo = (lo + Math.imul(al3, bl8)) | 0;    mid = (mid + Math.imul(al3, bh8)) | 0;    mid = (mid + Math.imul(ah3, bl8)) | 0;    hi = (hi + Math.imul(ah3, bh8)) | 0;    lo = (lo + Math.imul(al2, bl9)) | 0;    mid = (mid + Math.imul(al2, bh9)) | 0;    mid = (mid + Math.imul(ah2, bl9)) | 0;    hi = (hi + Math.imul(ah2, bh9)) | 0;    var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;    c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0;    w11 &= 0x3ffffff;    /* k = 12 */    lo = Math.imul(al9, bl3);    mid = Math.imul(al9, bh3);    mid = (mid + Math.imul(ah9, bl3)) | 0;    hi = Math.imul(ah9, bh3);    lo = (lo + Math.imul(al8, bl4)) | 0;    mid = (mid + Math.imul(al8, bh4)) | 0;    mid = (mid + Math.imul(ah8, bl4)) | 0;    hi = (hi + Math.imul(ah8, bh4)) | 0;    lo = (lo + Math.imul(al7, bl5)) | 0;    mid = (mid + Math.imul(al7, bh5)) | 0;    mid = (mid + Math.imul(ah7, bl5)) | 0;    hi = (hi + Math.imul(ah7, bh5)) | 0;    lo = (lo + Math.imul(al6, bl6)) | 0;    mid = (mid + Math.imul(al6, bh6)) | 0;    mid = (mid + Math.imul(ah6, bl6)) | 0;    hi = (hi + Math.imul(ah6, bh6)) | 0;    lo = (lo + Math.imul(al5, bl7)) | 0;    mid = (mid + Math.imul(al5, bh7)) | 0;    mid = (mid + Math.imul(ah5, bl7)) | 0;    hi = (hi + Math.imul(ah5, bh7)) | 0;    lo = (lo + Math.imul(al4, bl8)) | 0;    mid = (mid + Math.imul(al4, bh8)) | 0;    mid = (mid + Math.imul(ah4, bl8)) | 0;    hi = (hi + Math.imul(ah4, bh8)) | 0;    lo = (lo + Math.imul(al3, bl9)) | 0;    mid = (mid + Math.imul(al3, bh9)) | 0;    mid = (mid + Math.imul(ah3, bl9)) | 0;    hi = (hi + Math.imul(ah3, bh9)) | 0;    var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;    c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0;    w12 &= 0x3ffffff;    /* k = 13 */    lo = Math.imul(al9, bl4);    mid = Math.imul(al9, bh4);    mid = (mid + Math.imul(ah9, bl4)) | 0;    hi = Math.imul(ah9, bh4);    lo = (lo + Math.imul(al8, bl5)) | 0;    mid = (mid + Math.imul(al8, bh5)) | 0;    mid = (mid + Math.imul(ah8, bl5)) | 0;    hi = (hi + Math.imul(ah8, bh5)) | 0;    lo = (lo + Math.imul(al7, bl6)) | 0;    mid = (mid + Math.imul(al7, bh6)) | 0;    mid = (mid + Math.imul(ah7, bl6)) | 0;    hi = (hi + Math.imul(ah7, bh6)) | 0;    lo = (lo + Math.imul(al6, bl7)) | 0;    mid = (mid + Math.imul(al6, bh7)) | 0;    mid = (mid + Math.imul(ah6, bl7)) | 0;    hi = (hi + Math.imul(ah6, bh7)) | 0;    lo = (lo + Math.imul(al5, bl8)) | 0;    mid = (mid + Math.imul(al5, bh8)) | 0;    mid = (mid + Math.imul(ah5, bl8)) | 0;    hi = (hi + Math.imul(ah5, bh8)) | 0;    lo = (lo + Math.imul(al4, bl9)) | 0;    mid = (mid + Math.imul(al4, bh9)) | 0;    mid = (mid + Math.imul(ah4, bl9)) | 0;    hi = (hi + Math.imul(ah4, bh9)) | 0;    var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;    c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0;    w13 &= 0x3ffffff;    /* k = 14 */    lo = Math.imul(al9, bl5);    mid = Math.imul(al9, bh5);    mid = (mid + Math.imul(ah9, bl5)) | 0;    hi = Math.imul(ah9, bh5);    lo = (lo + Math.imul(al8, bl6)) | 0;    mid = (mid + Math.imul(al8, bh6)) | 0;    mid = (mid + Math.imul(ah8, bl6)) | 0;    hi = (hi + Math.imul(ah8, bh6)) | 0;    lo = (lo + Math.imul(al7, bl7)) | 0;    mid = (mid + Math.imul(al7, bh7)) | 0;    mid = (mid + Math.imul(ah7, bl7)) | 0;    hi = (hi + Math.imul(ah7, bh7)) | 0;    lo = (lo + Math.imul(al6, bl8)) | 0;    mid = (mid + Math.imul(al6, bh8)) | 0;    mid = (mid + Math.imul(ah6, bl8)) | 0;    hi = (hi + Math.imul(ah6, bh8)) | 0;    lo = (lo + Math.imul(al5, bl9)) | 0;    mid = (mid + Math.imul(al5, bh9)) | 0;    mid = (mid + Math.imul(ah5, bl9)) | 0;    hi = (hi + Math.imul(ah5, bh9)) | 0;    var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;    c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0;    w14 &= 0x3ffffff;    /* k = 15 */    lo = Math.imul(al9, bl6);    mid = Math.imul(al9, bh6);    mid = (mid + Math.imul(ah9, bl6)) | 0;    hi = Math.imul(ah9, bh6);    lo = (lo + Math.imul(al8, bl7)) | 0;    mid = (mid + Math.imul(al8, bh7)) | 0;    mid = (mid + Math.imul(ah8, bl7)) | 0;    hi = (hi + Math.imul(ah8, bh7)) | 0;    lo = (lo + Math.imul(al7, bl8)) | 0;    mid = (mid + Math.imul(al7, bh8)) | 0;    mid = (mid + Math.imul(ah7, bl8)) | 0;    hi = (hi + Math.imul(ah7, bh8)) | 0;    lo = (lo + Math.imul(al6, bl9)) | 0;    mid = (mid + Math.imul(al6, bh9)) | 0;    mid = (mid + Math.imul(ah6, bl9)) | 0;    hi = (hi + Math.imul(ah6, bh9)) | 0;    var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;    c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0;    w15 &= 0x3ffffff;    /* k = 16 */    lo = Math.imul(al9, bl7);    mid = Math.imul(al9, bh7);    mid = (mid + Math.imul(ah9, bl7)) | 0;    hi = Math.imul(ah9, bh7);    lo = (lo + Math.imul(al8, bl8)) | 0;    mid = (mid + Math.imul(al8, bh8)) | 0;    mid = (mid + Math.imul(ah8, bl8)) | 0;    hi = (hi + Math.imul(ah8, bh8)) | 0;    lo = (lo + Math.imul(al7, bl9)) | 0;    mid = (mid + Math.imul(al7, bh9)) | 0;    mid = (mid + Math.imul(ah7, bl9)) | 0;    hi = (hi + Math.imul(ah7, bh9)) | 0;    var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;    c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0;    w16 &= 0x3ffffff;    /* k = 17 */    lo = Math.imul(al9, bl8);    mid = Math.imul(al9, bh8);    mid = (mid + Math.imul(ah9, bl8)) | 0;    hi = Math.imul(ah9, bh8);    lo = (lo + Math.imul(al8, bl9)) | 0;    mid = (mid + Math.imul(al8, bh9)) | 0;    mid = (mid + Math.imul(ah8, bl9)) | 0;    hi = (hi + Math.imul(ah8, bh9)) | 0;    var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;    c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0;    w17 &= 0x3ffffff;    /* k = 18 */    lo = Math.imul(al9, bl9);    mid = Math.imul(al9, bh9);    mid = (mid + Math.imul(ah9, bl9)) | 0;    hi = Math.imul(ah9, bh9);    var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;    c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0;    w18 &= 0x3ffffff;    o[0] = w0;    o[1] = w1;    o[2] = w2;    o[3] = w3;    o[4] = w4;    o[5] = w5;    o[6] = w6;    o[7] = w7;    o[8] = w8;    o[9] = w9;    o[10] = w10;    o[11] = w11;    o[12] = w12;    o[13] = w13;    o[14] = w14;    o[15] = w15;    o[16] = w16;    o[17] = w17;    o[18] = w18;    if (c !== 0) {      o[19] = c;      out.length++;    }    return out;  };  // Polyfill comb  if (!Math.imul) {    comb10MulTo = smallMulTo;  }  function bigMulTo (self, num, out) {    out.negative = num.negative ^ self.negative;    out.length = self.length + num.length;    var carry = 0;    var hncarry = 0;    for (var k = 0; k < out.length - 1; k++) {      // Sum all words with the same `i + j = k` and accumulate `ncarry`,      // note that ncarry could be >= 0x3ffffff      var ncarry = hncarry;      hncarry = 0;      var rword = carry & 0x3ffffff;      var maxJ = Math.min(k, num.length - 1);      for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {        var i = k - j;        var a = self.words[i] | 0;        var b = num.words[j] | 0;        var r = a * b;        var lo = r & 0x3ffffff;        ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;        lo = (lo + rword) | 0;        rword = lo & 0x3ffffff;        ncarry = (ncarry + (lo >>> 26)) | 0;        hncarry += ncarry >>> 26;        ncarry &= 0x3ffffff;      }      out.words[k] = rword;      carry = ncarry;      ncarry = hncarry;    }    if (carry !== 0) {      out.words[k] = carry;    } else {      out.length--;    }    return out.strip();  }  function jumboMulTo (self, num, out) {    var fftm = new FFTM();    return fftm.mulp(self, num, out);  }  BN.prototype.mulTo = function mulTo (num, out) {    var res;    var len = this.length + num.length;    if (this.length === 10 && num.length === 10) {      res = comb10MulTo(this, num, out);    } else if (len < 63) {      res = smallMulTo(this, num, out);    } else if (len < 1024) {      res = bigMulTo(this, num, out);    } else {      res = jumboMulTo(this, num, out);    }    return res;  };  // Cooley-Tukey algorithm for FFT  // slightly revisited to rely on looping instead of recursion  function FFTM (x, y) {    this.x = x;    this.y = y;  }  FFTM.prototype.makeRBT = function makeRBT (N) {    var t = new Array(N);    var l = BN.prototype._countBits(N) - 1;    for (var i = 0; i < N; i++) {      t[i] = this.revBin(i, l, N);    }    return t;  };  // Returns binary-reversed representation of `x`  FFTM.prototype.revBin = function revBin (x, l, N) {    if (x === 0 || x === N - 1) return x;    var rb = 0;    for (var i = 0; i < l; i++) {      rb |= (x & 1) << (l - i - 1);      x >>= 1;    }    return rb;  };  // Performs "tweedling" phase, therefore 'emulating'  // behaviour of the recursive algorithm  FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) {    for (var i = 0; i < N; i++) {      rtws[i] = rws[rbt[i]];      itws[i] = iws[rbt[i]];    }  };  FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) {    this.permute(rbt, rws, iws, rtws, itws, N);    for (var s = 1; s < N; s <<= 1) {      var l = s << 1;      var rtwdf = Math.cos(2 * Math.PI / l);      var itwdf = Math.sin(2 * Math.PI / l);      for (var p = 0; p < N; p += l) {        var rtwdf_ = rtwdf;        var itwdf_ = itwdf;        for (var j = 0; j < s; j++) {          var re = rtws[p + j];          var ie = itws[p + j];          var ro = rtws[p + j + s];          var io = itws[p + j + s];          var rx = rtwdf_ * ro - itwdf_ * io;          io = rtwdf_ * io + itwdf_ * ro;          ro = rx;          rtws[p + j] = re + ro;          itws[p + j] = ie + io;          rtws[p + j + s] = re - ro;          itws[p + j + s] = ie - io;          /* jshint maxdepth : false */          if (j !== l) {            rx = rtwdf * rtwdf_ - itwdf * itwdf_;            itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_;            rtwdf_ = rx;          }        }      }    }  };  FFTM.prototype.guessLen13b = function guessLen13b (n, m) {    var N = Math.max(m, n) | 1;    var odd = N & 1;    var i = 0;    for (N = N / 2 | 0; N; N = N >>> 1) {      i++;    }    return 1 << i + 1 + odd;  };  FFTM.prototype.conjugate = function conjugate (rws, iws, N) {    if (N <= 1) return;    for (var i = 0; i < N / 2; i++) {      var t = rws[i];      rws[i] = rws[N - i - 1];      rws[N - i - 1] = t;      t = iws[i];      iws[i] = -iws[N - i - 1];      iws[N - i - 1] = -t;    }  };  FFTM.prototype.normalize13b = function normalize13b (ws, N) {    var carry = 0;    for (var i = 0; i < N / 2; i++) {      var w = Math.round(ws[2 * i + 1] / N) * 0x2000 +        Math.round(ws[2 * i] / N) +        carry;      ws[i] = w & 0x3ffffff;      if (w < 0x4000000) {        carry = 0;      } else {        carry = w / 0x4000000 | 0;      }    }    return ws;  };  FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) {    var carry = 0;    for (var i = 0; i < len; i++) {      carry = carry + (ws[i] | 0);      rws[2 * i] = carry & 0x1fff; carry = carry >>> 13;      rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13;    }    // Pad with zeroes    for (i = 2 * len; i < N; ++i) {      rws[i] = 0;    }    assert(carry === 0);    assert((carry & ~0x1fff) === 0);  };  FFTM.prototype.stub = function stub (N) {    var ph = new Array(N);    for (var i = 0; i < N; i++) {      ph[i] = 0;    }    return ph;  };  FFTM.prototype.mulp = function mulp (x, y, out) {    var N = 2 * this.guessLen13b(x.length, y.length);    var rbt = this.makeRBT(N);    var _ = this.stub(N);    var rws = new Array(N);    var rwst = new Array(N);    var iwst = new Array(N);    var nrws = new Array(N);    var nrwst = new Array(N);    var niwst = new Array(N);    var rmws = out.words;    rmws.length = N;    this.convert13b(x.words, x.length, rws, N);    this.convert13b(y.words, y.length, nrws, N);    this.transform(rws, _, rwst, iwst, N, rbt);    this.transform(nrws, _, nrwst, niwst, N, rbt);    for (var i = 0; i < N; i++) {      var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i];      iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i];      rwst[i] = rx;    }    this.conjugate(rwst, iwst, N);    this.transform(rwst, iwst, rmws, _, N, rbt);    this.conjugate(rmws, _, N);    this.normalize13b(rmws, N);    out.negative = x.negative ^ y.negative;    out.length = x.length + y.length;    return out.strip();  };  // Multiply `this` by `num`  BN.prototype.mul = function mul (num) {    var out = new BN(null);    out.words = new Array(this.length + num.length);    return this.mulTo(num, out);  };  // Multiply employing FFT  BN.prototype.mulf = function mulf (num) {    var out = new BN(null);    out.words = new Array(this.length + num.length);    return jumboMulTo(this, num, out);  };  // In-place Multiplication  BN.prototype.imul = function imul (num) {    return this.clone().mulTo(num, this);  };  BN.prototype.imuln = function imuln (num) {    assert(typeof num === 'number');    assert(num < 0x4000000);    // Carry    var carry = 0;    for (var i = 0; i < this.length; i++) {      var w = (this.words[i] | 0) * num;      var lo = (w & 0x3ffffff) + (carry & 0x3ffffff);      carry >>= 26;      carry += (w / 0x4000000) | 0;      // NOTE: lo is 27bit maximum      carry += lo >>> 26;      this.words[i] = lo & 0x3ffffff;    }    if (carry !== 0) {      this.words[i] = carry;      this.length++;    }    return this;  };  BN.prototype.muln = function muln (num) {    return this.clone().imuln(num);  };  // `this` * `this`  BN.prototype.sqr = function sqr () {    return this.mul(this);  };  // `this` * `this` in-place  BN.prototype.isqr = function isqr () {    return this.imul(this.clone());  };  // Math.pow(`this`, `num`)  BN.prototype.pow = function pow (num) {    var w = toBitArray(num);    if (w.length === 0) return new BN(1);    // Skip leading zeroes    var res = this;    for (var i = 0; i < w.length; i++, res = res.sqr()) {      if (w[i] !== 0) break;    }    if (++i < w.length) {      for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) {        if (w[i] === 0) continue;        res = res.mul(q);      }    }    return res;  };  // Shift-left in-place  BN.prototype.iushln = function iushln (bits) {    assert(typeof bits === 'number' && bits >= 0);    var r = bits % 26;    var s = (bits - r) / 26;    var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);    var i;    if (r !== 0) {      var carry = 0;      for (i = 0; i < this.length; i++) {        var newCarry = this.words[i] & carryMask;        var c = ((this.words[i] | 0) - newCarry) << r;        this.words[i] = c | carry;        carry = newCarry >>> (26 - r);      }      if (carry) {        this.words[i] = carry;        this.length++;      }    }    if (s !== 0) {      for (i = this.length - 1; i >= 0; i--) {        this.words[i + s] = this.words[i];      }      for (i = 0; i < s; i++) {        this.words[i] = 0;      }      this.length += s;    }    return this.strip();  };  BN.prototype.ishln = function ishln (bits) {    // TODO(indutny): implement me    assert(this.negative === 0);    return this.iushln(bits);  };  // Shift-right in-place  // NOTE: `hint` is a lowest bit before trailing zeroes  // NOTE: if `extended` is present - it will be filled with destroyed bits  BN.prototype.iushrn = function iushrn (bits, hint, extended) {    assert(typeof bits === 'number' && bits >= 0);    var h;    if (hint) {      h = (hint - (hint % 26)) / 26;    } else {      h = 0;    }    var r = bits % 26;    var s = Math.min((bits - r) / 26, this.length);    var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);    var maskedWords = extended;    h -= s;    h = Math.max(0, h);    // Extended mode, copy masked part    if (maskedWords) {      for (var i = 0; i < s; i++) {        maskedWords.words[i] = this.words[i];      }      maskedWords.length = s;    }    if (s === 0) {      // No-op, we should not move anything at all    } else if (this.length > s) {      this.length -= s;      for (i = 0; i < this.length; i++) {        this.words[i] = this.words[i + s];      }    } else {      this.words[0] = 0;      this.length = 1;    }    var carry = 0;    for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {      var word = this.words[i] | 0;      this.words[i] = (carry << (26 - r)) | (word >>> r);      carry = word & mask;    }    // Push carried bits as a mask    if (maskedWords && carry !== 0) {      maskedWords.words[maskedWords.length++] = carry;    }    if (this.length === 0) {      this.words[0] = 0;      this.length = 1;    }    return this.strip();  };  BN.prototype.ishrn = function ishrn (bits, hint, extended) {    // TODO(indutny): implement me    assert(this.negative === 0);    return this.iushrn(bits, hint, extended);  };  // Shift-left  BN.prototype.shln = function shln (bits) {    return this.clone().ishln(bits);  };  BN.prototype.ushln = function ushln (bits) {    return this.clone().iushln(bits);  };  // Shift-right  BN.prototype.shrn = function shrn (bits) {    return this.clone().ishrn(bits);  };  BN.prototype.ushrn = function ushrn (bits) {    return this.clone().iushrn(bits);  };  // Test if n bit is set  BN.prototype.testn = function testn (bit) {    assert(typeof bit === 'number' && bit >= 0);    var r = bit % 26;    var s = (bit - r) / 26;    var q = 1 << r;    // Fast case: bit is much higher than all existing words    if (this.length <= s) return false;    // Check bit and return    var w = this.words[s];    return !!(w & q);  };  // Return only lowers bits of number (in-place)  BN.prototype.imaskn = function imaskn (bits) {    assert(typeof bits === 'number' && bits >= 0);    var r = bits % 26;    var s = (bits - r) / 26;    assert(this.negative === 0, 'imaskn works only with positive numbers');    if (this.length <= s) {      return this;    }    if (r !== 0) {      s++;    }    this.length = Math.min(s, this.length);    if (r !== 0) {      var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);      this.words[this.length - 1] &= mask;    }    return this.strip();  };  // Return only lowers bits of number  BN.prototype.maskn = function maskn (bits) {    return this.clone().imaskn(bits);  };  // Add plain number `num` to `this`  BN.prototype.iaddn = function iaddn (num) {    assert(typeof num === 'number');    assert(num < 0x4000000);    if (num < 0) return this.isubn(-num);    // Possible sign change    if (this.negative !== 0) {      if (this.length === 1 && (this.words[0] | 0) < num) {        this.words[0] = num - (this.words[0] | 0);        this.negative = 0;        return this;      }      this.negative = 0;      this.isubn(num);      this.negative = 1;      return this;    }    // Add without checks    return this._iaddn(num);  };  BN.prototype._iaddn = function _iaddn (num) {    this.words[0] += num;    // Carry    for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) {      this.words[i] -= 0x4000000;      if (i === this.length - 1) {        this.words[i + 1] = 1;      } else {        this.words[i + 1]++;      }    }    this.length = Math.max(this.length, i + 1);    return this;  };  // Subtract plain number `num` from `this`  BN.prototype.isubn = function isubn (num) {    assert(typeof num === 'number');    assert(num < 0x4000000);    if (num < 0) return this.iaddn(-num);    if (this.negative !== 0) {      this.negative = 0;      this.iaddn(num);      this.negative = 1;      return this;    }    this.words[0] -= num;    if (this.length === 1 && this.words[0] < 0) {      this.words[0] = -this.words[0];      this.negative = 1;    } else {      // Carry      for (var i = 0; i < this.length && this.words[i] < 0; i++) {        this.words[i] += 0x4000000;        this.words[i + 1] -= 1;      }    }    return this.strip();  };  BN.prototype.addn = function addn (num) {    return this.clone().iaddn(num);  };  BN.prototype.subn = function subn (num) {    return this.clone().isubn(num);  };  BN.prototype.iabs = function iabs () {    this.negative = 0;    return this;  };  BN.prototype.abs = function abs () {    return this.clone().iabs();  };  BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) {    var len = num.length + shift;    var i;    this._expand(len);    var w;    var carry = 0;    for (i = 0; i < num.length; i++) {      w = (this.words[i + shift] | 0) + carry;      var right = (num.words[i] | 0) * mul;      w -= right & 0x3ffffff;      carry = (w >> 26) - ((right / 0x4000000) | 0);      this.words[i + shift] = w & 0x3ffffff;    }    for (; i < this.length - shift; i++) {      w = (this.words[i + shift] | 0) + carry;      carry = w >> 26;      this.words[i + shift] = w & 0x3ffffff;    }    if (carry === 0) return this.strip();    // Subtraction overflow    assert(carry === -1);    carry = 0;    for (i = 0; i < this.length; i++) {      w = -(this.words[i] | 0) + carry;      carry = w >> 26;      this.words[i] = w & 0x3ffffff;    }    this.negative = 1;    return this.strip();  };  BN.prototype._wordDiv = function _wordDiv (num, mode) {    var shift = this.length - num.length;    var a = this.clone();    var b = num;    // Normalize    var bhi = b.words[b.length - 1] | 0;    var bhiBits = this._countBits(bhi);    shift = 26 - bhiBits;    if (shift !== 0) {      b = b.ushln(shift);      a.iushln(shift);      bhi = b.words[b.length - 1] | 0;    }    // Initialize quotient    var m = a.length - b.length;    var q;    if (mode !== 'mod') {      q = new BN(null);      q.length = m + 1;      q.words = new Array(q.length);      for (var i = 0; i < q.length; i++) {        q.words[i] = 0;      }    }    var diff = a.clone()._ishlnsubmul(b, 1, m);    if (diff.negative === 0) {      a = diff;      if (q) {        q.words[m] = 1;      }    }    for (var j = m - 1; j >= 0; j--) {      var qj = (a.words[b.length + j] | 0) * 0x4000000 +        (a.words[b.length + j - 1] | 0);      // NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max      // (0x7ffffff)      qj = Math.min((qj / bhi) | 0, 0x3ffffff);      a._ishlnsubmul(b, qj, j);      while (a.negative !== 0) {        qj--;        a.negative = 0;        a._ishlnsubmul(b, 1, j);        if (!a.isZero()) {          a.negative ^= 1;        }      }      if (q) {        q.words[j] = qj;      }    }    if (q) {      q.strip();    }    a.strip();    // Denormalize    if (mode !== 'div' && shift !== 0) {      a.iushrn(shift);    }    return {      div: q || null,      mod: a    };  };  // NOTE: 1) `mode` can be set to `mod` to request mod only,  //       to `div` to request div only, or be absent to  //       request both div & mod  //       2) `positive` is true if unsigned mod is requested  BN.prototype.divmod = function divmod (num, mode, positive) {    assert(!num.isZero());    if (this.isZero()) {      return {        div: new BN(0),        mod: new BN(0)      };    }    var div, mod, res;    if (this.negative !== 0 && num.negative === 0) {      res = this.neg().divmod(num, mode);      if (mode !== 'mod') {        div = res.div.neg();      }      if (mode !== 'div') {        mod = res.mod.neg();        if (positive && mod.negative !== 0) {          mod.iadd(num);        }      }      return {        div: div,        mod: mod      };    }    if (this.negative === 0 && num.negative !== 0) {      res = this.divmod(num.neg(), mode);      if (mode !== 'mod') {        div = res.div.neg();      }      return {        div: div,        mod: res.mod      };    }    if ((this.negative & num.negative) !== 0) {      res = this.neg().divmod(num.neg(), mode);      if (mode !== 'div') {        mod = res.mod.neg();        if (positive && mod.negative !== 0) {          mod.isub(num);        }      }      return {        div: res.div,        mod: mod      };    }    // Both numbers are positive at this point    // Strip both numbers to approximate shift value    if (num.length > this.length || this.cmp(num) < 0) {      return {        div: new BN(0),        mod: this      };    }    // Very short reduction    if (num.length === 1) {      if (mode === 'div') {        return {          div: this.divn(num.words[0]),          mod: null        };      }      if (mode === 'mod') {        return {          div: null,          mod: new BN(this.modn(num.words[0]))        };      }      return {        div: this.divn(num.words[0]),        mod: new BN(this.modn(num.words[0]))      };    }    return this._wordDiv(num, mode);  };  // Find `this` / `num`  BN.prototype.div = function div (num) {    return this.divmod(num, 'div', false).div;  };  // Find `this` % `num`  BN.prototype.mod = function mod (num) {    return this.divmod(num, 'mod', false).mod;  };  BN.prototype.umod = function umod (num) {    return this.divmod(num, 'mod', true).mod;  };  // Find Round(`this` / `num`)  BN.prototype.divRound = function divRound (num) {    var dm = this.divmod(num);    // Fast case - exact division    if (dm.mod.isZero()) return dm.div;    var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod;    var half = num.ushrn(1);    var r2 = num.andln(1);    var cmp = mod.cmp(half);    // Round down    if (cmp < 0 || r2 === 1 && cmp === 0) return dm.div;    // Round up    return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1);  };  BN.prototype.modn = function modn (num) {    assert(num <= 0x3ffffff);    var p = (1 << 26) % num;    var acc = 0;    for (var i = this.length - 1; i >= 0; i--) {      acc = (p * acc + (this.words[i] | 0)) % num;    }    return acc;  };  // In-place division by number  BN.prototype.idivn = function idivn (num) {    assert(num <= 0x3ffffff);    var carry = 0;    for (var i = this.length - 1; i >= 0; i--) {      var w = (this.words[i] | 0) + carry * 0x4000000;      this.words[i] = (w / num) | 0;      carry = w % num;    }    return this.strip();  };  BN.prototype.divn = function divn (num) {    return this.clone().idivn(num);  };  BN.prototype.egcd = function egcd (p) {    assert(p.negative === 0);    assert(!p.isZero());    var x = this;    var y = p.clone();    if (x.negative !== 0) {      x = x.umod(p);    } else {      x = x.clone();    }    // A * x + B * y = x    var A = new BN(1);    var B = new BN(0);    // C * x + D * y = y    var C = new BN(0);    var D = new BN(1);    var g = 0;    while (x.isEven() && y.isEven()) {      x.iushrn(1);      y.iushrn(1);      ++g;    }    var yp = y.clone();    var xp = x.clone();    while (!x.isZero()) {      for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1);      if (i > 0) {        x.iushrn(i);        while (i-- > 0) {          if (A.isOdd() || B.isOdd()) {            A.iadd(yp);            B.isub(xp);          }          A.iushrn(1);          B.iushrn(1);        }      }      for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);      if (j > 0) {        y.iushrn(j);        while (j-- > 0) {          if (C.isOdd() || D.isOdd()) {            C.iadd(yp);            D.isub(xp);          }          C.iushrn(1);          D.iushrn(1);        }      }      if (x.cmp(y) >= 0) {        x.isub(y);        A.isub(C);        B.isub(D);      } else {        y.isub(x);        C.isub(A);        D.isub(B);      }    }    return {      a: C,      b: D,      gcd: y.iushln(g)    };  };  // This is reduced incarnation of the binary EEA  // above, designated to invert members of the  // _prime_ fields F(p) at a maximal speed  BN.prototype._invmp = function _invmp (p) {    assert(p.negative === 0);    assert(!p.isZero());    var a = this;    var b = p.clone();    if (a.negative !== 0) {      a = a.umod(p);    } else {      a = a.clone();    }    var x1 = new BN(1);    var x2 = new BN(0);    var delta = b.clone();    while (a.cmpn(1) > 0 && b.cmpn(1) > 0) {      for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1);      if (i > 0) {        a.iushrn(i);        while (i-- > 0) {          if (x1.isOdd()) {            x1.iadd(delta);          }          x1.iushrn(1);        }      }      for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);      if (j > 0) {        b.iushrn(j);        while (j-- > 0) {          if (x2.isOdd()) {            x2.iadd(delta);          }          x2.iushrn(1);        }      }      if (a.cmp(b) >= 0) {        a.isub(b);        x1.isub(x2);      } else {        b.isub(a);        x2.isub(x1);      }    }    var res;    if (a.cmpn(1) === 0) {      res = x1;    } else {      res = x2;    }    if (res.cmpn(0) < 0) {      res.iadd(p);    }    return res;  };  BN.prototype.gcd = function gcd (num) {    if (this.isZero()) return num.abs();    if (num.isZero()) return this.abs();    var a = this.clone();    var b = num.clone();    a.negative = 0;    b.negative = 0;    // Remove common factor of two    for (var shift = 0; a.isEven() && b.isEven(); shift++) {      a.iushrn(1);      b.iushrn(1);    }    do {      while (a.isEven()) {        a.iushrn(1);      }      while (b.isEven()) {        b.iushrn(1);      }      var r = a.cmp(b);      if (r < 0) {        // Swap `a` and `b` to make `a` always bigger than `b`        var t = a;        a = b;        b = t;      } else if (r === 0 || b.cmpn(1) === 0) {        break;      }      a.isub(b);    } while (true);    return b.iushln(shift);  };  // Invert number in the field F(num)  BN.prototype.invm = function invm (num) {    return this.egcd(num).a.umod(num);  };  BN.prototype.isEven = function isEven () {    return (this.words[0] & 1) === 0;  };  BN.prototype.isOdd = function isOdd () {    return (this.words[0] & 1) === 1;  };  // And first word and num  BN.prototype.andln = function andln (num) {    return this.words[0] & num;  };  // Increment at the bit position in-line  BN.prototype.bincn = function bincn (bit) {    assert(typeof bit === 'number');    var r = bit % 26;    var s = (bit - r) / 26;    var q = 1 << r;    // Fast case: bit is much higher than all existing words    if (this.length <= s) {      this._expand(s + 1);      this.words[s] |= q;      return this;    }    // Add bit and propagate, if needed    var carry = q;    for (var i = s; carry !== 0 && i < this.length; i++) {      var w = this.words[i] | 0;      w += carry;      carry = w >>> 26;      w &= 0x3ffffff;      this.words[i] = w;    }    if (carry !== 0) {      this.words[i] = carry;      this.length++;    }    return this;  };  BN.prototype.isZero = function isZero () {    return this.length === 1 && this.words[0] === 0;  };  BN.prototype.cmpn = function cmpn (num) {    var negative = num < 0;    if (this.negative !== 0 && !negative) return -1;    if (this.negative === 0 && negative) return 1;    this.strip();    var res;    if (this.length > 1) {      res = 1;    } else {      if (negative) {        num = -num;      }      assert(num <= 0x3ffffff, 'Number is too big');      var w = this.words[0] | 0;      res = w === num ? 0 : w < num ? -1 : 1;    }    if (this.negative !== 0) return -res | 0;    return res;  };  // Compare two numbers and return:  // 1 - if `this` > `num`  // 0 - if `this` == `num`  // -1 - if `this` < `num`  BN.prototype.cmp = function cmp (num) {    if (this.negative !== 0 && num.negative === 0) return -1;    if (this.negative === 0 && num.negative !== 0) return 1;    var res = this.ucmp(num);    if (this.negative !== 0) return -res | 0;    return res;  };  // Unsigned comparison  BN.prototype.ucmp = function ucmp (num) {    // At this point both numbers have the same sign    if (this.length > num.length) return 1;    if (this.length < num.length) return -1;    var res = 0;    for (var i = this.length - 1; i >= 0; i--) {      var a = this.words[i] | 0;      var b = num.words[i] | 0;      if (a === b) continue;      if (a < b) {        res = -1;      } else if (a > b) {        res = 1;      }      break;    }    return res;  };  BN.prototype.gtn = function gtn (num) {    return this.cmpn(num) === 1;  };  BN.prototype.gt = function gt (num) {    return this.cmp(num) === 1;  };  BN.prototype.gten = function gten (num) {    return this.cmpn(num) >= 0;  };  BN.prototype.gte = function gte (num) {    return this.cmp(num) >= 0;  };  BN.prototype.ltn = function ltn (num) {    return this.cmpn(num) === -1;  };  BN.prototype.lt = function lt (num) {    return this.cmp(num) === -1;  };  BN.prototype.lten = function lten (num) {    return this.cmpn(num) <= 0;  };  BN.prototype.lte = function lte (num) {    return this.cmp(num) <= 0;  };  BN.prototype.eqn = function eqn (num) {    return this.cmpn(num) === 0;  };  BN.prototype.eq = function eq (num) {    return this.cmp(num) === 0;  };  //  // A reduce context, could be using montgomery or something better, depending  // on the `m` itself.  //  BN.red = function red (num) {    return new Red(num);  };  BN.prototype.toRed = function toRed (ctx) {    assert(!this.red, 'Already a number in reduction context');    assert(this.negative === 0, 'red works only with positives');    return ctx.convertTo(this)._forceRed(ctx);  };  BN.prototype.fromRed = function fromRed () {    assert(this.red, 'fromRed works only with numbers in reduction context');    return this.red.convertFrom(this);  };  BN.prototype._forceRed = function _forceRed (ctx) {    this.red = ctx;    return this;  };  BN.prototype.forceRed = function forceRed (ctx) {    assert(!this.red, 'Already a number in reduction context');    return this._forceRed(ctx);  };  BN.prototype.redAdd = function redAdd (num) {    assert(this.red, 'redAdd works only with red numbers');    return this.red.add(this, num);  };  BN.prototype.redIAdd = function redIAdd (num) {    assert(this.red, 'redIAdd works only with red numbers');    return this.red.iadd(this, num);  };  BN.prototype.redSub = function redSub (num) {    assert(this.red, 'redSub works only with red numbers');    return this.red.sub(this, num);  };  BN.prototype.redISub = function redISub (num) {    assert(this.red, 'redISub works only with red numbers');    return this.red.isub(this, num);  };  BN.prototype.redShl = function redShl (num) {    assert(this.red, 'redShl works only with red numbers');    return this.red.shl(this, num);  };  BN.prototype.redMul = function redMul (num) {    assert(this.red, 'redMul works only with red numbers');    this.red._verify2(this, num);    return this.red.mul(this, num);  };  BN.prototype.redIMul = function redIMul (num) {    assert(this.red, 'redMul works only with red numbers');    this.red._verify2(this, num);    return this.red.imul(this, num);  };  BN.prototype.redSqr = function redSqr () {    assert(this.red, 'redSqr works only with red numbers');    this.red._verify1(this);    return this.red.sqr(this);  };  BN.prototype.redISqr = function redISqr () {    assert(this.red, 'redISqr works only with red numbers');    this.red._verify1(this);    return this.red.isqr(this);  };  // Square root over p  BN.prototype.redSqrt = function redSqrt () {    assert(this.red, 'redSqrt works only with red numbers');    this.red._verify1(this);    return this.red.sqrt(this);  };  BN.prototype.redInvm = function redInvm () {    assert(this.red, 'redInvm works only with red numbers');    this.red._verify1(this);    return this.red.invm(this);  };  // Return negative clone of `this` % `red modulo`  BN.prototype.redNeg = function redNeg () {    assert(this.red, 'redNeg works only with red numbers');    this.red._verify1(this);    return this.red.neg(this);  };  BN.prototype.redPow = function redPow (num) {    assert(this.red && !num.red, 'redPow(normalNum)');    this.red._verify1(this);    return this.red.pow(this, num);  };  // Prime numbers with efficient reduction  var primes = {    k256: null,    p224: null,    p192: null,    p25519: null  };  // Pseudo-Mersenne prime  function MPrime (name, p) {    // P = 2 ^ N - K    this.name = name;    this.p = new BN(p, 16);    this.n = this.p.bitLength();    this.k = new BN(1).iushln(this.n).isub(this.p);    this.tmp = this._tmp();  }  MPrime.prototype._tmp = function _tmp () {    var tmp = new BN(null);    tmp.words = new Array(Math.ceil(this.n / 13));    return tmp;  };  MPrime.prototype.ireduce = function ireduce (num) {    // Assumes that `num` is less than `P^2`    // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P)    var r = num;    var rlen;    do {      this.split(r, this.tmp);      r = this.imulK(r);      r = r.iadd(this.tmp);      rlen = r.bitLength();    } while (rlen > this.n);    var cmp = rlen < this.n ? -1 : r.ucmp(this.p);    if (cmp === 0) {      r.words[0] = 0;      r.length = 1;    } else if (cmp > 0) {      r.isub(this.p);    } else {      r.strip();    }    return r;  };  MPrime.prototype.split = function split (input, out) {    input.iushrn(this.n, 0, out);  };  MPrime.prototype.imulK = function imulK (num) {    return num.imul(this.k);  };  function K256 () {    MPrime.call(      this,      'k256',      'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f');  }  inherits(K256, MPrime);  K256.prototype.split = function split (input, output) {    // 256 = 9 * 26 + 22    var mask = 0x3fffff;    var outLen = Math.min(input.length, 9);    for (var i = 0; i < outLen; i++) {      output.words[i] = input.words[i];    }    output.length = outLen;    if (input.length <= 9) {      input.words[0] = 0;      input.length = 1;      return;    }    // Shift by 9 limbs    var prev = input.words[9];    output.words[output.length++] = prev & mask;    for (i = 10; i < input.length; i++) {      var next = input.words[i] | 0;      input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22);      prev = next;    }    prev >>>= 22;    input.words[i - 10] = prev;    if (prev === 0 && input.length > 10) {      input.length -= 10;    } else {      input.length -= 9;    }  };  K256.prototype.imulK = function imulK (num) {    // K = 0x1000003d1 = [ 0x40, 0x3d1 ]    num.words[num.length] = 0;    num.words[num.length + 1] = 0;    num.length += 2;    // bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390    var lo = 0;    for (var i = 0; i < num.length; i++) {      var w = num.words[i] | 0;      lo += w * 0x3d1;      num.words[i] = lo & 0x3ffffff;      lo = w * 0x40 + ((lo / 0x4000000) | 0);    }    // Fast length reduction    if (num.words[num.length - 1] === 0) {      num.length--;      if (num.words[num.length - 1] === 0) {        num.length--;      }    }    return num;  };  function P224 () {    MPrime.call(      this,      'p224',      'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001');  }  inherits(P224, MPrime);  function P192 () {    MPrime.call(      this,      'p192',      'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff');  }  inherits(P192, MPrime);  function P25519 () {    // 2 ^ 255 - 19    MPrime.call(      this,      '25519',      '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed');  }  inherits(P25519, MPrime);  P25519.prototype.imulK = function imulK (num) {    // K = 0x13    var carry = 0;    for (var i = 0; i < num.length; i++) {      var hi = (num.words[i] | 0) * 0x13 + carry;      var lo = hi & 0x3ffffff;      hi >>>= 26;      num.words[i] = lo;      carry = hi;    }    if (carry !== 0) {      num.words[num.length++] = carry;    }    return num;  };  // Exported mostly for testing purposes, use plain name instead  BN._prime = function prime (name) {    // Cached version of prime    if (primes[name]) return primes[name];    var prime;    if (name === 'k256') {      prime = new K256();    } else if (name === 'p224') {      prime = new P224();    } else if (name === 'p192') {      prime = new P192();    } else if (name === 'p25519') {      prime = new P25519();    } else {      throw new Error('Unknown prime ' + name);    }    primes[name] = prime;    return prime;  };  //  // Base reduction engine  //  function Red (m) {    if (typeof m === 'string') {      var prime = BN._prime(m);      this.m = prime.p;      this.prime = prime;    } else {      assert(m.gtn(1), 'modulus must be greater than 1');      this.m = m;      this.prime = null;    }  }  Red.prototype._verify1 = function _verify1 (a) {    assert(a.negative === 0, 'red works only with positives');    assert(a.red, 'red works only with red numbers');  };  Red.prototype._verify2 = function _verify2 (a, b) {    assert((a.negative | b.negative) === 0, 'red works only with positives');    assert(a.red && a.red === b.red,      'red works only with red numbers');  };  Red.prototype.imod = function imod (a) {    if (this.prime) return this.prime.ireduce(a)._forceRed(this);    return a.umod(this.m)._forceRed(this);  };  Red.prototype.neg = function neg (a) {    if (a.isZero()) {      return a.clone();    }    return this.m.sub(a)._forceRed(this);  };  Red.prototype.add = function add (a, b) {    this._verify2(a, b);    var res = a.add(b);    if (res.cmp(this.m) >= 0) {      res.isub(this.m);    }    return res._forceRed(this);  };  Red.prototype.iadd = function iadd (a, b) {    this._verify2(a, b);    var res = a.iadd(b);    if (res.cmp(this.m) >= 0) {      res.isub(this.m);    }    return res;  };  Red.prototype.sub = function sub (a, b) {    this._verify2(a, b);    var res = a.sub(b);    if (res.cmpn(0) < 0) {      res.iadd(this.m);    }    return res._forceRed(this);  };  Red.prototype.isub = function isub (a, b) {    this._verify2(a, b);    var res = a.isub(b);    if (res.cmpn(0) < 0) {      res.iadd(this.m);    }    return res;  };  Red.prototype.shl = function shl (a, num) {    this._verify1(a);    return this.imod(a.ushln(num));  };  Red.prototype.imul = function imul (a, b) {    this._verify2(a, b);    return this.imod(a.imul(b));  };  Red.prototype.mul = function mul (a, b) {    this._verify2(a, b);    return this.imod(a.mul(b));  };  Red.prototype.isqr = function isqr (a) {    return this.imul(a, a.clone());  };  Red.prototype.sqr = function sqr (a) {    return this.mul(a, a);  };  Red.prototype.sqrt = function sqrt (a) {    if (a.isZero()) return a.clone();    var mod3 = this.m.andln(3);    assert(mod3 % 2 === 1);    // Fast case    if (mod3 === 3) {      var pow = this.m.add(new BN(1)).iushrn(2);      return this.pow(a, pow);    }    // Tonelli-Shanks algorithm (Totally unoptimized and slow)    //    // Find Q and S, that Q * 2 ^ S = (P - 1)    var q = this.m.subn(1);    var s = 0;    while (!q.isZero() && q.andln(1) === 0) {      s++;      q.iushrn(1);    }    assert(!q.isZero());    var one = new BN(1).toRed(this);    var nOne = one.redNeg();    // Find quadratic non-residue    // NOTE: Max is such because of generalized Riemann hypothesis.    var lpow = this.m.subn(1).iushrn(1);    var z = this.m.bitLength();    z = new BN(2 * z * z).toRed(this);    while (this.pow(z, lpow).cmp(nOne) !== 0) {      z.redIAdd(nOne);    }    var c = this.pow(z, q);    var r = this.pow(a, q.addn(1).iushrn(1));    var t = this.pow(a, q);    var m = s;    while (t.cmp(one) !== 0) {      var tmp = t;      for (var i = 0; tmp.cmp(one) !== 0; i++) {        tmp = tmp.redSqr();      }      assert(i < m);      var b = this.pow(c, new BN(1).iushln(m - i - 1));      r = r.redMul(b);      c = b.redSqr();      t = t.redMul(c);      m = i;    }    return r;  };  Red.prototype.invm = function invm (a) {    var inv = a._invmp(this.m);    if (inv.negative !== 0) {      inv.negative = 0;      return this.imod(inv).redNeg();    } else {      return this.imod(inv);    }  };  Red.prototype.pow = function pow (a, num) {    if (num.isZero()) return new BN(1).toRed(this);    if (num.cmpn(1) === 0) return a.clone();    var windowSize = 4;    var wnd = new Array(1 << windowSize);    wnd[0] = new BN(1).toRed(this);    wnd[1] = a;    for (var i = 2; i < wnd.length; i++) {      wnd[i] = this.mul(wnd[i - 1], a);    }    var res = wnd[0];    var current = 0;    var currentLen = 0;    var start = num.bitLength() % 26;    if (start === 0) {      start = 26;    }    for (i = num.length - 1; i >= 0; i--) {      var word = num.words[i];      for (var j = start - 1; j >= 0; j--) {        var bit = (word >> j) & 1;        if (res !== wnd[0]) {          res = this.sqr(res);        }        if (bit === 0 && current === 0) {          currentLen = 0;          continue;        }        current <<= 1;        current |= bit;        currentLen++;        if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue;        res = this.mul(res, wnd[current]);        currentLen = 0;        current = 0;      }      start = 26;    }    return res;  };  Red.prototype.convertTo = function convertTo (num) {    var r = num.umod(this.m);    return r === num ? r.clone() : r;  };  Red.prototype.convertFrom = function convertFrom (num) {    var res = num.clone();    res.red = null;    return res;  };  //  // Montgomery method engine  //  BN.mont = function mont (num) {    return new Mont(num);  };  function Mont (m) {    Red.call(this, m);    this.shift = this.m.bitLength();    if (this.shift % 26 !== 0) {      this.shift += 26 - (this.shift % 26);    }    this.r = new BN(1).iushln(this.shift);    this.r2 = this.imod(this.r.sqr());    this.rinv = this.r._invmp(this.m);    this.minv = this.rinv.mul(this.r).isubn(1).div(this.m);    this.minv = this.minv.umod(this.r);    this.minv = this.r.sub(this.minv);  }  inherits(Mont, Red);  Mont.prototype.convertTo = function convertTo (num) {    return this.imod(num.ushln(this.shift));  };  Mont.prototype.convertFrom = function convertFrom (num) {    var r = this.imod(num.mul(this.rinv));    r.red = null;    return r;  };  Mont.prototype.imul = function imul (a, b) {    if (a.isZero() || b.isZero()) {      a.words[0] = 0;      a.length = 1;      return a;    }    var t = a.imul(b);    var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);    var u = t.isub(c).iushrn(this.shift);    var res = u;    if (u.cmp(this.m) >= 0) {      res = u.isub(this.m);    } else if (u.cmpn(0) < 0) {      res = u.iadd(this.m);    }    return res._forceRed(this);  };  Mont.prototype.mul = function mul (a, b) {    if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this);    var t = a.mul(b);    var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);    var u = t.isub(c).iushrn(this.shift);    var res = u;    if (u.cmp(this.m) >= 0) {      res = u.isub(this.m);    } else if (u.cmpn(0) < 0) {      res = u.iadd(this.m);    }    return res._forceRed(this);  };  Mont.prototype.invm = function invm (a) {    // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R    var res = this.imod(a._invmp(this.m).mul(this.r2));    return res._forceRed(this);  };})(typeof module === 'undefined' || module, this);},{"buffer":47}],46:[function(require,module,exports){var r;module.exports = function rand(len) {  if (!r)    r = new Rand(null);  return r.generate(len);};function Rand(rand) {  this.rand = rand;}module.exports.Rand = Rand;Rand.prototype.generate = function generate(len) {  return this._rand(len);};// Emulate crypto API using randyRand.prototype._rand = function _rand(n) {  if (this.rand.getBytes)    return this.rand.getBytes(n);  var res = new Uint8Array(n);  for (var i = 0; i < res.length; i++)    res[i] = this.rand.getByte();  return res;};if (typeof self === 'object') {  if (self.crypto && self.crypto.getRandomValues) {    // Modern browsers    Rand.prototype._rand = function _rand(n) {      var arr = new Uint8Array(n);      self.crypto.getRandomValues(arr);      return arr;    };  } else if (self.msCrypto && self.msCrypto.getRandomValues) {    // IE    Rand.prototype._rand = function _rand(n) {      var arr = new Uint8Array(n);      self.msCrypto.getRandomValues(arr);      return arr;    };  // Safari's WebWorkers do not have `crypto`  } else if (typeof window === 'object') {    // Old junk    Rand.prototype._rand = function() {      throw new Error('Not implemented yet');    };  }} else {  // Node.js or Web worker with no crypto support  try {    var crypto = require('crypto');    if (typeof crypto.randomBytes !== 'function')      throw new Error('Not supported');    Rand.prototype._rand = function _rand(n) {      return crypto.randomBytes(n);    };  } catch (e) {  }}},{"crypto":47}],47:[function(require,module,exports){},{}],48:[function(require,module,exports){// based on the aes implimentation in triple sec// https://github.com/keybase/triplesec// which is in turn based on the one from crypto-js// https://code.google.com/p/crypto-js/var Buffer = require('safe-buffer').Bufferfunction asUInt32Array (buf) {  if (!Buffer.isBuffer(buf)) buf = Buffer.from(buf)  var len = (buf.length / 4) | 0  var out = new Array(len)  for (var i = 0; i < len; i++) {    out[i] = buf.readUInt32BE(i * 4)  }  return out}function scrubVec (v) {  for (var i = 0; i < v.length; v++) {    v[i] = 0  }}function cryptBlock (M, keySchedule, SUB_MIX, SBOX, nRounds) {  var SUB_MIX0 = SUB_MIX[0]  var SUB_MIX1 = SUB_MIX[1]  var SUB_MIX2 = SUB_MIX[2]  var SUB_MIX3 = SUB_MIX[3]  var s0 = M[0] ^ keySchedule[0]  var s1 = M[1] ^ keySchedule[1]  var s2 = M[2] ^ keySchedule[2]  var s3 = M[3] ^ keySchedule[3]  var t0, t1, t2, t3  var ksRow = 4  for (var round = 1; round < nRounds; round++) {    t0 = SUB_MIX0[s0 >>> 24] ^ SUB_MIX1[(s1 >>> 16) & 0xff] ^ SUB_MIX2[(s2 >>> 8) & 0xff] ^ SUB_MIX3[s3 & 0xff] ^ keySchedule[ksRow++]    t1 = SUB_MIX0[s1 >>> 24] ^ SUB_MIX1[(s2 >>> 16) & 0xff] ^ SUB_MIX2[(s3 >>> 8) & 0xff] ^ SUB_MIX3[s0 & 0xff] ^ keySchedule[ksRow++]    t2 = SUB_MIX0[s2 >>> 24] ^ SUB_MIX1[(s3 >>> 16) & 0xff] ^ SUB_MIX2[(s0 >>> 8) & 0xff] ^ SUB_MIX3[s1 & 0xff] ^ keySchedule[ksRow++]    t3 = SUB_MIX0[s3 >>> 24] ^ SUB_MIX1[(s0 >>> 16) & 0xff] ^ SUB_MIX2[(s1 >>> 8) & 0xff] ^ SUB_MIX3[s2 & 0xff] ^ keySchedule[ksRow++]    s0 = t0    s1 = t1    s2 = t2    s3 = t3  }  t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++]  t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++]  t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++]  t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++]  t0 = t0 >>> 0  t1 = t1 >>> 0  t2 = t2 >>> 0  t3 = t3 >>> 0  return [t0, t1, t2, t3]}// AES constantsvar RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]var G = (function () {  // Compute double table  var d = new Array(256)  for (var j = 0; j < 256; j++) {    if (j < 128) {      d[j] = j << 1    } else {      d[j] = (j << 1) ^ 0x11b    }  }  var SBOX = []  var INV_SBOX = []  var SUB_MIX = [[], [], [], []]  var INV_SUB_MIX = [[], [], [], []]  // Walk GF(2^8)  var x = 0  var xi = 0  for (var i = 0; i < 256; ++i) {    // Compute sbox    var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4)    sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63    SBOX[x] = sx    INV_SBOX[sx] = x    // Compute multiplication    var x2 = d[x]    var x4 = d[x2]    var x8 = d[x4]    // Compute sub bytes, mix columns tables    var t = (d[sx] * 0x101) ^ (sx * 0x1010100)    SUB_MIX[0][x] = (t << 24) | (t >>> 8)    SUB_MIX[1][x] = (t << 16) | (t >>> 16)    SUB_MIX[2][x] = (t << 8) | (t >>> 24)    SUB_MIX[3][x] = t    // Compute inv sub bytes, inv mix columns tables    t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100)    INV_SUB_MIX[0][sx] = (t << 24) | (t >>> 8)    INV_SUB_MIX[1][sx] = (t << 16) | (t >>> 16)    INV_SUB_MIX[2][sx] = (t << 8) | (t >>> 24)    INV_SUB_MIX[3][sx] = t    if (x === 0) {      x = xi = 1    } else {      x = x2 ^ d[d[d[x8 ^ x2]]]      xi ^= d[d[xi]]    }  }  return {    SBOX: SBOX,    INV_SBOX: INV_SBOX,    SUB_MIX: SUB_MIX,    INV_SUB_MIX: INV_SUB_MIX  }})()function AES (key) {  this._key = asUInt32Array(key)  this._reset()}AES.blockSize = 4 * 4AES.keySize = 256 / 8AES.prototype.blockSize = AES.blockSizeAES.prototype.keySize = AES.keySizeAES.prototype._reset = function () {  var keyWords = this._key  var keySize = keyWords.length  var nRounds = keySize + 6  var ksRows = (nRounds + 1) * 4  var keySchedule = []  for (var k = 0; k < keySize; k++) {    keySchedule[k] = keyWords[k]  }  for (k = keySize; k < ksRows; k++) {    var t = keySchedule[k - 1]    if (k % keySize === 0) {      t = (t << 8) | (t >>> 24)      t =        (G.SBOX[t >>> 24] << 24) |        (G.SBOX[(t >>> 16) & 0xff] << 16) |        (G.SBOX[(t >>> 8) & 0xff] << 8) |        (G.SBOX[t & 0xff])      t ^= RCON[(k / keySize) | 0] << 24    } else if (keySize > 6 && k % keySize === 4) {      t =        (G.SBOX[t >>> 24] << 24) |        (G.SBOX[(t >>> 16) & 0xff] << 16) |        (G.SBOX[(t >>> 8) & 0xff] << 8) |        (G.SBOX[t & 0xff])    }    keySchedule[k] = keySchedule[k - keySize] ^ t  }  var invKeySchedule = []  for (var ik = 0; ik < ksRows; ik++) {    var ksR = ksRows - ik    var tt = keySchedule[ksR - (ik % 4 ? 0 : 4)]    if (ik < 4 || ksR <= 4) {      invKeySchedule[ik] = tt    } else {      invKeySchedule[ik] =        G.INV_SUB_MIX[0][G.SBOX[tt >>> 24]] ^        G.INV_SUB_MIX[1][G.SBOX[(tt >>> 16) & 0xff]] ^        G.INV_SUB_MIX[2][G.SBOX[(tt >>> 8) & 0xff]] ^        G.INV_SUB_MIX[3][G.SBOX[tt & 0xff]]    }  }  this._nRounds = nRounds  this._keySchedule = keySchedule  this._invKeySchedule = invKeySchedule}AES.prototype.encryptBlockRaw = function (M) {  M = asUInt32Array(M)  return cryptBlock(M, this._keySchedule, G.SUB_MIX, G.SBOX, this._nRounds)}AES.prototype.encryptBlock = function (M) {  var out = this.encryptBlockRaw(M)  var buf = Buffer.allocUnsafe(16)  buf.writeUInt32BE(out[0], 0)  buf.writeUInt32BE(out[1], 4)  buf.writeUInt32BE(out[2], 8)  buf.writeUInt32BE(out[3], 12)  return buf}AES.prototype.decryptBlock = function (M) {  M = asUInt32Array(M)  // swap  var m1 = M[1]  M[1] = M[3]  M[3] = m1  var out = cryptBlock(M, this._invKeySchedule, G.INV_SUB_MIX, G.INV_SBOX, this._nRounds)  var buf = Buffer.allocUnsafe(16)  buf.writeUInt32BE(out[0], 0)  buf.writeUInt32BE(out[3], 4)  buf.writeUInt32BE(out[2], 8)  buf.writeUInt32BE(out[1], 12)  return buf}AES.prototype.scrub = function () {  scrubVec(this._keySchedule)  scrubVec(this._invKeySchedule)  scrubVec(this._key)}module.exports.AES = AES},{"safe-buffer":247}],49:[function(require,module,exports){var aes = require('./aes')var Buffer = require('safe-buffer').Buffervar Transform = require('cipher-base')var inherits = require('inherits')var GHASH = require('./ghash')var xor = require('buffer-xor')var incr32 = require('./incr32')function xorTest (a, b) {  var out = 0  if (a.length !== b.length) out++  var len = Math.min(a.length, b.length)  for (var i = 0; i < len; ++i) {    out += (a[i] ^ b[i])  }  return out}function calcIv (self, iv, ck) {  if (iv.length === 12) {    self._finID = Buffer.concat([iv, Buffer.from([0, 0, 0, 1])])    return Buffer.concat([iv, Buffer.from([0, 0, 0, 2])])  }  var ghash = new GHASH(ck)  var len = iv.length  var toPad = len % 16  ghash.update(iv)  if (toPad) {    toPad = 16 - toPad    ghash.update(Buffer.alloc(toPad, 0))  }  ghash.update(Buffer.alloc(8, 0))  var ivBits = len * 8  var tail = Buffer.alloc(8)  tail.writeUIntBE(ivBits, 0, 8)  ghash.update(tail)  self._finID = ghash.state  var out = Buffer.from(self._finID)  incr32(out)  return out}function StreamCipher (mode, key, iv, decrypt) {  Transform.call(this)  var h = Buffer.alloc(4, 0)  this._cipher = new aes.AES(key)  var ck = this._cipher.encryptBlock(h)  this._ghash = new GHASH(ck)  iv = calcIv(this, iv, ck)  this._prev = Buffer.from(iv)  this._cache = Buffer.allocUnsafe(0)  this._secCache = Buffer.allocUnsafe(0)  this._decrypt = decrypt  this._alen = 0  this._len = 0  this._mode = mode  this._authTag = null  this._called = false}inherits(StreamCipher, Transform)StreamCipher.prototype._update = function (chunk) {  if (!this._called && this._alen) {    var rump = 16 - (this._alen % 16)    if (rump < 16) {      rump = Buffer.alloc(rump, 0)      this._ghash.update(rump)    }  }  this._called = true  var out = this._mode.encrypt(this, chunk)  if (this._decrypt) {    this._ghash.update(chunk)  } else {    this._ghash.update(out)  }  this._len += chunk.length  return out}StreamCipher.prototype._final = function () {  if (this._decrypt && !this._authTag) throw new Error('Unsupported state or unable to authenticate data')  var tag = xor(this._ghash.final(this._alen * 8, this._len * 8), this._cipher.encryptBlock(this._finID))  if (this._decrypt && xorTest(tag, this._authTag)) throw new Error('Unsupported state or unable to authenticate data')  this._authTag = tag  this._cipher.scrub()}StreamCipher.prototype.getAuthTag = function getAuthTag () {  if (this._decrypt || !Buffer.isBuffer(this._authTag)) throw new Error('Attempting to get auth tag in unsupported state')  return this._authTag}StreamCipher.prototype.setAuthTag = function setAuthTag (tag) {  if (!this._decrypt) throw new Error('Attempting to set auth tag in unsupported state')  this._authTag = tag}StreamCipher.prototype.setAAD = function setAAD (buf) {  if (this._called) throw new Error('Attempting to set AAD in unsupported state')  this._ghash.update(buf)  this._alen += buf.length}module.exports = StreamCipher},{"./aes":48,"./ghash":53,"./incr32":54,"buffer-xor":78,"cipher-base":81,"inherits":154,"safe-buffer":247}],50:[function(require,module,exports){var ciphers = require('./encrypter')var deciphers = require('./decrypter')var modes = require('./modes/list.json')function getCiphers () {  return Object.keys(modes)}exports.createCipher = exports.Cipher = ciphers.createCipherexports.createCipheriv = exports.Cipheriv = ciphers.createCipherivexports.createDecipher = exports.Decipher = deciphers.createDecipherexports.createDecipheriv = exports.Decipheriv = deciphers.createDecipherivexports.listCiphers = exports.getCiphers = getCiphers},{"./decrypter":51,"./encrypter":52,"./modes/list.json":62}],51:[function(require,module,exports){var AuthCipher = require('./authCipher')var Buffer = require('safe-buffer').Buffervar MODES = require('./modes')var StreamCipher = require('./streamCipher')var Transform = require('cipher-base')var aes = require('./aes')var ebtk = require('evp_bytestokey')var inherits = require('inherits')function Decipher (mode, key, iv) {  Transform.call(this)  this._cache = new Splitter()  this._last = void 0  this._cipher = new aes.AES(key)  this._prev = Buffer.from(iv)  this._mode = mode  this._autopadding = true}inherits(Decipher, Transform)Decipher.prototype._update = function (data) {  this._cache.add(data)  var chunk  var thing  var out = []  while ((chunk = this._cache.get(this._autopadding))) {    thing = this._mode.decrypt(this, chunk)    out.push(thing)  }  return Buffer.concat(out)}Decipher.prototype._final = function () {  var chunk = this._cache.flush()  if (this._autopadding) {    return unpad(this._mode.decrypt(this, chunk))  } else if (chunk) {    throw new Error('data not multiple of block length')  }}Decipher.prototype.setAutoPadding = function (setTo) {  this._autopadding = !!setTo  return this}function Splitter () {  this.cache = Buffer.allocUnsafe(0)}Splitter.prototype.add = function (data) {  this.cache = Buffer.concat([this.cache, data])}Splitter.prototype.get = function (autoPadding) {  var out  if (autoPadding) {    if (this.cache.length > 16) {      out = this.cache.slice(0, 16)      this.cache = this.cache.slice(16)      return out    }  } else {    if (this.cache.length >= 16) {      out = this.cache.slice(0, 16)      this.cache = this.cache.slice(16)      return out    }  }  return null}Splitter.prototype.flush = function () {  if (this.cache.length) return this.cache}function unpad (last) {  var padded = last[15]  if (padded < 1 || padded > 16) {    throw new Error('unable to decrypt data')  }  var i = -1  while (++i < padded) {    if (last[(i + (16 - padded))] !== padded) {      throw new Error('unable to decrypt data')    }  }  if (padded === 16) return  return last.slice(0, 16 - padded)}function createDecipheriv (suite, password, iv) {  var config = MODES[suite.toLowerCase()]  if (!config) throw new TypeError('invalid suite type')  if (typeof iv === 'string') iv = Buffer.from(iv)  if (config.mode !== 'GCM' && iv.length !== config.iv) throw new TypeError('invalid iv length ' + iv.length)  if (typeof password === 'string') password = Buffer.from(password)  if (password.length !== config.key / 8) throw new TypeError('invalid key length ' + password.length)  if (config.type === 'stream') {    return new StreamCipher(config.module, password, iv, true)  } else if (config.type === 'auth') {    return new AuthCipher(config.module, password, iv, true)  }  return new Decipher(config.module, password, iv)}function createDecipher (suite, password) {  var config = MODES[suite.toLowerCase()]  if (!config) throw new TypeError('invalid suite type')  var keys = ebtk(password, false, config.key, config.iv)  return createDecipheriv(suite, keys.key, keys.iv)}exports.createDecipher = createDecipherexports.createDecipheriv = createDecipheriv},{"./aes":48,"./authCipher":49,"./modes":61,"./streamCipher":64,"cipher-base":81,"evp_bytestokey":137,"inherits":154,"safe-buffer":247}],52:[function(require,module,exports){var MODES = require('./modes')var AuthCipher = require('./authCipher')var Buffer = require('safe-buffer').Buffervar StreamCipher = require('./streamCipher')var Transform = require('cipher-base')var aes = require('./aes')var ebtk = require('evp_bytestokey')var inherits = require('inherits')function Cipher (mode, key, iv) {  Transform.call(this)  this._cache = new Splitter()  this._cipher = new aes.AES(key)  this._prev = Buffer.from(iv)  this._mode = mode  this._autopadding = true}inherits(Cipher, Transform)Cipher.prototype._update = function (data) {  this._cache.add(data)  var chunk  var thing  var out = []  while ((chunk = this._cache.get())) {    thing = this._mode.encrypt(this, chunk)    out.push(thing)  }  return Buffer.concat(out)}var PADDING = Buffer.alloc(16, 0x10)Cipher.prototype._final = function () {  var chunk = this._cache.flush()  if (this._autopadding) {    chunk = this._mode.encrypt(this, chunk)    this._cipher.scrub()    return chunk  }  if (!chunk.equals(PADDING)) {    this._cipher.scrub()    throw new Error('data not multiple of block length')  }}Cipher.prototype.setAutoPadding = function (setTo) {  this._autopadding = !!setTo  return this}function Splitter () {  this.cache = Buffer.allocUnsafe(0)}Splitter.prototype.add = function (data) {  this.cache = Buffer.concat([this.cache, data])}Splitter.prototype.get = function () {  if (this.cache.length > 15) {    var out = this.cache.slice(0, 16)    this.cache = this.cache.slice(16)    return out  }  return null}Splitter.prototype.flush = function () {  var len = 16 - this.cache.length  var padBuff = Buffer.allocUnsafe(len)  var i = -1  while (++i < len) {    padBuff.writeUInt8(len, i)  }  return Buffer.concat([this.cache, padBuff])}function createCipheriv (suite, password, iv) {  var config = MODES[suite.toLowerCase()]  if (!config) throw new TypeError('invalid suite type')  if (typeof password === 'string') password = Buffer.from(password)  if (password.length !== config.key / 8) throw new TypeError('invalid key length ' + password.length)  if (typeof iv === 'string') iv = Buffer.from(iv)  if (config.mode !== 'GCM' && iv.length !== config.iv) throw new TypeError('invalid iv length ' + iv.length)  if (config.type === 'stream') {    return new StreamCipher(config.module, password, iv)  } else if (config.type === 'auth') {    return new AuthCipher(config.module, password, iv)  }  return new Cipher(config.module, password, iv)}function createCipher (suite, password) {  var config = MODES[suite.toLowerCase()]  if (!config) throw new TypeError('invalid suite type')  var keys = ebtk(password, false, config.key, config.iv)  return createCipheriv(suite, keys.key, keys.iv)}exports.createCipheriv = createCipherivexports.createCipher = createCipher},{"./aes":48,"./authCipher":49,"./modes":61,"./streamCipher":64,"cipher-base":81,"evp_bytestokey":137,"inherits":154,"safe-buffer":247}],53:[function(require,module,exports){var Buffer = require('safe-buffer').Buffervar ZEROES = Buffer.alloc(16, 0)function toArray (buf) {  return [    buf.readUInt32BE(0),    buf.readUInt32BE(4),    buf.readUInt32BE(8),    buf.readUInt32BE(12)  ]}function fromArray (out) {  var buf = Buffer.allocUnsafe(16)  buf.writeUInt32BE(out[0] >>> 0, 0)  buf.writeUInt32BE(out[1] >>> 0, 4)  buf.writeUInt32BE(out[2] >>> 0, 8)  buf.writeUInt32BE(out[3] >>> 0, 12)  return buf}function GHASH (key) {  this.h = key  this.state = Buffer.alloc(16, 0)  this.cache = Buffer.allocUnsafe(0)}// from http://bitwiseshiftleft.github.io/sjcl/doc/symbols/src/core_gcm.js.html// by Juho Vähä-HerttuaGHASH.prototype.ghash = function (block) {  var i = -1  while (++i < block.length) {    this.state[i] ^= block[i]  }  this._multiply()}GHASH.prototype._multiply = function () {  var Vi = toArray(this.h)  var Zi = [0, 0, 0, 0]  var j, xi, lsbVi  var i = -1  while (++i < 128) {    xi = (this.state[~~(i / 8)] & (1 << (7 - (i % 8)))) !== 0    if (xi) {      // Z_i+1 = Z_i ^ V_i      Zi[0] ^= Vi[0]      Zi[1] ^= Vi[1]      Zi[2] ^= Vi[2]      Zi[3] ^= Vi[3]    }    // Store the value of LSB(V_i)    lsbVi = (Vi[3] & 1) !== 0    // V_i+1 = V_i >> 1    for (j = 3; j > 0; j--) {      Vi[j] = (Vi[j] >>> 1) | ((Vi[j - 1] & 1) << 31)    }    Vi[0] = Vi[0] >>> 1    // If LSB(V_i) is 1, V_i+1 = (V_i >> 1) ^ R    if (lsbVi) {      Vi[0] = Vi[0] ^ (0xe1 << 24)    }  }  this.state = fromArray(Zi)}GHASH.prototype.update = function (buf) {  this.cache = Buffer.concat([this.cache, buf])  var chunk  while (this.cache.length >= 16) {    chunk = this.cache.slice(0, 16)    this.cache = this.cache.slice(16)    this.ghash(chunk)  }}GHASH.prototype.final = function (abl, bl) {  if (this.cache.length) {    this.ghash(Buffer.concat([this.cache, ZEROES], 16))  }  this.ghash(fromArray([0, abl, 0, bl]))  return this.state}module.exports = GHASH},{"safe-buffer":247}],54:[function(require,module,exports){function incr32 (iv) {  var len = iv.length  var item  while (len--) {    item = iv.readUInt8(len)    if (item === 255) {      iv.writeUInt8(0, len)    } else {      item++      iv.writeUInt8(item, len)      break    }  }}module.exports = incr32},{}],55:[function(require,module,exports){var xor = require('buffer-xor')exports.encrypt = function (self, block) {  var data = xor(block, self._prev)  self._prev = self._cipher.encryptBlock(data)  return self._prev}exports.decrypt = function (self, block) {  var pad = self._prev  self._prev = block  var out = self._cipher.decryptBlock(block)  return xor(out, pad)}},{"buffer-xor":78}],56:[function(require,module,exports){var Buffer = require('safe-buffer').Buffervar xor = require('buffer-xor')function encryptStart (self, data, decrypt) {  var len = data.length  var out = xor(data, self._cache)  self._cache = self._cache.slice(len)  self._prev = Buffer.concat([self._prev, decrypt ? data : out])  return out}exports.encrypt = function (self, data, decrypt) {  var out = Buffer.allocUnsafe(0)  var len  while (data.length) {    if (self._cache.length === 0) {      self._cache = self._cipher.encryptBlock(self._prev)      self._prev = Buffer.allocUnsafe(0)    }    if (self._cache.length <= data.length) {      len = self._cache.length      out = Buffer.concat([out, encryptStart(self, data.slice(0, len), decrypt)])      data = data.slice(len)    } else {      out = Buffer.concat([out, encryptStart(self, data, decrypt)])      break    }  }  return out}},{"buffer-xor":78,"safe-buffer":247}],57:[function(require,module,exports){var Buffer = require('safe-buffer').Bufferfunction encryptByte (self, byteParam, decrypt) {  var pad  var i = -1  var len = 8  var out = 0  var bit, value  while (++i < len) {    pad = self._cipher.encryptBlock(self._prev)    bit = (byteParam & (1 << (7 - i))) ? 0x80 : 0    value = pad[0] ^ bit    out += ((value & 0x80) >> (i % 8))    self._prev = shiftIn(self._prev, decrypt ? bit : value)  }  return out}function shiftIn (buffer, value) {  var len = buffer.length  var i = -1  var out = Buffer.allocUnsafe(buffer.length)  buffer = Buffer.concat([buffer, Buffer.from([value])])  while (++i < len) {    out[i] = buffer[i] << 1 | buffer[i + 1] >> (7)  }  return out}exports.encrypt = function (self, chunk, decrypt) {  var len = chunk.length  var out = Buffer.allocUnsafe(len)  var i = -1  while (++i < len) {    out[i] = encryptByte(self, chunk[i], decrypt)  }  return out}},{"safe-buffer":247}],58:[function(require,module,exports){var Buffer = require('safe-buffer').Bufferfunction encryptByte (self, byteParam, decrypt) {  var pad = self._cipher.encryptBlock(self._prev)  var out = pad[0] ^ byteParam  self._prev = Buffer.concat([    self._prev.slice(1),    Buffer.from([decrypt ? byteParam : out])  ])  return out}exports.encrypt = function (self, chunk, decrypt) {  var len = chunk.length  var out = Buffer.allocUnsafe(len)  var i = -1  while (++i < len) {    out[i] = encryptByte(self, chunk[i], decrypt)  }  return out}},{"safe-buffer":247}],59:[function(require,module,exports){var xor = require('buffer-xor')var Buffer = require('safe-buffer').Buffervar incr32 = require('../incr32')function getBlock (self) {  var out = self._cipher.encryptBlockRaw(self._prev)  incr32(self._prev)  return out}var blockSize = 16exports.encrypt = function (self, chunk) {  var chunkNum = Math.ceil(chunk.length / blockSize)  var start = self._cache.length  self._cache = Buffer.concat([    self._cache,    Buffer.allocUnsafe(chunkNum * blockSize)  ])  for (var i = 0; i < chunkNum; i++) {    var out = getBlock(self)    var offset = start + i * blockSize    self._cache.writeUInt32BE(out[0], offset + 0)    self._cache.writeUInt32BE(out[1], offset + 4)    self._cache.writeUInt32BE(out[2], offset + 8)    self._cache.writeUInt32BE(out[3], offset + 12)  }  var pad = self._cache.slice(0, chunk.length)  self._cache = self._cache.slice(chunk.length)  return xor(chunk, pad)}},{"../incr32":54,"buffer-xor":78,"safe-buffer":247}],60:[function(require,module,exports){exports.encrypt = function (self, block) {  return self._cipher.encryptBlock(block)}exports.decrypt = function (self, block) {  return self._cipher.decryptBlock(block)}},{}],61:[function(require,module,exports){var modeModules = {  ECB: require('./ecb'),  CBC: require('./cbc'),  CFB: require('./cfb'),  CFB8: require('./cfb8'),  CFB1: require('./cfb1'),  OFB: require('./ofb'),  CTR: require('./ctr'),  GCM: require('./ctr')}var modes = require('./list.json')for (var key in modes) {  modes[key].module = modeModules[modes[key].mode]}module.exports = modes},{"./cbc":55,"./cfb":56,"./cfb1":57,"./cfb8":58,"./ctr":59,"./ecb":60,"./list.json":62,"./ofb":63}],62:[function(require,module,exports){module.exports={  "aes-128-ecb": {    "cipher": "AES",    "key": 128,    "iv": 0,    "mode": "ECB",    "type": "block"  },  "aes-192-ecb": {    "cipher": "AES",    "key": 192,    "iv": 0,    "mode": "ECB",    "type": "block"  },  "aes-256-ecb": {    "cipher": "AES",    "key": 256,    "iv": 0,    "mode": "ECB",    "type": "block"  },  "aes-128-cbc": {    "cipher": "AES",    "key": 128,    "iv": 16,    "mode": "CBC",    "type": "block"  },  "aes-192-cbc": {    "cipher": "AES",    "key": 192,    "iv": 16,    "mode": "CBC",    "type": "block"  },  "aes-256-cbc": {    "cipher": "AES",    "key": 256,    "iv": 16,    "mode": "CBC",    "type": "block"  },  "aes128": {    "cipher": "AES",    "key": 128,    "iv": 16,    "mode": "CBC",    "type": "block"  },  "aes192": {    "cipher": "AES",    "key": 192,    "iv": 16,    "mode": "CBC",    "type": "block"  },  "aes256": {    "cipher": "AES",    "key": 256,    "iv": 16,    "mode": "CBC",    "type": "block"  },  "aes-128-cfb": {    "cipher": "AES",    "key": 128,    "iv": 16,    "mode": "CFB",    "type": "stream"  },  "aes-192-cfb": {    "cipher": "AES",    "key": 192,    "iv": 16,    "mode": "CFB",    "type": "stream"  },  "aes-256-cfb": {    "cipher": "AES",    "key": 256,    "iv": 16,    "mode": "CFB",    "type": "stream"  },  "aes-128-cfb8": {    "cipher": "AES",    "key": 128,    "iv": 16,    "mode": "CFB8",    "type": "stream"  },  "aes-192-cfb8": {    "cipher": "AES",    "key": 192,    "iv": 16,    "mode": "CFB8",    "type": "stream"  },  "aes-256-cfb8": {    "cipher": "AES",    "key": 256,    "iv": 16,    "mode": "CFB8",    "type": "stream"  },  "aes-128-cfb1": {    "cipher": "AES",    "key": 128,    "iv": 16,    "mode": "CFB1",    "type": "stream"  },  "aes-192-cfb1": {    "cipher": "AES",    "key": 192,    "iv": 16,    "mode": "CFB1",    "type": "stream"  },  "aes-256-cfb1": {    "cipher": "AES",    "key": 256,    "iv": 16,    "mode": "CFB1",    "type": "stream"  },  "aes-128-ofb": {    "cipher": "AES",    "key": 128,    "iv": 16,    "mode": "OFB",    "type": "stream"  },  "aes-192-ofb": {    "cipher": "AES",    "key": 192,    "iv": 16,    "mode": "OFB",    "type": "stream"  },  "aes-256-ofb": {    "cipher": "AES",    "key": 256,    "iv": 16,    "mode": "OFB",    "type": "stream"  },  "aes-128-ctr": {    "cipher": "AES",    "key": 128,    "iv": 16,    "mode": "CTR",    "type": "stream"  },  "aes-192-ctr": {    "cipher": "AES",    "key": 192,    "iv": 16,    "mode": "CTR",    "type": "stream"  },  "aes-256-ctr": {    "cipher": "AES",    "key": 256,    "iv": 16,    "mode": "CTR",    "type": "stream"  },  "aes-128-gcm": {    "cipher": "AES",    "key": 128,    "iv": 12,    "mode": "GCM",    "type": "auth"  },  "aes-192-gcm": {    "cipher": "AES",    "key": 192,    "iv": 12,    "mode": "GCM",    "type": "auth"  },  "aes-256-gcm": {    "cipher": "AES",    "key": 256,    "iv": 12,    "mode": "GCM",    "type": "auth"  }}},{}],63:[function(require,module,exports){(function (Buffer){var xor = require('buffer-xor')function getBlock (self) {  self._prev = self._cipher.encryptBlock(self._prev)  return self._prev}exports.encrypt = function (self, chunk) {  while (self._cache.length < chunk.length) {    self._cache = Buffer.concat([self._cache, getBlock(self)])  }  var pad = self._cache.slice(0, chunk.length)  self._cache = self._cache.slice(chunk.length)  return xor(chunk, pad)}}).call(this,require("buffer").Buffer)},{"buffer":79,"buffer-xor":78}],64:[function(require,module,exports){var aes = require('./aes')var Buffer = require('safe-buffer').Buffervar Transform = require('cipher-base')var inherits = require('inherits')function StreamCipher (mode, key, iv, decrypt) {  Transform.call(this)  this._cipher = new aes.AES(key)  this._prev = Buffer.from(iv)  this._cache = Buffer.allocUnsafe(0)  this._secCache = Buffer.allocUnsafe(0)  this._decrypt = decrypt  this._mode = mode}inherits(StreamCipher, Transform)StreamCipher.prototype._update = function (chunk) {  return this._mode.encrypt(this, chunk, this._decrypt)}StreamCipher.prototype._final = function () {  this._cipher.scrub()}module.exports = StreamCipher},{"./aes":48,"cipher-base":81,"inherits":154,"safe-buffer":247}],65:[function(require,module,exports){var DES = require('browserify-des')var aes = require('browserify-aes/browser')var aesModes = require('browserify-aes/modes')var desModes = require('browserify-des/modes')var ebtk = require('evp_bytestokey')function createCipher (suite, password) {  suite = suite.toLowerCase()  var keyLen, ivLen  if (aesModes[suite]) {    keyLen = aesModes[suite].key    ivLen = aesModes[suite].iv  } else if (desModes[suite]) {    keyLen = desModes[suite].key * 8    ivLen = desModes[suite].iv  } else {    throw new TypeError('invalid suite type')  }  var keys = ebtk(password, false, keyLen, ivLen)  return createCipheriv(suite, keys.key, keys.iv)}function createDecipher (suite, password) {  suite = suite.toLowerCase()  var keyLen, ivLen  if (aesModes[suite]) {    keyLen = aesModes[suite].key    ivLen = aesModes[suite].iv  } else if (desModes[suite]) {    keyLen = desModes[suite].key * 8    ivLen = desModes[suite].iv  } else {    throw new TypeError('invalid suite type')  }  var keys = ebtk(password, false, keyLen, ivLen)  return createDecipheriv(suite, keys.key, keys.iv)}function createCipheriv (suite, key, iv) {  suite = suite.toLowerCase()  if (aesModes[suite]) return aes.createCipheriv(suite, key, iv)  if (desModes[suite]) return new DES({ key: key, iv: iv, mode: suite })  throw new TypeError('invalid suite type')}function createDecipheriv (suite, key, iv) {  suite = suite.toLowerCase()  if (aesModes[suite]) return aes.createDecipheriv(suite, key, iv)  if (desModes[suite]) return new DES({ key: key, iv: iv, mode: suite, decrypt: true })  throw new TypeError('invalid suite type')}function getCiphers () {  return Object.keys(desModes).concat(aes.getCiphers())}exports.createCipher = exports.Cipher = createCipherexports.createCipheriv = exports.Cipheriv = createCipherivexports.createDecipher = exports.Decipher = createDecipherexports.createDecipheriv = exports.Decipheriv = createDecipherivexports.listCiphers = exports.getCiphers = getCiphers},{"browserify-aes/browser":50,"browserify-aes/modes":61,"browserify-des":66,"browserify-des/modes":67,"evp_bytestokey":137}],66:[function(require,module,exports){var CipherBase = require('cipher-base')var des = require('des.js')var inherits = require('inherits')var Buffer = require('safe-buffer').Buffervar modes = {  'des-ede3-cbc': des.CBC.instantiate(des.EDE),  'des-ede3': des.EDE,  'des-ede-cbc': des.CBC.instantiate(des.EDE),  'des-ede': des.EDE,  'des-cbc': des.CBC.instantiate(des.DES),  'des-ecb': des.DES}modes.des = modes['des-cbc']modes.des3 = modes['des-ede3-cbc']module.exports = DESinherits(DES, CipherBase)function DES (opts) {  CipherBase.call(this)  var modeName = opts.mode.toLowerCase()  var mode = modes[modeName]  var type  if (opts.decrypt) {    type = 'decrypt'  } else {    type = 'encrypt'  }  var key = opts.key  if (!Buffer.isBuffer(key)) {    key = Buffer.from(key)  }  if (modeName === 'des-ede' || modeName === 'des-ede-cbc') {    key = Buffer.concat([key, key.slice(0, 8)])  }  var iv = opts.iv  if (!Buffer.isBuffer(iv)) {    iv = Buffer.from(iv)  }  this._des = mode.create({    key: key,    iv: iv,    type: type  })}DES.prototype._update = function (data) {  return Buffer.from(this._des.update(data))}DES.prototype._final = function () {  return Buffer.from(this._des.final())}},{"cipher-base":81,"des.js":110,"inherits":154,"safe-buffer":68}],67:[function(require,module,exports){exports['des-ecb'] = {  key: 8,  iv: 0}exports['des-cbc'] = exports.des = {  key: 8,  iv: 8}exports['des-ede3-cbc'] = exports.des3 = {  key: 24,  iv: 8}exports['des-ede3'] = {  key: 24,  iv: 0}exports['des-ede-cbc'] = {  key: 16,  iv: 8}exports['des-ede'] = {  key: 16,  iv: 0}},{}],68:[function(require,module,exports){/* eslint-disable node/no-deprecated-api */var buffer = require('buffer')var Buffer = buffer.Buffer// alternative to using Object.keys for old browsersfunction copyProps (src, dst) {  for (var key in src) {    dst[key] = src[key]  }}if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {  module.exports = buffer} else {  // Copy properties from require('buffer')  copyProps(buffer, exports)  exports.Buffer = SafeBuffer}function SafeBuffer (arg, encodingOrOffset, length) {  return Buffer(arg, encodingOrOffset, length)}// Copy static methods from BuffercopyProps(Buffer, SafeBuffer)SafeBuffer.from = function (arg, encodingOrOffset, length) {  if (typeof arg === 'number') {    throw new TypeError('Argument must not be a number')  }  return Buffer(arg, encodingOrOffset, length)}SafeBuffer.alloc = function (size, fill, encoding) {  if (typeof size !== 'number') {    throw new TypeError('Argument must be a number')  }  var buf = Buffer(size)  if (fill !== undefined) {    if (typeof encoding === 'string') {      buf.fill(fill, encoding)    } else {      buf.fill(fill)    }  } else {    buf.fill(0)  }  return buf}SafeBuffer.allocUnsafe = function (size) {  if (typeof size !== 'number') {    throw new TypeError('Argument must be a number')  }  return Buffer(size)}SafeBuffer.allocUnsafeSlow = function (size) {  if (typeof size !== 'number') {    throw new TypeError('Argument must be a number')  }  return buffer.SlowBuffer(size)}},{"buffer":79}],69:[function(require,module,exports){(function (Buffer){var bn = require('bn.js');var randomBytes = require('randombytes');module.exports = crt;function blind(priv) {  var r = getr(priv);  var blinder = r.toRed(bn.mont(priv.modulus))  .redPow(new bn(priv.publicExponent)).fromRed();  return {    blinder: blinder,    unblinder:r.invm(priv.modulus)  };}function crt(msg, priv) {  var blinds = blind(priv);  var len = priv.modulus.byteLength();  var mod = bn.mont(priv.modulus);  var blinded = new bn(msg).mul(blinds.blinder).umod(priv.modulus);  var c1 = blinded.toRed(bn.mont(priv.prime1));  var c2 = blinded.toRed(bn.mont(priv.prime2));  var qinv = priv.coefficient;  var p = priv.prime1;  var q = priv.prime2;  var m1 = c1.redPow(priv.exponent1);  var m2 = c2.redPow(priv.exponent2);  m1 = m1.fromRed();  m2 = m2.fromRed();  var h = m1.isub(m2).imul(qinv).umod(p);  h.imul(q);  m2.iadd(h);  return new Buffer(m2.imul(blinds.unblinder).umod(priv.modulus).toArray(false, len));}crt.getr = getr;function getr(priv) {  var len = priv.modulus.byteLength();  var r = new bn(randomBytes(len));  while (r.cmp(priv.modulus) >=  0 || !r.umod(priv.prime1) || !r.umod(priv.prime2)) {    r = new bn(randomBytes(len));  }  return r;}}).call(this,require("buffer").Buffer)},{"bn.js":45,"buffer":79,"randombytes":234}],70:[function(require,module,exports){module.exports = require('./browser/algorithms.json')},{"./browser/algorithms.json":71}],71:[function(require,module,exports){module.exports={  "sha224WithRSAEncryption": {    "sign": "rsa",    "hash": "sha224",    "id": "302d300d06096086480165030402040500041c"  },  "RSA-SHA224": {    "sign": "ecdsa/rsa",    "hash": "sha224",    "id": "302d300d06096086480165030402040500041c"  },  "sha256WithRSAEncryption": {    "sign": "rsa",    "hash": "sha256",    "id": "3031300d060960864801650304020105000420"  },  "RSA-SHA256": {    "sign": "ecdsa/rsa",    "hash": "sha256",    "id": "3031300d060960864801650304020105000420"  },  "sha384WithRSAEncryption": {    "sign": "rsa",    "hash": "sha384",    "id": "3041300d060960864801650304020205000430"  },  "RSA-SHA384": {    "sign": "ecdsa/rsa",    "hash": "sha384",    "id": "3041300d060960864801650304020205000430"  },  "sha512WithRSAEncryption": {    "sign": "rsa",    "hash": "sha512",    "id": "3051300d060960864801650304020305000440"  },  "RSA-SHA512": {    "sign": "ecdsa/rsa",    "hash": "sha512",    "id": "3051300d060960864801650304020305000440"  },  "RSA-SHA1": {    "sign": "rsa",    "hash": "sha1",    "id": "3021300906052b0e03021a05000414"  },  "ecdsa-with-SHA1": {    "sign": "ecdsa",    "hash": "sha1",    "id": ""  },  "sha256": {    "sign": "ecdsa",    "hash": "sha256",    "id": ""  },  "sha224": {    "sign": "ecdsa",    "hash": "sha224",    "id": ""  },  "sha384": {    "sign": "ecdsa",    "hash": "sha384",    "id": ""  },  "sha512": {    "sign": "ecdsa",    "hash": "sha512",    "id": ""  },  "DSA-SHA": {    "sign": "dsa",    "hash": "sha1",    "id": ""  },  "DSA-SHA1": {    "sign": "dsa",    "hash": "sha1",    "id": ""  },  "DSA": {    "sign": "dsa",    "hash": "sha1",    "id": ""  },  "DSA-WITH-SHA224": {    "sign": "dsa",    "hash": "sha224",    "id": ""  },  "DSA-SHA224": {    "sign": "dsa",    "hash": "sha224",    "id": ""  },  "DSA-WITH-SHA256": {    "sign": "dsa",    "hash": "sha256",    "id": ""  },  "DSA-SHA256": {    "sign": "dsa",    "hash": "sha256",    "id": ""  },  "DSA-WITH-SHA384": {    "sign": "dsa",    "hash": "sha384",    "id": ""  },  "DSA-SHA384": {    "sign": "dsa",    "hash": "sha384",    "id": ""  },  "DSA-WITH-SHA512": {    "sign": "dsa",    "hash": "sha512",    "id": ""  },  "DSA-SHA512": {    "sign": "dsa",    "hash": "sha512",    "id": ""  },  "DSA-RIPEMD160": {    "sign": "dsa",    "hash": "rmd160",    "id": ""  },  "ripemd160WithRSA": {    "sign": "rsa",    "hash": "rmd160",    "id": "3021300906052b2403020105000414"  },  "RSA-RIPEMD160": {    "sign": "rsa",    "hash": "rmd160",    "id": "3021300906052b2403020105000414"  },  "md5WithRSAEncryption": {    "sign": "rsa",    "hash": "md5",    "id": "3020300c06082a864886f70d020505000410"  },  "RSA-MD5": {    "sign": "rsa",    "hash": "md5",    "id": "3020300c06082a864886f70d020505000410"  }}},{}],72:[function(require,module,exports){module.exports={  "1.3.132.0.10": "secp256k1",  "1.3.132.0.33": "p224",  "1.2.840.10045.3.1.1": "p192",  "1.2.840.10045.3.1.7": "p256",  "1.3.132.0.34": "p384",  "1.3.132.0.35": "p521"}},{}],73:[function(require,module,exports){(function (Buffer){var createHash = require('create-hash')var stream = require('stream')var inherits = require('inherits')var sign = require('./sign')var verify = require('./verify')var algorithms = require('./algorithms.json')Object.keys(algorithms).forEach(function (key) {  algorithms[key].id = new Buffer(algorithms[key].id, 'hex')  algorithms[key.toLowerCase()] = algorithms[key]})function Sign (algorithm) {  stream.Writable.call(this)  var data = algorithms[algorithm]  if (!data) throw new Error('Unknown message digest')  this._hashType = data.hash  this._hash = createHash(data.hash)  this._tag = data.id  this._signType = data.sign}inherits(Sign, stream.Writable)Sign.prototype._write = function _write (data, _, done) {  this._hash.update(data)  done()}Sign.prototype.update = function update (data, enc) {  if (typeof data === 'string') data = new Buffer(data, enc)  this._hash.update(data)  return this}Sign.prototype.sign = function signMethod (key, enc) {  this.end()  var hash = this._hash.digest()  var sig = sign(hash, key, this._hashType, this._signType, this._tag)  return enc ? sig.toString(enc) : sig}function Verify (algorithm) {  stream.Writable.call(this)  var data = algorithms[algorithm]  if (!data) throw new Error('Unknown message digest')  this._hash = createHash(data.hash)  this._tag = data.id  this._signType = data.sign}inherits(Verify, stream.Writable)Verify.prototype._write = function _write (data, _, done) {  this._hash.update(data)  done()}Verify.prototype.update = function update (data, enc) {  if (typeof data === 'string') data = new Buffer(data, enc)  this._hash.update(data)  return this}Verify.prototype.verify = function verifyMethod (key, sig, enc) {  if (typeof sig === 'string') sig = new Buffer(sig, enc)  this.end()  var hash = this._hash.digest()  return verify(sig, hash, key, this._signType, this._tag)}function createSign (algorithm) {  return new Sign(algorithm)}function createVerify (algorithm) {  return new Verify(algorithm)}module.exports = {  Sign: createSign,  Verify: createVerify,  createSign: createSign,  createVerify: createVerify}}).call(this,require("buffer").Buffer)},{"./algorithms.json":71,"./sign":74,"./verify":75,"buffer":79,"create-hash":105,"inherits":154,"stream":257}],74:[function(require,module,exports){(function (Buffer){// much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.jsvar createHmac = require('create-hmac')var crt = require('browserify-rsa')var EC = require('elliptic').ecvar BN = require('bn.js')var parseKeys = require('parse-asn1')var curves = require('./curves.json')function sign (hash, key, hashType, signType, tag) {  var priv = parseKeys(key)  if (priv.curve) {    // rsa keys can be interpreted as ecdsa ones in openssl    if (signType !== 'ecdsa' && signType !== 'ecdsa/rsa') throw new Error('wrong private key type')    return ecSign(hash, priv)  } else if (priv.type === 'dsa') {    if (signType !== 'dsa') throw new Error('wrong private key type')    return dsaSign(hash, priv, hashType)  } else {    if (signType !== 'rsa' && signType !== 'ecdsa/rsa') throw new Error('wrong private key type')  }  hash = Buffer.concat([tag, hash])  var len = priv.modulus.byteLength()  var pad = [ 0, 1 ]  while (hash.length + pad.length + 1 < len) pad.push(0xff)  pad.push(0x00)  var i = -1  while (++i < hash.length) pad.push(hash[i])  var out = crt(pad, priv)  return out}function ecSign (hash, priv) {  var curveId = curves[priv.curve.join('.')]  if (!curveId) throw new Error('unknown curve ' + priv.curve.join('.'))  var curve = new EC(curveId)  var key = curve.keyFromPrivate(priv.privateKey)  var out = key.sign(hash)  return new Buffer(out.toDER())}function dsaSign (hash, priv, algo) {  var x = priv.params.priv_key  var p = priv.params.p  var q = priv.params.q  var g = priv.params.g  var r = new BN(0)  var k  var H = bits2int(hash, q).mod(q)  var s = false  var kv = getKey(x, q, hash, algo)  while (s === false) {    k = makeKey(q, kv, algo)    r = makeR(g, k, p, q)    s = k.invm(q).imul(H.add(x.mul(r))).mod(q)    if (s.cmpn(0) === 0) {      s = false      r = new BN(0)    }  }  return toDER(r, s)}function toDER (r, s) {  r = r.toArray()  s = s.toArray()  // Pad values  if (r[0] & 0x80) r = [ 0 ].concat(r)  if (s[0] & 0x80) s = [ 0 ].concat(s)  var total = r.length + s.length + 4  var res = [ 0x30, total, 0x02, r.length ]  res = res.concat(r, [ 0x02, s.length ], s)  return new Buffer(res)}function getKey (x, q, hash, algo) {  x = new Buffer(x.toArray())  if (x.length < q.byteLength()) {    var zeros = new Buffer(q.byteLength() - x.length)    zeros.fill(0)    x = Buffer.concat([ zeros, x ])  }  var hlen = hash.length  var hbits = bits2octets(hash, q)  var v = new Buffer(hlen)  v.fill(1)  var k = new Buffer(hlen)  k.fill(0)  k = createHmac(algo, k).update(v).update(new Buffer([ 0 ])).update(x).update(hbits).digest()  v = createHmac(algo, k).update(v).digest()  k = createHmac(algo, k).update(v).update(new Buffer([ 1 ])).update(x).update(hbits).digest()  v = createHmac(algo, k).update(v).digest()  return { k: k, v: v }}function bits2int (obits, q) {  var bits = new BN(obits)  var shift = (obits.length << 3) - q.bitLength()  if (shift > 0) bits.ishrn(shift)  return bits}function bits2octets (bits, q) {  bits = bits2int(bits, q)  bits = bits.mod(q)  var out = new Buffer(bits.toArray())  if (out.length < q.byteLength()) {    var zeros = new Buffer(q.byteLength() - out.length)    zeros.fill(0)    out = Buffer.concat([ zeros, out ])  }  return out}function makeKey (q, kv, algo) {  var t  var k  do {    t = new Buffer(0)    while (t.length * 8 < q.bitLength()) {      kv.v = createHmac(algo, kv.k).update(kv.v).digest()      t = Buffer.concat([ t, kv.v ])    }    k = bits2int(t, q)    kv.k = createHmac(algo, kv.k).update(kv.v).update(new Buffer([ 0 ])).digest()    kv.v = createHmac(algo, kv.k).update(kv.v).digest()  } while (k.cmp(q) !== -1)  return k}function makeR (g, k, p, q) {  return g.toRed(BN.mont(p)).redPow(k).fromRed().mod(q)}module.exports = signmodule.exports.getKey = getKeymodule.exports.makeKey = makeKey}).call(this,require("buffer").Buffer)},{"./curves.json":72,"bn.js":45,"browserify-rsa":69,"buffer":79,"create-hmac":107,"elliptic":120,"parse-asn1":219}],75:[function(require,module,exports){(function (Buffer){// much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.jsvar BN = require('bn.js')var EC = require('elliptic').ecvar parseKeys = require('parse-asn1')var curves = require('./curves.json')function verify (sig, hash, key, signType, tag) {  var pub = parseKeys(key)  if (pub.type === 'ec') {    // rsa keys can be interpreted as ecdsa ones in openssl    if (signType !== 'ecdsa' && signType !== 'ecdsa/rsa') throw new Error('wrong public key type')    return ecVerify(sig, hash, pub)  } else if (pub.type === 'dsa') {    if (signType !== 'dsa') throw new Error('wrong public key type')    return dsaVerify(sig, hash, pub)  } else {    if (signType !== 'rsa' && signType !== 'ecdsa/rsa') throw new Error('wrong public key type')  }  hash = Buffer.concat([tag, hash])  var len = pub.modulus.byteLength()  var pad = [ 1 ]  var padNum = 0  while (hash.length + pad.length + 2 < len) {    pad.push(0xff)    padNum++  }  pad.push(0x00)  var i = -1  while (++i < hash.length) {    pad.push(hash[i])  }  pad = new Buffer(pad)  var red = BN.mont(pub.modulus)  sig = new BN(sig).toRed(red)  sig = sig.redPow(new BN(pub.publicExponent))  sig = new Buffer(sig.fromRed().toArray())  var out = padNum < 8 ? 1 : 0  len = Math.min(sig.length, pad.length)  if (sig.length !== pad.length) out = 1  i = -1  while (++i < len) out |= sig[i] ^ pad[i]  return out === 0}function ecVerify (sig, hash, pub) {  var curveId = curves[pub.data.algorithm.curve.join('.')]  if (!curveId) throw new Error('unknown curve ' + pub.data.algorithm.curve.join('.'))  var curve = new EC(curveId)  var pubkey = pub.data.subjectPrivateKey.data  return curve.verify(hash, sig, pubkey)}function dsaVerify (sig, hash, pub) {  var p = pub.data.p  var q = pub.data.q  var g = pub.data.g  var y = pub.data.pub_key  var unpacked = parseKeys.signature.decode(sig, 'der')  var s = unpacked.s  var r = unpacked.r  checkValue(s, q)  checkValue(r, q)  var montp = BN.mont(p)  var w = s.invm(q)  var v = g.toRed(montp)    .redPow(new BN(hash).mul(w).mod(q))    .fromRed()    .mul(y.toRed(montp).redPow(r.mul(w).mod(q)).fromRed())    .mod(p)    .mod(q)  return v.cmp(r) === 0}function checkValue (b, q) {  if (b.cmpn(0) <= 0) throw new Error('invalid sig')  if (b.cmp(q) >= q) throw new Error('invalid sig')}module.exports = verify}).call(this,require("buffer").Buffer)},{"./curves.json":72,"bn.js":45,"buffer":79,"elliptic":120,"parse-asn1":219}],76:[function(require,module,exports){arguments[4][47][0].apply(exports,arguments)},{"dup":47}],77:[function(require,module,exports){// Copyright Joyent, Inc. and other Node contributors.//// Permission is hereby granted, free of charge, to any person obtaining a// copy of this software and associated documentation files (the// "Software"), to deal in the Software without restriction, including// without limitation the rights to use, copy, modify, merge, publish,// distribute, sublicense, and/or sell copies of the Software, and to permit// persons to whom the Software is furnished to do so, subject to the// following conditions://// The above copyright notice and this permission notice shall be included// in all copies or substantial portions of the Software.//// THE SOFTWARE IS 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. IN// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE// USE OR OTHER DEALINGS IN THE SOFTWARE.'use strict';/*<replacement>*/var Buffer = require('safe-buffer').Buffer;/*</replacement>*/var isEncoding = Buffer.isEncoding || function (encoding) {  encoding = '' + encoding;  switch (encoding && encoding.toLowerCase()) {    case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw':      return true;    default:      return false;  }};function _normalizeEncoding(enc) {  if (!enc) return 'utf8';  var retried;  while (true) {    switch (enc) {      case 'utf8':      case 'utf-8':        return 'utf8';      case 'ucs2':      case 'ucs-2':      case 'utf16le':      case 'utf-16le':        return 'utf16le';      case 'latin1':      case 'binary':        return 'latin1';      case 'base64':      case 'ascii':      case 'hex':        return enc;      default:        if (retried) return; // undefined        enc = ('' + enc).toLowerCase();        retried = true;    }  }};// Do not cache `Buffer.isEncoding` when checking encoding names as some// modules monkey-patch it to support additional encodingsfunction normalizeEncoding(enc) {  var nenc = _normalizeEncoding(enc);  if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc);  return nenc || enc;}// StringDecoder provides an interface for efficiently splitting a series of// buffers into a series of JS strings without breaking apart multi-byte// characters.exports.StringDecoder = StringDecoder;function StringDecoder(encoding) {  this.encoding = normalizeEncoding(encoding);  var nb;  switch (this.encoding) {    case 'utf16le':      this.text = utf16Text;      this.end = utf16End;      nb = 4;      break;    case 'utf8':      this.fillLast = utf8FillLast;      nb = 4;      break;    case 'base64':      this.text = base64Text;      this.end = base64End;      nb = 3;      break;    default:      this.write = simpleWrite;      this.end = simpleEnd;      return;  }  this.lastNeed = 0;  this.lastTotal = 0;  this.lastChar = Buffer.allocUnsafe(nb);}StringDecoder.prototype.write = function (buf) {  if (buf.length === 0) return '';  var r;  var i;  if (this.lastNeed) {    r = this.fillLast(buf);    if (r === undefined) return '';    i = this.lastNeed;    this.lastNeed = 0;  } else {    i = 0;  }  if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i);  return r || '';};StringDecoder.prototype.end = utf8End;// Returns only complete characters in a BufferStringDecoder.prototype.text = utf8Text;// Attempts to complete a partial non-UTF-8 character using bytes from a BufferStringDecoder.prototype.fillLast = function (buf) {  if (this.lastNeed <= buf.length) {    buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed);    return this.lastChar.toString(this.encoding, 0, this.lastTotal);  }  buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length);  this.lastNeed -= buf.length;};// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a// continuation byte. If an invalid byte is detected, -2 is returned.function utf8CheckByte(byte) {  if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4;  return byte >> 6 === 0x02 ? -1 : -2;}// Checks at most 3 bytes at the end of a Buffer in order to detect an// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4)// needed to complete the UTF-8 character (if applicable) are returned.function utf8CheckIncomplete(self, buf, i) {  var j = buf.length - 1;  if (j < i) return 0;  var nb = utf8CheckByte(buf[j]);  if (nb >= 0) {    if (nb > 0) self.lastNeed = nb - 1;    return nb;  }  if (--j < i || nb === -2) return 0;  nb = utf8CheckByte(buf[j]);  if (nb >= 0) {    if (nb > 0) self.lastNeed = nb - 2;    return nb;  }  if (--j < i || nb === -2) return 0;  nb = utf8CheckByte(buf[j]);  if (nb >= 0) {    if (nb > 0) {      if (nb === 2) nb = 0;else self.lastNeed = nb - 3;    }    return nb;  }  return 0;}// Validates as many continuation bytes for a multi-byte UTF-8 character as// needed or are available. If we see a non-continuation byte where we expect// one, we "replace" the validated continuation bytes we've seen so far with// a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding// behavior. The continuation byte check is included three times in the case// where all of the continuation bytes for a character exist in the same buffer.// It is also done this way as a slight performance increase instead of using a// loop.function utf8CheckExtraBytes(self, buf, p) {  if ((buf[0] & 0xC0) !== 0x80) {    self.lastNeed = 0;    return '\ufffd';  }  if (self.lastNeed > 1 && buf.length > 1) {    if ((buf[1] & 0xC0) !== 0x80) {      self.lastNeed = 1;      return '\ufffd';    }    if (self.lastNeed > 2 && buf.length > 2) {      if ((buf[2] & 0xC0) !== 0x80) {        self.lastNeed = 2;        return '\ufffd';      }    }  }}// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer.function utf8FillLast(buf) {  var p = this.lastTotal - this.lastNeed;  var r = utf8CheckExtraBytes(this, buf, p);  if (r !== undefined) return r;  if (this.lastNeed <= buf.length) {    buf.copy(this.lastChar, p, 0, this.lastNeed);    return this.lastChar.toString(this.encoding, 0, this.lastTotal);  }  buf.copy(this.lastChar, p, 0, buf.length);  this.lastNeed -= buf.length;}// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a// partial character, the character's bytes are buffered until the required// number of bytes are available.function utf8Text(buf, i) {  var total = utf8CheckIncomplete(this, buf, i);  if (!this.lastNeed) return buf.toString('utf8', i);  this.lastTotal = total;  var end = buf.length - (total - this.lastNeed);  buf.copy(this.lastChar, 0, end);  return buf.toString('utf8', i, end);}// For UTF-8, a replacement character is added when ending on a partial// character.function utf8End(buf) {  var r = buf && buf.length ? this.write(buf) : '';  if (this.lastNeed) return r + '\ufffd';  return r;}// UTF-16LE typically needs two bytes per character, but even if we have an even// number of bytes available, we need to check if we end on a leading/high// surrogate. In that case, we need to wait for the next two bytes in order to// decode the last character properly.function utf16Text(buf, i) {  if ((buf.length - i) % 2 === 0) {    var r = buf.toString('utf16le', i);    if (r) {      var c = r.charCodeAt(r.length - 1);      if (c >= 0xD800 && c <= 0xDBFF) {        this.lastNeed = 2;        this.lastTotal = 4;        this.lastChar[0] = buf[buf.length - 2];        this.lastChar[1] = buf[buf.length - 1];        return r.slice(0, -1);      }    }    return r;  }  this.lastNeed = 1;  this.lastTotal = 2;  this.lastChar[0] = buf[buf.length - 1];  return buf.toString('utf16le', i, buf.length - 1);}// For UTF-16LE we do not explicitly append special replacement characters if we// end on a partial character, we simply let v8 handle that.function utf16End(buf) {  var r = buf && buf.length ? this.write(buf) : '';  if (this.lastNeed) {    var end = this.lastTotal - this.lastNeed;    return r + this.lastChar.toString('utf16le', 0, end);  }  return r;}function base64Text(buf, i) {  var n = (buf.length - i) % 3;  if (n === 0) return buf.toString('base64', i);  this.lastNeed = 3 - n;  this.lastTotal = 3;  if (n === 1) {    this.lastChar[0] = buf[buf.length - 1];  } else {    this.lastChar[0] = buf[buf.length - 2];    this.lastChar[1] = buf[buf.length - 1];  }  return buf.toString('base64', i, buf.length - n);}function base64End(buf) {  var r = buf && buf.length ? this.write(buf) : '';  if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed);  return r;}// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex)function simpleWrite(buf) {  return buf.toString(this.encoding);}function simpleEnd(buf) {  return buf && buf.length ? this.write(buf) : '';}},{"safe-buffer":247}],78:[function(require,module,exports){(function (Buffer){module.exports = function xor (a, b) {  var length = Math.min(a.length, b.length)  var buffer = new Buffer(length)  for (var i = 0; i < length; ++i) {    buffer[i] = a[i] ^ b[i]  }  return buffer}}).call(this,require("buffer").Buffer)},{"buffer":79}],79:[function(require,module,exports){/*! * The buffer module from node.js, for the browser. * * @author   Feross Aboukhadijeh <https://feross.org> * @license  MIT *//* eslint-disable no-proto */'use strict'var base64 = require('base64-js')var ieee754 = require('ieee754')exports.Buffer = Bufferexports.SlowBuffer = SlowBufferexports.INSPECT_MAX_BYTES = 50var K_MAX_LENGTH = 0x7fffffffexports.kMaxLength = K_MAX_LENGTH/** * If `Buffer.TYPED_ARRAY_SUPPORT`: *   === true    Use Uint8Array implementation (fastest) *   === false   Print warning and recommend using `buffer` v4.x which has an Object *               implementation (most compatible, even IE6) * * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, * Opera 11.6+, iOS 4.2+. * * We report that the browser does not support typed arrays if the are not subclassable * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array` * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support * for __proto__ and has a buggy typed array implementation. */Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport()if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' &&    typeof console.error === 'function') {  console.error(    'This browser lacks typed array (Uint8Array) support which is required by ' +    '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'  )}function typedArraySupport () {  // Can typed array instances can be augmented?  try {    var arr = new Uint8Array(1)    arr.__proto__ = { __proto__: Uint8Array.prototype, foo: function () { return 42 } }    return arr.foo() === 42  } catch (e) {    return false  }}Object.defineProperty(Buffer.prototype, 'parent', {  enumerable: true,  get: function () {    if (!Buffer.isBuffer(this)) return undefined    return this.buffer  }})Object.defineProperty(Buffer.prototype, 'offset', {  enumerable: true,  get: function () {    if (!Buffer.isBuffer(this)) return undefined    return this.byteOffset  }})function createBuffer (length) {  if (length > K_MAX_LENGTH) {    throw new RangeError('The value "' + length + '" is invalid for option "size"')  }  // Return an augmented `Uint8Array` instance  var buf = new Uint8Array(length)  buf.__proto__ = Buffer.prototype  return buf}/** * The Buffer constructor returns instances of `Uint8Array` that have their * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of * `Uint8Array`, so the returned instances will have all the node `Buffer` methods * and the `Uint8Array` methods. Square bracket notation works as expected -- it * returns a single octet. * * The `Uint8Array` prototype remains unmodified. */function Buffer (arg, encodingOrOffset, length) {  // Common case.  if (typeof arg === 'number') {    if (typeof encodingOrOffset === 'string') {      throw new TypeError(        'The "string" argument must be of type string. Received type number'      )    }    return allocUnsafe(arg)  }  return from(arg, encodingOrOffset, length)}// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97if (typeof Symbol !== 'undefined' && Symbol.species != null &&    Buffer[Symbol.species] === Buffer) {  Object.defineProperty(Buffer, Symbol.species, {    value: null,    configurable: true,    enumerable: false,    writable: false  })}Buffer.poolSize = 8192 // not used by this implementationfunction from (value, encodingOrOffset, length) {  if (typeof value === 'string') {    return fromString(value, encodingOrOffset)  }  if (ArrayBuffer.isView(value)) {    return fromArrayLike(value)  }  if (value == null) {    throw TypeError(      'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +      'or Array-like Object. Received type ' + (typeof value)    )  }  if (isInstance(value, ArrayBuffer) ||      (value && isInstance(value.buffer, ArrayBuffer))) {    return fromArrayBuffer(value, encodingOrOffset, length)  }  if (typeof value === 'number') {    throw new TypeError(      'The "value" argument must not be of type number. Received type number'    )  }  var valueOf = value.valueOf && value.valueOf()  if (valueOf != null && valueOf !== value) {    return Buffer.from(valueOf, encodingOrOffset, length)  }  var b = fromObject(value)  if (b) return b  if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null &&      typeof value[Symbol.toPrimitive] === 'function') {    return Buffer.from(      value[Symbol.toPrimitive]('string'), encodingOrOffset, length    )  }  throw new TypeError(    'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +    'or Array-like Object. Received type ' + (typeof value)  )}/** * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError * if value is a number. * Buffer.from(str[, encoding]) * Buffer.from(array) * Buffer.from(buffer) * Buffer.from(arrayBuffer[, byteOffset[, length]]) **/Buffer.from = function (value, encodingOrOffset, length) {  return from(value, encodingOrOffset, length)}// Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:// https://github.com/feross/buffer/pull/148Buffer.prototype.__proto__ = Uint8Array.prototypeBuffer.__proto__ = Uint8Arrayfunction assertSize (size) {  if (typeof size !== 'number') {    throw new TypeError('"size" argument must be of type number')  } else if (size < 0) {    throw new RangeError('The value "' + size + '" is invalid for option "size"')  }}function alloc (size, fill, encoding) {  assertSize(size)  if (size <= 0) {    return createBuffer(size)  }  if (fill !== undefined) {    // Only pay attention to encoding if it's a string. This    // prevents accidentally sending in a number that would    // be interpretted as a start offset.    return typeof encoding === 'string'      ? createBuffer(size).fill(fill, encoding)      : createBuffer(size).fill(fill)  }  return createBuffer(size)}/** * Creates a new filled Buffer instance. * alloc(size[, fill[, encoding]]) **/Buffer.alloc = function (size, fill, encoding) {  return alloc(size, fill, encoding)}function allocUnsafe (size) {  assertSize(size)  return createBuffer(size < 0 ? 0 : checked(size) | 0)}/** * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. * */Buffer.allocUnsafe = function (size) {  return allocUnsafe(size)}/** * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. */Buffer.allocUnsafeSlow = function (size) {  return allocUnsafe(size)}function fromString (string, encoding) {  if (typeof encoding !== 'string' || encoding === '') {    encoding = 'utf8'  }  if (!Buffer.isEncoding(encoding)) {    throw new TypeError('Unknown encoding: ' + encoding)  }  var length = byteLength(string, encoding) | 0  var buf = createBuffer(length)  var actual = buf.write(string, encoding)  if (actual !== length) {    // Writing a hex string, for example, that contains invalid characters will    // cause everything after the first invalid character to be ignored. (e.g.    // 'abxxcd' will be treated as 'ab')    buf = buf.slice(0, actual)  }  return buf}function fromArrayLike (array) {  var length = array.length < 0 ? 0 : checked(array.length) | 0  var buf = createBuffer(length)  for (var i = 0; i < length; i += 1) {    buf[i] = array[i] & 255  }  return buf}function fromArrayBuffer (array, byteOffset, length) {  if (byteOffset < 0 || array.byteLength < byteOffset) {    throw new RangeError('"offset" is outside of buffer bounds')  }  if (array.byteLength < byteOffset + (length || 0)) {    throw new RangeError('"length" is outside of buffer bounds')  }  var buf  if (byteOffset === undefined && length === undefined) {    buf = new Uint8Array(array)  } else if (length === undefined) {    buf = new Uint8Array(array, byteOffset)  } else {    buf = new Uint8Array(array, byteOffset, length)  }  // Return an augmented `Uint8Array` instance  buf.__proto__ = Buffer.prototype  return buf}function fromObject (obj) {  if (Buffer.isBuffer(obj)) {    var len = checked(obj.length) | 0    var buf = createBuffer(len)    if (buf.length === 0) {      return buf    }    obj.copy(buf, 0, 0, len)    return buf  }  if (obj.length !== undefined) {    if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {      return createBuffer(0)    }    return fromArrayLike(obj)  }  if (obj.type === 'Buffer' && Array.isArray(obj.data)) {    return fromArrayLike(obj.data)  }}function checked (length) {  // Note: cannot use `length < K_MAX_LENGTH` here because that fails when  // length is NaN (which is otherwise coerced to zero.)  if (length >= K_MAX_LENGTH) {    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +                         'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes')  }  return length | 0}function SlowBuffer (length) {  if (+length != length) { // eslint-disable-line eqeqeq    length = 0  }  return Buffer.alloc(+length)}Buffer.isBuffer = function isBuffer (b) {  return b != null && b._isBuffer === true &&    b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false}Buffer.compare = function compare (a, b) {  if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength)  if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength)  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {    throw new TypeError(      'The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array'    )  }  if (a === b) return 0  var x = a.length  var y = b.length  for (var i = 0, len = Math.min(x, y); i < len; ++i) {    if (a[i] !== b[i]) {      x = a[i]      y = b[i]      break    }  }  if (x < y) return -1  if (y < x) return 1  return 0}Buffer.isEncoding = function isEncoding (encoding) {  switch (String(encoding).toLowerCase()) {    case 'hex':    case 'utf8':    case 'utf-8':    case 'ascii':    case 'latin1':    case 'binary':    case 'base64':    case 'ucs2':    case 'ucs-2':    case 'utf16le':    case 'utf-16le':      return true    default:      return false  }}Buffer.concat = function concat (list, length) {  if (!Array.isArray(list)) {    throw new TypeError('"list" argument must be an Array of Buffers')  }  if (list.length === 0) {    return Buffer.alloc(0)  }  var i  if (length === undefined) {    length = 0    for (i = 0; i < list.length; ++i) {      length += list[i].length    }  }  var buffer = Buffer.allocUnsafe(length)  var pos = 0  for (i = 0; i < list.length; ++i) {    var buf = list[i]    if (isInstance(buf, Uint8Array)) {      buf = Buffer.from(buf)    }    if (!Buffer.isBuffer(buf)) {      throw new TypeError('"list" argument must be an Array of Buffers')    }    buf.copy(buffer, pos)    pos += buf.length  }  return buffer}function byteLength (string, encoding) {  if (Buffer.isBuffer(string)) {    return string.length  }  if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {    return string.byteLength  }  if (typeof string !== 'string') {    throw new TypeError(      'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' +      'Received type ' + typeof string    )  }  var len = string.length  var mustMatch = (arguments.length > 2 && arguments[2] === true)  if (!mustMatch && len === 0) return 0  // Use a for loop to avoid recursion  var loweredCase = false  for (;;) {    switch (encoding) {      case 'ascii':      case 'latin1':      case 'binary':        return len      case 'utf8':      case 'utf-8':        return utf8ToBytes(string).length      case 'ucs2':      case 'ucs-2':      case 'utf16le':      case 'utf-16le':        return len * 2      case 'hex':        return len >>> 1      case 'base64':        return base64ToBytes(string).length      default:        if (loweredCase) {          return mustMatch ? -1 : utf8ToBytes(string).length // assume utf8        }        encoding = ('' + encoding).toLowerCase()        loweredCase = true    }  }}Buffer.byteLength = byteLengthfunction slowToString (encoding, start, end) {  var loweredCase = false  // No need to verify that "this.length <= MAX_UINT32" since it's a read-only  // property of a typed array.  // This behaves neither like String nor Uint8Array in that we set start/end  // to their upper/lower bounds if the value passed is out of range.  // undefined is handled specially as per ECMA-262 6th Edition,  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.  if (start === undefined || start < 0) {    start = 0  }  // Return early if start > this.length. Done here to prevent potential uint32  // coercion fail below.  if (start > this.length) {    return ''  }  if (end === undefined || end > this.length) {    end = this.length  }  if (end <= 0) {    return ''  }  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.  end >>>= 0  start >>>= 0  if (end <= start) {    return ''  }  if (!encoding) encoding = 'utf8'  while (true) {    switch (encoding) {      case 'hex':        return hexSlice(this, start, end)      case 'utf8':      case 'utf-8':        return utf8Slice(this, start, end)      case 'ascii':        return asciiSlice(this, start, end)      case 'latin1':      case 'binary':        return latin1Slice(this, start, end)      case 'base64':        return base64Slice(this, start, end)      case 'ucs2':      case 'ucs-2':      case 'utf16le':      case 'utf-16le':        return utf16leSlice(this, start, end)      default:        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)        encoding = (encoding + '').toLowerCase()        loweredCase = true    }  }}// This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)// to detect a Buffer instance. It's not possible to use `instanceof Buffer`// reliably in a browserify context because there could be multiple different// copies of the 'buffer' package in use. This method works even for Buffer// instances that were created from another copy of the `buffer` package.// See: https://github.com/feross/buffer/issues/154Buffer.prototype._isBuffer = truefunction swap (b, n, m) {  var i = b[n]  b[n] = b[m]  b[m] = i}Buffer.prototype.swap16 = function swap16 () {  var len = this.length  if (len % 2 !== 0) {    throw new RangeError('Buffer size must be a multiple of 16-bits')  }  for (var i = 0; i < len; i += 2) {    swap(this, i, i + 1)  }  return this}Buffer.prototype.swap32 = function swap32 () {  var len = this.length  if (len % 4 !== 0) {    throw new RangeError('Buffer size must be a multiple of 32-bits')  }  for (var i = 0; i < len; i += 4) {    swap(this, i, i + 3)    swap(this, i + 1, i + 2)  }  return this}Buffer.prototype.swap64 = function swap64 () {  var len = this.length  if (len % 8 !== 0) {    throw new RangeError('Buffer size must be a multiple of 64-bits')  }  for (var i = 0; i < len; i += 8) {    swap(this, i, i + 7)    swap(this, i + 1, i + 6)    swap(this, i + 2, i + 5)    swap(this, i + 3, i + 4)  }  return this}Buffer.prototype.toString = function toString () {  var length = this.length  if (length === 0) return ''  if (arguments.length === 0) return utf8Slice(this, 0, length)  return slowToString.apply(this, arguments)}Buffer.prototype.toLocaleString = Buffer.prototype.toStringBuffer.prototype.equals = function equals (b) {  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')  if (this === b) return true  return Buffer.compare(this, b) === 0}Buffer.prototype.inspect = function inspect () {  var str = ''  var max = exports.INSPECT_MAX_BYTES  str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim()  if (this.length > max) str += ' ... '  return '<Buffer ' + str + '>'}Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {  if (isInstance(target, Uint8Array)) {    target = Buffer.from(target, target.offset, target.byteLength)  }  if (!Buffer.isBuffer(target)) {    throw new TypeError(      'The "target" argument must be one of type Buffer or Uint8Array. ' +      'Received type ' + (typeof target)    )  }  if (start === undefined) {    start = 0  }  if (end === undefined) {    end = target ? target.length : 0  }  if (thisStart === undefined) {    thisStart = 0  }  if (thisEnd === undefined) {    thisEnd = this.length  }  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {    throw new RangeError('out of range index')  }  if (thisStart >= thisEnd && start >= end) {    return 0  }  if (thisStart >= thisEnd) {    return -1  }  if (start >= end) {    return 1  }  start >>>= 0  end >>>= 0  thisStart >>>= 0  thisEnd >>>= 0  if (this === target) return 0  var x = thisEnd - thisStart  var y = end - start  var len = Math.min(x, y)  var thisCopy = this.slice(thisStart, thisEnd)  var targetCopy = target.slice(start, end)  for (var i = 0; i < len; ++i) {    if (thisCopy[i] !== targetCopy[i]) {      x = thisCopy[i]      y = targetCopy[i]      break    }  }  if (x < y) return -1  if (y < x) return 1  return 0}// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,// OR the last index of `val` in `buffer` at offset <= `byteOffset`.//// Arguments:// - buffer - a Buffer to search// - val - a string, Buffer, or number// - byteOffset - an index into `buffer`; will be clamped to an int32// - encoding - an optional encoding, relevant is val is a string// - dir - true for indexOf, false for lastIndexOffunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {  // Empty buffer means no match  if (buffer.length === 0) return -1  // Normalize byteOffset  if (typeof byteOffset === 'string') {    encoding = byteOffset    byteOffset = 0  } else if (byteOffset > 0x7fffffff) {    byteOffset = 0x7fffffff  } else if (byteOffset < -0x80000000) {    byteOffset = -0x80000000  }  byteOffset = +byteOffset // Coerce to Number.  if (numberIsNaN(byteOffset)) {    // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer    byteOffset = dir ? 0 : (buffer.length - 1)  }  // Normalize byteOffset: negative offsets start from the end of the buffer  if (byteOffset < 0) byteOffset = buffer.length + byteOffset  if (byteOffset >= buffer.length) {    if (dir) return -1    else byteOffset = buffer.length - 1  } else if (byteOffset < 0) {    if (dir) byteOffset = 0    else return -1  }  // Normalize val  if (typeof val === 'string') {    val = Buffer.from(val, encoding)  }  // Finally, search either indexOf (if dir is true) or lastIndexOf  if (Buffer.isBuffer(val)) {    // Special case: looking for empty string/buffer always fails    if (val.length === 0) {      return -1    }    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)  } else if (typeof val === 'number') {    val = val & 0xFF // Search for a byte value [0-255]    if (typeof Uint8Array.prototype.indexOf === 'function') {      if (dir) {        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)      } else {        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)      }    }    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)  }  throw new TypeError('val must be string, number or Buffer')}function arrayIndexOf (arr, val, byteOffset, encoding, dir) {  var indexSize = 1  var arrLength = arr.length  var valLength = val.length  if (encoding !== undefined) {    encoding = String(encoding).toLowerCase()    if (encoding === 'ucs2' || encoding === 'ucs-2' ||        encoding === 'utf16le' || encoding === 'utf-16le') {      if (arr.length < 2 || val.length < 2) {        return -1      }      indexSize = 2      arrLength /= 2      valLength /= 2      byteOffset /= 2    }  }  function read (buf, i) {    if (indexSize === 1) {      return buf[i]    } else {      return buf.readUInt16BE(i * indexSize)    }  }  var i  if (dir) {    var foundIndex = -1    for (i = byteOffset; i < arrLength; i++) {      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {        if (foundIndex === -1) foundIndex = i        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize      } else {        if (foundIndex !== -1) i -= i - foundIndex        foundIndex = -1      }    }  } else {    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength    for (i = byteOffset; i >= 0; i--) {      var found = true      for (var j = 0; j < valLength; j++) {        if (read(arr, i + j) !== read(val, j)) {          found = false          break        }      }      if (found) return i    }  }  return -1}Buffer.prototype.includes = function includes (val, byteOffset, encoding) {  return this.indexOf(val, byteOffset, encoding) !== -1}Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)}Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)}function hexWrite (buf, string, offset, length) {  offset = Number(offset) || 0  var remaining = buf.length - offset  if (!length) {    length = remaining  } else {    length = Number(length)    if (length > remaining) {      length = remaining    }  }  var strLen = string.length  if (length > strLen / 2) {    length = strLen / 2  }  for (var i = 0; i < length; ++i) {    var parsed = parseInt(string.substr(i * 2, 2), 16)    if (numberIsNaN(parsed)) return i    buf[offset + i] = parsed  }  return i}function utf8Write (buf, string, offset, length) {  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)}function asciiWrite (buf, string, offset, length) {  return blitBuffer(asciiToBytes(string), buf, offset, length)}function latin1Write (buf, string, offset, length) {  return asciiWrite(buf, string, offset, length)}function base64Write (buf, string, offset, length) {  return blitBuffer(base64ToBytes(string), buf, offset, length)}function ucs2Write (buf, string, offset, length) {  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)}Buffer.prototype.write = function write (string, offset, length, encoding) {  // Buffer#write(string)  if (offset === undefined) {    encoding = 'utf8'    length = this.length    offset = 0  // Buffer#write(string, encoding)  } else if (length === undefined && typeof offset === 'string') {    encoding = offset    length = this.length    offset = 0  // Buffer#write(string, offset[, length][, encoding])  } else if (isFinite(offset)) {    offset = offset >>> 0    if (isFinite(length)) {      length = length >>> 0      if (encoding === undefined) encoding = 'utf8'    } else {      encoding = length      length = undefined    }  } else {    throw new Error(      'Buffer.write(string, encoding, offset[, length]) is no longer supported'    )  }  var remaining = this.length - offset  if (length === undefined || length > remaining) length = remaining  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {    throw new RangeError('Attempt to write outside buffer bounds')  }  if (!encoding) encoding = 'utf8'  var loweredCase = false  for (;;) {    switch (encoding) {      case 'hex':        return hexWrite(this, string, offset, length)      case 'utf8':      case 'utf-8':        return utf8Write(this, string, offset, length)      case 'ascii':        return asciiWrite(this, string, offset, length)      case 'latin1':      case 'binary':        return latin1Write(this, string, offset, length)      case 'base64':        // Warning: maxLength not taken into account in base64Write        return base64Write(this, string, offset, length)      case 'ucs2':      case 'ucs-2':      case 'utf16le':      case 'utf-16le':        return ucs2Write(this, string, offset, length)      default:        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)        encoding = ('' + encoding).toLowerCase()        loweredCase = true    }  }}Buffer.prototype.toJSON = function toJSON () {  return {    type: 'Buffer',    data: Array.prototype.slice.call(this._arr || this, 0)  }}function base64Slice (buf, start, end) {  if (start === 0 && end === buf.length) {    return base64.fromByteArray(buf)  } else {    return base64.fromByteArray(buf.slice(start, end))  }}function utf8Slice (buf, start, end) {  end = Math.min(buf.length, end)  var res = []  var i = start  while (i < end) {    var firstByte = buf[i]    var codePoint = null    var bytesPerSequence = (firstByte > 0xEF) ? 4      : (firstByte > 0xDF) ? 3        : (firstByte > 0xBF) ? 2          : 1    if (i + bytesPerSequence <= end) {      var secondByte, thirdByte, fourthByte, tempCodePoint      switch (bytesPerSequence) {        case 1:          if (firstByte < 0x80) {            codePoint = firstByte          }          break        case 2:          secondByte = buf[i + 1]          if ((secondByte & 0xC0) === 0x80) {            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)            if (tempCodePoint > 0x7F) {              codePoint = tempCodePoint            }          }          break        case 3:          secondByte = buf[i + 1]          thirdByte = buf[i + 2]          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {              codePoint = tempCodePoint            }          }          break        case 4:          secondByte = buf[i + 1]          thirdByte = buf[i + 2]          fourthByte = buf[i + 3]          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {              codePoint = tempCodePoint            }          }      }    }    if (codePoint === null) {      // we did not generate a valid codePoint so insert a      // replacement char (U+FFFD) and advance only 1 byte      codePoint = 0xFFFD      bytesPerSequence = 1    } else if (codePoint > 0xFFFF) {      // encode to utf16 (surrogate pair dance)      codePoint -= 0x10000      res.push(codePoint >>> 10 & 0x3FF | 0xD800)      codePoint = 0xDC00 | codePoint & 0x3FF    }    res.push(codePoint)    i += bytesPerSequence  }  return decodeCodePointsArray(res)}// Based on http://stackoverflow.com/a/22747272/680742, the browser with// the lowest limit is Chrome, with 0x10000 args.// We go 1 magnitude less, for safetyvar MAX_ARGUMENTS_LENGTH = 0x1000function decodeCodePointsArray (codePoints) {  var len = codePoints.length  if (len <= MAX_ARGUMENTS_LENGTH) {    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()  }  // Decode in chunks to avoid "call stack size exceeded".  var res = ''  var i = 0  while (i < len) {    res += String.fromCharCode.apply(      String,      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)    )  }  return res}function asciiSlice (buf, start, end) {  var ret = ''  end = Math.min(buf.length, end)  for (var i = start; i < end; ++i) {    ret += String.fromCharCode(buf[i] & 0x7F)  }  return ret}function latin1Slice (buf, start, end) {  var ret = ''  end = Math.min(buf.length, end)  for (var i = start; i < end; ++i) {    ret += String.fromCharCode(buf[i])  }  return ret}function hexSlice (buf, start, end) {  var len = buf.length  if (!start || start < 0) start = 0  if (!end || end < 0 || end > len) end = len  var out = ''  for (var i = start; i < end; ++i) {    out += toHex(buf[i])  }  return out}function utf16leSlice (buf, start, end) {  var bytes = buf.slice(start, end)  var res = ''  for (var i = 0; i < bytes.length; i += 2) {    res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256))  }  return res}Buffer.prototype.slice = function slice (start, end) {  var len = this.length  start = ~~start  end = end === undefined ? len : ~~end  if (start < 0) {    start += len    if (start < 0) start = 0  } else if (start > len) {    start = len  }  if (end < 0) {    end += len    if (end < 0) end = 0  } else if (end > len) {    end = len  }  if (end < start) end = start  var newBuf = this.subarray(start, end)  // Return an augmented `Uint8Array` instance  newBuf.__proto__ = Buffer.prototype  return newBuf}/* * Need to make sure that buffer isn't trying to write out of bounds. */function checkOffset (offset, ext, length) {  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')}Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {  offset = offset >>> 0  byteLength = byteLength >>> 0  if (!noAssert) checkOffset(offset, byteLength, this.length)  var val = this[offset]  var mul = 1  var i = 0  while (++i < byteLength && (mul *= 0x100)) {    val += this[offset + i] * mul  }  return val}Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {  offset = offset >>> 0  byteLength = byteLength >>> 0  if (!noAssert) {    checkOffset(offset, byteLength, this.length)  }  var val = this[offset + --byteLength]  var mul = 1  while (byteLength > 0 && (mul *= 0x100)) {    val += this[offset + --byteLength] * mul  }  return val}Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {  offset = offset >>> 0  if (!noAssert) checkOffset(offset, 1, this.length)  return this[offset]}Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {  offset = offset >>> 0  if (!noAssert) checkOffset(offset, 2, this.length)  return this[offset] | (this[offset + 1] << 8)}Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {  offset = offset >>> 0  if (!noAssert) checkOffset(offset, 2, this.length)  return (this[offset] << 8) | this[offset + 1]}Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {  offset = offset >>> 0  if (!noAssert) checkOffset(offset, 4, this.length)  return ((this[offset]) |      (this[offset + 1] << 8) |      (this[offset + 2] << 16)) +      (this[offset + 3] * 0x1000000)}Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {  offset = offset >>> 0  if (!noAssert) checkOffset(offset, 4, this.length)  return (this[offset] * 0x1000000) +    ((this[offset + 1] << 16) |    (this[offset + 2] << 8) |    this[offset + 3])}Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {  offset = offset >>> 0  byteLength = byteLength >>> 0  if (!noAssert) checkOffset(offset, byteLength, this.length)  var val = this[offset]  var mul = 1  var i = 0  while (++i < byteLength && (mul *= 0x100)) {    val += this[offset + i] * mul  }  mul *= 0x80  if (val >= mul) val -= Math.pow(2, 8 * byteLength)  return val}Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {  offset = offset >>> 0  byteLength = byteLength >>> 0  if (!noAssert) checkOffset(offset, byteLength, this.length)  var i = byteLength  var mul = 1  var val = this[offset + --i]  while (i > 0 && (mul *= 0x100)) {    val += this[offset + --i] * mul  }  mul *= 0x80  if (val >= mul) val -= Math.pow(2, 8 * byteLength)  return val}Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {  offset = offset >>> 0  if (!noAssert) checkOffset(offset, 1, this.length)  if (!(this[offset] & 0x80)) return (this[offset])  return ((0xff - this[offset] + 1) * -1)}Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {  offset = offset >>> 0  if (!noAssert) checkOffset(offset, 2, this.length)  var val = this[offset] | (this[offset + 1] << 8)  return (val & 0x8000) ? val | 0xFFFF0000 : val}Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {  offset = offset >>> 0  if (!noAssert) checkOffset(offset, 2, this.length)  var val = this[offset + 1] | (this[offset] << 8)  return (val & 0x8000) ? val | 0xFFFF0000 : val}Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {  offset = offset >>> 0  if (!noAssert) checkOffset(offset, 4, this.length)  return (this[offset]) |    (this[offset + 1] << 8) |    (this[offset + 2] << 16) |    (this[offset + 3] << 24)}Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {  offset = offset >>> 0  if (!noAssert) checkOffset(offset, 4, this.length)  return (this[offset] << 24) |    (this[offset + 1] << 16) |    (this[offset + 2] << 8) |    (this[offset + 3])}Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {  offset = offset >>> 0  if (!noAssert) checkOffset(offset, 4, this.length)  return ieee754.read(this, offset, true, 23, 4)}Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {  offset = offset >>> 0  if (!noAssert) checkOffset(offset, 4, this.length)  return ieee754.read(this, offset, false, 23, 4)}Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {  offset = offset >>> 0  if (!noAssert) checkOffset(offset, 8, this.length)  return ieee754.read(this, offset, true, 52, 8)}Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {  offset = offset >>> 0  if (!noAssert) checkOffset(offset, 8, this.length)  return ieee754.read(this, offset, false, 52, 8)}function checkInt (buf, value, offset, ext, max, min) {  if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')  if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')  if (offset + ext > buf.length) throw new RangeError('Index out of range')}Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {  value = +value  offset = offset >>> 0  byteLength = byteLength >>> 0  if (!noAssert) {    var maxBytes = Math.pow(2, 8 * byteLength) - 1    checkInt(this, value, offset, byteLength, maxBytes, 0)  }  var mul = 1  var i = 0  this[offset] = value & 0xFF  while (++i < byteLength && (mul *= 0x100)) {    this[offset + i] = (value / mul) & 0xFF  }  return offset + byteLength}Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {  value = +value  offset = offset >>> 0  byteLength = byteLength >>> 0  if (!noAssert) {    var maxBytes = Math.pow(2, 8 * byteLength) - 1    checkInt(this, value, offset, byteLength, maxBytes, 0)  }  var i = byteLength - 1  var mul = 1  this[offset + i] = value & 0xFF  while (--i >= 0 && (mul *= 0x100)) {    this[offset + i] = (value / mul) & 0xFF  }  return offset + byteLength}Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {  value = +value  offset = offset >>> 0  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)  this[offset] = (value & 0xff)  return offset + 1}Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {  value = +value  offset = offset >>> 0  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)  this[offset] = (value & 0xff)  this[offset + 1] = (value >>> 8)  return offset + 2}Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {  value = +value  offset = offset >>> 0  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)  this[offset] = (value >>> 8)  this[offset + 1] = (value & 0xff)  return offset + 2}Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {  value = +value  offset = offset >>> 0  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)  this[offset + 3] = (value >>> 24)  this[offset + 2] = (value >>> 16)  this[offset + 1] = (value >>> 8)  this[offset] = (value & 0xff)  return offset + 4}Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {  value = +value  offset = offset >>> 0  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)  this[offset] = (value >>> 24)  this[offset + 1] = (value >>> 16)  this[offset + 2] = (value >>> 8)  this[offset + 3] = (value & 0xff)  return offset + 4}Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {  value = +value  offset = offset >>> 0  if (!noAssert) {    var limit = Math.pow(2, (8 * byteLength) - 1)    checkInt(this, value, offset, byteLength, limit - 1, -limit)  }  var i = 0  var mul = 1  var sub = 0  this[offset] = value & 0xFF  while (++i < byteLength && (mul *= 0x100)) {    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {      sub = 1    }    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF  }  return offset + byteLength}Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {  value = +value  offset = offset >>> 0  if (!noAssert) {    var limit = Math.pow(2, (8 * byteLength) - 1)    checkInt(this, value, offset, byteLength, limit - 1, -limit)  }  var i = byteLength - 1  var mul = 1  var sub = 0  this[offset + i] = value & 0xFF  while (--i >= 0 && (mul *= 0x100)) {    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {      sub = 1    }    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF  }  return offset + byteLength}Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {  value = +value  offset = offset >>> 0  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)  if (value < 0) value = 0xff + value + 1  this[offset] = (value & 0xff)  return offset + 1}Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {  value = +value  offset = offset >>> 0  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)  this[offset] = (value & 0xff)  this[offset + 1] = (value >>> 8)  return offset + 2}Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {  value = +value  offset = offset >>> 0  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)  this[offset] = (value >>> 8)  this[offset + 1] = (value & 0xff)  return offset + 2}Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {  value = +value  offset = offset >>> 0  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)  this[offset] = (value & 0xff)  this[offset + 1] = (value >>> 8)  this[offset + 2] = (value >>> 16)  this[offset + 3] = (value >>> 24)  return offset + 4}Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {  value = +value  offset = offset >>> 0  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)  if (value < 0) value = 0xffffffff + value + 1  this[offset] = (value >>> 24)  this[offset + 1] = (value >>> 16)  this[offset + 2] = (value >>> 8)  this[offset + 3] = (value & 0xff)  return offset + 4}function checkIEEE754 (buf, value, offset, ext, max, min) {  if (offset + ext > buf.length) throw new RangeError('Index out of range')  if (offset < 0) throw new RangeError('Index out of range')}function writeFloat (buf, value, offset, littleEndian, noAssert) {  value = +value  offset = offset >>> 0  if (!noAssert) {    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)  }  ieee754.write(buf, value, offset, littleEndian, 23, 4)  return offset + 4}Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {  return writeFloat(this, value, offset, true, noAssert)}Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {  return writeFloat(this, value, offset, false, noAssert)}function writeDouble (buf, value, offset, littleEndian, noAssert) {  value = +value  offset = offset >>> 0  if (!noAssert) {    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)  }  ieee754.write(buf, value, offset, littleEndian, 52, 8)  return offset + 8}Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {  return writeDouble(this, value, offset, true, noAssert)}Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {  return writeDouble(this, value, offset, false, noAssert)}// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)Buffer.prototype.copy = function copy (target, targetStart, start, end) {  if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer')  if (!start) start = 0  if (!end && end !== 0) end = this.length  if (targetStart >= target.length) targetStart = target.length  if (!targetStart) targetStart = 0  if (end > 0 && end < start) end = start  // Copy 0 bytes; we're done  if (end === start) return 0  if (target.length === 0 || this.length === 0) return 0  // Fatal error conditions  if (targetStart < 0) {    throw new RangeError('targetStart out of bounds')  }  if (start < 0 || start >= this.length) throw new RangeError('Index out of range')  if (end < 0) throw new RangeError('sourceEnd out of bounds')  // Are we oob?  if (end > this.length) end = this.length  if (target.length - targetStart < end - start) {    end = target.length - targetStart + start  }  var len = end - start  if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {    // Use built-in when available, missing from IE11    this.copyWithin(targetStart, start, end)  } else if (this === target && start < targetStart && targetStart < end) {    // descending copy from end    for (var i = len - 1; i >= 0; --i) {      target[i + targetStart] = this[i + start]    }  } else {    Uint8Array.prototype.set.call(      target,      this.subarray(start, end),      targetStart    )  }  return len}// Usage://    buffer.fill(number[, offset[, end]])//    buffer.fill(buffer[, offset[, end]])//    buffer.fill(string[, offset[, end]][, encoding])Buffer.prototype.fill = function fill (val, start, end, encoding) {  // Handle string cases:  if (typeof val === 'string') {    if (typeof start === 'string') {      encoding = start      start = 0      end = this.length    } else if (typeof end === 'string') {      encoding = end      end = this.length    }    if (encoding !== undefined && typeof encoding !== 'string') {      throw new TypeError('encoding must be a string')    }    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {      throw new TypeError('Unknown encoding: ' + encoding)    }    if (val.length === 1) {      var code = val.charCodeAt(0)      if ((encoding === 'utf8' && code < 128) ||          encoding === 'latin1') {        // Fast path: If `val` fits into a single byte, use that numeric value.        val = code      }    }  } else if (typeof val === 'number') {    val = val & 255  }  // Invalid ranges are not set to a default, so can range check early.  if (start < 0 || this.length < start || this.length < end) {    throw new RangeError('Out of range index')  }  if (end <= start) {    return this  }  start = start >>> 0  end = end === undefined ? this.length : end >>> 0  if (!val) val = 0  var i  if (typeof val === 'number') {    for (i = start; i < end; ++i) {      this[i] = val    }  } else {    var bytes = Buffer.isBuffer(val)      ? val      : Buffer.from(val, encoding)    var len = bytes.length    if (len === 0) {      throw new TypeError('The value "' + val +        '" is invalid for argument "value"')    }    for (i = 0; i < end - start; ++i) {      this[i + start] = bytes[i % len]    }  }  return this}// HELPER FUNCTIONS// ================var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/gfunction base64clean (str) {  // Node takes equal signs as end of the Base64 encoding  str = str.split('=')[0]  // Node strips out invalid characters like \n and \t from the string, base64-js does not  str = str.trim().replace(INVALID_BASE64_RE, '')  // Node converts strings with length < 2 to ''  if (str.length < 2) return ''  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not  while (str.length % 4 !== 0) {    str = str + '='  }  return str}function toHex (n) {  if (n < 16) return '0' + n.toString(16)  return n.toString(16)}function utf8ToBytes (string, units) {  units = units || Infinity  var codePoint  var length = string.length  var leadSurrogate = null  var bytes = []  for (var i = 0; i < length; ++i) {    codePoint = string.charCodeAt(i)    // is surrogate component    if (codePoint > 0xD7FF && codePoint < 0xE000) {      // last char was a lead      if (!leadSurrogate) {        // no lead yet        if (codePoint > 0xDBFF) {          // unexpected trail          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)          continue        } else if (i + 1 === length) {          // unpaired lead          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)          continue        }        // valid lead        leadSurrogate = codePoint        continue      }      // 2 leads in a row      if (codePoint < 0xDC00) {        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)        leadSurrogate = codePoint        continue      }      // valid surrogate pair      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000    } else if (leadSurrogate) {      // valid bmp char, but last char was a lead      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)    }    leadSurrogate = null    // encode utf8    if (codePoint < 0x80) {      if ((units -= 1) < 0) break      bytes.push(codePoint)    } else if (codePoint < 0x800) {      if ((units -= 2) < 0) break      bytes.push(        codePoint >> 0x6 | 0xC0,        codePoint & 0x3F | 0x80      )    } else if (codePoint < 0x10000) {      if ((units -= 3) < 0) break      bytes.push(        codePoint >> 0xC | 0xE0,        codePoint >> 0x6 & 0x3F | 0x80,        codePoint & 0x3F | 0x80      )    } else if (codePoint < 0x110000) {      if ((units -= 4) < 0) break      bytes.push(        codePoint >> 0x12 | 0xF0,        codePoint >> 0xC & 0x3F | 0x80,        codePoint >> 0x6 & 0x3F | 0x80,        codePoint & 0x3F | 0x80      )    } else {      throw new Error('Invalid code point')    }  }  return bytes}function asciiToBytes (str) {  var byteArray = []  for (var i = 0; i < str.length; ++i) {    // Node's code seems to be doing this and not & 0x7F..    byteArray.push(str.charCodeAt(i) & 0xFF)  }  return byteArray}function utf16leToBytes (str, units) {  var c, hi, lo  var byteArray = []  for (var i = 0; i < str.length; ++i) {    if ((units -= 2) < 0) break    c = str.charCodeAt(i)    hi = c >> 8    lo = c % 256    byteArray.push(lo)    byteArray.push(hi)  }  return byteArray}function base64ToBytes (str) {  return base64.toByteArray(base64clean(str))}function blitBuffer (src, dst, offset, length) {  for (var i = 0; i < length; ++i) {    if ((i + offset >= dst.length) || (i >= src.length)) break    dst[i + offset] = src[i]  }  return i}// ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass// the `instanceof` check but they should be treated as of that type.// See: https://github.com/feross/buffer/issues/166function isInstance (obj, type) {  return obj instanceof type ||    (obj != null && obj.constructor != null && obj.constructor.name != null &&      obj.constructor.name === type.name)}function numberIsNaN (obj) {  // For IE11 support  return obj !== obj // eslint-disable-line no-self-compare}},{"base64-js":44,"ieee754":152}],80:[function(require,module,exports){(function (process,Buffer){/* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com *//* vim: set ts=2: *//*jshint eqnull:true *//*exported CFB *//*global module, require:false, process:false, Buffer:false, Uint8Array:false, Uint16Array:false */var Base64 = (function make_b64(){	var map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";	return {		encode: function(input) {			var o = "";			var c1=0, c2=0, c3=0, e1=0, e2=0, e3=0, e4=0;			for(var i = 0; i < input.length; ) {				c1 = input.charCodeAt(i++);				e1 = (c1 >> 2);				c2 = input.charCodeAt(i++);				e2 = ((c1 & 3) << 4) | (c2 >> 4);				c3 = input.charCodeAt(i++);				e3 = ((c2 & 15) << 2) | (c3 >> 6);				e4 = (c3 & 63);				if (isNaN(c2)) { e3 = e4 = 64; }				else if (isNaN(c3)) { e4 = 64; }				o += map.charAt(e1) + map.charAt(e2) + map.charAt(e3) + map.charAt(e4);			}			return o;		},		decode: function b64_decode(input) {			var o = "";			var c1=0, c2=0, c3=0, e1=0, e2=0, e3=0, e4=0;			input = input.replace(/[^\w\+\/\=]/g, "");			for(var i = 0; i < input.length;) {				e1 = map.indexOf(input.charAt(i++));				e2 = map.indexOf(input.charAt(i++));				c1 = (e1 << 2) | (e2 >> 4);				o += String.fromCharCode(c1);				e3 = map.indexOf(input.charAt(i++));				c2 = ((e2 & 15) << 4) | (e3 >> 2);				if (e3 !== 64) { o += String.fromCharCode(c2); }				e4 = map.indexOf(input.charAt(i++));				c3 = ((e3 & 3) << 6) | e4;				if (e4 !== 64) { o += String.fromCharCode(c3); }			}			return o;		}	};})();var has_buf = (typeof Buffer !== 'undefined' && typeof process !== 'undefined' && typeof process.versions !== 'undefined' && process.versions.node);var Buffer_from = function(){};if(typeof Buffer !== 'undefined') {	var nbfs = !Buffer.from;	if(!nbfs) try { Buffer.from("foo", "utf8"); } catch(e) { nbfs = true; }	Buffer_from = nbfs ? function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); } : Buffer.from.bind(Buffer);	// $FlowIgnore	if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); };	// $FlowIgnore	if(!Buffer.allocUnsafe) Buffer.allocUnsafe = function(n) { return new Buffer(n); };}function new_raw_buf(len) {	/* jshint -W056 */	return has_buf ? Buffer.alloc(len) : new Array(len);	/* jshint +W056 */}function new_unsafe_buf(len) {	/* jshint -W056 */	return has_buf ? Buffer.allocUnsafe(len) : new Array(len);	/* jshint +W056 */}var s2a = function s2a(s) {	if(has_buf) return Buffer_from(s, "binary");	return s.split("").map(function(x){ return x.charCodeAt(0) & 0xff; });};var chr0 = /\u0000/g, chr1 = /[\u0001-\u0006]/g;var __toBuffer = function(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; };var ___toBuffer = __toBuffer;var __utf16le = function(b,s,e) { var ss=[]; for(var i=s; i<e; i+=2) ss.push(String.fromCharCode(__readUInt16LE(b,i))); return ss.join("").replace(chr0,''); };var ___utf16le = __utf16le;var __hexlify = function(b,s,l) { var ss=[]; for(var i=s; i<s+l; ++i) ss.push(("0" + b[i].toString(16)).slice(-2)); return ss.join(""); };var ___hexlify = __hexlify;var __bconcat = function(bufs) {	if(Array.isArray(bufs[0])) return [].concat.apply([], bufs);	var maxlen = 0, i = 0;	for(i = 0; i < bufs.length; ++i) maxlen += bufs[i].length;	var o = new Uint8Array(maxlen);	for(i = 0, maxlen = 0; i < bufs.length; maxlen += bufs[i].length, ++i) o.set(bufs[i], maxlen);	return o;};var bconcat = __bconcat;if(has_buf) {	__utf16le = function(b,s,e) {		if(!Buffer.isBuffer(b)) return ___utf16le(b,s,e);		return b.toString('utf16le',s,e).replace(chr0,'')/*.replace(chr1,'!')*/;	};	__hexlify = function(b,s,l) { return Buffer.isBuffer(b) ? b.toString('hex',s,s+l) : ___hexlify(b,s,l); };	__toBuffer = function(bufs) { return (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat((bufs[0])) : ___toBuffer(bufs);};	s2a = function(s) { return Buffer_from(s, "binary"); };	bconcat = function(bufs) { return Buffer.isBuffer(bufs[0]) ? Buffer.concat(bufs) : __bconcat(bufs); };}var __readUInt8 = function(b, idx) { return b[idx]; };var __readUInt16LE = function(b, idx) { return b[idx+1]*(1<<8)+b[idx]; };var __readInt16LE = function(b, idx) { var u = b[idx+1]*(1<<8)+b[idx]; return (u < 0x8000) ? u : (0xffff - u + 1) * -1; };var __readUInt32LE = function(b, idx) { return b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };var __readInt32LE = function(b, idx) { return (b[idx+3]<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };function ReadShift(size, t) {	var oI, oS, type = 0;	switch(size) {		case 1: oI = __readUInt8(this, this.l); break;		case 2: oI = (t !== 'i' ? __readUInt16LE : __readInt16LE)(this, this.l); break;		case 4: oI = __readInt32LE(this, this.l); break;		case 16: type = 2; oS = __hexlify(this, this.l, size);	}	this.l += size; if(type === 0) return oI; return oS;}var __writeUInt32LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); b[idx+2] = ((val >>> 16) & 0xFF); b[idx+3] = ((val >>> 24) & 0xFF); };var __writeInt32LE  = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >> 8) & 0xFF); b[idx+2] = ((val >> 16) & 0xFF); b[idx+3] = ((val >> 24) & 0xFF); };function WriteShift(t, val, f) {	var size = 0, i = 0;	switch(f) {		case "hex": for(; i < t; ++i) {this[this.l++] = parseInt(val.slice(2*i, 2*i+2), 16)||0;		} return this;		case "utf16le":var end = this.l + t;			for(i = 0; i < Math.min(val.length, t); ++i) {				var cc = val.charCodeAt(i);				this[this.l++] = cc & 0xff;				this[this.l++] = cc >> 8;			}			while(this.l < end) this[this.l++] = 0;			return this;	}switch(t) {		case  1: size = 1; this[this.l] = val&0xFF; break;		case  2: size = 2; this[this.l] = val&0xFF; val >>>= 8; this[this.l+1] = val&0xFF; break;		case  4: size = 4; __writeUInt32LE(this, val, this.l); break;		case -4: size = 4; __writeInt32LE(this, val, this.l); break;	}	this.l += size; return this;}function CheckField(hexstr, fld) {	var m = __hexlify(this,this.l,hexstr.length>>1);	if(m !== hexstr) throw new Error(fld + 'Expected ' + hexstr + ' saw ' + m);	this.l += hexstr.length>>1;}function prep_blob(blob, pos) {	blob.l = pos;	blob.read_shift = ReadShift;	blob.chk = CheckField;	blob.write_shift = WriteShift;}function new_buf(sz) {	var o = (new_raw_buf(sz));	prep_blob(o, 0);	return o;}/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com *//* vim: set ts=2: *//*exported CRC32 */var CRC32;(function (factory) {	/*jshint ignore:start */	/*eslint-disable */	factory(CRC32 = {});	/*eslint-enable */	/*jshint ignore:end */}(function(CRC32) {CRC32.version = '1.2.0';/* see perf/crc32table.js *//*global Int32Array */function signed_crc_table() {	var c = 0, table = new Array(256);	for(var n =0; n != 256; ++n){		c = n;		c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));		c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));		c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));		c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));		c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));		c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));		c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));		c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));		table[n] = c;	}	return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table;}var T = signed_crc_table();function crc32_bstr(bstr, seed) {	var C = seed ^ -1, L = bstr.length - 1;	for(var i = 0; i < L;) {		C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF];		C = (C>>>8) ^ T[(C^bstr.charCodeAt(i++))&0xFF];	}	if(i === L) C = (C>>>8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF];	return C ^ -1;}function crc32_buf(buf, seed) {	if(buf.length > 10000) return crc32_buf_8(buf, seed);	var C = seed ^ -1, L = buf.length - 3;	for(var i = 0; i < L;) {		C = (C>>>8) ^ T[(C^buf[i++])&0xFF];		C = (C>>>8) ^ T[(C^buf[i++])&0xFF];		C = (C>>>8) ^ T[(C^buf[i++])&0xFF];		C = (C>>>8) ^ T[(C^buf[i++])&0xFF];	}	while(i < L+3) C = (C>>>8) ^ T[(C^buf[i++])&0xFF];	return C ^ -1;}function crc32_buf_8(buf, seed) {	var C = seed ^ -1, L = buf.length - 7;	for(var i = 0; i < L;) {		C = (C>>>8) ^ T[(C^buf[i++])&0xFF];		C = (C>>>8) ^ T[(C^buf[i++])&0xFF];		C = (C>>>8) ^ T[(C^buf[i++])&0xFF];		C = (C>>>8) ^ T[(C^buf[i++])&0xFF];		C = (C>>>8) ^ T[(C^buf[i++])&0xFF];		C = (C>>>8) ^ T[(C^buf[i++])&0xFF];		C = (C>>>8) ^ T[(C^buf[i++])&0xFF];		C = (C>>>8) ^ T[(C^buf[i++])&0xFF];	}	while(i < L+7) C = (C>>>8) ^ T[(C^buf[i++])&0xFF];	return C ^ -1;}function crc32_str(str, seed) {	var C = seed ^ -1;	for(var i = 0, L=str.length, c, d; i < L;) {		c = str.charCodeAt(i++);		if(c < 0x80) {			C = (C>>>8) ^ T[(C ^ c)&0xFF];		} else if(c < 0x800) {			C = (C>>>8) ^ T[(C ^ (192|((c>>6)&31)))&0xFF];			C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF];		} else if(c >= 0xD800 && c < 0xE000) {			c = (c&1023)+64; d = str.charCodeAt(i++)&1023;			C = (C>>>8) ^ T[(C ^ (240|((c>>8)&7)))&0xFF];			C = (C>>>8) ^ T[(C ^ (128|((c>>2)&63)))&0xFF];			C = (C>>>8) ^ T[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF];			C = (C>>>8) ^ T[(C ^ (128|(d&63)))&0xFF];		} else {			C = (C>>>8) ^ T[(C ^ (224|((c>>12)&15)))&0xFF];			C = (C>>>8) ^ T[(C ^ (128|((c>>6)&63)))&0xFF];			C = (C>>>8) ^ T[(C ^ (128|(c&63)))&0xFF];		}	}	return C ^ -1;}CRC32.table = T;CRC32.bstr = crc32_bstr;CRC32.buf = crc32_buf;CRC32.str = crc32_str;}));/* [MS-CFB] v20171201 */var CFB = (function _CFB(){var exports = {};exports.version = '1.1.0';/* [MS-CFB] 2.6.4 */function namecmp(l, r) {	var L = l.split("/"), R = r.split("/");	for(var i = 0, c = 0, Z = Math.min(L.length, R.length); i < Z; ++i) {		if((c = L[i].length - R[i].length)) return c;		if(L[i] != R[i]) return L[i] < R[i] ? -1 : 1;	}	return L.length - R.length;}function dirname(p) {	if(p.charAt(p.length - 1) == "/") return (p.slice(0,-1).indexOf("/") === -1) ? p : dirname(p.slice(0, -1));	var c = p.lastIndexOf("/");	return (c === -1) ? p : p.slice(0, c+1);}function filename(p) {	if(p.charAt(p.length - 1) == "/") return filename(p.slice(0, -1));	var c = p.lastIndexOf("/");	return (c === -1) ? p : p.slice(c+1);}/* -------------------------------------------------------------------------- *//* DOS Date format:   high|YYYYYYYm.mmmddddd.HHHHHMMM.MMMSSSSS|low   add 1980 to stored year   stored second should be doubled*//* write JS date to buf as a DOS date */function write_dos_date(buf, date) {	if(typeof date === "string") date = new Date(date);	var hms = date.getHours();	hms = hms << 6 | date.getMinutes();	hms = hms << 5 | (date.getSeconds()>>>1);	buf.write_shift(2, hms);	var ymd = (date.getFullYear() - 1980);	ymd = ymd << 4 | (date.getMonth()+1);	ymd = ymd << 5 | date.getDate();	buf.write_shift(2, ymd);}/* read four bytes from buf and interpret as a DOS date */function parse_dos_date(buf) {	var hms = buf.read_shift(2) & 0xFFFF;	var ymd = buf.read_shift(2) & 0xFFFF;	var val = new Date();	var d = ymd & 0x1F; ymd >>>= 5;	var m = ymd & 0x0F; ymd >>>= 4;	val.setMilliseconds(0);	val.setFullYear(ymd + 1980);	val.setMonth(m-1);	val.setDate(d);	var S = hms & 0x1F; hms >>>= 5;	var M = hms & 0x3F; hms >>>= 6;	val.setHours(hms);	val.setMinutes(M);	val.setSeconds(S<<1);	return val;}function parse_extra_field(blob) {	prep_blob(blob, 0);	var o = {};	var flags = 0;	while(blob.l <= blob.length - 4) {		var type = blob.read_shift(2);		var sz = blob.read_shift(2), tgt = blob.l + sz;		var p = {};		switch(type) {			/* UNIX-style Timestamps */			case 0x5455: {				flags = blob.read_shift(1);				if(flags & 1) p.mtime = blob.read_shift(4);				/* for some reason, CD flag corresponds to LFH */				if(sz > 5) {					if(flags & 2) p.atime = blob.read_shift(4);					if(flags & 4) p.ctime = blob.read_shift(4);				}				if(p.mtime) p.mt = new Date(p.mtime*1000);			}			break;		}		blob.l = tgt;		o[type] = p;	}	return o;}var fs;function get_fs() { return fs || (fs = require('fs')); }function parse(file, options) {if(file[0] == 0x50 && file[1] == 0x4b) return parse_zip(file, options);if(file.length < 512) throw new Error("CFB file size " + file.length + " < 512");var mver = 3;var ssz = 512;var nmfs = 0; // number of mini FAT sectorsvar difat_sec_cnt = 0;var dir_start = 0;var minifat_start = 0;var difat_start = 0;var fat_addrs = []; // locations of FAT sectors/* [MS-CFB] 2.2 Compound File Header */var blob = file.slice(0,512);prep_blob(blob, 0);/* major version */var mv = check_get_mver(blob);mver = mv[0];switch(mver) {	case 3: ssz = 512; break; case 4: ssz = 4096; break;	case 0: if(mv[1] == 0) return parse_zip(file, options);	/* falls through */	default: throw new Error("Major Version: Expected 3 or 4 saw " + mver);}/* reprocess header */if(ssz !== 512) { blob = file.slice(0,ssz); prep_blob(blob, 28 /* blob.l */); }/* Save header for final object */var header = file.slice(0,ssz);check_shifts(blob, mver);// Number of Directory Sectorsvar dir_cnt = blob.read_shift(4, 'i');if(mver === 3 && dir_cnt !== 0) throw new Error('# Directory Sectors: Expected 0 saw ' + dir_cnt);// Number of FAT Sectorsblob.l += 4;// First Directory Sector Locationdir_start = blob.read_shift(4, 'i');// Transaction Signatureblob.l += 4;// Mini Stream Cutoff Sizeblob.chk('00100000', 'Mini Stream Cutoff Size: ');// First Mini FAT Sector Locationminifat_start = blob.read_shift(4, 'i');// Number of Mini FAT Sectorsnmfs = blob.read_shift(4, 'i');// First DIFAT sector locationdifat_start = blob.read_shift(4, 'i');// Number of DIFAT Sectorsdifat_sec_cnt = blob.read_shift(4, 'i');// Grab FAT Sector Locationsfor(var q = -1, j = 0; j < 109; ++j) { /* 109 = (512 - blob.l)>>>2; */	q = blob.read_shift(4, 'i');	if(q<0) break;	fat_addrs[j] = q;}/** Break the file up into sectors */var sectors = sectorify(file, ssz);sleuth_fat(difat_start, difat_sec_cnt, sectors, ssz, fat_addrs);/** Chains */var sector_list = make_sector_list(sectors, dir_start, fat_addrs, ssz);sector_list[dir_start].name = "!Directory";if(nmfs > 0 && minifat_start !== ENDOFCHAIN) sector_list[minifat_start].name = "!MiniFAT";sector_list[fat_addrs[0]].name = "!FAT";sector_list.fat_addrs = fat_addrs;sector_list.ssz = ssz;/* [MS-CFB] 2.6.1 Compound File Directory Entry */var files = {}, Paths = [], FileIndex = [], FullPaths = [];read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex, minifat_start);build_full_paths(FileIndex, FullPaths, Paths);Paths.shift();var o = {	FileIndex: FileIndex,	FullPaths: FullPaths};// $FlowIgnoreif(options && options.raw) o.raw = {header: header, sectors: sectors};return o;} // parse/* [MS-CFB] 2.2 Compound File Header -- read up to major version */function check_get_mver(blob) {	if(blob[blob.l] == 0x50 && blob[blob.l + 1] == 0x4b) return [0, 0];	// header signature 8	blob.chk(HEADER_SIGNATURE, 'Header Signature: ');	// clsid 16	blob.chk(HEADER_CLSID, 'CLSID: ');	// minor version 2	var mver = blob.read_shift(2, 'u');	return [blob.read_shift(2,'u'), mver];}function check_shifts(blob, mver) {	var shift = 0x09;	// Byte Order	//blob.chk('feff', 'Byte Order: '); // note: some writers put 0xffff	blob.l += 2;	// Sector Shift	switch((shift = blob.read_shift(2))) {		case 0x09: if(mver != 3) throw new Error('Sector Shift: Expected 9 saw ' + shift); break;		case 0x0c: if(mver != 4) throw new Error('Sector Shift: Expected 12 saw ' + shift); break;		default: throw new Error('Sector Shift: Expected 9 or 12 saw ' + shift);	}	// Mini Sector Shift	blob.chk('0600', 'Mini Sector Shift: ');	// Reserved	blob.chk('000000000000', 'Reserved: ');}/** Break the file up into sectors */function sectorify(file, ssz) {	var nsectors = Math.ceil(file.length/ssz)-1;	var sectors = [];	for(var i=1; i < nsectors; ++i) sectors[i-1] = file.slice(i*ssz,(i+1)*ssz);	sectors[nsectors-1] = file.slice(nsectors*ssz);	return sectors;}/* [MS-CFB] 2.6.4 Red-Black Tree */function build_full_paths(FI, FP, Paths) {	var i = 0, L = 0, R = 0, C = 0, j = 0, pl = Paths.length;	var dad = [], q = [];	for(; i < pl; ++i) { dad[i]=q[i]=i; FP[i]=Paths[i]; }	for(; j < q.length; ++j) {		i = q[j];		L = FI[i].L; R = FI[i].R; C = FI[i].C;		if(dad[i] === i) {			if(L !== -1 /*NOSTREAM*/ && dad[L] !== L) dad[i] = dad[L];			if(R !== -1 && dad[R] !== R) dad[i] = dad[R];		}		if(C !== -1 /*NOSTREAM*/) dad[C] = i;		if(L !== -1) { dad[L] = dad[i]; if(q.lastIndexOf(L) < j) q.push(L); }		if(R !== -1) { dad[R] = dad[i]; if(q.lastIndexOf(R) < j) q.push(R); }	}	for(i=1; i < pl; ++i) if(dad[i] === i) {		if(R !== -1 /*NOSTREAM*/ && dad[R] !== R) dad[i] = dad[R];		else if(L !== -1 && dad[L] !== L) dad[i] = dad[L];	}	for(i=1; i < pl; ++i) {		if(FI[i].type === 0 /* unknown */) continue;		j = dad[i];		if(j === 0) FP[i] = FP[0] + "/" + FP[i];		else while(j !== 0 && j !== dad[j]) {			FP[i] = FP[j] + "/" + FP[i];			j = dad[j];		}		dad[i] = 0;	}	FP[0] += "/";	for(i=1; i < pl; ++i) {		if(FI[i].type !== 2 /* stream */) FP[i] += "/";	}}function get_mfat_entry(entry, payload, mini) {	var start = entry.start, size = entry.size;	//return (payload.slice(start*MSSZ, start*MSSZ + size));	var o = [];	var idx = start;	while(mini && size > 0 && idx >= 0) {		o.push(payload.slice(idx * MSSZ, idx * MSSZ + MSSZ));		size -= MSSZ;		idx = __readInt32LE(mini, idx * 4);	}	if(o.length === 0) return (new_buf(0));	return (bconcat(o).slice(0, entry.size));}/** Chase down the rest of the DIFAT chain to build a comprehensive list    DIFAT chains by storing the next sector number as the last 32 bits */function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) {	var q = ENDOFCHAIN;	if(idx === ENDOFCHAIN) {		if(cnt !== 0) throw new Error("DIFAT chain shorter than expected");	} else if(idx !== -1 /*FREESECT*/) {		var sector = sectors[idx], m = (ssz>>>2)-1;		if(!sector) return;		for(var i = 0; i < m; ++i) {			if((q = __readInt32LE(sector,i*4)) === ENDOFCHAIN) break;			fat_addrs.push(q);		}		sleuth_fat(__readInt32LE(sector,ssz-4),cnt - 1, sectors, ssz, fat_addrs);	}}/** Follow the linked list of sectors for a given starting point */function get_sector_list(sectors, start, fat_addrs, ssz, chkd) {	var buf = [], buf_chain = [];	if(!chkd) chkd = [];	var modulus = ssz - 1, j = 0, jj = 0;	for(j=start; j>=0;) {		chkd[j] = true;		buf[buf.length] = j;		buf_chain.push(sectors[j]);		var addr = fat_addrs[Math.floor(j*4/ssz)];		jj = ((j*4) & modulus);		if(ssz < 4 + jj) throw new Error("FAT boundary crossed: " + j + " 4 "+ssz);		if(!sectors[addr]) break;		j = __readInt32LE(sectors[addr], jj);	}	return {nodes: buf, data:__toBuffer([buf_chain])};}/** Chase down the sector linked lists */function make_sector_list(sectors, dir_start, fat_addrs, ssz) {	var sl = sectors.length, sector_list = ([]);	var chkd = [], buf = [], buf_chain = [];	var modulus = ssz - 1, i=0, j=0, k=0, jj=0;	for(i=0; i < sl; ++i) {		buf = ([]);		k = (i + dir_start); if(k >= sl) k-=sl;		if(chkd[k]) continue;		buf_chain = [];		for(j=k; j>=0;) {			chkd[j] = true;			buf[buf.length] = j;			buf_chain.push(sectors[j]);			var addr = fat_addrs[Math.floor(j*4/ssz)];			jj = ((j*4) & modulus);			if(ssz < 4 + jj) throw new Error("FAT boundary crossed: " + j + " 4 "+ssz);			if(!sectors[addr]) break;			j = __readInt32LE(sectors[addr], jj);		}		sector_list[k] = ({nodes: buf, data:__toBuffer([buf_chain])});	}	return sector_list;}/* [MS-CFB] 2.6.1 Compound File Directory Entry */function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex, mini) {	var minifat_store = 0, pl = (Paths.length?2:0);	var sector = sector_list[dir_start].data;	var i = 0, namelen = 0, name;	for(; i < sector.length; i+= 128) {		var blob = sector.slice(i, i+128);		prep_blob(blob, 64);		namelen = blob.read_shift(2);		name = __utf16le(blob,0,namelen-pl);		Paths.push(name);		var o = ({			name:  name,			type:  blob.read_shift(1),			color: blob.read_shift(1),			L:     blob.read_shift(4, 'i'),			R:     blob.read_shift(4, 'i'),			C:     blob.read_shift(4, 'i'),			clsid: blob.read_shift(16),			state: blob.read_shift(4, 'i'),			start: 0,			size: 0		});		var ctime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2);		if(ctime !== 0) o.ct = read_date(blob, blob.l-8);		var mtime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2);		if(mtime !== 0) o.mt = read_date(blob, blob.l-8);		o.start = blob.read_shift(4, 'i');		o.size = blob.read_shift(4, 'i');		if(o.size < 0 && o.start < 0) { o.size = o.type = 0; o.start = ENDOFCHAIN; o.name = ""; }		if(o.type === 5) { /* root */			minifat_store = o.start;			if(nmfs > 0 && minifat_store !== ENDOFCHAIN) sector_list[minifat_store].name = "!StreamData";			/*minifat_size = o.size;*/		} else if(o.size >= 4096 /* MSCSZ */) {			o.storage = 'fat';			if(sector_list[o.start] === undefined) sector_list[o.start] = get_sector_list(sectors, o.start, sector_list.fat_addrs, sector_list.ssz);			sector_list[o.start].name = o.name;			o.content = (sector_list[o.start].data.slice(0,o.size));		} else {			o.storage = 'minifat';			if(o.size < 0) o.size = 0;			else if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) {				o.content = get_mfat_entry(o, sector_list[minifat_store].data, (sector_list[mini]||{}).data);			}		}		if(o.content) prep_blob(o.content, 0);		files[name] = o;		FileIndex.push(o);	}}function read_date(blob, offset) {	return new Date(( ( (__readUInt32LE(blob,offset+4)/1e7)*Math.pow(2,32)+__readUInt32LE(blob,offset)/1e7 ) - 11644473600)*1000);}function read_file(filename, options) {	get_fs();	return parse(fs.readFileSync(filename), options);}function read(blob, options) {	switch(options && options.type || "base64") {		case "file": return read_file(blob, options);		case "base64": return parse(s2a(Base64.decode(blob)), options);		case "binary": return parse(s2a(blob), options);	}	return parse(blob, options);}function init_cfb(cfb, opts) {	var o = opts || {}, root = o.root || "Root Entry";	if(!cfb.FullPaths) cfb.FullPaths = [];	if(!cfb.FileIndex) cfb.FileIndex = [];	if(cfb.FullPaths.length !== cfb.FileIndex.length) throw new Error("inconsistent CFB structure");	if(cfb.FullPaths.length === 0) {		cfb.FullPaths[0] = root + "/";		cfb.FileIndex[0] = ({ name: root, type: 5 });	}	if(o.CLSID) cfb.FileIndex[0].clsid = o.CLSID;	seed_cfb(cfb);}function seed_cfb(cfb) {	var nm = "\u0001Sh33tJ5";	if(CFB.find(cfb, "/" + nm)) return;	var p = new_buf(4); p[0] = 55; p[1] = p[3] = 50; p[2] = 54;	cfb.FileIndex.push(({ name: nm, type: 2, content:p, size:4, L:69, R:69, C:69 }));	cfb.FullPaths.push(cfb.FullPaths[0] + nm);	rebuild_cfb(cfb);}function rebuild_cfb(cfb, f) {	init_cfb(cfb);	var gc = false, s = false;	for(var i = cfb.FullPaths.length - 1; i >= 0; --i) {		var _file = cfb.FileIndex[i];		switch(_file.type) {			case 0:				if(s) gc = true;				else { cfb.FileIndex.pop(); cfb.FullPaths.pop(); }				break;			case 1: case 2: case 5:				s = true;				if(isNaN(_file.R * _file.L * _file.C)) gc = true;				if(_file.R > -1 && _file.L > -1 && _file.R == _file.L) gc = true;				break;			default: gc = true; break;		}	}	if(!gc && !f) return;	var now = new Date(1987, 1, 19), j = 0;	var data = [];	for(i = 0; i < cfb.FullPaths.length; ++i) {		if(cfb.FileIndex[i].type === 0) continue;		data.push([cfb.FullPaths[i], cfb.FileIndex[i]]);	}	for(i = 0; i < data.length; ++i) {		var dad = dirname(data[i][0]);		s = false;		for(j = 0; j < data.length; ++j) if(data[j][0] === dad) s = true;		if(!s) data.push([dad, ({			name: filename(dad).replace("/",""),			type: 1,			clsid: HEADER_CLSID,			ct: now, mt: now,			content: null		})]);	}	data.sort(function(x,y) { return namecmp(x[0], y[0]); });	cfb.FullPaths = []; cfb.FileIndex = [];	for(i = 0; i < data.length; ++i) { cfb.FullPaths[i] = data[i][0]; cfb.FileIndex[i] = data[i][1]; }	for(i = 0; i < data.length; ++i) {		var elt = cfb.FileIndex[i];		var nm = cfb.FullPaths[i];		elt.name =  filename(nm).replace("/","");		elt.L = elt.R = elt.C = -(elt.color = 1);		elt.size = elt.content ? elt.content.length : 0;		elt.start = 0;		elt.clsid = (elt.clsid || HEADER_CLSID);		if(i === 0) {			elt.C = data.length > 1 ? 1 : -1;			elt.size = 0;			elt.type = 5;		} else if(nm.slice(-1) == "/") {			for(j=i+1;j < data.length; ++j) if(dirname(cfb.FullPaths[j])==nm) break;			elt.C = j >= data.length ? -1 : j;			for(j=i+1;j < data.length; ++j) if(dirname(cfb.FullPaths[j])==dirname(nm)) break;			elt.R = j >= data.length ? -1 : j;			elt.type = 1;		} else {			if(dirname(cfb.FullPaths[i+1]||"") == dirname(nm)) elt.R = i + 1;			elt.type = 2;		}	}}function _write(cfb, options) {	var _opts = options || {};	rebuild_cfb(cfb);	if(_opts.fileType == 'zip') return write_zip(cfb, _opts);	var L = (function(cfb){		var mini_size = 0, fat_size = 0;		for(var i = 0; i < cfb.FileIndex.length; ++i) {			var file = cfb.FileIndex[i];			if(!file.content) continue;var flen = file.content.length;			if(flen > 0){				if(flen < 0x1000) mini_size += (flen + 0x3F) >> 6;				else fat_size += (flen + 0x01FF) >> 9;			}		}		var dir_cnt = (cfb.FullPaths.length +3) >> 2;		var mini_cnt = (mini_size + 7) >> 3;		var mfat_cnt = (mini_size + 0x7F) >> 7;		var fat_base = mini_cnt + fat_size + dir_cnt + mfat_cnt;		var fat_cnt = (fat_base + 0x7F) >> 7;		var difat_cnt = fat_cnt <= 109 ? 0 : Math.ceil((fat_cnt-109)/0x7F);		while(((fat_base + fat_cnt + difat_cnt + 0x7F) >> 7) > fat_cnt) difat_cnt = ++fat_cnt <= 109 ? 0 : Math.ceil((fat_cnt-109)/0x7F);		var L =  [1, difat_cnt, fat_cnt, mfat_cnt, dir_cnt, fat_size, mini_size, 0];		cfb.FileIndex[0].size = mini_size << 6;		L[7] = (cfb.FileIndex[0].start=L[0]+L[1]+L[2]+L[3]+L[4]+L[5])+((L[6]+7) >> 3);		return L;	})(cfb);	var o = new_buf(L[7] << 9);	var i = 0, T = 0;	{		for(i = 0; i < 8; ++i) o.write_shift(1, HEADER_SIG[i]);		for(i = 0; i < 8; ++i) o.write_shift(2, 0);		o.write_shift(2, 0x003E);		o.write_shift(2, 0x0003);		o.write_shift(2, 0xFFFE);		o.write_shift(2, 0x0009);		o.write_shift(2, 0x0006);		for(i = 0; i < 3; ++i) o.write_shift(2, 0);		o.write_shift(4, 0);		o.write_shift(4, L[2]);		o.write_shift(4, L[0] + L[1] + L[2] + L[3] - 1);		o.write_shift(4, 0);		o.write_shift(4, 1<<12);		o.write_shift(4, L[3] ? L[0] + L[1] + L[2] - 1: ENDOFCHAIN);		o.write_shift(4, L[3]);		o.write_shift(-4, L[1] ? L[0] - 1: ENDOFCHAIN);		o.write_shift(4, L[1]);		for(i = 0; i < 109; ++i) o.write_shift(-4, i < L[2] ? L[1] + i : -1);	}	if(L[1]) {		for(T = 0; T < L[1]; ++T) {			for(; i < 236 + T * 127; ++i) o.write_shift(-4, i < L[2] ? L[1] + i : -1);			o.write_shift(-4, T === L[1] - 1 ? ENDOFCHAIN : T + 1);		}	}	var chainit = function(w) {		for(T += w; i<T-1; ++i) o.write_shift(-4, i+1);		if(w) { ++i; o.write_shift(-4, ENDOFCHAIN); }	};	T = i = 0;	for(T+=L[1]; i<T; ++i) o.write_shift(-4, consts.DIFSECT);	for(T+=L[2]; i<T; ++i) o.write_shift(-4, consts.FATSECT);	chainit(L[3]);	chainit(L[4]);	var j = 0, flen = 0;	var file = cfb.FileIndex[0];	for(; j < cfb.FileIndex.length; ++j) {		file = cfb.FileIndex[j];		if(!file.content) continue;flen = file.content.length;		if(flen < 0x1000) continue;		file.start = T;		chainit((flen + 0x01FF) >> 9);	}	chainit((L[6] + 7) >> 3);	while(o.l & 0x1FF) o.write_shift(-4, consts.ENDOFCHAIN);	T = i = 0;	for(j = 0; j < cfb.FileIndex.length; ++j) {		file = cfb.FileIndex[j];		if(!file.content) continue;flen = file.content.length;		if(!flen || flen >= 0x1000) continue;		file.start = T;		chainit((flen + 0x3F) >> 6);	}	while(o.l & 0x1FF) o.write_shift(-4, consts.ENDOFCHAIN);	for(i = 0; i < L[4]<<2; ++i) {		var nm = cfb.FullPaths[i];		if(!nm || nm.length === 0) {			for(j = 0; j < 17; ++j) o.write_shift(4, 0);			for(j = 0; j < 3; ++j) o.write_shift(4, -1);			for(j = 0; j < 12; ++j) o.write_shift(4, 0);			continue;		}		file = cfb.FileIndex[i];		if(i === 0) file.start = file.size ? file.start - 1 : ENDOFCHAIN;		var _nm = (i === 0 && _opts.root) || file.name;		flen = 2*(_nm.length+1);		o.write_shift(64, _nm, "utf16le");		o.write_shift(2, flen);		o.write_shift(1, file.type);		o.write_shift(1, file.color);		o.write_shift(-4, file.L);		o.write_shift(-4, file.R);		o.write_shift(-4, file.C);		if(!file.clsid) for(j = 0; j < 4; ++j) o.write_shift(4, 0);		else o.write_shift(16, file.clsid, "hex");		o.write_shift(4, file.state || 0);		o.write_shift(4, 0); o.write_shift(4, 0);		o.write_shift(4, 0); o.write_shift(4, 0);		o.write_shift(4, file.start);		o.write_shift(4, file.size); o.write_shift(4, 0);	}	for(i = 1; i < cfb.FileIndex.length; ++i) {		file = cfb.FileIndex[i];if(file.size >= 0x1000) {			o.l = (file.start+1) << 9;			for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]);			for(; j & 0x1FF; ++j) o.write_shift(1, 0);		}	}	for(i = 1; i < cfb.FileIndex.length; ++i) {		file = cfb.FileIndex[i];if(file.size > 0 && file.size < 0x1000) {			for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]);			for(; j & 0x3F; ++j) o.write_shift(1, 0);		}	}	while(o.l < o.length) o.write_shift(1, 0);	return o;}/* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */function find(cfb, path) {	var UCFullPaths = cfb.FullPaths.map(function(x) { return x.toUpperCase(); });	var UCPaths = UCFullPaths.map(function(x) { var y = x.split("/"); return y[y.length - (x.slice(-1) == "/" ? 2 : 1)]; });	var k = false;	if(path.charCodeAt(0) === 47 /* "/" */) { k = true; path = UCFullPaths[0].slice(0, -1) + path; }	else k = path.indexOf("/") !== -1;	var UCPath = path.toUpperCase();	var w = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath);	if(w !== -1) return cfb.FileIndex[w];	var m = !UCPath.match(chr1);	UCPath = UCPath.replace(chr0,'');	if(m) UCPath = UCPath.replace(chr1,'!');	for(w = 0; w < UCFullPaths.length; ++w) {		if((m ? UCFullPaths[w].replace(chr1,'!') : UCFullPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];		if((m ? UCPaths[w].replace(chr1,'!') : UCPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];	}	return null;}/** CFB Constants */var MSSZ = 64; /* Mini Sector Size = 1<<6 *///var MSCSZ = 4096; /* Mini Stream Cutoff Size *//* 2.1 Compound File Sector Numbers and Types */var ENDOFCHAIN = -2;/* 2.2 Compound File Header */var HEADER_SIGNATURE = 'd0cf11e0a1b11ae1';var HEADER_SIG = [0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1];var HEADER_CLSID = '00000000000000000000000000000000';var consts = {	/* 2.1 Compund File Sector Numbers and Types */	MAXREGSECT: -6,	DIFSECT: -4,	FATSECT: -3,	ENDOFCHAIN: ENDOFCHAIN,	FREESECT: -1,	/* 2.2 Compound File Header */	HEADER_SIGNATURE: HEADER_SIGNATURE,	HEADER_MINOR_VERSION: '3e00',	MAXREGSID: -6,	NOSTREAM: -1,	HEADER_CLSID: HEADER_CLSID,	/* 2.6.1 Compound File Directory Entry */	EntryTypes: ['unknown','storage','stream','lockbytes','property','root']};function write_file(cfb, filename, options) {	get_fs();	var o = _write(cfb, options);fs.writeFileSync(filename, o);}function a2s(o) {	var out = new Array(o.length);	for(var i = 0; i < o.length; ++i) out[i] = String.fromCharCode(o[i]);	return out.join("");}function write(cfb, options) {	var o = _write(cfb, options);	switch(options && options.type) {		case "file": get_fs(); fs.writeFileSync(options.filename, (o)); return o;		case "binary": return a2s(o);		case "base64": return Base64.encode(a2s(o));	}	return o;}/* node < 8.1 zlib does not expose bytesRead, so default to pure JS */var _zlib;function use_zlib(zlib) { try {	var InflateRaw = zlib.InflateRaw;	var InflRaw = new InflateRaw();	InflRaw._processChunk(new Uint8Array([3, 0]), InflRaw._finishFlushFlag);	if(InflRaw.bytesRead) _zlib = zlib;	else throw new Error("zlib does not expose bytesRead");} catch(e) {console.error("cannot use native zlib: " + (e.message || e)); } }function _inflateRawSync(payload, usz) {	if(!_zlib) return _inflate(payload, usz);	var InflateRaw = _zlib.InflateRaw;	var InflRaw = new InflateRaw();	var out = InflRaw._processChunk(payload.slice(payload.l), InflRaw._finishFlushFlag);	payload.l += InflRaw.bytesRead;	return out;}function _deflateRawSync(payload) {	return _zlib ? _zlib.deflateRawSync(payload) : _deflate(payload);}var CLEN_ORDER = [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];/*  LEN_ID = [ 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285 ]; */var LEN_LN = [   3,   4,   5,   6,   7,   8,   9,  10,  11,  13 , 15,  17,  19,  23,  27,  31,  35,  43,  51,  59,  67,  83,  99, 115, 131, 163, 195, 227, 258 ];/*  DST_ID = [  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13,  14,  15,  16,  17,  18,  19,   20,   21,   22,   23,   24,   25,   26,    27,    28,    29 ]; */var DST_LN = [  1,  2,  3,  4,  5,  7,  9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 ];function bit_swap_8(n) { var t = (((((n<<1)|(n<<11)) & 0x22110) | (((n<<5)|(n<<15)) & 0x88440))); return ((t>>16) | (t>>8) |t)&0xFF; }var use_typed_arrays = typeof Uint8Array !== 'undefined';var bitswap8 = use_typed_arrays ? new Uint8Array(1<<8) : [];for(var q = 0; q < (1<<8); ++q) bitswap8[q] = bit_swap_8(q);function bit_swap_n(n, b) {	var rev = bitswap8[n & 0xFF];	if(b <= 8) return rev >>> (8-b);	rev = (rev << 8) | bitswap8[(n>>8)&0xFF];	if(b <= 16) return rev >>> (16-b);	rev = (rev << 8) | bitswap8[(n>>16)&0xFF];	return rev >>> (24-b);}/* helpers for unaligned bit reads */function read_bits_2(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 6 ? 0 : buf[h+1]<<8))>>>w)& 0x03; }function read_bits_3(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 5 ? 0 : buf[h+1]<<8))>>>w)& 0x07; }function read_bits_4(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 4 ? 0 : buf[h+1]<<8))>>>w)& 0x0F; }function read_bits_5(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 3 ? 0 : buf[h+1]<<8))>>>w)& 0x1F; }function read_bits_7(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 1 ? 0 : buf[h+1]<<8))>>>w)& 0x7F; }/* works up to n = 3 * 8 + 1 = 25 */function read_bits_n(buf, bl, n) {	var w = (bl&7), h = (bl>>>3), f = ((1<<n)-1);	var v = buf[h] >>> w;	if(n < 8 - w) return v & f;	v |= buf[h+1]<<(8-w);	if(n < 16 - w) return v & f;	v |= buf[h+2]<<(16-w);	if(n < 24 - w) return v & f;	v |= buf[h+3]<<(24-w);	return v & f;}/* until ArrayBuffer#realloc is a thing, fake a realloc */function realloc(b, sz) {	var L = b.length, M = 2*L > sz ? 2*L : sz + 5, i = 0;	if(L >= sz) return b;	if(has_buf) {		var o = new_unsafe_buf(M);		// $FlowIgnore		if(b.copy) b.copy(o);		else for(; i < b.length; ++i) o[i] = b[i];		return o;	} else if(use_typed_arrays) {		var a = new Uint8Array(M);		if(a.set) a.set(b);		else for(; i < b.length; ++i) a[i] = b[i];		return a;	}	b.length = M;	return b;}/* zero-filled arrays for older browsers */function zero_fill_array(n) {	var o = new Array(n);	for(var i = 0; i < n; ++i) o[i] = 0;	return o;}var _deflate = (function() {var _deflateRaw = (function() {	return function deflateRaw(data, out) {		var boff = 0;		while(boff < data.length) {			var L = Math.min(0xFFFF, data.length - boff);			var h = boff + L == data.length;			/* TODO: this is only type 0 stored */			out.write_shift(1, +h);			out.write_shift(2, L);			out.write_shift(2, (~L) & 0xFFFF);			while(L-- > 0) out[out.l++] = data[boff++];		}		return out.l;	};})();return function(data) {	var buf = new_buf(50+Math.floor(data.length*1.1));	var off = _deflateRaw(data, buf);	return buf.slice(0, off);};})();/* modified inflate function also moves original read head *//* build tree (used for literals and lengths) */function build_tree(clens, cmap, MAX) {	var maxlen = 1, w = 0, i = 0, j = 0, ccode = 0, L = clens.length;	var bl_count  = use_typed_arrays ? new Uint16Array(32) : zero_fill_array(32);	for(i = 0; i < 32; ++i) bl_count[i] = 0;	for(i = L; i < MAX; ++i) clens[i] = 0;	L = clens.length;	var ctree = use_typed_arrays ? new Uint16Array(L) : zero_fill_array(L); // []	/* build code tree */	for(i = 0; i < L; ++i) {		bl_count[(w = clens[i])]++;		if(maxlen < w) maxlen = w;		ctree[i] = 0;	}	bl_count[0] = 0;	for(i = 1; i <= maxlen; ++i) bl_count[i+16] = (ccode = (ccode + bl_count[i-1])<<1);	for(i = 0; i < L; ++i) {		ccode = clens[i];		if(ccode != 0) ctree[i] = bl_count[ccode+16]++;	}	/* cmap[maxlen + 4 bits] = (off&15) + (lit<<4) reverse mapping */	var cleni = 0;	for(i = 0; i < L; ++i) {		cleni = clens[i];		if(cleni != 0) {			ccode = bit_swap_n(ctree[i], maxlen)>>(maxlen-cleni);			for(j = (1<<(maxlen + 4 - cleni)) - 1; j>=0; --j)				cmap[ccode|(j<<cleni)] = (cleni&15) | (i<<4);		}	}	return maxlen;}var fix_lmap = use_typed_arrays ? new Uint16Array(512) : zero_fill_array(512);var fix_dmap = use_typed_arrays ? new Uint16Array(32)  : zero_fill_array(32);if(!use_typed_arrays) {	for(var i = 0; i < 512; ++i) fix_lmap[i] = 0;	for(i = 0; i < 32; ++i) fix_dmap[i] = 0;}(function() {	var dlens = [];	var i = 0;	for(;i<32; i++) dlens.push(5);	build_tree(dlens, fix_dmap, 32);	var clens = [];	i = 0;	for(; i<=143; i++) clens.push(8);	for(; i<=255; i++) clens.push(9);	for(; i<=279; i++) clens.push(7);	for(; i<=287; i++) clens.push(8);	build_tree(clens, fix_lmap, 288);})();var dyn_lmap = use_typed_arrays ? new Uint16Array(32768) : zero_fill_array(32768);var dyn_dmap = use_typed_arrays ? new Uint16Array(32768) : zero_fill_array(32768);var dyn_cmap = use_typed_arrays ? new Uint16Array(128)   : zero_fill_array(128);var dyn_len_1 = 1, dyn_len_2 = 1;/* 5.5.3 Expanding Huffman Codes */function dyn(data, boff) {	/* nomenclature from RFC1951 refers to bit values; these are offset by the implicit constant */	var _HLIT = read_bits_5(data, boff) + 257; boff += 5;	var _HDIST = read_bits_5(data, boff) + 1; boff += 5;	var _HCLEN = read_bits_4(data, boff) + 4; boff += 4;	var w = 0;	/* grab and store code lengths */	var clens = use_typed_arrays ? new Uint8Array(19) : zero_fill_array(19);	var ctree = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];	var maxlen = 1;	var bl_count =  use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8);	var next_code = use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8);	var L = clens.length; /* 19 */	for(var i = 0; i < _HCLEN; ++i) {		clens[CLEN_ORDER[i]] = w = read_bits_3(data, boff);		if(maxlen < w) maxlen = w;		bl_count[w]++;		boff += 3;	}	/* build code tree */	var ccode = 0;	bl_count[0] = 0;	for(i = 1; i <= maxlen; ++i) next_code[i] = ccode = (ccode + bl_count[i-1])<<1;	for(i = 0; i < L; ++i) if((ccode = clens[i]) != 0) ctree[i] = next_code[ccode]++;	/* cmap[7 bits from stream] = (off&7) + (lit<<3) */	var cleni = 0;	for(i = 0; i < L; ++i) {		cleni = clens[i];		if(cleni != 0) {			ccode = bitswap8[ctree[i]]>>(8-cleni);			for(var j = (1<<(7-cleni))-1; j>=0; --j) dyn_cmap[ccode|(j<<cleni)] = (cleni&7) | (i<<3);		}	}	/* read literal and dist codes at once */	var hcodes = [];	maxlen = 1;	for(; hcodes.length < _HLIT + _HDIST;) {		ccode = dyn_cmap[read_bits_7(data, boff)];		boff += ccode & 7;		switch((ccode >>>= 3)) {			case 16:				w = 3 + read_bits_2(data, boff); boff += 2;				ccode = hcodes[hcodes.length - 1];				while(w-- > 0) hcodes.push(ccode);				break;			case 17:				w = 3 + read_bits_3(data, boff); boff += 3;				while(w-- > 0) hcodes.push(0);				break;			case 18:				w = 11 + read_bits_7(data, boff); boff += 7;				while(w -- > 0) hcodes.push(0);				break;			default:				hcodes.push(ccode);				if(maxlen < ccode) maxlen = ccode;				break;		}	}	/* build literal / length trees */	var h1 = hcodes.slice(0, _HLIT), h2 = hcodes.slice(_HLIT);	for(i = _HLIT; i < 286; ++i) h1[i] = 0;	for(i = _HDIST; i < 30; ++i) h2[i] = 0;	dyn_len_1 = build_tree(h1, dyn_lmap, 286);	dyn_len_2 = build_tree(h2, dyn_dmap, 30);	return boff;}/* return [ data, bytesRead ] */function inflate(data, usz) {	/* shortcircuit for empty buffer [0x03, 0x00] */	if(data[0] == 3 && !(data[1] & 0x3)) { return [new_raw_buf(usz), 2]; }	/* bit offset */	var boff = 0;	/* header includes final bit and type bits */	var header = 0;	var outbuf = new_unsafe_buf(usz ? usz : (1<<18));	var woff = 0;	var OL = outbuf.length>>>0;	var max_len_1 = 0, max_len_2 = 0;	while((header&1) == 0) {		header = read_bits_3(data, boff); boff += 3;		if((header >>> 1) == 0) {			/* Stored block */			if(boff & 7) boff += 8 - (boff&7);			/* 2 bytes sz, 2 bytes bit inverse */			var sz = data[boff>>>3] | data[(boff>>>3)+1]<<8;			boff += 32;			/* push sz bytes */			if(!usz && OL < woff + sz) { outbuf = realloc(outbuf, woff + sz); OL = outbuf.length; }			if(typeof data.copy === 'function') {				// $FlowIgnore				data.copy(outbuf, woff, boff>>>3, (boff>>>3)+sz);				woff += sz; boff += 8*sz;			} else while(sz-- > 0) { outbuf[woff++] = data[boff>>>3]; boff += 8; }			continue;		} else if((header >>> 1) == 1) {			/* Fixed Huffman */			max_len_1 = 9; max_len_2 = 5;		} else {			/* Dynamic Huffman */			boff = dyn(data, boff);			max_len_1 = dyn_len_1; max_len_2 = dyn_len_2;		}		if(!usz && (OL < woff + 32767)) { outbuf = realloc(outbuf, woff + 32767); OL = outbuf.length; }		for(;;) { // while(true) is apparently out of vogue in modern JS circles			/* ingest code and move read head */			var bits = read_bits_n(data, boff, max_len_1);			var code = (header>>>1) == 1 ? fix_lmap[bits] : dyn_lmap[bits];			boff += code & 15; code >>>= 4;			/* 0-255 are literals, 256 is end of block token, 257+ are copy tokens */			if(((code>>>8)&0xFF) === 0) outbuf[woff++] = code;			else if(code == 256) break;			else {				code -= 257;				var len_eb = (code < 8) ? 0 : ((code-4)>>2); if(len_eb > 5) len_eb = 0;				var tgt = woff + LEN_LN[code];				/* length extra bits */				if(len_eb > 0) {					tgt += read_bits_n(data, boff, len_eb);					boff += len_eb;				}				/* dist code */				bits = read_bits_n(data, boff, max_len_2);				code = (header>>>1) == 1 ? fix_dmap[bits] : dyn_dmap[bits];				boff += code & 15; code >>>= 4;				var dst_eb = (code < 4 ? 0 : (code-2)>>1);				var dst = DST_LN[code];				/* dist extra bits */				if(dst_eb > 0) {					dst += read_bits_n(data, boff, dst_eb);					boff += dst_eb;				}				/* in the common case, manual byte copy is faster than TA set / Buffer copy */				if(!usz && OL < tgt) { outbuf = realloc(outbuf, tgt); OL = outbuf.length; }				while(woff < tgt) { outbuf[woff] = outbuf[woff - dst]; ++woff; }			}		}	}	return [usz ? outbuf : outbuf.slice(0, woff), (boff+7)>>>3];}function _inflate(payload, usz) {	var data = payload.slice(payload.l||0);	var out = inflate(data, usz);	payload.l += out[1];	return out[0];}function warn_or_throw(wrn, msg) {	if(wrn) { if(typeof console !== 'undefined') console.error(msg); }	else throw new Error(msg);}function parse_zip(file, options) {	var blob = file;	prep_blob(blob, 0);	var FileIndex = [], FullPaths = [];	var o = {		FileIndex: FileIndex,		FullPaths: FullPaths	};	init_cfb(o, { root: options.root });	/* find end of central directory, start just after signature */	var i = blob.length - 4;	while((blob[i] != 0x50 || blob[i+1] != 0x4b || blob[i+2] != 0x05 || blob[i+3] != 0x06) && i >= 0) --i;	blob.l = i + 4;	/* parse end of central directory */	blob.l += 4;	var fcnt = blob.read_shift(2);	blob.l += 6;	var start_cd = blob.read_shift(4);	/* parse central directory */	blob.l = start_cd;	for(i = 0; i < fcnt; ++i) {		/* trust local file header instead of CD entry */		blob.l += 20;		var csz = blob.read_shift(4);		var usz = blob.read_shift(4);		var namelen = blob.read_shift(2);		var efsz = blob.read_shift(2);		var fcsz = blob.read_shift(2);		blob.l += 8;		var offset = blob.read_shift(4);		var EF = parse_extra_field(blob.slice(blob.l+namelen, blob.l+namelen+efsz));		blob.l += namelen + efsz + fcsz;		var L = blob.l;		blob.l = offset + 4;		parse_local_file(blob, csz, usz, o, EF);		blob.l = L;	}	return o;}/* head starts just after local file header signature */function parse_local_file(blob, csz, usz, o, EF) {	/* [local file header] */	blob.l += 2;	var flags = blob.read_shift(2);	var meth = blob.read_shift(2);	var date = parse_dos_date(blob);	if(flags & 0x2041) throw new Error("Unsupported ZIP encryption");	var crc32 = blob.read_shift(4);	var _csz = blob.read_shift(4);	var _usz = blob.read_shift(4);	var namelen = blob.read_shift(2);	var efsz = blob.read_shift(2);	// TODO: flags & (1<<11) // UTF8	var name = ""; for(var i = 0; i < namelen; ++i) name += String.fromCharCode(blob[blob.l++]);	if(efsz) {		var ef = parse_extra_field(blob.slice(blob.l, blob.l + efsz));		if((ef[0x5455]||{}).mt) date = ef[0x5455].mt;		if(((EF||{})[0x5455]||{}).mt) date = EF[0x5455].mt;	}	blob.l += efsz;	/* [encryption header] */	/* [file data] */	var data = blob.slice(blob.l, blob.l + _csz);	switch(meth) {		case 8: data = _inflateRawSync(blob, _usz); break;		case 0: break;		default: throw new Error("Unsupported ZIP Compression method " + meth);	}	/* [data descriptor] */	var wrn = false;	if(flags & 8) {		crc32 = blob.read_shift(4);		if(crc32 == 0x08074b50) { crc32 = blob.read_shift(4); wrn = true; }		_csz = blob.read_shift(4);		_usz = blob.read_shift(4);	}	if(_csz != csz) warn_or_throw(wrn, "Bad compressed size: " + csz + " != " + _csz);	if(_usz != usz) warn_or_throw(wrn, "Bad uncompressed size: " + usz + " != " + _usz);	var _crc32 = CRC32.buf(data, 0);	if(crc32 != _crc32) warn_or_throw(wrn, "Bad CRC32 checksum: " + crc32 + " != " + _crc32);	cfb_add(o, name, data, {unsafe: true, mt: date});}function write_zip(cfb, options) {	var _opts = options || {};	var out = [], cdirs = [];	var o = new_buf(1);	var method = (_opts.compression ? 8 : 0), flags = 0;	var desc = false;	if(desc) flags |= 8;	var i = 0, j = 0;	var start_cd = 0, fcnt = 0;	var root = cfb.FullPaths[0], fp = root, fi = cfb.FileIndex[0];	var crcs = [];	var sz_cd = 0;	for(i = 1; i < cfb.FullPaths.length; ++i) {		fp = cfb.FullPaths[i].slice(root.length); fi = cfb.FileIndex[i];		if(!fi.size || !fi.content || fp == "\u0001Sh33tJ5") continue;		var start = start_cd;		/* TODO: CP437 filename */		var namebuf = new_buf(fp.length);		for(j = 0; j < fp.length; ++j) namebuf.write_shift(1, fp.charCodeAt(j) & 0x7F);		namebuf = namebuf.slice(0, namebuf.l);		crcs[fcnt] = CRC32.buf(fi.content, 0);		var outbuf = fi.content;		if(method == 8) outbuf = _deflateRawSync(outbuf);		/* local file header */		o = new_buf(30);		o.write_shift(4, 0x04034b50);		o.write_shift(2, 20);		o.write_shift(2, flags);		o.write_shift(2, method);		/* TODO: last mod file time/date */		if(fi.mt) write_dos_date(o, fi.mt);		else o.write_shift(4, 0);		o.write_shift(-4, (flags & 8) ? 0 : crcs[fcnt]);		o.write_shift(4,  (flags & 8) ? 0 : outbuf.length);		o.write_shift(4,  (flags & 8) ? 0 : fi.content.length);		o.write_shift(2, namebuf.length);		o.write_shift(2, 0);		start_cd += o.length;		out.push(o);		start_cd += namebuf.length;		out.push(namebuf);		/* TODO: encryption header ? */		start_cd += outbuf.length;		out.push(outbuf);		/* data descriptor */		if(flags & 8) {			o = new_buf(12);			o.write_shift(-4, crcs[fcnt]);			o.write_shift(4, outbuf.length);			o.write_shift(4, fi.content.length);			start_cd += o.l;			out.push(o);		}		/* central directory */		o = new_buf(46);		o.write_shift(4, 0x02014b50);		o.write_shift(2, 0);		o.write_shift(2, 20);		o.write_shift(2, flags);		o.write_shift(2, method);		o.write_shift(4, 0); /* TODO: last mod file time/date */		o.write_shift(-4, crcs[fcnt]);		o.write_shift(4, outbuf.length);		o.write_shift(4, fi.content.length);		o.write_shift(2, namebuf.length);		o.write_shift(2, 0);		o.write_shift(2, 0);		o.write_shift(2, 0);		o.write_shift(2, 0);		o.write_shift(4, 0);		o.write_shift(4, start);		sz_cd += o.l;		cdirs.push(o);		sz_cd += namebuf.length;		cdirs.push(namebuf);		++fcnt;	}	/* end of central directory */	o = new_buf(22);	o.write_shift(4, 0x06054b50);	o.write_shift(2, 0);	o.write_shift(2, 0);	o.write_shift(2, fcnt);	o.write_shift(2, fcnt);	o.write_shift(4, sz_cd);	o.write_shift(4, start_cd);	o.write_shift(2, 0);	return bconcat(([bconcat((out)), bconcat(cdirs), o]));}function cfb_new(opts) {	var o = ({});	init_cfb(o, opts);	return o;}function cfb_add(cfb, name, content, opts) {	var unsafe = opts && opts.unsafe;	if(!unsafe) init_cfb(cfb);	var file = !unsafe && CFB.find(cfb, name);	if(!file) {		var fpath = cfb.FullPaths[0];		if(name.slice(0, fpath.length) == fpath) fpath = name;		else {			if(fpath.slice(-1) != "/") fpath += "/";			fpath = (fpath + name).replace("//","/");		}		file = ({name: filename(name), type: 2});		cfb.FileIndex.push(file);		cfb.FullPaths.push(fpath);		if(!unsafe) CFB.utils.cfb_gc(cfb);	}file.content = (content);	file.size = content ? content.length : 0;	if(opts) {		if(opts.CLSID) file.clsid = opts.CLSID;		if(opts.mt) file.mt = opts.mt;		if(opts.ct) file.ct = opts.ct;	}	return file;}function cfb_del(cfb, name) {	init_cfb(cfb);	var file = CFB.find(cfb, name);	if(file) for(var j = 0; j < cfb.FileIndex.length; ++j) if(cfb.FileIndex[j] == file) {		cfb.FileIndex.splice(j, 1);		cfb.FullPaths.splice(j, 1);		return true;	}	return false;}function cfb_mov(cfb, old_name, new_name) {	init_cfb(cfb);	var file = CFB.find(cfb, old_name);	if(file) for(var j = 0; j < cfb.FileIndex.length; ++j) if(cfb.FileIndex[j] == file) {		cfb.FileIndex[j].name = filename(new_name);		cfb.FullPaths[j] = new_name;		return true;	}	return false;}function cfb_gc(cfb) { rebuild_cfb(cfb, true); }exports.find = find;exports.read = read;exports.parse = parse;exports.write = write;exports.writeFile = write_file;exports.utils = {	cfb_new: cfb_new,	cfb_add: cfb_add,	cfb_del: cfb_del,	cfb_mov: cfb_mov,	cfb_gc: cfb_gc,	ReadShift: ReadShift,	CheckField: CheckField,	prep_blob: prep_blob,	bconcat: bconcat,	use_zlib: use_zlib,	_deflateRaw: _deflate,	_inflateRaw: _inflate,	consts: consts};return exports;})();if(typeof require !== 'undefined' && typeof module !== 'undefined' && typeof DO_NOT_EXPORT_CFB === 'undefined') { module.exports = CFB; }}).call(this,require('_process'),require("buffer").Buffer)},{"_process":226,"buffer":79,"fs":47}],81:[function(require,module,exports){var Buffer = require('safe-buffer').Buffervar Transform = require('stream').Transformvar StringDecoder = require('string_decoder').StringDecodervar inherits = require('inherits')function CipherBase (hashMode) {  Transform.call(this)  this.hashMode = typeof hashMode === 'string'  if (this.hashMode) {    this[hashMode] = this._finalOrDigest  } else {    this.final = this._finalOrDigest  }  if (this._final) {    this.__final = this._final    this._final = null  }  this._decoder = null  this._encoding = null}inherits(CipherBase, Transform)CipherBase.prototype.update = function (data, inputEnc, outputEnc) {  if (typeof data === 'string') {    data = Buffer.from(data, inputEnc)  }  var outData = this._update(data)  if (this.hashMode) return this  if (outputEnc) {    outData = this._toString(outData, outputEnc)  }  return outData}CipherBase.prototype.setAutoPadding = function () {}CipherBase.prototype.getAuthTag = function () {  throw new Error('trying to get auth tag in unsupported state')}CipherBase.prototype.setAuthTag = function () {  throw new Error('trying to set auth tag in unsupported state')}CipherBase.prototype.setAAD = function () {  throw new Error('trying to set aad in unsupported state')}CipherBase.prototype._transform = function (data, _, next) {  var err  try {    if (this.hashMode) {      this._update(data)    } else {      this.push(this._update(data))    }  } catch (e) {    err = e  } finally {    next(err)  }}CipherBase.prototype._flush = function (done) {  var err  try {    this.push(this.__final())  } catch (e) {    err = e  }  done(err)}CipherBase.prototype._finalOrDigest = function (outputEnc) {  var outData = this.__final() || Buffer.alloc(0)  if (outputEnc) {    outData = this._toString(outData, outputEnc, true)  }  return outData}CipherBase.prototype._toString = function (value, enc, fin) {  if (!this._decoder) {    this._decoder = new StringDecoder(enc)    this._encoding = enc  }  if (this._encoding !== enc) throw new Error('can\'t switch encodings')  var out = this._decoder.write(value)  if (fin) {    out += this._decoder.end()  }  return out}module.exports = CipherBase},{"inherits":154,"safe-buffer":247,"stream":257,"string_decoder":77}],82:[function(require,module,exports){require('../modules/web.immediate');module.exports = require('../modules/_core').setImmediate;},{"../modules/_core":86,"../modules/web.immediate":102}],83:[function(require,module,exports){module.exports = function(it){  if(typeof it != 'function')throw TypeError(it + ' is not a function!');  return it;};},{}],84:[function(require,module,exports){var isObject = require('./_is-object');module.exports = function(it){  if(!isObject(it))throw TypeError(it + ' is not an object!');  return it;};},{"./_is-object":97}],85:[function(require,module,exports){var toString = {}.toString;module.exports = function(it){  return toString.call(it).slice(8, -1);};},{}],86:[function(require,module,exports){var core = module.exports = {version: '2.3.0'};if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef},{}],87:[function(require,module,exports){// optional / simple context bindingvar aFunction = require('./_a-function');module.exports = function(fn, that, length){  aFunction(fn);  if(that === undefined)return fn;  switch(length){    case 1: return function(a){      return fn.call(that, a);    };    case 2: return function(a, b){      return fn.call(that, a, b);    };    case 3: return function(a, b, c){      return fn.call(that, a, b, c);    };  }  return function(/* ...args */){    return fn.apply(that, arguments);  };};},{"./_a-function":83}],88:[function(require,module,exports){// Thank's IE8 for his funny definePropertymodule.exports = !require('./_fails')(function(){  return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7;});},{"./_fails":91}],89:[function(require,module,exports){var isObject = require('./_is-object')  , document = require('./_global').document  // in old IE typeof document.createElement is 'object'  , is = isObject(document) && isObject(document.createElement);module.exports = function(it){  return is ? document.createElement(it) : {};};},{"./_global":92,"./_is-object":97}],90:[function(require,module,exports){var global    = require('./_global')  , core      = require('./_core')  , ctx       = require('./_ctx')  , hide      = require('./_hide')  , PROTOTYPE = 'prototype';var $export = function(type, name, source){  var IS_FORCED = type & $export.F    , IS_GLOBAL = type & $export.G    , IS_STATIC = type & $export.S    , IS_PROTO  = type & $export.P    , IS_BIND   = type & $export.B    , IS_WRAP   = type & $export.W    , exports   = IS_GLOBAL ? core : core[name] || (core[name] = {})    , expProto  = exports[PROTOTYPE]    , target    = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]    , key, own, out;  if(IS_GLOBAL)source = name;  for(key in source){    // contains in native    own = !IS_FORCED && target && target[key] !== undefined;    if(own && key in exports)continue;    // export native or passed    out = own ? target[key] : source[key];    // prevent global pollution for namespaces    exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key]    // bind timers to global for call from export context    : IS_BIND && own ? ctx(out, global)    // wrap global constructors for prevent change them in library    : IS_WRAP && target[key] == out ? (function(C){      var F = function(a, b, c){        if(this instanceof C){          switch(arguments.length){            case 0: return new C;            case 1: return new C(a);            case 2: return new C(a, b);          } return new C(a, b, c);        } return C.apply(this, arguments);      };      F[PROTOTYPE] = C[PROTOTYPE];      return F;    // make static versions for prototype methods    })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;    // export proto methods to core.%CONSTRUCTOR%.methods.%NAME%    if(IS_PROTO){      (exports.virtual || (exports.virtual = {}))[key] = out;      // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME%      if(type & $export.R && expProto && !expProto[key])hide(expProto, key, out);    }  }};// type bitmap$export.F = 1;   // forced$export.G = 2;   // global$export.S = 4;   // static$export.P = 8;   // proto$export.B = 16;  // bind$export.W = 32;  // wrap$export.U = 64;  // safe$export.R = 128; // real proto method for `library` module.exports = $export;},{"./_core":86,"./_ctx":87,"./_global":92,"./_hide":93}],91:[function(require,module,exports){module.exports = function(exec){  try {    return !!exec();  } catch(e){    return true;  }};},{}],92:[function(require,module,exports){// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028var global = module.exports = typeof window != 'undefined' && window.Math == Math  ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef},{}],93:[function(require,module,exports){var dP         = require('./_object-dp')  , createDesc = require('./_property-desc');module.exports = require('./_descriptors') ? function(object, key, value){  return dP.f(object, key, createDesc(1, value));} : function(object, key, value){  object[key] = value;  return object;};},{"./_descriptors":88,"./_object-dp":98,"./_property-desc":99}],94:[function(require,module,exports){module.exports = require('./_global').document && document.documentElement;},{"./_global":92}],95:[function(require,module,exports){module.exports = !require('./_descriptors') && !require('./_fails')(function(){  return Object.defineProperty(require('./_dom-create')('div'), 'a', {get: function(){ return 7; }}).a != 7;});},{"./_descriptors":88,"./_dom-create":89,"./_fails":91}],96:[function(require,module,exports){// fast apply, http://jsperf.lnkit.com/fast-apply/5module.exports = function(fn, args, that){  var un = that === undefined;  switch(args.length){    case 0: return un ? fn()                      : fn.call(that);    case 1: return un ? fn(args[0])                      : fn.call(that, args[0]);    case 2: return un ? fn(args[0], args[1])                      : fn.call(that, args[0], args[1]);    case 3: return un ? fn(args[0], args[1], args[2])                      : fn.call(that, args[0], args[1], args[2]);    case 4: return un ? fn(args[0], args[1], args[2], args[3])                      : fn.call(that, args[0], args[1], args[2], args[3]);  } return              fn.apply(that, args);};},{}],97:[function(require,module,exports){module.exports = function(it){  return typeof it === 'object' ? it !== null : typeof it === 'function';};},{}],98:[function(require,module,exports){var anObject       = require('./_an-object')  , IE8_DOM_DEFINE = require('./_ie8-dom-define')  , toPrimitive    = require('./_to-primitive')  , dP             = Object.defineProperty;exports.f = require('./_descriptors') ? Object.defineProperty : function defineProperty(O, P, Attributes){  anObject(O);  P = toPrimitive(P, true);  anObject(Attributes);  if(IE8_DOM_DEFINE)try {    return dP(O, P, Attributes);  } catch(e){ /* empty */ }  if('get' in Attributes || 'set' in Attributes)throw TypeError('Accessors not supported!');  if('value' in Attributes)O[P] = Attributes.value;  return O;};},{"./_an-object":84,"./_descriptors":88,"./_ie8-dom-define":95,"./_to-primitive":101}],99:[function(require,module,exports){module.exports = function(bitmap, value){  return {    enumerable  : !(bitmap & 1),    configurable: !(bitmap & 2),    writable    : !(bitmap & 4),    value       : value  };};},{}],100:[function(require,module,exports){var ctx                = require('./_ctx')  , invoke             = require('./_invoke')  , html               = require('./_html')  , cel                = require('./_dom-create')  , global             = require('./_global')  , process            = global.process  , setTask            = global.setImmediate  , clearTask          = global.clearImmediate  , MessageChannel     = global.MessageChannel  , counter            = 0  , queue              = {}  , ONREADYSTATECHANGE = 'onreadystatechange'  , defer, channel, port;var run = function(){  var id = +this;  if(queue.hasOwnProperty(id)){    var fn = queue[id];    delete queue[id];    fn();  }};var listener = function(event){  run.call(event.data);};// Node.js 0.9+ & IE10+ has setImmediate, otherwise:if(!setTask || !clearTask){  setTask = function setImmediate(fn){    var args = [], i = 1;    while(arguments.length > i)args.push(arguments[i++]);    queue[++counter] = function(){      invoke(typeof fn == 'function' ? fn : Function(fn), args);    };    defer(counter);    return counter;  };  clearTask = function clearImmediate(id){    delete queue[id];  };  // Node.js 0.8-  if(require('./_cof')(process) == 'process'){    defer = function(id){      process.nextTick(ctx(run, id, 1));    };  // Browsers with MessageChannel, includes WebWorkers  } else if(MessageChannel){    channel = new MessageChannel;    port    = channel.port2;    channel.port1.onmessage = listener;    defer = ctx(port.postMessage, port, 1);  // Browsers with postMessage, skip WebWorkers  // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'  } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){    defer = function(id){      global.postMessage(id + '', '*');    };    global.addEventListener('message', listener, false);  // IE8-  } else if(ONREADYSTATECHANGE in cel('script')){    defer = function(id){      html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){        html.removeChild(this);        run.call(id);      };    };  // Rest old browsers  } else {    defer = function(id){      setTimeout(ctx(run, id, 1), 0);    };  }}module.exports = {  set:   setTask,  clear: clearTask};},{"./_cof":85,"./_ctx":87,"./_dom-create":89,"./_global":92,"./_html":94,"./_invoke":96}],101:[function(require,module,exports){// 7.1.1 ToPrimitive(input [, PreferredType])var isObject = require('./_is-object');// instead of the ES6 spec version, we didn't implement @@toPrimitive case// and the second argument - flag - preferred type is a stringmodule.exports = function(it, S){  if(!isObject(it))return it;  var fn, val;  if(S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;  if(typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it)))return val;  if(!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it)))return val;  throw TypeError("Can't convert object to primitive value");};},{"./_is-object":97}],102:[function(require,module,exports){var $export = require('./_export')  , $task   = require('./_task');$export($export.G + $export.B, {  setImmediate:   $task.set,  clearImmediate: $task.clear});},{"./_export":90,"./_task":100}],103:[function(require,module,exports){(function (Buffer){// Copyright Joyent, Inc. and other Node contributors.//// Permission is hereby granted, free of charge, to any person obtaining a// copy of this software and associated documentation files (the// "Software"), to deal in the Software without restriction, including// without limitation the rights to use, copy, modify, merge, publish,// distribute, sublicense, and/or sell copies of the Software, and to permit// persons to whom the Software is furnished to do so, subject to the// following conditions://// The above copyright notice and this permission notice shall be included// in all copies or substantial portions of the Software.//// THE SOFTWARE IS 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. IN// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE// USE OR OTHER DEALINGS IN THE SOFTWARE.// NOTE: These type checking functions intentionally don't use `instanceof`// because it is fragile and can be easily faked with `Object.create()`.function isArray(arg) {  if (Array.isArray) {    return Array.isArray(arg);  }  return objectToString(arg) === '[object Array]';}exports.isArray = isArray;function isBoolean(arg) {  return typeof arg === 'boolean';}exports.isBoolean = isBoolean;function isNull(arg) {  return arg === null;}exports.isNull = isNull;function isNullOrUndefined(arg) {  return arg == null;}exports.isNullOrUndefined = isNullOrUndefined;function isNumber(arg) {  return typeof arg === 'number';}exports.isNumber = isNumber;function isString(arg) {  return typeof arg === 'string';}exports.isString = isString;function isSymbol(arg) {  return typeof arg === 'symbol';}exports.isSymbol = isSymbol;function isUndefined(arg) {  return arg === void 0;}exports.isUndefined = isUndefined;function isRegExp(re) {  return objectToString(re) === '[object RegExp]';}exports.isRegExp = isRegExp;function isObject(arg) {  return typeof arg === 'object' && arg !== null;}exports.isObject = isObject;function isDate(d) {  return objectToString(d) === '[object Date]';}exports.isDate = isDate;function isError(e) {  return (objectToString(e) === '[object Error]' || e instanceof Error);}exports.isError = isError;function isFunction(arg) {  return typeof arg === 'function';}exports.isFunction = isFunction;function isPrimitive(arg) {  return arg === null ||         typeof arg === 'boolean' ||         typeof arg === 'number' ||         typeof arg === 'string' ||         typeof arg === 'symbol' ||  // ES6 symbol         typeof arg === 'undefined';}exports.isPrimitive = isPrimitive;exports.isBuffer = Buffer.isBuffer;function objectToString(o) {  return Object.prototype.toString.call(o);}}).call(this,{"isBuffer":require("../../is-buffer/index.js")})},{"../../is-buffer/index.js":155}],104:[function(require,module,exports){(function (Buffer){var elliptic = require('elliptic')var BN = require('bn.js')module.exports = function createECDH (curve) {  return new ECDH(curve)}var aliases = {  secp256k1: {    name: 'secp256k1',    byteLength: 32  },  secp224r1: {    name: 'p224',    byteLength: 28  },  prime256v1: {    name: 'p256',    byteLength: 32  },  prime192v1: {    name: 'p192',    byteLength: 24  },  ed25519: {    name: 'ed25519',    byteLength: 32  },  secp384r1: {    name: 'p384',    byteLength: 48  },  secp521r1: {    name: 'p521',    byteLength: 66  }}aliases.p224 = aliases.secp224r1aliases.p256 = aliases.secp256r1 = aliases.prime256v1aliases.p192 = aliases.secp192r1 = aliases.prime192v1aliases.p384 = aliases.secp384r1aliases.p521 = aliases.secp521r1function ECDH (curve) {  this.curveType = aliases[curve]  if (!this.curveType) {    this.curveType = {      name: curve    }  }  this.curve = new elliptic.ec(this.curveType.name) // eslint-disable-line new-cap  this.keys = void 0}ECDH.prototype.generateKeys = function (enc, format) {  this.keys = this.curve.genKeyPair()  return this.getPublicKey(enc, format)}ECDH.prototype.computeSecret = function (other, inenc, enc) {  inenc = inenc || 'utf8'  if (!Buffer.isBuffer(other)) {    other = new Buffer(other, inenc)  }  var otherPub = this.curve.keyFromPublic(other).getPublic()  var out = otherPub.mul(this.keys.getPrivate()).getX()  return formatReturnValue(out, enc, this.curveType.byteLength)}ECDH.prototype.getPublicKey = function (enc, format) {  var key = this.keys.getPublic(format === 'compressed', true)  if (format === 'hybrid') {    if (key[key.length - 1] % 2) {      key[0] = 7    } else {      key[0] = 6    }  }  return formatReturnValue(key, enc)}ECDH.prototype.getPrivateKey = function (enc) {  return formatReturnValue(this.keys.getPrivate(), enc)}ECDH.prototype.setPublicKey = function (pub, enc) {  enc = enc || 'utf8'  if (!Buffer.isBuffer(pub)) {    pub = new Buffer(pub, enc)  }  this.keys._importPublic(pub)  return this}ECDH.prototype.setPrivateKey = function (priv, enc) {  enc = enc || 'utf8'  if (!Buffer.isBuffer(priv)) {    priv = new Buffer(priv, enc)  }  var _priv = new BN(priv)  _priv = _priv.toString(16)  this.keys = this.curve.genKeyPair()  this.keys._importPrivate(_priv)  return this}function formatReturnValue (bn, enc, len) {  if (!Array.isArray(bn)) {    bn = bn.toArray()  }  var buf = new Buffer(bn)  if (len && buf.length < len) {    var zeros = new Buffer(len - buf.length)    zeros.fill(0)    buf = Buffer.concat([zeros, buf])  }  if (!enc) {    return buf  } else {    return buf.toString(enc)  }}}).call(this,require("buffer").Buffer)},{"bn.js":45,"buffer":79,"elliptic":120}],105:[function(require,module,exports){'use strict'var inherits = require('inherits')var MD5 = require('md5.js')var RIPEMD160 = require('ripemd160')var sha = require('sha.js')var Base = require('cipher-base')function Hash (hash) {  Base.call(this, 'digest')  this._hash = hash}inherits(Hash, Base)Hash.prototype._update = function (data) {  this._hash.update(data)}Hash.prototype._final = function () {  return this._hash.digest()}module.exports = function createHash (alg) {  alg = alg.toLowerCase()  if (alg === 'md5') return new MD5()  if (alg === 'rmd160' || alg === 'ripemd160') return new RIPEMD160()  return new Hash(sha(alg))}},{"cipher-base":81,"inherits":154,"md5.js":194,"ripemd160":246,"sha.js":250}],106:[function(require,module,exports){var MD5 = require('md5.js')module.exports = function (buffer) {  return new MD5().update(buffer).digest()}},{"md5.js":194}],107:[function(require,module,exports){'use strict'var inherits = require('inherits')var Legacy = require('./legacy')var Base = require('cipher-base')var Buffer = require('safe-buffer').Buffervar md5 = require('create-hash/md5')var RIPEMD160 = require('ripemd160')var sha = require('sha.js')var ZEROS = Buffer.alloc(128)function Hmac (alg, key) {  Base.call(this, 'digest')  if (typeof key === 'string') {    key = Buffer.from(key)  }  var blocksize = (alg === 'sha512' || alg === 'sha384') ? 128 : 64  this._alg = alg  this._key = key  if (key.length > blocksize) {    var hash = alg === 'rmd160' ? new RIPEMD160() : sha(alg)    key = hash.update(key).digest()  } else if (key.length < blocksize) {    key = Buffer.concat([key, ZEROS], blocksize)  }  var ipad = this._ipad = Buffer.allocUnsafe(blocksize)  var opad = this._opad = Buffer.allocUnsafe(blocksize)  for (var i = 0; i < blocksize; i++) {    ipad[i] = key[i] ^ 0x36    opad[i] = key[i] ^ 0x5C  }  this._hash = alg === 'rmd160' ? new RIPEMD160() : sha(alg)  this._hash.update(ipad)}inherits(Hmac, Base)Hmac.prototype._update = function (data) {  this._hash.update(data)}Hmac.prototype._final = function () {  var h = this._hash.digest()  var hash = this._alg === 'rmd160' ? new RIPEMD160() : sha(this._alg)  return hash.update(this._opad).update(h).digest()}module.exports = function createHmac (alg, key) {  alg = alg.toLowerCase()  if (alg === 'rmd160' || alg === 'ripemd160') {    return new Hmac('rmd160', key)  }  if (alg === 'md5') {    return new Legacy(md5, key)  }  return new Hmac(alg, key)}},{"./legacy":108,"cipher-base":81,"create-hash/md5":106,"inherits":154,"ripemd160":246,"safe-buffer":247,"sha.js":250}],108:[function(require,module,exports){'use strict'var inherits = require('inherits')var Buffer = require('safe-buffer').Buffervar Base = require('cipher-base')var ZEROS = Buffer.alloc(128)var blocksize = 64function Hmac (alg, key) {  Base.call(this, 'digest')  if (typeof key === 'string') {    key = Buffer.from(key)  }  this._alg = alg  this._key = key  if (key.length > blocksize) {    key = alg(key)  } else if (key.length < blocksize) {    key = Buffer.concat([key, ZEROS], blocksize)  }  var ipad = this._ipad = Buffer.allocUnsafe(blocksize)  var opad = this._opad = Buffer.allocUnsafe(blocksize)  for (var i = 0; i < blocksize; i++) {    ipad[i] = key[i] ^ 0x36    opad[i] = key[i] ^ 0x5C  }  this._hash = [ipad]}inherits(Hmac, Base)Hmac.prototype._update = function (data) {  this._hash.push(data)}Hmac.prototype._final = function () {  var h = this._alg(Buffer.concat(this._hash))  return this._alg(Buffer.concat([this._opad, h]))}module.exports = Hmac},{"cipher-base":81,"inherits":154,"safe-buffer":247}],109:[function(require,module,exports){'use strict'exports.randomBytes = exports.rng = exports.pseudoRandomBytes = exports.prng = require('randombytes')exports.createHash = exports.Hash = require('create-hash')exports.createHmac = exports.Hmac = require('create-hmac')var algos = require('browserify-sign/algos')var algoKeys = Object.keys(algos)var hashes = ['sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'md5', 'rmd160'].concat(algoKeys)exports.getHashes = function () {  return hashes}var p = require('pbkdf2')exports.pbkdf2 = p.pbkdf2exports.pbkdf2Sync = p.pbkdf2Syncvar aes = require('browserify-cipher')exports.Cipher = aes.Cipherexports.createCipher = aes.createCipherexports.Cipheriv = aes.Cipherivexports.createCipheriv = aes.createCipherivexports.Decipher = aes.Decipherexports.createDecipher = aes.createDecipherexports.Decipheriv = aes.Decipherivexports.createDecipheriv = aes.createDecipherivexports.getCiphers = aes.getCiphersexports.listCiphers = aes.listCiphersvar dh = require('diffie-hellman')exports.DiffieHellmanGroup = dh.DiffieHellmanGroupexports.createDiffieHellmanGroup = dh.createDiffieHellmanGroupexports.getDiffieHellman = dh.getDiffieHellmanexports.createDiffieHellman = dh.createDiffieHellmanexports.DiffieHellman = dh.DiffieHellmanvar sign = require('browserify-sign')exports.createSign = sign.createSignexports.Sign = sign.Signexports.createVerify = sign.createVerifyexports.Verify = sign.Verifyexports.createECDH = require('create-ecdh')var publicEncrypt = require('public-encrypt')exports.publicEncrypt = publicEncrypt.publicEncryptexports.privateEncrypt = publicEncrypt.privateEncryptexports.publicDecrypt = publicEncrypt.publicDecryptexports.privateDecrypt = publicEncrypt.privateDecrypt// the least I can do is make error messages for the rest of the node.js/crypto api.// ;[//   'createCredentials'// ].forEach(function (name) {//   exports[name] = function () {//     throw new Error([//       'sorry, ' + name + ' is not implemented yet',//       'we accept pull requests',//       'https://github.com/crypto-browserify/crypto-browserify'//     ].join('\n'))//   }// })var rf = require('randomfill')exports.randomFill = rf.randomFillexports.randomFillSync = rf.randomFillSyncexports.createCredentials = function () {  throw new Error([    'sorry, createCredentials is not implemented yet',    'we accept pull requests',    'https://github.com/crypto-browserify/crypto-browserify'  ].join('\n'))}exports.constants = {  'DH_CHECK_P_NOT_SAFE_PRIME': 2,  'DH_CHECK_P_NOT_PRIME': 1,  'DH_UNABLE_TO_CHECK_GENERATOR': 4,  'DH_NOT_SUITABLE_GENERATOR': 8,  'NPN_ENABLED': 1,  'ALPN_ENABLED': 1,  'RSA_PKCS1_PADDING': 1,  'RSA_SSLV23_PADDING': 2,  'RSA_NO_PADDING': 3,  'RSA_PKCS1_OAEP_PADDING': 4,  'RSA_X931_PADDING': 5,  'RSA_PKCS1_PSS_PADDING': 6,  'POINT_CONVERSION_COMPRESSED': 2,  'POINT_CONVERSION_UNCOMPRESSED': 4,  'POINT_CONVERSION_HYBRID': 6}},{"browserify-cipher":65,"browserify-sign":73,"browserify-sign/algos":70,"create-ecdh":104,"create-hash":105,"create-hmac":107,"diffie-hellman":116,"pbkdf2":220,"public-encrypt":227,"randombytes":234,"randomfill":235}],110:[function(require,module,exports){'use strict';exports.utils = require('./des/utils');exports.Cipher = require('./des/cipher');exports.DES = require('./des/des');exports.CBC = require('./des/cbc');exports.EDE = require('./des/ede');},{"./des/cbc":111,"./des/cipher":112,"./des/des":113,"./des/ede":114,"./des/utils":115}],111:[function(require,module,exports){'use strict';var assert = require('minimalistic-assert');var inherits = require('inherits');var proto = {};function CBCState(iv) {  assert.equal(iv.length, 8, 'Invalid IV length');  this.iv = new Array(8);  for (var i = 0; i < this.iv.length; i++)    this.iv[i] = iv[i];}function instantiate(Base) {  function CBC(options) {    Base.call(this, options);    this._cbcInit();  }  inherits(CBC, Base);  var keys = Object.keys(proto);  for (var i = 0; i < keys.length; i++) {    var key = keys[i];    CBC.prototype[key] = proto[key];  }  CBC.create = function create(options) {    return new CBC(options);  };  return CBC;}exports.instantiate = instantiate;proto._cbcInit = function _cbcInit() {  var state = new CBCState(this.options.iv);  this._cbcState = state;};proto._update = function _update(inp, inOff, out, outOff) {  var state = this._cbcState;  var superProto = this.constructor.super_.prototype;  var iv = state.iv;  if (this.type === 'encrypt') {    for (var i = 0; i < this.blockSize; i++)      iv[i] ^= inp[inOff + i];    superProto._update.call(this, iv, 0, out, outOff);    for (var i = 0; i < this.blockSize; i++)      iv[i] = out[outOff + i];  } else {    superProto._update.call(this, inp, inOff, out, outOff);    for (var i = 0; i < this.blockSize; i++)      out[outOff + i] ^= iv[i];    for (var i = 0; i < this.blockSize; i++)      iv[i] = inp[inOff + i];  }};},{"inherits":154,"minimalistic-assert":197}],112:[function(require,module,exports){'use strict';var assert = require('minimalistic-assert');function Cipher(options) {  this.options = options;  this.type = this.options.type;  this.blockSize = 8;  this._init();  this.buffer = new Array(this.blockSize);  this.bufferOff = 0;}module.exports = Cipher;Cipher.prototype._init = function _init() {  // Might be overrided};Cipher.prototype.update = function update(data) {  if (data.length === 0)    return [];  if (this.type === 'decrypt')    return this._updateDecrypt(data);  else    return this._updateEncrypt(data);};Cipher.prototype._buffer = function _buffer(data, off) {  // Append data to buffer  var min = Math.min(this.buffer.length - this.bufferOff, data.length - off);  for (var i = 0; i < min; i++)    this.buffer[this.bufferOff + i] = data[off + i];  this.bufferOff += min;  // Shift next  return min;};Cipher.prototype._flushBuffer = function _flushBuffer(out, off) {  this._update(this.buffer, 0, out, off);  this.bufferOff = 0;  return this.blockSize;};Cipher.prototype._updateEncrypt = function _updateEncrypt(data) {  var inputOff = 0;  var outputOff = 0;  var count = ((this.bufferOff + data.length) / this.blockSize) | 0;  var out = new Array(count * this.blockSize);  if (this.bufferOff !== 0) {    inputOff += this._buffer(data, inputOff);    if (this.bufferOff === this.buffer.length)      outputOff += this._flushBuffer(out, outputOff);  }  // Write blocks  var max = data.length - ((data.length - inputOff) % this.blockSize);  for (; inputOff < max; inputOff += this.blockSize) {    this._update(data, inputOff, out, outputOff);    outputOff += this.blockSize;  }  // Queue rest  for (; inputOff < data.length; inputOff++, this.bufferOff++)    this.buffer[this.bufferOff] = data[inputOff];  return out;};Cipher.prototype._updateDecrypt = function _updateDecrypt(data) {  var inputOff = 0;  var outputOff = 0;  var count = Math.ceil((this.bufferOff + data.length) / this.blockSize) - 1;  var out = new Array(count * this.blockSize);  // TODO(indutny): optimize it, this is far from optimal  for (; count > 0; count--) {    inputOff += this._buffer(data, inputOff);    outputOff += this._flushBuffer(out, outputOff);  }  // Buffer rest of the input  inputOff += this._buffer(data, inputOff);  return out;};Cipher.prototype.final = function final(buffer) {  var first;  if (buffer)    first = this.update(buffer);  var last;  if (this.type === 'encrypt')    last = this._finalEncrypt();  else    last = this._finalDecrypt();  if (first)    return first.concat(last);  else    return last;};Cipher.prototype._pad = function _pad(buffer, off) {  if (off === 0)    return false;  while (off < buffer.length)    buffer[off++] = 0;  return true;};Cipher.prototype._finalEncrypt = function _finalEncrypt() {  if (!this._pad(this.buffer, this.bufferOff))    return [];  var out = new Array(this.blockSize);  this._update(this.buffer, 0, out, 0);  return out;};Cipher.prototype._unpad = function _unpad(buffer) {  return buffer;};Cipher.prototype._finalDecrypt = function _finalDecrypt() {  assert.equal(this.bufferOff, this.blockSize, 'Not enough data to decrypt');  var out = new Array(this.blockSize);  this._flushBuffer(out, 0);  return this._unpad(out);};},{"minimalistic-assert":197}],113:[function(require,module,exports){'use strict';var assert = require('minimalistic-assert');var inherits = require('inherits');var des = require('../des');var utils = des.utils;var Cipher = des.Cipher;function DESState() {  this.tmp = new Array(2);  this.keys = null;}function DES(options) {  Cipher.call(this, options);  var state = new DESState();  this._desState = state;  this.deriveKeys(state, options.key);}inherits(DES, Cipher);module.exports = DES;DES.create = function create(options) {  return new DES(options);};var shiftTable = [  1, 1, 2, 2, 2, 2, 2, 2,  1, 2, 2, 2, 2, 2, 2, 1];DES.prototype.deriveKeys = function deriveKeys(state, key) {  state.keys = new Array(16 * 2);  assert.equal(key.length, this.blockSize, 'Invalid key length');  var kL = utils.readUInt32BE(key, 0);  var kR = utils.readUInt32BE(key, 4);  utils.pc1(kL, kR, state.tmp, 0);  kL = state.tmp[0];  kR = state.tmp[1];  for (var i = 0; i < state.keys.length; i += 2) {    var shift = shiftTable[i >>> 1];    kL = utils.r28shl(kL, shift);    kR = utils.r28shl(kR, shift);    utils.pc2(kL, kR, state.keys, i);  }};DES.prototype._update = function _update(inp, inOff, out, outOff) {  var state = this._desState;  var l = utils.readUInt32BE(inp, inOff);  var r = utils.readUInt32BE(inp, inOff + 4);  // Initial Permutation  utils.ip(l, r, state.tmp, 0);  l = state.tmp[0];  r = state.tmp[1];  if (this.type === 'encrypt')    this._encrypt(state, l, r, state.tmp, 0);  else    this._decrypt(state, l, r, state.tmp, 0);  l = state.tmp[0];  r = state.tmp[1];  utils.writeUInt32BE(out, l, outOff);  utils.writeUInt32BE(out, r, outOff + 4);};DES.prototype._pad = function _pad(buffer, off) {  var value = buffer.length - off;  for (var i = off; i < buffer.length; i++)    buffer[i] = value;  return true;};DES.prototype._unpad = function _unpad(buffer) {  var pad = buffer[buffer.length - 1];  for (var i = buffer.length - pad; i < buffer.length; i++)    assert.equal(buffer[i], pad);  return buffer.slice(0, buffer.length - pad);};DES.prototype._encrypt = function _encrypt(state, lStart, rStart, out, off) {  var l = lStart;  var r = rStart;  // Apply f() x16 times  for (var i = 0; i < state.keys.length; i += 2) {    var keyL = state.keys[i];    var keyR = state.keys[i + 1];    // f(r, k)    utils.expand(r, state.tmp, 0);    keyL ^= state.tmp[0];    keyR ^= state.tmp[1];    var s = utils.substitute(keyL, keyR);    var f = utils.permute(s);    var t = r;    r = (l ^ f) >>> 0;    l = t;  }  // Reverse Initial Permutation  utils.rip(r, l, out, off);};DES.prototype._decrypt = function _decrypt(state, lStart, rStart, out, off) {  var l = rStart;  var r = lStart;  // Apply f() x16 times  for (var i = state.keys.length - 2; i >= 0; i -= 2) {    var keyL = state.keys[i];    var keyR = state.keys[i + 1];    // f(r, k)    utils.expand(l, state.tmp, 0);    keyL ^= state.tmp[0];    keyR ^= state.tmp[1];    var s = utils.substitute(keyL, keyR);    var f = utils.permute(s);    var t = l;    l = (r ^ f) >>> 0;    r = t;  }  // Reverse Initial Permutation  utils.rip(l, r, out, off);};},{"../des":110,"inherits":154,"minimalistic-assert":197}],114:[function(require,module,exports){'use strict';var assert = require('minimalistic-assert');var inherits = require('inherits');var des = require('../des');var Cipher = des.Cipher;var DES = des.DES;function EDEState(type, key) {  assert.equal(key.length, 24, 'Invalid key length');  var k1 = key.slice(0, 8);  var k2 = key.slice(8, 16);  var k3 = key.slice(16, 24);  if (type === 'encrypt') {    this.ciphers = [      DES.create({ type: 'encrypt', key: k1 }),      DES.create({ type: 'decrypt', key: k2 }),      DES.create({ type: 'encrypt', key: k3 })    ];  } else {    this.ciphers = [      DES.create({ type: 'decrypt', key: k3 }),      DES.create({ type: 'encrypt', key: k2 }),      DES.create({ type: 'decrypt', key: k1 })    ];  }}function EDE(options) {  Cipher.call(this, options);  var state = new EDEState(this.type, this.options.key);  this._edeState = state;}inherits(EDE, Cipher);module.exports = EDE;EDE.create = function create(options) {  return new EDE(options);};EDE.prototype._update = function _update(inp, inOff, out, outOff) {  var state = this._edeState;  state.ciphers[0]._update(inp, inOff, out, outOff);  state.ciphers[1]._update(out, outOff, out, outOff);  state.ciphers[2]._update(out, outOff, out, outOff);};EDE.prototype._pad = DES.prototype._pad;EDE.prototype._unpad = DES.prototype._unpad;},{"../des":110,"inherits":154,"minimalistic-assert":197}],115:[function(require,module,exports){'use strict';exports.readUInt32BE = function readUInt32BE(bytes, off) {  var res =  (bytes[0 + off] << 24) |             (bytes[1 + off] << 16) |             (bytes[2 + off] << 8) |             bytes[3 + off];  return res >>> 0;};exports.writeUInt32BE = function writeUInt32BE(bytes, value, off) {  bytes[0 + off] = value >>> 24;  bytes[1 + off] = (value >>> 16) & 0xff;  bytes[2 + off] = (value >>> 8) & 0xff;  bytes[3 + off] = value & 0xff;};exports.ip = function ip(inL, inR, out, off) {  var outL = 0;  var outR = 0;  for (var i = 6; i >= 0; i -= 2) {    for (var j = 0; j <= 24; j += 8) {      outL <<= 1;      outL |= (inR >>> (j + i)) & 1;    }    for (var j = 0; j <= 24; j += 8) {      outL <<= 1;      outL |= (inL >>> (j + i)) & 1;    }  }  for (var i = 6; i >= 0; i -= 2) {    for (var j = 1; j <= 25; j += 8) {      outR <<= 1;      outR |= (inR >>> (j + i)) & 1;    }    for (var j = 1; j <= 25; j += 8) {      outR <<= 1;      outR |= (inL >>> (j + i)) & 1;    }  }  out[off + 0] = outL >>> 0;  out[off + 1] = outR >>> 0;};exports.rip = function rip(inL, inR, out, off) {  var outL = 0;  var outR = 0;  for (var i = 0; i < 4; i++) {    for (var j = 24; j >= 0; j -= 8) {      outL <<= 1;      outL |= (inR >>> (j + i)) & 1;      outL <<= 1;      outL |= (inL >>> (j + i)) & 1;    }  }  for (var i = 4; i < 8; i++) {    for (var j = 24; j >= 0; j -= 8) {      outR <<= 1;      outR |= (inR >>> (j + i)) & 1;      outR <<= 1;      outR |= (inL >>> (j + i)) & 1;    }  }  out[off + 0] = outL >>> 0;  out[off + 1] = outR >>> 0;};exports.pc1 = function pc1(inL, inR, out, off) {  var outL = 0;  var outR = 0;  // 7, 15, 23, 31, 39, 47, 55, 63  // 6, 14, 22, 30, 39, 47, 55, 63  // 5, 13, 21, 29, 39, 47, 55, 63  // 4, 12, 20, 28  for (var i = 7; i >= 5; i--) {    for (var j = 0; j <= 24; j += 8) {      outL <<= 1;      outL |= (inR >> (j + i)) & 1;    }    for (var j = 0; j <= 24; j += 8) {      outL <<= 1;      outL |= (inL >> (j + i)) & 1;    }  }  for (var j = 0; j <= 24; j += 8) {    outL <<= 1;    outL |= (inR >> (j + i)) & 1;  }  // 1, 9, 17, 25, 33, 41, 49, 57  // 2, 10, 18, 26, 34, 42, 50, 58  // 3, 11, 19, 27, 35, 43, 51, 59  // 36, 44, 52, 60  for (var i = 1; i <= 3; i++) {    for (var j = 0; j <= 24; j += 8) {      outR <<= 1;      outR |= (inR >> (j + i)) & 1;    }    for (var j = 0; j <= 24; j += 8) {      outR <<= 1;      outR |= (inL >> (j + i)) & 1;    }  }  for (var j = 0; j <= 24; j += 8) {    outR <<= 1;    outR |= (inL >> (j + i)) & 1;  }  out[off + 0] = outL >>> 0;  out[off + 1] = outR >>> 0;};exports.r28shl = function r28shl(num, shift) {  return ((num << shift) & 0xfffffff) | (num >>> (28 - shift));};var pc2table = [  // inL => outL  14, 11, 17, 4, 27, 23, 25, 0,  13, 22, 7, 18, 5, 9, 16, 24,  2, 20, 12, 21, 1, 8, 15, 26,  // inR => outR  15, 4, 25, 19, 9, 1, 26, 16,  5, 11, 23, 8, 12, 7, 17, 0,  22, 3, 10, 14, 6, 20, 27, 24];exports.pc2 = function pc2(inL, inR, out, off) {  var outL = 0;  var outR = 0;  var len = pc2table.length >>> 1;  for (var i = 0; i < len; i++) {    outL <<= 1;    outL |= (inL >>> pc2table[i]) & 0x1;  }  for (var i = len; i < pc2table.length; i++) {    outR <<= 1;    outR |= (inR >>> pc2table[i]) & 0x1;  }  out[off + 0] = outL >>> 0;  out[off + 1] = outR >>> 0;};exports.expand = function expand(r, out, off) {  var outL = 0;  var outR = 0;  outL = ((r & 1) << 5) | (r >>> 27);  for (var i = 23; i >= 15; i -= 4) {    outL <<= 6;    outL |= (r >>> i) & 0x3f;  }  for (var i = 11; i >= 3; i -= 4) {    outR |= (r >>> i) & 0x3f;    outR <<= 6;  }  outR |= ((r & 0x1f) << 1) | (r >>> 31);  out[off + 0] = outL >>> 0;  out[off + 1] = outR >>> 0;};var sTable = [  14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1,  3, 10, 10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8,  4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7,  15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13,  15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14,  9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5,  0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2,  5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9,  10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10,  1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1,  13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7,  11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12,  7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3,  1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9,  10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8,  15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14,  2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1,  8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6,  4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13,  15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3,  12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5,  0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8,  9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10,  7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13,  4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10,  3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6,  1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7,  10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12,  13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4,  10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2,  7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13,  0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11];exports.substitute = function substitute(inL, inR) {  var out = 0;  for (var i = 0; i < 4; i++) {    var b = (inL >>> (18 - i * 6)) & 0x3f;    var sb = sTable[i * 0x40 + b];    out <<= 4;    out |= sb;  }  for (var i = 0; i < 4; i++) {    var b = (inR >>> (18 - i * 6)) & 0x3f;    var sb = sTable[4 * 0x40 + i * 0x40 + b];    out <<= 4;    out |= sb;  }  return out >>> 0;};var permuteTable = [  16, 25, 12, 11, 3, 20, 4, 15, 31, 17, 9, 6, 27, 14, 1, 22,  30, 24, 8, 18, 0, 5, 29, 23, 13, 19, 2, 26, 10, 21, 28, 7];exports.permute = function permute(num) {  var out = 0;  for (var i = 0; i < permuteTable.length; i++) {    out <<= 1;    out |= (num >>> permuteTable[i]) & 0x1;  }  return out >>> 0;};exports.padSplit = function padSplit(num, size, group) {  var str = num.toString(2);  while (str.length < size)    str = '0' + str;  var out = [];  for (var i = 0; i < size; i += group)    out.push(str.slice(i, i + group));  return out.join(' ');};},{}],116:[function(require,module,exports){(function (Buffer){var generatePrime = require('./lib/generatePrime')var primes = require('./lib/primes.json')var DH = require('./lib/dh')function getDiffieHellman (mod) {  var prime = new Buffer(primes[mod].prime, 'hex')  var gen = new Buffer(primes[mod].gen, 'hex')  return new DH(prime, gen)}var ENCODINGS = {  'binary': true, 'hex': true, 'base64': true}function createDiffieHellman (prime, enc, generator, genc) {  if (Buffer.isBuffer(enc) || ENCODINGS[enc] === undefined) {    return createDiffieHellman(prime, 'binary', enc, generator)  }  enc = enc || 'binary'  genc = genc || 'binary'  generator = generator || new Buffer([2])  if (!Buffer.isBuffer(generator)) {    generator = new Buffer(generator, genc)  }  if (typeof prime === 'number') {    return new DH(generatePrime(prime, generator), generator, true)  }  if (!Buffer.isBuffer(prime)) {    prime = new Buffer(prime, enc)  }  return new DH(prime, generator, true)}exports.DiffieHellmanGroup = exports.createDiffieHellmanGroup = exports.getDiffieHellman = getDiffieHellmanexports.createDiffieHellman = exports.DiffieHellman = createDiffieHellman}).call(this,require("buffer").Buffer)},{"./lib/dh":117,"./lib/generatePrime":118,"./lib/primes.json":119,"buffer":79}],117:[function(require,module,exports){(function (Buffer){var BN = require('bn.js');var MillerRabin = require('miller-rabin');var millerRabin = new MillerRabin();var TWENTYFOUR = new BN(24);var ELEVEN = new BN(11);var TEN = new BN(10);var THREE = new BN(3);var SEVEN = new BN(7);var primes = require('./generatePrime');var randomBytes = require('randombytes');module.exports = DH;function setPublicKey(pub, enc) {  enc = enc || 'utf8';  if (!Buffer.isBuffer(pub)) {    pub = new Buffer(pub, enc);  }  this._pub = new BN(pub);  return this;}function setPrivateKey(priv, enc) {  enc = enc || 'utf8';  if (!Buffer.isBuffer(priv)) {    priv = new Buffer(priv, enc);  }  this._priv = new BN(priv);  return this;}var primeCache = {};function checkPrime(prime, generator) {  var gen = generator.toString('hex');  var hex = [gen, prime.toString(16)].join('_');  if (hex in primeCache) {    return primeCache[hex];  }  var error = 0;  if (prime.isEven() ||    !primes.simpleSieve ||    !primes.fermatTest(prime) ||    !millerRabin.test(prime)) {    //not a prime so +1    error += 1;    if (gen === '02' || gen === '05') {      // we'd be able to check the generator      // it would fail so +8      error += 8;    } else {      //we wouldn't be able to test the generator      // so +4      error += 4;    }    primeCache[hex] = error;    return error;  }  if (!millerRabin.test(prime.shrn(1))) {    //not a safe prime    error += 2;  }  var rem;  switch (gen) {    case '02':      if (prime.mod(TWENTYFOUR).cmp(ELEVEN)) {        // unsuidable generator        error += 8;      }      break;    case '05':      rem = prime.mod(TEN);      if (rem.cmp(THREE) && rem.cmp(SEVEN)) {        // prime mod 10 needs to equal 3 or 7        error += 8;      }      break;    default:      error += 4;  }  primeCache[hex] = error;  return error;}function DH(prime, generator, malleable) {  this.setGenerator(generator);  this.__prime = new BN(prime);  this._prime = BN.mont(this.__prime);  this._primeLen = prime.length;  this._pub = undefined;  this._priv = undefined;  this._primeCode = undefined;  if (malleable) {    this.setPublicKey = setPublicKey;    this.setPrivateKey = setPrivateKey;  } else {    this._primeCode = 8;  }}Object.defineProperty(DH.prototype, 'verifyError', {  enumerable: true,  get: function () {    if (typeof this._primeCode !== 'number') {      this._primeCode = checkPrime(this.__prime, this.__gen);    }    return this._primeCode;  }});DH.prototype.generateKeys = function () {  if (!this._priv) {    this._priv = new BN(randomBytes(this._primeLen));  }  this._pub = this._gen.toRed(this._prime).redPow(this._priv).fromRed();  return this.getPublicKey();};DH.prototype.computeSecret = function (other) {  other = new BN(other);  other = other.toRed(this._prime);  var secret = other.redPow(this._priv).fromRed();  var out = new Buffer(secret.toArray());  var prime = this.getPrime();  if (out.length < prime.length) {    var front = new Buffer(prime.length - out.length);    front.fill(0);    out = Buffer.concat([front, out]);  }  return out;};DH.prototype.getPublicKey = function getPublicKey(enc) {  return formatReturnValue(this._pub, enc);};DH.prototype.getPrivateKey = function getPrivateKey(enc) {  return formatReturnValue(this._priv, enc);};DH.prototype.getPrime = function (enc) {  return formatReturnValue(this.__prime, enc);};DH.prototype.getGenerator = function (enc) {  return formatReturnValue(this._gen, enc);};DH.prototype.setGenerator = function (gen, enc) {  enc = enc || 'utf8';  if (!Buffer.isBuffer(gen)) {    gen = new Buffer(gen, enc);  }  this.__gen = gen;  this._gen = new BN(gen);  return this;};function formatReturnValue(bn, enc) {  var buf = new Buffer(bn.toArray());  if (!enc) {    return buf;  } else {    return buf.toString(enc);  }}}).call(this,require("buffer").Buffer)},{"./generatePrime":118,"bn.js":45,"buffer":79,"miller-rabin":196,"randombytes":234}],118:[function(require,module,exports){var randomBytes = require('randombytes');module.exports = findPrime;findPrime.simpleSieve = simpleSieve;findPrime.fermatTest = fermatTest;var BN = require('bn.js');var TWENTYFOUR = new BN(24);var MillerRabin = require('miller-rabin');var millerRabin = new MillerRabin();var ONE = new BN(1);var TWO = new BN(2);var FIVE = new BN(5);var SIXTEEN = new BN(16);var EIGHT = new BN(8);var TEN = new BN(10);var THREE = new BN(3);var SEVEN = new BN(7);var ELEVEN = new BN(11);var FOUR = new BN(4);var TWELVE = new BN(12);var primes = null;function _getPrimes() {  if (primes !== null)    return primes;  var limit = 0x100000;  var res = [];  res[0] = 2;  for (var i = 1, k = 3; k < limit; k += 2) {    var sqrt = Math.ceil(Math.sqrt(k));    for (var j = 0; j < i && res[j] <= sqrt; j++)      if (k % res[j] === 0)        break;    if (i !== j && res[j] <= sqrt)      continue;    res[i++] = k;  }  primes = res;  return res;}function simpleSieve(p) {  var primes = _getPrimes();  for (var i = 0; i < primes.length; i++)    if (p.modn(primes[i]) === 0) {      if (p.cmpn(primes[i]) === 0) {        return true;      } else {        return false;      }    }  return true;}function fermatTest(p) {  var red = BN.mont(p);  return TWO.toRed(red).redPow(p.subn(1)).fromRed().cmpn(1) === 0;}function findPrime(bits, gen) {  if (bits < 16) {    // this is what openssl does    if (gen === 2 || gen === 5) {      return new BN([0x8c, 0x7b]);    } else {      return new BN([0x8c, 0x27]);    }  }  gen = new BN(gen);  var num, n2;  while (true) {    num = new BN(randomBytes(Math.ceil(bits / 8)));    while (num.bitLength() > bits) {      num.ishrn(1);    }    if (num.isEven()) {      num.iadd(ONE);    }    if (!num.testn(1)) {      num.iadd(TWO);    }    if (!gen.cmp(TWO)) {      while (num.mod(TWENTYFOUR).cmp(ELEVEN)) {        num.iadd(FOUR);      }    } else if (!gen.cmp(FIVE)) {      while (num.mod(TEN).cmp(THREE)) {        num.iadd(FOUR);      }    }    n2 = num.shrn(1);    if (simpleSieve(n2) && simpleSieve(num) &&      fermatTest(n2) && fermatTest(num) &&      millerRabin.test(n2) && millerRabin.test(num)) {      return num;    }  }}},{"bn.js":45,"miller-rabin":196,"randombytes":234}],119:[function(require,module,exports){module.exports={    "modp1": {        "gen": "02",        "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a63a3620ffffffffffffffff"    },    "modp2": {        "gen": "02",        "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece65381ffffffffffffffff"    },    "modp5": {        "gen": "02",        "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff"    },    "modp14": {        "gen": "02",        "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff"    },    "modp15": {        "gen": "02",        "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a93ad2caffffffffffffffff"    },    "modp16": {        "gen": "02",        "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c934063199ffffffffffffffff"    },    "modp17": {        "gen": "02",        "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dcc4024ffffffffffffffff"    },    "modp18": {        "gen": "02",        "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dbe115974a3926f12fee5e438777cb6a932df8cd8bec4d073b931ba3bc832b68d9dd300741fa7bf8afc47ed2576f6936ba424663aab639c5ae4f5683423b4742bf1c978238f16cbe39d652de3fdb8befc848ad922222e04a4037c0713eb57a81a23f0c73473fc646cea306b4bcbc8862f8385ddfa9d4b7fa2c087e879683303ed5bdd3a062b3cf5b3a278a66d2a13f83f44f82ddf310ee074ab6a364597e899a0255dc164f31cc50846851df9ab48195ded7ea1b1d510bd7ee74d73faf36bc31ecfa268359046f4eb879f924009438b481c6cd7889a002ed5ee382bc9190da6fc026e479558e4475677e9aa9e3050e2765694dfc81f56e880b96e7160c980dd98edd3dfffffffffffffffff"    }}},{}],120:[function(require,module,exports){'use strict';var elliptic = exports;elliptic.version = require('../package.json').version;elliptic.utils = require('./elliptic/utils');elliptic.rand = require('brorand');elliptic.curve = require('./elliptic/curve');elliptic.curves = require('./elliptic/curves');// Protocolselliptic.ec = require('./elliptic/ec');elliptic.eddsa = require('./elliptic/eddsa');},{"../package.json":135,"./elliptic/curve":123,"./elliptic/curves":126,"./elliptic/ec":127,"./elliptic/eddsa":130,"./elliptic/utils":134,"brorand":46}],121:[function(require,module,exports){'use strict';var BN = require('bn.js');var elliptic = require('../../elliptic');var utils = elliptic.utils;var getNAF = utils.getNAF;var getJSF = utils.getJSF;var assert = utils.assert;function BaseCurve(type, conf) {  this.type = type;  this.p = new BN(conf.p, 16);  // Use Montgomery, when there is no fast reduction for the prime  this.red = conf.prime ? BN.red(conf.prime) : BN.mont(this.p);  // Useful for many curves  this.zero = new BN(0).toRed(this.red);  this.one = new BN(1).toRed(this.red);  this.two = new BN(2).toRed(this.red);  // Curve configuration, optional  this.n = conf.n && new BN(conf.n, 16);  this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed);  // Temporary arrays  this._wnafT1 = new Array(4);  this._wnafT2 = new Array(4);  this._wnafT3 = new Array(4);  this._wnafT4 = new Array(4);  // Generalized Greg Maxwell's trick  var adjustCount = this.n && this.p.div(this.n);  if (!adjustCount || adjustCount.cmpn(100) > 0) {    this.redN = null;  } else {    this._maxwellTrick = true;    this.redN = this.n.toRed(this.red);  }}module.exports = BaseCurve;BaseCurve.prototype.point = function point() {  throw new Error('Not implemented');};BaseCurve.prototype.validate = function validate() {  throw new Error('Not implemented');};BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) {  assert(p.precomputed);  var doubles = p._getDoubles();  var naf = getNAF(k, 1);  var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1);  I /= 3;  // Translate into more windowed form  var repr = [];  for (var j = 0; j < naf.length; j += doubles.step) {    var nafW = 0;    for (var k = j + doubles.step - 1; k >= j; k--)      nafW = (nafW << 1) + naf[k];    repr.push(nafW);  }  var a = this.jpoint(null, null, null);  var b = this.jpoint(null, null, null);  for (var i = I; i > 0; i--) {    for (var j = 0; j < repr.length; j++) {      var nafW = repr[j];      if (nafW === i)        b = b.mixedAdd(doubles.points[j]);      else if (nafW === -i)        b = b.mixedAdd(doubles.points[j].neg());    }    a = a.add(b);  }  return a.toP();};BaseCurve.prototype._wnafMul = function _wnafMul(p, k) {  var w = 4;  // Precompute window  var nafPoints = p._getNAFPoints(w);  w = nafPoints.wnd;  var wnd = nafPoints.points;  // Get NAF form  var naf = getNAF(k, w);  // Add `this`*(N+1) for every w-NAF index  var acc = this.jpoint(null, null, null);  for (var i = naf.length - 1; i >= 0; i--) {    // Count zeroes    for (var k = 0; i >= 0 && naf[i] === 0; i--)      k++;    if (i >= 0)      k++;    acc = acc.dblp(k);    if (i < 0)      break;    var z = naf[i];    assert(z !== 0);    if (p.type === 'affine') {      // J +- P      if (z > 0)        acc = acc.mixedAdd(wnd[(z - 1) >> 1]);      else        acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg());    } else {      // J +- J      if (z > 0)        acc = acc.add(wnd[(z - 1) >> 1]);      else        acc = acc.add(wnd[(-z - 1) >> 1].neg());    }  }  return p.type === 'affine' ? acc.toP() : acc;};BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW,                                                       points,                                                       coeffs,                                                       len,                                                       jacobianResult) {  var wndWidth = this._wnafT1;  var wnd = this._wnafT2;  var naf = this._wnafT3;  // Fill all arrays  var max = 0;  for (var i = 0; i < len; i++) {    var p = points[i];    var nafPoints = p._getNAFPoints(defW);    wndWidth[i] = nafPoints.wnd;    wnd[i] = nafPoints.points;  }  // Comb small window NAFs  for (var i = len - 1; i >= 1; i -= 2) {    var a = i - 1;    var b = i;    if (wndWidth[a] !== 1 || wndWidth[b] !== 1) {      naf[a] = getNAF(coeffs[a], wndWidth[a]);      naf[b] = getNAF(coeffs[b], wndWidth[b]);      max = Math.max(naf[a].length, max);      max = Math.max(naf[b].length, max);      continue;    }    var comb = [      points[a], /* 1 */      null, /* 3 */      null, /* 5 */      points[b] /* 7 */    ];    // Try to avoid Projective points, if possible    if (points[a].y.cmp(points[b].y) === 0) {      comb[1] = points[a].add(points[b]);      comb[2] = points[a].toJ().mixedAdd(points[b].neg());    } else if (points[a].y.cmp(points[b].y.redNeg()) === 0) {      comb[1] = points[a].toJ().mixedAdd(points[b]);      comb[2] = points[a].add(points[b].neg());    } else {      comb[1] = points[a].toJ().mixedAdd(points[b]);      comb[2] = points[a].toJ().mixedAdd(points[b].neg());    }    var index = [      -3, /* -1 -1 */      -1, /* -1 0 */      -5, /* -1 1 */      -7, /* 0 -1 */      0, /* 0 0 */      7, /* 0 1 */      5, /* 1 -1 */      1, /* 1 0 */      3  /* 1 1 */    ];    var jsf = getJSF(coeffs[a], coeffs[b]);    max = Math.max(jsf[0].length, max);    naf[a] = new Array(max);    naf[b] = new Array(max);    for (var j = 0; j < max; j++) {      var ja = jsf[0][j] | 0;      var jb = jsf[1][j] | 0;      naf[a][j] = index[(ja + 1) * 3 + (jb + 1)];      naf[b][j] = 0;      wnd[a] = comb;    }  }  var acc = this.jpoint(null, null, null);  var tmp = this._wnafT4;  for (var i = max; i >= 0; i--) {    var k = 0;    while (i >= 0) {      var zero = true;      for (var j = 0; j < len; j++) {        tmp[j] = naf[j][i] | 0;        if (tmp[j] !== 0)          zero = false;      }      if (!zero)        break;      k++;      i--;    }    if (i >= 0)      k++;    acc = acc.dblp(k);    if (i < 0)      break;    for (var j = 0; j < len; j++) {      var z = tmp[j];      var p;      if (z === 0)        continue;      else if (z > 0)        p = wnd[j][(z - 1) >> 1];      else if (z < 0)        p = wnd[j][(-z - 1) >> 1].neg();      if (p.type === 'affine')        acc = acc.mixedAdd(p);      else        acc = acc.add(p);    }  }  // Zeroify references  for (var i = 0; i < len; i++)    wnd[i] = null;  if (jacobianResult)    return acc;  else    return acc.toP();};function BasePoint(curve, type) {  this.curve = curve;  this.type = type;  this.precomputed = null;}BaseCurve.BasePoint = BasePoint;BasePoint.prototype.eq = function eq(/*other*/) {  throw new Error('Not implemented');};BasePoint.prototype.validate = function validate() {  return this.curve.validate(this);};BaseCurve.prototype.decodePoint = function decodePoint(bytes, enc) {  bytes = utils.toArray(bytes, enc);  var len = this.p.byteLength();  // uncompressed, hybrid-odd, hybrid-even  if ((bytes[0] === 0x04 || bytes[0] === 0x06 || bytes[0] === 0x07) &&      bytes.length - 1 === 2 * len) {    if (bytes[0] === 0x06)      assert(bytes[bytes.length - 1] % 2 === 0);    else if (bytes[0] === 0x07)      assert(bytes[bytes.length - 1] % 2 === 1);    var res =  this.point(bytes.slice(1, 1 + len),                          bytes.slice(1 + len, 1 + 2 * len));    return res;  } else if ((bytes[0] === 0x02 || bytes[0] === 0x03) &&              bytes.length - 1 === len) {    return this.pointFromX(bytes.slice(1, 1 + len), bytes[0] === 0x03);  }  throw new Error('Unknown point format');};BasePoint.prototype.encodeCompressed = function encodeCompressed(enc) {  return this.encode(enc, true);};BasePoint.prototype._encode = function _encode(compact) {  var len = this.curve.p.byteLength();  var x = this.getX().toArray('be', len);  if (compact)    return [ this.getY().isEven() ? 0x02 : 0x03 ].concat(x);  return [ 0x04 ].concat(x, this.getY().toArray('be', len)) ;};BasePoint.prototype.encode = function encode(enc, compact) {  return utils.encode(this._encode(compact), enc);};BasePoint.prototype.precompute = function precompute(power) {  if (this.precomputed)    return this;  var precomputed = {    doubles: null,    naf: null,    beta: null  };  precomputed.naf = this._getNAFPoints(8);  precomputed.doubles = this._getDoubles(4, power);  precomputed.beta = this._getBeta();  this.precomputed = precomputed;  return this;};BasePoint.prototype._hasDoubles = function _hasDoubles(k) {  if (!this.precomputed)    return false;  var doubles = this.precomputed.doubles;  if (!doubles)    return false;  return doubles.points.length >= Math.ceil((k.bitLength() + 1) / doubles.step);};BasePoint.prototype._getDoubles = function _getDoubles(step, power) {  if (this.precomputed && this.precomputed.doubles)    return this.precomputed.doubles;  var doubles = [ this ];  var acc = this;  for (var i = 0; i < power; i += step) {    for (var j = 0; j < step; j++)      acc = acc.dbl();    doubles.push(acc);  }  return {    step: step,    points: doubles  };};BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) {  if (this.precomputed && this.precomputed.naf)    return this.precomputed.naf;  var res = [ this ];  var max = (1 << wnd) - 1;  var dbl = max === 1 ? null : this.dbl();  for (var i = 1; i < max; i++)    res[i] = res[i - 1].add(dbl);  return {    wnd: wnd,    points: res  };};BasePoint.prototype._getBeta = function _getBeta() {  return null;};BasePoint.prototype.dblp = function dblp(k) {  var r = this;  for (var i = 0; i < k; i++)    r = r.dbl();  return r;};},{"../../elliptic":120,"bn.js":45}],122:[function(require,module,exports){'use strict';var curve = require('../curve');var elliptic = require('../../elliptic');var BN = require('bn.js');var inherits = require('inherits');var Base = curve.base;var assert = elliptic.utils.assert;function EdwardsCurve(conf) {  // NOTE: Important as we are creating point in Base.call()  this.twisted = (conf.a | 0) !== 1;  this.mOneA = this.twisted && (conf.a | 0) === -1;  this.extended = this.mOneA;  Base.call(this, 'edwards', conf);  this.a = new BN(conf.a, 16).umod(this.red.m);  this.a = this.a.toRed(this.red);  this.c = new BN(conf.c, 16).toRed(this.red);  this.c2 = this.c.redSqr();  this.d = new BN(conf.d, 16).toRed(this.red);  this.dd = this.d.redAdd(this.d);  assert(!this.twisted || this.c.fromRed().cmpn(1) === 0);  this.oneC = (conf.c | 0) === 1;}inherits(EdwardsCurve, Base);module.exports = EdwardsCurve;EdwardsCurve.prototype._mulA = function _mulA(num) {  if (this.mOneA)    return num.redNeg();  else    return this.a.redMul(num);};EdwardsCurve.prototype._mulC = function _mulC(num) {  if (this.oneC)    return num;  else    return this.c.redMul(num);};// Just for compatibility with Short curveEdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) {  return this.point(x, y, z, t);};EdwardsCurve.prototype.pointFromX = function pointFromX(x, odd) {  x = new BN(x, 16);  if (!x.red)    x = x.toRed(this.red);  var x2 = x.redSqr();  var rhs = this.c2.redSub(this.a.redMul(x2));  var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2));  var y2 = rhs.redMul(lhs.redInvm());  var y = y2.redSqrt();  if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)    throw new Error('invalid point');  var isOdd = y.fromRed().isOdd();  if (odd && !isOdd || !odd && isOdd)    y = y.redNeg();  return this.point(x, y);};EdwardsCurve.prototype.pointFromY = function pointFromY(y, odd) {  y = new BN(y, 16);  if (!y.red)    y = y.toRed(this.red);  // x^2 = (y^2 - c^2) / (c^2 d y^2 - a)  var y2 = y.redSqr();  var lhs = y2.redSub(this.c2);  var rhs = y2.redMul(this.d).redMul(this.c2).redSub(this.a);  var x2 = lhs.redMul(rhs.redInvm());  if (x2.cmp(this.zero) === 0) {    if (odd)      throw new Error('invalid point');    else      return this.point(this.zero, y);  }  var x = x2.redSqrt();  if (x.redSqr().redSub(x2).cmp(this.zero) !== 0)    throw new Error('invalid point');  if (x.fromRed().isOdd() !== odd)    x = x.redNeg();  return this.point(x, y);};EdwardsCurve.prototype.validate = function validate(point) {  if (point.isInfinity())    return true;  // Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2)  point.normalize();  var x2 = point.x.redSqr();  var y2 = point.y.redSqr();  var lhs = x2.redMul(this.a).redAdd(y2);  var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2)));  return lhs.cmp(rhs) === 0;};function Point(curve, x, y, z, t) {  Base.BasePoint.call(this, curve, 'projective');  if (x === null && y === null && z === null) {    this.x = this.curve.zero;    this.y = this.curve.one;    this.z = this.curve.one;    this.t = this.curve.zero;    this.zOne = true;  } else {    this.x = new BN(x, 16);    this.y = new BN(y, 16);    this.z = z ? new BN(z, 16) : this.curve.one;    this.t = t && new BN(t, 16);    if (!this.x.red)      this.x = this.x.toRed(this.curve.red);    if (!this.y.red)      this.y = this.y.toRed(this.curve.red);    if (!this.z.red)      this.z = this.z.toRed(this.curve.red);    if (this.t && !this.t.red)      this.t = this.t.toRed(this.curve.red);    this.zOne = this.z === this.curve.one;    // Use extended coordinates    if (this.curve.extended && !this.t) {      this.t = this.x.redMul(this.y);      if (!this.zOne)        this.t = this.t.redMul(this.z.redInvm());    }  }}inherits(Point, Base.BasePoint);EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) {  return Point.fromJSON(this, obj);};EdwardsCurve.prototype.point = function point(x, y, z, t) {  return new Point(this, x, y, z, t);};Point.fromJSON = function fromJSON(curve, obj) {  return new Point(curve, obj[0], obj[1], obj[2]);};Point.prototype.inspect = function inspect() {  if (this.isInfinity())    return '<EC Point Infinity>';  return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +      ' y: ' + this.y.fromRed().toString(16, 2) +      ' z: ' + this.z.fromRed().toString(16, 2) + '>';};Point.prototype.isInfinity = function isInfinity() {  // XXX This code assumes that zero is always zero in red  return this.x.cmpn(0) === 0 &&    (this.y.cmp(this.z) === 0 ||    (this.zOne && this.y.cmp(this.curve.c) === 0));};Point.prototype._extDbl = function _extDbl() {  // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html  //     #doubling-dbl-2008-hwcd  // 4M + 4S  // A = X1^2  var a = this.x.redSqr();  // B = Y1^2  var b = this.y.redSqr();  // C = 2 * Z1^2  var c = this.z.redSqr();  c = c.redIAdd(c);  // D = a * A  var d = this.curve._mulA(a);  // E = (X1 + Y1)^2 - A - B  var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b);  // G = D + B  var g = d.redAdd(b);  // F = G - C  var f = g.redSub(c);  // H = D - B  var h = d.redSub(b);  // X3 = E * F  var nx = e.redMul(f);  // Y3 = G * H  var ny = g.redMul(h);  // T3 = E * H  var nt = e.redMul(h);  // Z3 = F * G  var nz = f.redMul(g);  return this.curve.point(nx, ny, nz, nt);};Point.prototype._projDbl = function _projDbl() {  // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html  //     #doubling-dbl-2008-bbjlp  //     #doubling-dbl-2007-bl  // and others  // Generally 3M + 4S or 2M + 4S  // B = (X1 + Y1)^2  var b = this.x.redAdd(this.y).redSqr();  // C = X1^2  var c = this.x.redSqr();  // D = Y1^2  var d = this.y.redSqr();  var nx;  var ny;  var nz;  if (this.curve.twisted) {    // E = a * C    var e = this.curve._mulA(c);    // F = E + D    var f = e.redAdd(d);    if (this.zOne) {      // X3 = (B - C - D) * (F - 2)      nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two));      // Y3 = F * (E - D)      ny = f.redMul(e.redSub(d));      // Z3 = F^2 - 2 * F      nz = f.redSqr().redSub(f).redSub(f);    } else {      // H = Z1^2      var h = this.z.redSqr();      // J = F - 2 * H      var j = f.redSub(h).redISub(h);      // X3 = (B-C-D)*J      nx = b.redSub(c).redISub(d).redMul(j);      // Y3 = F * (E - D)      ny = f.redMul(e.redSub(d));      // Z3 = F * J      nz = f.redMul(j);    }  } else {    // E = C + D    var e = c.redAdd(d);    // H = (c * Z1)^2    var h = this.curve._mulC(this.z).redSqr();    // J = E - 2 * H    var j = e.redSub(h).redSub(h);    // X3 = c * (B - E) * J    nx = this.curve._mulC(b.redISub(e)).redMul(j);    // Y3 = c * E * (C - D)    ny = this.curve._mulC(e).redMul(c.redISub(d));    // Z3 = E * J    nz = e.redMul(j);  }  return this.curve.point(nx, ny, nz);};Point.prototype.dbl = function dbl() {  if (this.isInfinity())    return this;  // Double in extended coordinates  if (this.curve.extended)    return this._extDbl();  else    return this._projDbl();};Point.prototype._extAdd = function _extAdd(p) {  // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html  //     #addition-add-2008-hwcd-3  // 8M  // A = (Y1 - X1) * (Y2 - X2)  var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x));  // B = (Y1 + X1) * (Y2 + X2)  var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x));  // C = T1 * k * T2  var c = this.t.redMul(this.curve.dd).redMul(p.t);  // D = Z1 * 2 * Z2  var d = this.z.redMul(p.z.redAdd(p.z));  // E = B - A  var e = b.redSub(a);  // F = D - C  var f = d.redSub(c);  // G = D + C  var g = d.redAdd(c);  // H = B + A  var h = b.redAdd(a);  // X3 = E * F  var nx = e.redMul(f);  // Y3 = G * H  var ny = g.redMul(h);  // T3 = E * H  var nt = e.redMul(h);  // Z3 = F * G  var nz = f.redMul(g);  return this.curve.point(nx, ny, nz, nt);};Point.prototype._projAdd = function _projAdd(p) {  // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html  //     #addition-add-2008-bbjlp  //     #addition-add-2007-bl  // 10M + 1S  // A = Z1 * Z2  var a = this.z.redMul(p.z);  // B = A^2  var b = a.redSqr();  // C = X1 * X2  var c = this.x.redMul(p.x);  // D = Y1 * Y2  var d = this.y.redMul(p.y);  // E = d * C * D  var e = this.curve.d.redMul(c).redMul(d);  // F = B - E  var f = b.redSub(e);  // G = B + E  var g = b.redAdd(e);  // X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D)  var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d);  var nx = a.redMul(f).redMul(tmp);  var ny;  var nz;  if (this.curve.twisted) {    // Y3 = A * G * (D - a * C)    ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c)));    // Z3 = F * G    nz = f.redMul(g);  } else {    // Y3 = A * G * (D - C)    ny = a.redMul(g).redMul(d.redSub(c));    // Z3 = c * F * G    nz = this.curve._mulC(f).redMul(g);  }  return this.curve.point(nx, ny, nz);};Point.prototype.add = function add(p) {  if (this.isInfinity())    return p;  if (p.isInfinity())    return this;  if (this.curve.extended)    return this._extAdd(p);  else    return this._projAdd(p);};Point.prototype.mul = function mul(k) {  if (this._hasDoubles(k))    return this.curve._fixedNafMul(this, k);  else    return this.curve._wnafMul(this, k);};Point.prototype.mulAdd = function mulAdd(k1, p, k2) {  return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, false);};Point.prototype.jmulAdd = function jmulAdd(k1, p, k2) {  return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, true);};Point.prototype.normalize = function normalize() {  if (this.zOne)    return this;  // Normalize coordinates  var zi = this.z.redInvm();  this.x = this.x.redMul(zi);  this.y = this.y.redMul(zi);  if (this.t)    this.t = this.t.redMul(zi);  this.z = this.curve.one;  this.zOne = true;  return this;};Point.prototype.neg = function neg() {  return this.curve.point(this.x.redNeg(),                          this.y,                          this.z,                          this.t && this.t.redNeg());};Point.prototype.getX = function getX() {  this.normalize();  return this.x.fromRed();};Point.prototype.getY = function getY() {  this.normalize();  return this.y.fromRed();};Point.prototype.eq = function eq(other) {  return this === other ||         this.getX().cmp(other.getX()) === 0 &&         this.getY().cmp(other.getY()) === 0;};Point.prototype.eqXToP = function eqXToP(x) {  var rx = x.toRed(this.curve.red).redMul(this.z);  if (this.x.cmp(rx) === 0)    return true;  var xc = x.clone();  var t = this.curve.redN.redMul(this.z);  for (;;) {    xc.iadd(this.curve.n);    if (xc.cmp(this.curve.p) >= 0)      return false;    rx.redIAdd(t);    if (this.x.cmp(rx) === 0)      return true;  }};// Compatibility with BaseCurvePoint.prototype.toP = Point.prototype.normalize;Point.prototype.mixedAdd = Point.prototype.add;},{"../../elliptic":120,"../curve":123,"bn.js":45,"inherits":154}],123:[function(require,module,exports){'use strict';var curve = exports;curve.base = require('./base');curve.short = require('./short');curve.mont = require('./mont');curve.edwards = require('./edwards');},{"./base":121,"./edwards":122,"./mont":124,"./short":125}],124:[function(require,module,exports){'use strict';var curve = require('../curve');var BN = require('bn.js');var inherits = require('inherits');var Base = curve.base;var elliptic = require('../../elliptic');var utils = elliptic.utils;function MontCurve(conf) {  Base.call(this, 'mont', conf);  this.a = new BN(conf.a, 16).toRed(this.red);  this.b = new BN(conf.b, 16).toRed(this.red);  this.i4 = new BN(4).toRed(this.red).redInvm();  this.two = new BN(2).toRed(this.red);  this.a24 = this.i4.redMul(this.a.redAdd(this.two));}inherits(MontCurve, Base);module.exports = MontCurve;MontCurve.prototype.validate = function validate(point) {  var x = point.normalize().x;  var x2 = x.redSqr();  var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x);  var y = rhs.redSqrt();  return y.redSqr().cmp(rhs) === 0;};function Point(curve, x, z) {  Base.BasePoint.call(this, curve, 'projective');  if (x === null && z === null) {    this.x = this.curve.one;    this.z = this.curve.zero;  } else {    this.x = new BN(x, 16);    this.z = new BN(z, 16);    if (!this.x.red)      this.x = this.x.toRed(this.curve.red);    if (!this.z.red)      this.z = this.z.toRed(this.curve.red);  }}inherits(Point, Base.BasePoint);MontCurve.prototype.decodePoint = function decodePoint(bytes, enc) {  return this.point(utils.toArray(bytes, enc), 1);};MontCurve.prototype.point = function point(x, z) {  return new Point(this, x, z);};MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) {  return Point.fromJSON(this, obj);};Point.prototype.precompute = function precompute() {  // No-op};Point.prototype._encode = function _encode() {  return this.getX().toArray('be', this.curve.p.byteLength());};Point.fromJSON = function fromJSON(curve, obj) {  return new Point(curve, obj[0], obj[1] || curve.one);};Point.prototype.inspect = function inspect() {  if (this.isInfinity())    return '<EC Point Infinity>';  return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +      ' z: ' + this.z.fromRed().toString(16, 2) + '>';};Point.prototype.isInfinity = function isInfinity() {  // XXX This code assumes that zero is always zero in red  return this.z.cmpn(0) === 0;};Point.prototype.dbl = function dbl() {  // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3  // 2M + 2S + 4A  // A = X1 + Z1  var a = this.x.redAdd(this.z);  // AA = A^2  var aa = a.redSqr();  // B = X1 - Z1  var b = this.x.redSub(this.z);  // BB = B^2  var bb = b.redSqr();  // C = AA - BB  var c = aa.redSub(bb);  // X3 = AA * BB  var nx = aa.redMul(bb);  // Z3 = C * (BB + A24 * C)  var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c)));  return this.curve.point(nx, nz);};Point.prototype.add = function add() {  throw new Error('Not supported on Montgomery curve');};Point.prototype.diffAdd = function diffAdd(p, diff) {  // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3  // 4M + 2S + 6A  // A = X2 + Z2  var a = this.x.redAdd(this.z);  // B = X2 - Z2  var b = this.x.redSub(this.z);  // C = X3 + Z3  var c = p.x.redAdd(p.z);  // D = X3 - Z3  var d = p.x.redSub(p.z);  // DA = D * A  var da = d.redMul(a);  // CB = C * B  var cb = c.redMul(b);  // X5 = Z1 * (DA + CB)^2  var nx = diff.z.redMul(da.redAdd(cb).redSqr());  // Z5 = X1 * (DA - CB)^2  var nz = diff.x.redMul(da.redISub(cb).redSqr());  return this.curve.point(nx, nz);};Point.prototype.mul = function mul(k) {  var t = k.clone();  var a = this; // (N / 2) * Q + Q  var b = this.curve.point(null, null); // (N / 2) * Q  var c = this; // Q  for (var bits = []; t.cmpn(0) !== 0; t.iushrn(1))    bits.push(t.andln(1));  for (var i = bits.length - 1; i >= 0; i--) {    if (bits[i] === 0) {      // N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q      a = a.diffAdd(b, c);      // N * Q = 2 * ((N / 2) * Q + Q))      b = b.dbl();    } else {      // N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q)      b = a.diffAdd(b, c);      // N * Q + Q = 2 * ((N / 2) * Q + Q)      a = a.dbl();    }  }  return b;};Point.prototype.mulAdd = function mulAdd() {  throw new Error('Not supported on Montgomery curve');};Point.prototype.jumlAdd = function jumlAdd() {  throw new Error('Not supported on Montgomery curve');};Point.prototype.eq = function eq(other) {  return this.getX().cmp(other.getX()) === 0;};Point.prototype.normalize = function normalize() {  this.x = this.x.redMul(this.z.redInvm());  this.z = this.curve.one;  return this;};Point.prototype.getX = function getX() {  // Normalize coordinates  this.normalize();  return this.x.fromRed();};},{"../../elliptic":120,"../curve":123,"bn.js":45,"inherits":154}],125:[function(require,module,exports){'use strict';var curve = require('../curve');var elliptic = require('../../elliptic');var BN = require('bn.js');var inherits = require('inherits');var Base = curve.base;var assert = elliptic.utils.assert;function ShortCurve(conf) {  Base.call(this, 'short', conf);  this.a = new BN(conf.a, 16).toRed(this.red);  this.b = new BN(conf.b, 16).toRed(this.red);  this.tinv = this.two.redInvm();  this.zeroA = this.a.fromRed().cmpn(0) === 0;  this.threeA = this.a.fromRed().sub(this.p).cmpn(-3) === 0;  // If the curve is endomorphic, precalculate beta and lambda  this.endo = this._getEndomorphism(conf);  this._endoWnafT1 = new Array(4);  this._endoWnafT2 = new Array(4);}inherits(ShortCurve, Base);module.exports = ShortCurve;ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) {  // No efficient endomorphism  if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1)    return;  // Compute beta and lambda, that lambda * P = (beta * Px; Py)  var beta;  var lambda;  if (conf.beta) {    beta = new BN(conf.beta, 16).toRed(this.red);  } else {    var betas = this._getEndoRoots(this.p);    // Choose the smallest beta    beta = betas[0].cmp(betas[1]) < 0 ? betas[0] : betas[1];    beta = beta.toRed(this.red);  }  if (conf.lambda) {    lambda = new BN(conf.lambda, 16);  } else {    // Choose the lambda that is matching selected beta    var lambdas = this._getEndoRoots(this.n);    if (this.g.mul(lambdas[0]).x.cmp(this.g.x.redMul(beta)) === 0) {      lambda = lambdas[0];    } else {      lambda = lambdas[1];      assert(this.g.mul(lambda).x.cmp(this.g.x.redMul(beta)) === 0);    }  }  // Get basis vectors, used for balanced length-two representation  var basis;  if (conf.basis) {    basis = conf.basis.map(function(vec) {      return {        a: new BN(vec.a, 16),        b: new BN(vec.b, 16)      };    });  } else {    basis = this._getEndoBasis(lambda);  }  return {    beta: beta,    lambda: lambda,    basis: basis  };};ShortCurve.prototype._getEndoRoots = function _getEndoRoots(num) {  // Find roots of for x^2 + x + 1 in F  // Root = (-1 +- Sqrt(-3)) / 2  //  var red = num === this.p ? this.red : BN.mont(num);  var tinv = new BN(2).toRed(red).redInvm();  var ntinv = tinv.redNeg();  var s = new BN(3).toRed(red).redNeg().redSqrt().redMul(tinv);  var l1 = ntinv.redAdd(s).fromRed();  var l2 = ntinv.redSub(s).fromRed();  return [ l1, l2 ];};ShortCurve.prototype._getEndoBasis = function _getEndoBasis(lambda) {  // aprxSqrt >= sqrt(this.n)  var aprxSqrt = this.n.ushrn(Math.floor(this.n.bitLength() / 2));  // 3.74  // Run EGCD, until r(L + 1) < aprxSqrt  var u = lambda;  var v = this.n.clone();  var x1 = new BN(1);  var y1 = new BN(0);  var x2 = new BN(0);  var y2 = new BN(1);  // NOTE: all vectors are roots of: a + b * lambda = 0 (mod n)  var a0;  var b0;  // First vector  var a1;  var b1;  // Second vector  var a2;  var b2;  var prevR;  var i = 0;  var r;  var x;  while (u.cmpn(0) !== 0) {    var q = v.div(u);    r = v.sub(q.mul(u));    x = x2.sub(q.mul(x1));    var y = y2.sub(q.mul(y1));    if (!a1 && r.cmp(aprxSqrt) < 0) {      a0 = prevR.neg();      b0 = x1;      a1 = r.neg();      b1 = x;    } else if (a1 && ++i === 2) {      break;    }    prevR = r;    v = u;    u = r;    x2 = x1;    x1 = x;    y2 = y1;    y1 = y;  }  a2 = r.neg();  b2 = x;  var len1 = a1.sqr().add(b1.sqr());  var len2 = a2.sqr().add(b2.sqr());  if (len2.cmp(len1) >= 0) {    a2 = a0;    b2 = b0;  }  // Normalize signs  if (a1.negative) {    a1 = a1.neg();    b1 = b1.neg();  }  if (a2.negative) {    a2 = a2.neg();    b2 = b2.neg();  }  return [    { a: a1, b: b1 },    { a: a2, b: b2 }  ];};ShortCurve.prototype._endoSplit = function _endoSplit(k) {  var basis = this.endo.basis;  var v1 = basis[0];  var v2 = basis[1];  var c1 = v2.b.mul(k).divRound(this.n);  var c2 = v1.b.neg().mul(k).divRound(this.n);  var p1 = c1.mul(v1.a);  var p2 = c2.mul(v2.a);  var q1 = c1.mul(v1.b);  var q2 = c2.mul(v2.b);  // Calculate answer  var k1 = k.sub(p1).sub(p2);  var k2 = q1.add(q2).neg();  return { k1: k1, k2: k2 };};ShortCurve.prototype.pointFromX = function pointFromX(x, odd) {  x = new BN(x, 16);  if (!x.red)    x = x.toRed(this.red);  var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b);  var y = y2.redSqrt();  if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)    throw new Error('invalid point');  // XXX Is there any way to tell if the number is odd without converting it  // to non-red form?  var isOdd = y.fromRed().isOdd();  if (odd && !isOdd || !odd && isOdd)    y = y.redNeg();  return this.point(x, y);};ShortCurve.prototype.validate = function validate(point) {  if (point.inf)    return true;  var x = point.x;  var y = point.y;  var ax = this.a.redMul(x);  var rhs = x.redSqr().redMul(x).redIAdd(ax).redIAdd(this.b);  return y.redSqr().redISub(rhs).cmpn(0) === 0;};ShortCurve.prototype._endoWnafMulAdd =    function _endoWnafMulAdd(points, coeffs, jacobianResult) {  var npoints = this._endoWnafT1;  var ncoeffs = this._endoWnafT2;  for (var i = 0; i < points.length; i++) {    var split = this._endoSplit(coeffs[i]);    var p = points[i];    var beta = p._getBeta();    if (split.k1.negative) {      split.k1.ineg();      p = p.neg(true);    }    if (split.k2.negative) {      split.k2.ineg();      beta = beta.neg(true);    }    npoints[i * 2] = p;    npoints[i * 2 + 1] = beta;    ncoeffs[i * 2] = split.k1;    ncoeffs[i * 2 + 1] = split.k2;  }  var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2, jacobianResult);  // Clean-up references to points and coefficients  for (var j = 0; j < i * 2; j++) {    npoints[j] = null;    ncoeffs[j] = null;  }  return res;};function Point(curve, x, y, isRed) {  Base.BasePoint.call(this, curve, 'affine');  if (x === null && y === null) {    this.x = null;    this.y = null;    this.inf = true;  } else {    this.x = new BN(x, 16);    this.y = new BN(y, 16);    // Force redgomery representation when loading from JSON    if (isRed) {      this.x.forceRed(this.curve.red);      this.y.forceRed(this.curve.red);    }    if (!this.x.red)      this.x = this.x.toRed(this.curve.red);    if (!this.y.red)      this.y = this.y.toRed(this.curve.red);    this.inf = false;  }}inherits(Point, Base.BasePoint);ShortCurve.prototype.point = function point(x, y, isRed) {  return new Point(this, x, y, isRed);};ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) {  return Point.fromJSON(this, obj, red);};Point.prototype._getBeta = function _getBeta() {  if (!this.curve.endo)    return;  var pre = this.precomputed;  if (pre && pre.beta)    return pre.beta;  var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y);  if (pre) {    var curve = this.curve;    var endoMul = function(p) {      return curve.point(p.x.redMul(curve.endo.beta), p.y);    };    pre.beta = beta;    beta.precomputed = {      beta: null,      naf: pre.naf && {        wnd: pre.naf.wnd,        points: pre.naf.points.map(endoMul)      },      doubles: pre.doubles && {        step: pre.doubles.step,        points: pre.doubles.points.map(endoMul)      }    };  }  return beta;};Point.prototype.toJSON = function toJSON() {  if (!this.precomputed)    return [ this.x, this.y ];  return [ this.x, this.y, this.precomputed && {    doubles: this.precomputed.doubles && {      step: this.precomputed.doubles.step,      points: this.precomputed.doubles.points.slice(1)    },    naf: this.precomputed.naf && {      wnd: this.precomputed.naf.wnd,      points: this.precomputed.naf.points.slice(1)    }  } ];};Point.fromJSON = function fromJSON(curve, obj, red) {  if (typeof obj === 'string')    obj = JSON.parse(obj);  var res = curve.point(obj[0], obj[1], red);  if (!obj[2])    return res;  function obj2point(obj) {    return curve.point(obj[0], obj[1], red);  }  var pre = obj[2];  res.precomputed = {    beta: null,    doubles: pre.doubles && {      step: pre.doubles.step,      points: [ res ].concat(pre.doubles.points.map(obj2point))    },    naf: pre.naf && {      wnd: pre.naf.wnd,      points: [ res ].concat(pre.naf.points.map(obj2point))    }  };  return res;};Point.prototype.inspect = function inspect() {  if (this.isInfinity())    return '<EC Point Infinity>';  return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +      ' y: ' + this.y.fromRed().toString(16, 2) + '>';};Point.prototype.isInfinity = function isInfinity() {  return this.inf;};Point.prototype.add = function add(p) {  // O + P = P  if (this.inf)    return p;  // P + O = P  if (p.inf)    return this;  // P + P = 2P  if (this.eq(p))    return this.dbl();  // P + (-P) = O  if (this.neg().eq(p))    return this.curve.point(null, null);  // P + Q = O  if (this.x.cmp(p.x) === 0)    return this.curve.point(null, null);  var c = this.y.redSub(p.y);  if (c.cmpn(0) !== 0)    c = c.redMul(this.x.redSub(p.x).redInvm());  var nx = c.redSqr().redISub(this.x).redISub(p.x);  var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);  return this.curve.point(nx, ny);};Point.prototype.dbl = function dbl() {  if (this.inf)    return this;  // 2P = O  var ys1 = this.y.redAdd(this.y);  if (ys1.cmpn(0) === 0)    return this.curve.point(null, null);  var a = this.curve.a;  var x2 = this.x.redSqr();  var dyinv = ys1.redInvm();  var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv);  var nx = c.redSqr().redISub(this.x.redAdd(this.x));  var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);  return this.curve.point(nx, ny);};Point.prototype.getX = function getX() {  return this.x.fromRed();};Point.prototype.getY = function getY() {  return this.y.fromRed();};Point.prototype.mul = function mul(k) {  k = new BN(k, 16);  if (this._hasDoubles(k))    return this.curve._fixedNafMul(this, k);  else if (this.curve.endo)    return this.curve._endoWnafMulAdd([ this ], [ k ]);  else    return this.curve._wnafMul(this, k);};Point.prototype.mulAdd = function mulAdd(k1, p2, k2) {  var points = [ this, p2 ];  var coeffs = [ k1, k2 ];  if (this.curve.endo)    return this.curve._endoWnafMulAdd(points, coeffs);  else    return this.curve._wnafMulAdd(1, points, coeffs, 2);};Point.prototype.jmulAdd = function jmulAdd(k1, p2, k2) {  var points = [ this, p2 ];  var coeffs = [ k1, k2 ];  if (this.curve.endo)    return this.curve._endoWnafMulAdd(points, coeffs, true);  else    return this.curve._wnafMulAdd(1, points, coeffs, 2, true);};Point.prototype.eq = function eq(p) {  return this === p ||         this.inf === p.inf &&             (this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0);};Point.prototype.neg = function neg(_precompute) {  if (this.inf)    return this;  var res = this.curve.point(this.x, this.y.redNeg());  if (_precompute && this.precomputed) {    var pre = this.precomputed;    var negate = function(p) {      return p.neg();    };    res.precomputed = {      naf: pre.naf && {        wnd: pre.naf.wnd,        points: pre.naf.points.map(negate)      },      doubles: pre.doubles && {        step: pre.doubles.step,        points: pre.doubles.points.map(negate)      }    };  }  return res;};Point.prototype.toJ = function toJ() {  if (this.inf)    return this.curve.jpoint(null, null, null);  var res = this.curve.jpoint(this.x, this.y, this.curve.one);  return res;};function JPoint(curve, x, y, z) {  Base.BasePoint.call(this, curve, 'jacobian');  if (x === null && y === null && z === null) {    this.x = this.curve.one;    this.y = this.curve.one;    this.z = new BN(0);  } else {    this.x = new BN(x, 16);    this.y = new BN(y, 16);    this.z = new BN(z, 16);  }  if (!this.x.red)    this.x = this.x.toRed(this.curve.red);  if (!this.y.red)    this.y = this.y.toRed(this.curve.red);  if (!this.z.red)    this.z = this.z.toRed(this.curve.red);  this.zOne = this.z === this.curve.one;}inherits(JPoint, Base.BasePoint);ShortCurve.prototype.jpoint = function jpoint(x, y, z) {  return new JPoint(this, x, y, z);};JPoint.prototype.toP = function toP() {  if (this.isInfinity())    return this.curve.point(null, null);  var zinv = this.z.redInvm();  var zinv2 = zinv.redSqr();  var ax = this.x.redMul(zinv2);  var ay = this.y.redMul(zinv2).redMul(zinv);  return this.curve.point(ax, ay);};JPoint.prototype.neg = function neg() {  return this.curve.jpoint(this.x, this.y.redNeg(), this.z);};JPoint.prototype.add = function add(p) {  // O + P = P  if (this.isInfinity())    return p;  // P + O = P  if (p.isInfinity())    return this;  // 12M + 4S + 7A  var pz2 = p.z.redSqr();  var z2 = this.z.redSqr();  var u1 = this.x.redMul(pz2);  var u2 = p.x.redMul(z2);  var s1 = this.y.redMul(pz2.redMul(p.z));  var s2 = p.y.redMul(z2.redMul(this.z));  var h = u1.redSub(u2);  var r = s1.redSub(s2);  if (h.cmpn(0) === 0) {    if (r.cmpn(0) !== 0)      return this.curve.jpoint(null, null, null);    else      return this.dbl();  }  var h2 = h.redSqr();  var h3 = h2.redMul(h);  var v = u1.redMul(h2);  var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);  var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));  var nz = this.z.redMul(p.z).redMul(h);  return this.curve.jpoint(nx, ny, nz);};JPoint.prototype.mixedAdd = function mixedAdd(p) {  // O + P = P  if (this.isInfinity())    return p.toJ();  // P + O = P  if (p.isInfinity())    return this;  // 8M + 3S + 7A  var z2 = this.z.redSqr();  var u1 = this.x;  var u2 = p.x.redMul(z2);  var s1 = this.y;  var s2 = p.y.redMul(z2).redMul(this.z);  var h = u1.redSub(u2);  var r = s1.redSub(s2);  if (h.cmpn(0) === 0) {    if (r.cmpn(0) !== 0)      return this.curve.jpoint(null, null, null);    else      return this.dbl();  }  var h2 = h.redSqr();  var h3 = h2.redMul(h);  var v = u1.redMul(h2);  var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);  var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));  var nz = this.z.redMul(h);  return this.curve.jpoint(nx, ny, nz);};JPoint.prototype.dblp = function dblp(pow) {  if (pow === 0)    return this;  if (this.isInfinity())    return this;  if (!pow)    return this.dbl();  if (this.curve.zeroA || this.curve.threeA) {    var r = this;    for (var i = 0; i < pow; i++)      r = r.dbl();    return r;  }  // 1M + 2S + 1A + N * (4S + 5M + 8A)  // N = 1 => 6M + 6S + 9A  var a = this.curve.a;  var tinv = this.curve.tinv;  var jx = this.x;  var jy = this.y;  var jz = this.z;  var jz4 = jz.redSqr().redSqr();  // Reuse results  var jyd = jy.redAdd(jy);  for (var i = 0; i < pow; i++) {    var jx2 = jx.redSqr();    var jyd2 = jyd.redSqr();    var jyd4 = jyd2.redSqr();    var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));    var t1 = jx.redMul(jyd2);    var nx = c.redSqr().redISub(t1.redAdd(t1));    var t2 = t1.redISub(nx);    var dny = c.redMul(t2);    dny = dny.redIAdd(dny).redISub(jyd4);    var nz = jyd.redMul(jz);    if (i + 1 < pow)      jz4 = jz4.redMul(jyd4);    jx = nx;    jz = nz;    jyd = dny;  }  return this.curve.jpoint(jx, jyd.redMul(tinv), jz);};JPoint.prototype.dbl = function dbl() {  if (this.isInfinity())    return this;  if (this.curve.zeroA)    return this._zeroDbl();  else if (this.curve.threeA)    return this._threeDbl();  else    return this._dbl();};JPoint.prototype._zeroDbl = function _zeroDbl() {  var nx;  var ny;  var nz;  // Z = 1  if (this.zOne) {    // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html    //     #doubling-mdbl-2007-bl    // 1M + 5S + 14A    // XX = X1^2    var xx = this.x.redSqr();    // YY = Y1^2    var yy = this.y.redSqr();    // YYYY = YY^2    var yyyy = yy.redSqr();    // S = 2 * ((X1 + YY)^2 - XX - YYYY)    var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);    s = s.redIAdd(s);    // M = 3 * XX + a; a = 0    var m = xx.redAdd(xx).redIAdd(xx);    // T = M ^ 2 - 2*S    var t = m.redSqr().redISub(s).redISub(s);    // 8 * YYYY    var yyyy8 = yyyy.redIAdd(yyyy);    yyyy8 = yyyy8.redIAdd(yyyy8);    yyyy8 = yyyy8.redIAdd(yyyy8);    // X3 = T    nx = t;    // Y3 = M * (S - T) - 8 * YYYY    ny = m.redMul(s.redISub(t)).redISub(yyyy8);    // Z3 = 2*Y1    nz = this.y.redAdd(this.y);  } else {    // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html    //     #doubling-dbl-2009-l    // 2M + 5S + 13A    // A = X1^2    var a = this.x.redSqr();    // B = Y1^2    var b = this.y.redSqr();    // C = B^2    var c = b.redSqr();    // D = 2 * ((X1 + B)^2 - A - C)    var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c);    d = d.redIAdd(d);    // E = 3 * A    var e = a.redAdd(a).redIAdd(a);    // F = E^2    var f = e.redSqr();    // 8 * C    var c8 = c.redIAdd(c);    c8 = c8.redIAdd(c8);    c8 = c8.redIAdd(c8);    // X3 = F - 2 * D    nx = f.redISub(d).redISub(d);    // Y3 = E * (D - X3) - 8 * C    ny = e.redMul(d.redISub(nx)).redISub(c8);    // Z3 = 2 * Y1 * Z1    nz = this.y.redMul(this.z);    nz = nz.redIAdd(nz);  }  return this.curve.jpoint(nx, ny, nz);};JPoint.prototype._threeDbl = function _threeDbl() {  var nx;  var ny;  var nz;  // Z = 1  if (this.zOne) {    // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html    //     #doubling-mdbl-2007-bl    // 1M + 5S + 15A    // XX = X1^2    var xx = this.x.redSqr();    // YY = Y1^2    var yy = this.y.redSqr();    // YYYY = YY^2    var yyyy = yy.redSqr();    // S = 2 * ((X1 + YY)^2 - XX - YYYY)    var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);    s = s.redIAdd(s);    // M = 3 * XX + a    var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a);    // T = M^2 - 2 * S    var t = m.redSqr().redISub(s).redISub(s);    // X3 = T    nx = t;    // Y3 = M * (S - T) - 8 * YYYY    var yyyy8 = yyyy.redIAdd(yyyy);    yyyy8 = yyyy8.redIAdd(yyyy8);    yyyy8 = yyyy8.redIAdd(yyyy8);    ny = m.redMul(s.redISub(t)).redISub(yyyy8);    // Z3 = 2 * Y1    nz = this.y.redAdd(this.y);  } else {    // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b    // 3M + 5S    // delta = Z1^2    var delta = this.z.redSqr();    // gamma = Y1^2    var gamma = this.y.redSqr();    // beta = X1 * gamma    var beta = this.x.redMul(gamma);    // alpha = 3 * (X1 - delta) * (X1 + delta)    var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta));    alpha = alpha.redAdd(alpha).redIAdd(alpha);    // X3 = alpha^2 - 8 * beta    var beta4 = beta.redIAdd(beta);    beta4 = beta4.redIAdd(beta4);    var beta8 = beta4.redAdd(beta4);    nx = alpha.redSqr().redISub(beta8);    // Z3 = (Y1 + Z1)^2 - gamma - delta    nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta);    // Y3 = alpha * (4 * beta - X3) - 8 * gamma^2    var ggamma8 = gamma.redSqr();    ggamma8 = ggamma8.redIAdd(ggamma8);    ggamma8 = ggamma8.redIAdd(ggamma8);    ggamma8 = ggamma8.redIAdd(ggamma8);    ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8);  }  return this.curve.jpoint(nx, ny, nz);};JPoint.prototype._dbl = function _dbl() {  var a = this.curve.a;  // 4M + 6S + 10A  var jx = this.x;  var jy = this.y;  var jz = this.z;  var jz4 = jz.redSqr().redSqr();  var jx2 = jx.redSqr();  var jy2 = jy.redSqr();  var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));  var jxd4 = jx.redAdd(jx);  jxd4 = jxd4.redIAdd(jxd4);  var t1 = jxd4.redMul(jy2);  var nx = c.redSqr().redISub(t1.redAdd(t1));  var t2 = t1.redISub(nx);  var jyd8 = jy2.redSqr();  jyd8 = jyd8.redIAdd(jyd8);  jyd8 = jyd8.redIAdd(jyd8);  jyd8 = jyd8.redIAdd(jyd8);  var ny = c.redMul(t2).redISub(jyd8);  var nz = jy.redAdd(jy).redMul(jz);  return this.curve.jpoint(nx, ny, nz);};JPoint.prototype.trpl = function trpl() {  if (!this.curve.zeroA)    return this.dbl().add(this);  // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl  // 5M + 10S + ...  // XX = X1^2  var xx = this.x.redSqr();  // YY = Y1^2  var yy = this.y.redSqr();  // ZZ = Z1^2  var zz = this.z.redSqr();  // YYYY = YY^2  var yyyy = yy.redSqr();  // M = 3 * XX + a * ZZ2; a = 0  var m = xx.redAdd(xx).redIAdd(xx);  // MM = M^2  var mm = m.redSqr();  // E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM  var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);  e = e.redIAdd(e);  e = e.redAdd(e).redIAdd(e);  e = e.redISub(mm);  // EE = E^2  var ee = e.redSqr();  // T = 16*YYYY  var t = yyyy.redIAdd(yyyy);  t = t.redIAdd(t);  t = t.redIAdd(t);  t = t.redIAdd(t);  // U = (M + E)^2 - MM - EE - T  var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t);  // X3 = 4 * (X1 * EE - 4 * YY * U)  var yyu4 = yy.redMul(u);  yyu4 = yyu4.redIAdd(yyu4);  yyu4 = yyu4.redIAdd(yyu4);  var nx = this.x.redMul(ee).redISub(yyu4);  nx = nx.redIAdd(nx);  nx = nx.redIAdd(nx);  // Y3 = 8 * Y1 * (U * (T - U) - E * EE)  var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee)));  ny = ny.redIAdd(ny);  ny = ny.redIAdd(ny);  ny = ny.redIAdd(ny);  // Z3 = (Z1 + E)^2 - ZZ - EE  var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee);  return this.curve.jpoint(nx, ny, nz);};JPoint.prototype.mul = function mul(k, kbase) {  k = new BN(k, kbase);  return this.curve._wnafMul(this, k);};JPoint.prototype.eq = function eq(p) {  if (p.type === 'affine')    return this.eq(p.toJ());  if (this === p)    return true;  // x1 * z2^2 == x2 * z1^2  var z2 = this.z.redSqr();  var pz2 = p.z.redSqr();  if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0)    return false;  // y1 * z2^3 == y2 * z1^3  var z3 = z2.redMul(this.z);  var pz3 = pz2.redMul(p.z);  return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0;};JPoint.prototype.eqXToP = function eqXToP(x) {  var zs = this.z.redSqr();  var rx = x.toRed(this.curve.red).redMul(zs);  if (this.x.cmp(rx) === 0)    return true;  var xc = x.clone();  var t = this.curve.redN.redMul(zs);  for (;;) {    xc.iadd(this.curve.n);    if (xc.cmp(this.curve.p) >= 0)      return false;    rx.redIAdd(t);    if (this.x.cmp(rx) === 0)      return true;  }};JPoint.prototype.inspect = function inspect() {  if (this.isInfinity())    return '<EC JPoint Infinity>';  return '<EC JPoint x: ' + this.x.toString(16, 2) +      ' y: ' + this.y.toString(16, 2) +      ' z: ' + this.z.toString(16, 2) + '>';};JPoint.prototype.isInfinity = function isInfinity() {  // XXX This code assumes that zero is always zero in red  return this.z.cmpn(0) === 0;};},{"../../elliptic":120,"../curve":123,"bn.js":45,"inherits":154}],126:[function(require,module,exports){'use strict';var curves = exports;var hash = require('hash.js');var elliptic = require('../elliptic');var assert = elliptic.utils.assert;function PresetCurve(options) {  if (options.type === 'short')    this.curve = new elliptic.curve.short(options);  else if (options.type === 'edwards')    this.curve = new elliptic.curve.edwards(options);  else    this.curve = new elliptic.curve.mont(options);  this.g = this.curve.g;  this.n = this.curve.n;  this.hash = options.hash;  assert(this.g.validate(), 'Invalid curve');  assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, G*N != O');}curves.PresetCurve = PresetCurve;function defineCurve(name, options) {  Object.defineProperty(curves, name, {    configurable: true,    enumerable: true,    get: function() {      var curve = new PresetCurve(options);      Object.defineProperty(curves, name, {        configurable: true,        enumerable: true,        value: curve      });      return curve;    }  });}defineCurve('p192', {  type: 'short',  prime: 'p192',  p: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff',  a: 'ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc',  b: '64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1',  n: 'ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831',  hash: hash.sha256,  gRed: false,  g: [    '188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012',    '07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811'  ]});defineCurve('p224', {  type: 'short',  prime: 'p224',  p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001',  a: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe',  b: 'b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4',  n: 'ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d',  hash: hash.sha256,  gRed: false,  g: [    'b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21',    'bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34'  ]});defineCurve('p256', {  type: 'short',  prime: null,  p: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff',  a: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc',  b: '5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b',  n: 'ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551',  hash: hash.sha256,  gRed: false,  g: [    '6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296',    '4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5'  ]});defineCurve('p384', {  type: 'short',  prime: null,  p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +     'fffffffe ffffffff 00000000 00000000 ffffffff',  a: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +     'fffffffe ffffffff 00000000 00000000 fffffffc',  b: 'b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f ' +     '5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef',  n: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 ' +     'f4372ddf 581a0db2 48b0a77a ecec196a ccc52973',  hash: hash.sha384,  gRed: false,  g: [    'aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98 59f741e0 82542a38 ' +    '5502f25d bf55296c 3a545e38 72760ab7',    '3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c e9da3113 b5f0b8c0 ' +    '0a60b1ce 1d7e819d 7a431d7c 90ea0e5f'  ]});defineCurve('p521', {  type: 'short',  prime: null,  p: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +     'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +     'ffffffff ffffffff ffffffff ffffffff ffffffff',  a: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +     'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +     'ffffffff ffffffff ffffffff ffffffff fffffffc',  b: '00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b ' +     '99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd ' +     '3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00',  n: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +     'ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 ' +     'f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409',  hash: hash.sha512,  gRed: false,  g: [    '000000c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139 ' +    '053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127 ' +    'a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66',    '00000118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449 ' +    '579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901 ' +    '3fad0761 353c7086 a272c240 88be9476 9fd16650'  ]});defineCurve('curve25519', {  type: 'mont',  prime: 'p25519',  p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',  a: '76d06',  b: '1',  n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',  hash: hash.sha256,  gRed: false,  g: [    '9'  ]});defineCurve('ed25519', {  type: 'edwards',  prime: 'p25519',  p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',  a: '-1',  c: '1',  // -121665 * (121666^(-1)) (mod P)  d: '52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3',  n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',  hash: hash.sha256,  gRed: false,  g: [    '216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a',    // 4/5    '6666666666666666666666666666666666666666666666666666666666666658'  ]});var pre;try {  pre = require('./precomputed/secp256k1');} catch (e) {  pre = undefined;}defineCurve('secp256k1', {  type: 'short',  prime: 'k256',  p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f',  a: '0',  b: '7',  n: 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141',  h: '1',  hash: hash.sha256,  // Precomputed endomorphism  beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee',  lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72',  basis: [    {      a: '3086d221a7d46bcde86c90e49284eb15',      b: '-e4437ed6010e88286f547fa90abfe4c3'    },    {      a: '114ca50f7a8e2f3f657c1108d9d44cfd8',      b: '3086d221a7d46bcde86c90e49284eb15'    }  ],  gRed: false,  g: [    '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',    '483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8',    pre  ]});},{"../elliptic":120,"./precomputed/secp256k1":133,"hash.js":139}],127:[function(require,module,exports){'use strict';var BN = require('bn.js');var HmacDRBG = require('hmac-drbg');var elliptic = require('../../elliptic');var utils = elliptic.utils;var assert = utils.assert;var KeyPair = require('./key');var Signature = require('./signature');function EC(options) {  if (!(this instanceof EC))    return new EC(options);  // Shortcut `elliptic.ec(curve-name)`  if (typeof options === 'string') {    assert(elliptic.curves.hasOwnProperty(options), 'Unknown curve ' + options);    options = elliptic.curves[options];  }  // Shortcut for `elliptic.ec(elliptic.curves.curveName)`  if (options instanceof elliptic.curves.PresetCurve)    options = { curve: options };  this.curve = options.curve.curve;  this.n = this.curve.n;  this.nh = this.n.ushrn(1);  this.g = this.curve.g;  // Point on curve  this.g = options.curve.g;  this.g.precompute(options.curve.n.bitLength() + 1);  // Hash for function for DRBG  this.hash = options.hash || options.curve.hash;}module.exports = EC;EC.prototype.keyPair = function keyPair(options) {  return new KeyPair(this, options);};EC.prototype.keyFromPrivate = function keyFromPrivate(priv, enc) {  return KeyPair.fromPrivate(this, priv, enc);};EC.prototype.keyFromPublic = function keyFromPublic(pub, enc) {  return KeyPair.fromPublic(this, pub, enc);};EC.prototype.genKeyPair = function genKeyPair(options) {  if (!options)    options = {};  // Instantiate Hmac_DRBG  var drbg = new HmacDRBG({    hash: this.hash,    pers: options.pers,    persEnc: options.persEnc || 'utf8',    entropy: options.entropy || elliptic.rand(this.hash.hmacStrength),    entropyEnc: options.entropy && options.entropyEnc || 'utf8',    nonce: this.n.toArray()  });  var bytes = this.n.byteLength();  var ns2 = this.n.sub(new BN(2));  do {    var priv = new BN(drbg.generate(bytes));    if (priv.cmp(ns2) > 0)      continue;    priv.iaddn(1);    return this.keyFromPrivate(priv);  } while (true);};EC.prototype._truncateToN = function truncateToN(msg, truncOnly) {  var delta = msg.byteLength() * 8 - this.n.bitLength();  if (delta > 0)    msg = msg.ushrn(delta);  if (!truncOnly && msg.cmp(this.n) >= 0)    return msg.sub(this.n);  else    return msg;};EC.prototype.sign = function sign(msg, key, enc, options) {  if (typeof enc === 'object') {    options = enc;    enc = null;  }  if (!options)    options = {};  key = this.keyFromPrivate(key, enc);  msg = this._truncateToN(new BN(msg, 16));  // Zero-extend key to provide enough entropy  var bytes = this.n.byteLength();  var bkey = key.getPrivate().toArray('be', bytes);  // Zero-extend nonce to have the same byte size as N  var nonce = msg.toArray('be', bytes);  // Instantiate Hmac_DRBG  var drbg = new HmacDRBG({    hash: this.hash,    entropy: bkey,    nonce: nonce,    pers: options.pers,    persEnc: options.persEnc || 'utf8'  });  // Number of bytes to generate  var ns1 = this.n.sub(new BN(1));  for (var iter = 0; true; iter++) {    var k = options.k ?        options.k(iter) :        new BN(drbg.generate(this.n.byteLength()));    k = this._truncateToN(k, true);    if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0)      continue;    var kp = this.g.mul(k);    if (kp.isInfinity())      continue;    var kpX = kp.getX();    var r = kpX.umod(this.n);    if (r.cmpn(0) === 0)      continue;    var s = k.invm(this.n).mul(r.mul(key.getPrivate()).iadd(msg));    s = s.umod(this.n);    if (s.cmpn(0) === 0)      continue;    var recoveryParam = (kp.getY().isOdd() ? 1 : 0) |                        (kpX.cmp(r) !== 0 ? 2 : 0);    // Use complement of `s`, if it is > `n / 2`    if (options.canonical && s.cmp(this.nh) > 0) {      s = this.n.sub(s);      recoveryParam ^= 1;    }    return new Signature({ r: r, s: s, recoveryParam: recoveryParam });  }};EC.prototype.verify = function verify(msg, signature, key, enc) {  msg = this._truncateToN(new BN(msg, 16));  key = this.keyFromPublic(key, enc);  signature = new Signature(signature, 'hex');  // Perform primitive values validation  var r = signature.r;  var s = signature.s;  if (r.cmpn(1) < 0 || r.cmp(this.n) >= 0)    return false;  if (s.cmpn(1) < 0 || s.cmp(this.n) >= 0)    return false;  // Validate signature  var sinv = s.invm(this.n);  var u1 = sinv.mul(msg).umod(this.n);  var u2 = sinv.mul(r).umod(this.n);  if (!this.curve._maxwellTrick) {    var p = this.g.mulAdd(u1, key.getPublic(), u2);    if (p.isInfinity())      return false;    return p.getX().umod(this.n).cmp(r) === 0;  }  // NOTE: Greg Maxwell's trick, inspired by:  // https://git.io/vad3K  var p = this.g.jmulAdd(u1, key.getPublic(), u2);  if (p.isInfinity())    return false;  // Compare `p.x` of Jacobian point with `r`,  // this will do `p.x == r * p.z^2` instead of multiplying `p.x` by the  // inverse of `p.z^2`  return p.eqXToP(r);};EC.prototype.recoverPubKey = function(msg, signature, j, enc) {  assert((3 & j) === j, 'The recovery param is more than two bits');  signature = new Signature(signature, enc);  var n = this.n;  var e = new BN(msg);  var r = signature.r;  var s = signature.s;  // A set LSB signifies that the y-coordinate is odd  var isYOdd = j & 1;  var isSecondKey = j >> 1;  if (r.cmp(this.curve.p.umod(this.curve.n)) >= 0 && isSecondKey)    throw new Error('Unable to find sencond key candinate');  // 1.1. Let x = r + jn.  if (isSecondKey)    r = this.curve.pointFromX(r.add(this.curve.n), isYOdd);  else    r = this.curve.pointFromX(r, isYOdd);  var rInv = signature.r.invm(n);  var s1 = n.sub(e).mul(rInv).umod(n);  var s2 = s.mul(rInv).umod(n);  // 1.6.1 Compute Q = r^-1 (sR -  eG)  //               Q = r^-1 (sR + -eG)  return this.g.mulAdd(s1, r, s2);};EC.prototype.getKeyRecoveryParam = function(e, signature, Q, enc) {  signature = new Signature(signature, enc);  if (signature.recoveryParam !== null)    return signature.recoveryParam;  for (var i = 0; i < 4; i++) {    var Qprime;    try {      Qprime = this.recoverPubKey(e, signature, i);    } catch (e) {      continue;    }    if (Qprime.eq(Q))      return i;  }  throw new Error('Unable to find valid recovery factor');};},{"../../elliptic":120,"./key":128,"./signature":129,"bn.js":45,"hmac-drbg":151}],128:[function(require,module,exports){'use strict';var BN = require('bn.js');var elliptic = require('../../elliptic');var utils = elliptic.utils;var assert = utils.assert;function KeyPair(ec, options) {  this.ec = ec;  this.priv = null;  this.pub = null;  // KeyPair(ec, { priv: ..., pub: ... })  if (options.priv)    this._importPrivate(options.priv, options.privEnc);  if (options.pub)    this._importPublic(options.pub, options.pubEnc);}module.exports = KeyPair;KeyPair.fromPublic = function fromPublic(ec, pub, enc) {  if (pub instanceof KeyPair)    return pub;  return new KeyPair(ec, {    pub: pub,    pubEnc: enc  });};KeyPair.fromPrivate = function fromPrivate(ec, priv, enc) {  if (priv instanceof KeyPair)    return priv;  return new KeyPair(ec, {    priv: priv,    privEnc: enc  });};KeyPair.prototype.validate = function validate() {  var pub = this.getPublic();  if (pub.isInfinity())    return { result: false, reason: 'Invalid public key' };  if (!pub.validate())    return { result: false, reason: 'Public key is not a point' };  if (!pub.mul(this.ec.curve.n).isInfinity())    return { result: false, reason: 'Public key * N != O' };  return { result: true, reason: null };};KeyPair.prototype.getPublic = function getPublic(compact, enc) {  // compact is optional argument  if (typeof compact === 'string') {    enc = compact;    compact = null;  }  if (!this.pub)    this.pub = this.ec.g.mul(this.priv);  if (!enc)    return this.pub;  return this.pub.encode(enc, compact);};KeyPair.prototype.getPrivate = function getPrivate(enc) {  if (enc === 'hex')    return this.priv.toString(16, 2);  else    return this.priv;};KeyPair.prototype._importPrivate = function _importPrivate(key, enc) {  this.priv = new BN(key, enc || 16);  // Ensure that the priv won't be bigger than n, otherwise we may fail  // in fixed multiplication method  this.priv = this.priv.umod(this.ec.curve.n);};KeyPair.prototype._importPublic = function _importPublic(key, enc) {  if (key.x || key.y) {    // Montgomery points only have an `x` coordinate.    // Weierstrass/Edwards points on the other hand have both `x` and    // `y` coordinates.    if (this.ec.curve.type === 'mont') {      assert(key.x, 'Need x coordinate');    } else if (this.ec.curve.type === 'short' ||               this.ec.curve.type === 'edwards') {      assert(key.x && key.y, 'Need both x and y coordinate');    }    this.pub = this.ec.curve.point(key.x, key.y);    return;  }  this.pub = this.ec.curve.decodePoint(key, enc);};// ECDHKeyPair.prototype.derive = function derive(pub) {  return pub.mul(this.priv).getX();};// ECDSAKeyPair.prototype.sign = function sign(msg, enc, options) {  return this.ec.sign(msg, this, enc, options);};KeyPair.prototype.verify = function verify(msg, signature) {  return this.ec.verify(msg, signature, this);};KeyPair.prototype.inspect = function inspect() {  return '<Key priv: ' + (this.priv && this.priv.toString(16, 2)) +         ' pub: ' + (this.pub && this.pub.inspect()) + ' >';};},{"../../elliptic":120,"bn.js":45}],129:[function(require,module,exports){'use strict';var BN = require('bn.js');var elliptic = require('../../elliptic');var utils = elliptic.utils;var assert = utils.assert;function Signature(options, enc) {  if (options instanceof Signature)    return options;  if (this._importDER(options, enc))    return;  assert(options.r && options.s, 'Signature without r or s');  this.r = new BN(options.r, 16);  this.s = new BN(options.s, 16);  if (options.recoveryParam === undefined)    this.recoveryParam = null;  else    this.recoveryParam = options.recoveryParam;}module.exports = Signature;function Position() {  this.place = 0;}function getLength(buf, p) {  var initial = buf[p.place++];  if (!(initial & 0x80)) {    return initial;  }  var octetLen = initial & 0xf;  var val = 0;  for (var i = 0, off = p.place; i < octetLen; i++, off++) {    val <<= 8;    val |= buf[off];  }  p.place = off;  return val;}function rmPadding(buf) {  var i = 0;  var len = buf.length - 1;  while (!buf[i] && !(buf[i + 1] & 0x80) && i < len) {    i++;  }  if (i === 0) {    return buf;  }  return buf.slice(i);}Signature.prototype._importDER = function _importDER(data, enc) {  data = utils.toArray(data, enc);  var p = new Position();  if (data[p.place++] !== 0x30) {    return false;  }  var len = getLength(data, p);  if ((len + p.place) !== data.length) {    return false;  }  if (data[p.place++] !== 0x02) {    return false;  }  var rlen = getLength(data, p);  var r = data.slice(p.place, rlen + p.place);  p.place += rlen;  if (data[p.place++] !== 0x02) {    return false;  }  var slen = getLength(data, p);  if (data.length !== slen + p.place) {    return false;  }  var s = data.slice(p.place, slen + p.place);  if (r[0] === 0 && (r[1] & 0x80)) {    r = r.slice(1);  }  if (s[0] === 0 && (s[1] & 0x80)) {    s = s.slice(1);  }  this.r = new BN(r);  this.s = new BN(s);  this.recoveryParam = null;  return true;};function constructLength(arr, len) {  if (len < 0x80) {    arr.push(len);    return;  }  var octets = 1 + (Math.log(len) / Math.LN2 >>> 3);  arr.push(octets | 0x80);  while (--octets) {    arr.push((len >>> (octets << 3)) & 0xff);  }  arr.push(len);}Signature.prototype.toDER = function toDER(enc) {  var r = this.r.toArray();  var s = this.s.toArray();  // Pad values  if (r[0] & 0x80)    r = [ 0 ].concat(r);  // Pad values  if (s[0] & 0x80)    s = [ 0 ].concat(s);  r = rmPadding(r);  s = rmPadding(s);  while (!s[0] && !(s[1] & 0x80)) {    s = s.slice(1);  }  var arr = [ 0x02 ];  constructLength(arr, r.length);  arr = arr.concat(r);  arr.push(0x02);  constructLength(arr, s.length);  var backHalf = arr.concat(s);  var res = [ 0x30 ];  constructLength(res, backHalf.length);  res = res.concat(backHalf);  return utils.encode(res, enc);};},{"../../elliptic":120,"bn.js":45}],130:[function(require,module,exports){'use strict';var hash = require('hash.js');var elliptic = require('../../elliptic');var utils = elliptic.utils;var assert = utils.assert;var parseBytes = utils.parseBytes;var KeyPair = require('./key');var Signature = require('./signature');function EDDSA(curve) {  assert(curve === 'ed25519', 'only tested with ed25519 so far');  if (!(this instanceof EDDSA))    return new EDDSA(curve);  var curve = elliptic.curves[curve].curve;  this.curve = curve;  this.g = curve.g;  this.g.precompute(curve.n.bitLength() + 1);  this.pointClass = curve.point().constructor;  this.encodingLength = Math.ceil(curve.n.bitLength() / 8);  this.hash = hash.sha512;}module.exports = EDDSA;/*** @param {Array|String} message - message bytes* @param {Array|String|KeyPair} secret - secret bytes or a keypair* @returns {Signature} - signature*/EDDSA.prototype.sign = function sign(message, secret) {  message = parseBytes(message);  var key = this.keyFromSecret(secret);  var r = this.hashInt(key.messagePrefix(), message);  var R = this.g.mul(r);  var Rencoded = this.encodePoint(R);  var s_ = this.hashInt(Rencoded, key.pubBytes(), message)               .mul(key.priv());  var S = r.add(s_).umod(this.curve.n);  return this.makeSignature({ R: R, S: S, Rencoded: Rencoded });};/*** @param {Array} message - message bytes* @param {Array|String|Signature} sig - sig bytes* @param {Array|String|Point|KeyPair} pub - public key* @returns {Boolean} - true if public key matches sig of message*/EDDSA.prototype.verify = function verify(message, sig, pub) {  message = parseBytes(message);  sig = this.makeSignature(sig);  var key = this.keyFromPublic(pub);  var h = this.hashInt(sig.Rencoded(), key.pubBytes(), message);  var SG = this.g.mul(sig.S());  var RplusAh = sig.R().add(key.pub().mul(h));  return RplusAh.eq(SG);};EDDSA.prototype.hashInt = function hashInt() {  var hash = this.hash();  for (var i = 0; i < arguments.length; i++)    hash.update(arguments[i]);  return utils.intFromLE(hash.digest()).umod(this.curve.n);};EDDSA.prototype.keyFromPublic = function keyFromPublic(pub) {  return KeyPair.fromPublic(this, pub);};EDDSA.prototype.keyFromSecret = function keyFromSecret(secret) {  return KeyPair.fromSecret(this, secret);};EDDSA.prototype.makeSignature = function makeSignature(sig) {  if (sig instanceof Signature)    return sig;  return new Signature(this, sig);};/*** * https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-5.2** EDDSA defines methods for encoding and decoding points and integers. These are* helper convenience methods, that pass along to utility functions implied* parameters.**/EDDSA.prototype.encodePoint = function encodePoint(point) {  var enc = point.getY().toArray('le', this.encodingLength);  enc[this.encodingLength - 1] |= point.getX().isOdd() ? 0x80 : 0;  return enc;};EDDSA.prototype.decodePoint = function decodePoint(bytes) {  bytes = utils.parseBytes(bytes);  var lastIx = bytes.length - 1;  var normed = bytes.slice(0, lastIx).concat(bytes[lastIx] & ~0x80);  var xIsOdd = (bytes[lastIx] & 0x80) !== 0;  var y = utils.intFromLE(normed);  return this.curve.pointFromY(y, xIsOdd);};EDDSA.prototype.encodeInt = function encodeInt(num) {  return num.toArray('le', this.encodingLength);};EDDSA.prototype.decodeInt = function decodeInt(bytes) {  return utils.intFromLE(bytes);};EDDSA.prototype.isPoint = function isPoint(val) {  return val instanceof this.pointClass;};},{"../../elliptic":120,"./key":131,"./signature":132,"hash.js":139}],131:[function(require,module,exports){'use strict';var elliptic = require('../../elliptic');var utils = elliptic.utils;var assert = utils.assert;var parseBytes = utils.parseBytes;var cachedProperty = utils.cachedProperty;/*** @param {EDDSA} eddsa - instance* @param {Object} params - public/private key parameters** @param {Array<Byte>} [params.secret] - secret seed bytes* @param {Point} [params.pub] - public key point (aka `A` in eddsa terms)* @param {Array<Byte>} [params.pub] - public key point encoded as bytes**/function KeyPair(eddsa, params) {  this.eddsa = eddsa;  this._secret = parseBytes(params.secret);  if (eddsa.isPoint(params.pub))    this._pub = params.pub;  else    this._pubBytes = parseBytes(params.pub);}KeyPair.fromPublic = function fromPublic(eddsa, pub) {  if (pub instanceof KeyPair)    return pub;  return new KeyPair(eddsa, { pub: pub });};KeyPair.fromSecret = function fromSecret(eddsa, secret) {  if (secret instanceof KeyPair)    return secret;  return new KeyPair(eddsa, { secret: secret });};KeyPair.prototype.secret = function secret() {  return this._secret;};cachedProperty(KeyPair, 'pubBytes', function pubBytes() {  return this.eddsa.encodePoint(this.pub());});cachedProperty(KeyPair, 'pub', function pub() {  if (this._pubBytes)    return this.eddsa.decodePoint(this._pubBytes);  return this.eddsa.g.mul(this.priv());});cachedProperty(KeyPair, 'privBytes', function privBytes() {  var eddsa = this.eddsa;  var hash = this.hash();  var lastIx = eddsa.encodingLength - 1;  var a = hash.slice(0, eddsa.encodingLength);  a[0] &= 248;  a[lastIx] &= 127;  a[lastIx] |= 64;  return a;});cachedProperty(KeyPair, 'priv', function priv() {  return this.eddsa.decodeInt(this.privBytes());});cachedProperty(KeyPair, 'hash', function hash() {  return this.eddsa.hash().update(this.secret()).digest();});cachedProperty(KeyPair, 'messagePrefix', function messagePrefix() {  return this.hash().slice(this.eddsa.encodingLength);});KeyPair.prototype.sign = function sign(message) {  assert(this._secret, 'KeyPair can only verify');  return this.eddsa.sign(message, this);};KeyPair.prototype.verify = function verify(message, sig) {  return this.eddsa.verify(message, sig, this);};KeyPair.prototype.getSecret = function getSecret(enc) {  assert(this._secret, 'KeyPair is public only');  return utils.encode(this.secret(), enc);};KeyPair.prototype.getPublic = function getPublic(enc) {  return utils.encode(this.pubBytes(), enc);};module.exports = KeyPair;},{"../../elliptic":120}],132:[function(require,module,exports){'use strict';var BN = require('bn.js');var elliptic = require('../../elliptic');var utils = elliptic.utils;var assert = utils.assert;var cachedProperty = utils.cachedProperty;var parseBytes = utils.parseBytes;/*** @param {EDDSA} eddsa - eddsa instance* @param {Array<Bytes>|Object} sig -* @param {Array<Bytes>|Point} [sig.R] - R point as Point or bytes* @param {Array<Bytes>|bn} [sig.S] - S scalar as bn or bytes* @param {Array<Bytes>} [sig.Rencoded] - R point encoded* @param {Array<Bytes>} [sig.Sencoded] - S scalar encoded*/function Signature(eddsa, sig) {  this.eddsa = eddsa;  if (typeof sig !== 'object')    sig = parseBytes(sig);  if (Array.isArray(sig)) {    sig = {      R: sig.slice(0, eddsa.encodingLength),      S: sig.slice(eddsa.encodingLength)    };  }  assert(sig.R && sig.S, 'Signature without R or S');  if (eddsa.isPoint(sig.R))    this._R = sig.R;  if (sig.S instanceof BN)    this._S = sig.S;  this._Rencoded = Array.isArray(sig.R) ? sig.R : sig.Rencoded;  this._Sencoded = Array.isArray(sig.S) ? sig.S : sig.Sencoded;}cachedProperty(Signature, 'S', function S() {  return this.eddsa.decodeInt(this.Sencoded());});cachedProperty(Signature, 'R', function R() {  return this.eddsa.decodePoint(this.Rencoded());});cachedProperty(Signature, 'Rencoded', function Rencoded() {  return this.eddsa.encodePoint(this.R());});cachedProperty(Signature, 'Sencoded', function Sencoded() {  return this.eddsa.encodeInt(this.S());});Signature.prototype.toBytes = function toBytes() {  return this.Rencoded().concat(this.Sencoded());};Signature.prototype.toHex = function toHex() {  return utils.encode(this.toBytes(), 'hex').toUpperCase();};module.exports = Signature;},{"../../elliptic":120,"bn.js":45}],133:[function(require,module,exports){module.exports = {  doubles: {    step: 4,    points: [      [        'e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a',        'f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821'      ],      [        '8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508',        '11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf'      ],      [        '175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739',        'd3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695'      ],      [        '363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640',        '4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9'      ],      [        '8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c',        '4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36'      ],      [        '723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda',        '96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f'      ],      [        'eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa',        '5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999'      ],      [        '100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0',        'cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09'      ],      [        'e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d',        '9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d'      ],      [        'feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d',        'e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088'      ],      [        'da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1',        '9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d'      ],      [        '53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0',        '5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8'      ],      [        '8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047',        '10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a'      ],      [        '385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862',        '283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453'      ],      [        '6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7',        '7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160'      ],      [        '3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd',        '56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0'      ],      [        '85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83',        '7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6'      ],      [        '948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a',        '53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589'      ],      [        '6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8',        'bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17'      ],      [        'e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d',        '4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda'      ],      [        'e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725',        '7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd'      ],      [        '213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754',        '4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2'      ],      [        '4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c',        '17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6'      ],      [        'fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6',        '6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f'      ],      [        '76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39',        'c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01'      ],      [        'c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891',        '893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3'      ],      [        'd895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b',        'febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f'      ],      [        'b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03',        '2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7'      ],      [        'e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d',        'eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78'      ],      [        'a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070',        '7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1'      ],      [        '90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4',        'e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150'      ],      [        '8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da',        '662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82'      ],      [        'e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11',        '1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc'      ],      [        '8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e',        'efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b'      ],      [        'e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41',        '2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51'      ],      [        'b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef',        '67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45'      ],      [        'd68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8',        'db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120'      ],      [        '324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d',        '648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84'      ],      [        '4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96',        '35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d'      ],      [        '9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd',        'ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d'      ],      [        '6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5',        '9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8'      ],      [        'a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266',        '40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8'      ],      [        '7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71',        '34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac'      ],      [        '928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac',        'c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f'      ],      [        '85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751',        '1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962'      ],      [        'ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e',        '493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907'      ],      [        '827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241',        'c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec'      ],      [        'eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3',        'be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d'      ],      [        'e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f',        '4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414'      ],      [        '1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19',        'aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd'      ],      [        '146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be',        'b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0'      ],      [        'fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9',        '6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811'      ],      [        'da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2',        '8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1'      ],      [        'a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13',        '7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c'      ],      [        '174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c',        'ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73'      ],      [        '959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba',        '2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd'      ],      [        'd2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151',        'e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405'      ],      [        '64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073',        'd99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589'      ],      [        '8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458',        '38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e'      ],      [        '13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b',        '69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27'      ],      [        'bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366',        'd3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1'      ],      [        '8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa',        '40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482'      ],      [        '8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0',        '620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945'      ],      [        'dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787',        '7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573'      ],      [        'f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e',        'ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82'      ]    ]  },  naf: {    wnd: 7,    points: [      [        'f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9',        '388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672'      ],      [        '2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4',        'd8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6'      ],      [        '5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc',        '6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da'      ],      [        'acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe',        'cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37'      ],      [        '774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb',        'd984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b'      ],      [        'f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8',        'ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81'      ],      [        'd7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e',        '581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58'      ],      [        'defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34',        '4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77'      ],      [        '2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c',        '85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a'      ],      [        '352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5',        '321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c'      ],      [        '2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f',        '2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67'      ],      [        '9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714',        '73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402'      ],      [        'daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729',        'a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55'      ],      [        'c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db',        '2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482'      ],      [        '6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4',        'e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82'      ],      [        '1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5',        'b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396'      ],      [        '605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479',        '2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49'      ],      [        '62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d',        '80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf'      ],      [        '80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f',        '1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a'      ],      [        '7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb',        'd0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7'      ],      [        'd528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9',        'eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933'      ],      [        '49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963',        '758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a'      ],      [        '77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74',        '958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6'      ],      [        'f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530',        'e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37'      ],      [        '463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b',        '5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e'      ],      [        'f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247',        'cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6'      ],      [        'caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1',        'cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476'      ],      [        '2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120',        '4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40'      ],      [        '7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435',        '91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61'      ],      [        '754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18',        '673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683'      ],      [        'e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8',        '59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5'      ],      [        '186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb',        '3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b'      ],      [        'df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f',        '55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417'      ],      [        '5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143',        'efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868'      ],      [        '290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba',        'e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a'      ],      [        'af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45',        'f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6'      ],      [        '766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a',        '744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996'      ],      [        '59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e',        'c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e'      ],      [        'f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8',        'e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d'      ],      [        '7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c',        '30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2'      ],      [        '948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519',        'e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e'      ],      [        '7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab',        '100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437'      ],      [        '3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca',        'ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311'      ],      [        'd3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf',        '8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4'      ],      [        '1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610',        '68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575'      ],      [        '733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4',        'f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d'      ],      [        '15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c',        'd56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d'      ],      [        'a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940',        'edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629'      ],      [        'e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980',        'a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06'      ],      [        '311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3',        '66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374'      ],      [        '34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf',        '9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee'      ],      [        'f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63',        '4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1'      ],      [        'd7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448',        'fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b'      ],      [        '32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf',        '5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661'      ],      [        '7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5',        '8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6'      ],      [        'ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6',        '8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e'      ],      [        '16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5',        '5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d'      ],      [        'eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99',        'f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc'      ],      [        '78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51',        'f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4'      ],      [        '494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5',        '42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c'      ],      [        'a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5',        '204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b'      ],      [        'c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997',        '4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913'      ],      [        '841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881',        '73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154'      ],      [        '5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5',        '39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865'      ],      [        '36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66',        'd2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc'      ],      [        '336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726',        'ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224'      ],      [        '8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede',        '6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e'      ],      [        '1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94',        '60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6'      ],      [        '85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31',        '3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511'      ],      [        '29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51',        'b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b'      ],      [        'a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252',        'ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2'      ],      [        '4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5',        'cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c'      ],      [        'd24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b',        '6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3'      ],      [        'ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4',        '322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d'      ],      [        'af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f',        '6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700'      ],      [        'e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889',        '2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4'      ],      [        '591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246',        'b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196'      ],      [        '11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984',        '998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4'      ],      [        '3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a',        'b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257'      ],      [        'cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030',        'bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13'      ],      [        'c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197',        '6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096'      ],      [        'c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593',        'c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38'      ],      [        'a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef',        '21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f'      ],      [        '347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38',        '60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448'      ],      [        'da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a',        '49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a'      ],      [        'c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111',        '5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4'      ],      [        '4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502',        '7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437'      ],      [        '3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea',        'be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7'      ],      [        'cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26',        '8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d'      ],      [        'b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986',        '39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a'      ],      [        'd4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e',        '62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54'      ],      [        '48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4',        '25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77'      ],      [        'dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda',        'ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517'      ],      [        '6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859',        'cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10'      ],      [        'e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f',        'f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125'      ],      [        'eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c',        '6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e'      ],      [        '13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942',        'fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1'      ],      [        'ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a',        '1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2'      ],      [        'b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80',        '5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423'      ],      [        'ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d',        '438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8'      ],      [        '8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1',        'cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758'      ],      [        '52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63',        'c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375'      ],      [        'e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352',        '6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d'      ],      [        '7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193',        'ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec'      ],      [        '5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00',        '9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0'      ],      [        '32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58',        'ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c'      ],      [        'e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7',        'd3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4'      ],      [        '8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8',        'c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f'      ],      [        '4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e',        '67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649'      ],      [        '3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d',        'cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826'      ],      [        '674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b',        '299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5'      ],      [        'd32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f',        'f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87'      ],      [        '30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6',        '462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b'      ],      [        'be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297',        '62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc'      ],      [        '93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a',        '7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c'      ],      [        'b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c',        'ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f'      ],      [        'd5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52',        '4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a'      ],      [        'd3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb',        'bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46'      ],      [        '463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065',        'bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f'      ],      [        '7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917',        '603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03'      ],      [        '74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9',        'cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08'      ],      [        '30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3',        '553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8'      ],      [        '9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57',        '712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373'      ],      [        '176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66',        'ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3'      ],      [        '75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8',        '9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8'      ],      [        '809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721',        '9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1'      ],      [        '1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180',        '4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9'      ]    ]  }};},{}],134:[function(require,module,exports){'use strict';var utils = exports;var BN = require('bn.js');var minAssert = require('minimalistic-assert');var minUtils = require('minimalistic-crypto-utils');utils.assert = minAssert;utils.toArray = minUtils.toArray;utils.zero2 = minUtils.zero2;utils.toHex = minUtils.toHex;utils.encode = minUtils.encode;// Represent num in a w-NAF formfunction getNAF(num, w) {  var naf = [];  var ws = 1 << (w + 1);  var k = num.clone();  while (k.cmpn(1) >= 0) {    var z;    if (k.isOdd()) {      var mod = k.andln(ws - 1);      if (mod > (ws >> 1) - 1)        z = (ws >> 1) - mod;      else        z = mod;      k.isubn(z);    } else {      z = 0;    }    naf.push(z);    // Optimization, shift by word if possible    var shift = (k.cmpn(0) !== 0 && k.andln(ws - 1) === 0) ? (w + 1) : 1;    for (var i = 1; i < shift; i++)      naf.push(0);    k.iushrn(shift);  }  return naf;}utils.getNAF = getNAF;// Represent k1, k2 in a Joint Sparse Formfunction getJSF(k1, k2) {  var jsf = [    [],    []  ];  k1 = k1.clone();  k2 = k2.clone();  var d1 = 0;  var d2 = 0;  while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) {    // First phase    var m14 = (k1.andln(3) + d1) & 3;    var m24 = (k2.andln(3) + d2) & 3;    if (m14 === 3)      m14 = -1;    if (m24 === 3)      m24 = -1;    var u1;    if ((m14 & 1) === 0) {      u1 = 0;    } else {      var m8 = (k1.andln(7) + d1) & 7;      if ((m8 === 3 || m8 === 5) && m24 === 2)        u1 = -m14;      else        u1 = m14;    }    jsf[0].push(u1);    var u2;    if ((m24 & 1) === 0) {      u2 = 0;    } else {      var m8 = (k2.andln(7) + d2) & 7;      if ((m8 === 3 || m8 === 5) && m14 === 2)        u2 = -m24;      else        u2 = m24;    }    jsf[1].push(u2);    // Second phase    if (2 * d1 === u1 + 1)      d1 = 1 - d1;    if (2 * d2 === u2 + 1)      d2 = 1 - d2;    k1.iushrn(1);    k2.iushrn(1);  }  return jsf;}utils.getJSF = getJSF;function cachedProperty(obj, name, computer) {  var key = '_' + name;  obj.prototype[name] = function cachedProperty() {    return this[key] !== undefined ? this[key] :           this[key] = computer.call(this);  };}utils.cachedProperty = cachedProperty;function parseBytes(bytes) {  return typeof bytes === 'string' ? utils.toArray(bytes, 'hex') :                                     bytes;}utils.parseBytes = parseBytes;function intFromLE(bytes) {  return new BN(bytes, 'hex', 'le');}utils.intFromLE = intFromLE;},{"bn.js":45,"minimalistic-assert":197,"minimalistic-crypto-utils":198}],135:[function(require,module,exports){module.exports={  "_args": [    [      "elliptic@6.4.1",      "C:\\Users\\Administrator\\code\\xlsx-populate"    ]  ],  "_development": true,  "_from": "elliptic@6.4.1",  "_id": "elliptic@6.4.1",  "_inBundle": false,  "_integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==",  "_location": "/elliptic",  "_phantomChildren": {},  "_requested": {    "type": "version",    "registry": true,    "raw": "elliptic@6.4.1",    "name": "elliptic",    "escapedName": "elliptic",    "rawSpec": "6.4.1",    "saveSpec": null,    "fetchSpec": "6.4.1"  },  "_requiredBy": [    "/browserify-sign",    "/create-ecdh"  ],  "_resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz",  "_spec": "6.4.1",  "_where": "C:\\Users\\Administrator\\code\\xlsx-populate",  "author": {    "name": "Fedor Indutny",    "email": "fedor@indutny.com"  },  "bugs": {    "url": "https://github.com/indutny/elliptic/issues"  },  "dependencies": {    "bn.js": "^4.4.0",    "brorand": "^1.0.1",    "hash.js": "^1.0.0",    "hmac-drbg": "^1.0.0",    "inherits": "^2.0.1",    "minimalistic-assert": "^1.0.0",    "minimalistic-crypto-utils": "^1.0.0"  },  "description": "EC cryptography",  "devDependencies": {    "brfs": "^1.4.3",    "coveralls": "^2.11.3",    "grunt": "^0.4.5",    "grunt-browserify": "^5.0.0",    "grunt-cli": "^1.2.0",    "grunt-contrib-connect": "^1.0.0",    "grunt-contrib-copy": "^1.0.0",    "grunt-contrib-uglify": "^1.0.1",    "grunt-mocha-istanbul": "^3.0.1",    "grunt-saucelabs": "^8.6.2",    "istanbul": "^0.4.2",    "jscs": "^2.9.0",    "jshint": "^2.6.0",    "mocha": "^2.1.0"  },  "files": [    "lib"  ],  "homepage": "https://github.com/indutny/elliptic",  "keywords": [    "EC",    "Elliptic",    "curve",    "Cryptography"  ],  "license": "MIT",  "main": "lib/elliptic.js",  "name": "elliptic",  "repository": {    "type": "git",    "url": "git+ssh://git@github.com/indutny/elliptic.git"  },  "scripts": {    "jscs": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js",    "jshint": "jscs benchmarks/*.js lib/*.js lib/**/*.js lib/**/**/*.js test/index.js",    "lint": "npm run jscs && npm run jshint",    "test": "npm run lint && npm run unit",    "unit": "istanbul test _mocha --reporter=spec test/index.js",    "version": "grunt dist && git add dist/"  },  "version": "6.4.1"}},{}],136:[function(require,module,exports){// Copyright Joyent, Inc. and other Node contributors.//// Permission is hereby granted, free of charge, to any person obtaining a// copy of this software and associated documentation files (the// "Software"), to deal in the Software without restriction, including// without limitation the rights to use, copy, modify, merge, publish,// distribute, sublicense, and/or sell copies of the Software, and to permit// persons to whom the Software is furnished to do so, subject to the// following conditions://// The above copyright notice and this permission notice shall be included// in all copies or substantial portions of the Software.//// THE SOFTWARE IS 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. IN// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE// USE OR OTHER DEALINGS IN THE SOFTWARE.var objectCreate = Object.create || objectCreatePolyfillvar objectKeys = Object.keys || objectKeysPolyfillvar bind = Function.prototype.bind || functionBindPolyfillfunction EventEmitter() {  if (!this._events || !Object.prototype.hasOwnProperty.call(this, '_events')) {    this._events = objectCreate(null);    this._eventsCount = 0;  }  this._maxListeners = this._maxListeners || undefined;}module.exports = EventEmitter;// Backwards-compat with node 0.10.xEventEmitter.EventEmitter = EventEmitter;EventEmitter.prototype._events = undefined;EventEmitter.prototype._maxListeners = undefined;// By default EventEmitters will print a warning if more than 10 listeners are// added to it. This is a useful default which helps finding memory leaks.var defaultMaxListeners = 10;var hasDefineProperty;try {  var o = {};  if (Object.defineProperty) Object.defineProperty(o, 'x', { value: 0 });  hasDefineProperty = o.x === 0;} catch (err) { hasDefineProperty = false }if (hasDefineProperty) {  Object.defineProperty(EventEmitter, 'defaultMaxListeners', {    enumerable: true,    get: function() {      return defaultMaxListeners;    },    set: function(arg) {      // check whether the input is a positive number (whose value is zero or      // greater and not a NaN).      if (typeof arg !== 'number' || arg < 0 || arg !== arg)        throw new TypeError('"defaultMaxListeners" must be a positive number');      defaultMaxListeners = arg;    }  });} else {  EventEmitter.defaultMaxListeners = defaultMaxListeners;}// Obviously not all Emitters should be limited to 10. This function allows// that to be increased. Set to zero for unlimited.EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {  if (typeof n !== 'number' || n < 0 || isNaN(n))    throw new TypeError('"n" argument must be a positive number');  this._maxListeners = n;  return this;};function $getMaxListeners(that) {  if (that._maxListeners === undefined)    return EventEmitter.defaultMaxListeners;  return that._maxListeners;}EventEmitter.prototype.getMaxListeners = function getMaxListeners() {  return $getMaxListeners(this);};// These standalone emit* functions are used to optimize calling of event// handlers for fast cases because emit() itself often has a variable number of// arguments and can be deoptimized because of that. These functions always have// the same number of arguments and thus do not get deoptimized, so the code// inside them can execute faster.function emitNone(handler, isFn, self) {  if (isFn)    handler.call(self);  else {    var len = handler.length;    var listeners = arrayClone(handler, len);    for (var i = 0; i < len; ++i)      listeners[i].call(self);  }}function emitOne(handler, isFn, self, arg1) {  if (isFn)    handler.call(self, arg1);  else {    var len = handler.length;    var listeners = arrayClone(handler, len);    for (var i = 0; i < len; ++i)      listeners[i].call(self, arg1);  }}function emitTwo(handler, isFn, self, arg1, arg2) {  if (isFn)    handler.call(self, arg1, arg2);  else {    var len = handler.length;    var listeners = arrayClone(handler, len);    for (var i = 0; i < len; ++i)      listeners[i].call(self, arg1, arg2);  }}function emitThree(handler, isFn, self, arg1, arg2, arg3) {  if (isFn)    handler.call(self, arg1, arg2, arg3);  else {    var len = handler.length;    var listeners = arrayClone(handler, len);    for (var i = 0; i < len; ++i)      listeners[i].call(self, arg1, arg2, arg3);  }}function emitMany(handler, isFn, self, args) {  if (isFn)    handler.apply(self, args);  else {    var len = handler.length;    var listeners = arrayClone(handler, len);    for (var i = 0; i < len; ++i)      listeners[i].apply(self, args);  }}EventEmitter.prototype.emit = function emit(type) {  var er, handler, len, args, i, events;  var doError = (type === 'error');  events = this._events;  if (events)    doError = (doError && events.error == null);  else if (!doError)    return false;  // If there is no 'error' event listener then throw.  if (doError) {    if (arguments.length > 1)      er = arguments[1];    if (er instanceof Error) {      throw er; // Unhandled 'error' event    } else {      // At least give some kind of context to the user      var err = new Error('Unhandled "error" event. (' + er + ')');      err.context = er;      throw err;    }    return false;  }  handler = events[type];  if (!handler)    return false;  var isFn = typeof handler === 'function';  len = arguments.length;  switch (len) {      // fast cases    case 1:      emitNone(handler, isFn, this);      break;    case 2:      emitOne(handler, isFn, this, arguments[1]);      break;    case 3:      emitTwo(handler, isFn, this, arguments[1], arguments[2]);      break;    case 4:      emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]);      break;      // slower    default:      args = new Array(len - 1);      for (i = 1; i < len; i++)        args[i - 1] = arguments[i];      emitMany(handler, isFn, this, args);  }  return true;};function _addListener(target, type, listener, prepend) {  var m;  var events;  var existing;  if (typeof listener !== 'function')    throw new TypeError('"listener" argument must be a function');  events = target._events;  if (!events) {    events = target._events = objectCreate(null);    target._eventsCount = 0;  } else {    // To avoid recursion in the case that type === "newListener"! Before    // adding it to the listeners, first emit "newListener".    if (events.newListener) {      target.emit('newListener', type,          listener.listener ? listener.listener : listener);      // Re-assign `events` because a newListener handler could have caused the      // this._events to be assigned to a new object      events = target._events;    }    existing = events[type];  }  if (!existing) {    // Optimize the case of one listener. Don't need the extra array object.    existing = events[type] = listener;    ++target._eventsCount;  } else {    if (typeof existing === 'function') {      // Adding the second element, need to change to array.      existing = events[type] =          prepend ? [listener, existing] : [existing, listener];    } else {      // If we've already got an array, just append.      if (prepend) {        existing.unshift(listener);      } else {        existing.push(listener);      }    }    // Check for listener leak    if (!existing.warned) {      m = $getMaxListeners(target);      if (m && m > 0 && existing.length > m) {        existing.warned = true;        var w = new Error('Possible EventEmitter memory leak detected. ' +            existing.length + ' "' + String(type) + '" listeners ' +            'added. Use emitter.setMaxListeners() to ' +            'increase limit.');        w.name = 'MaxListenersExceededWarning';        w.emitter = target;        w.type = type;        w.count = existing.length;        if (typeof console === 'object' && console.warn) {          console.warn('%s: %s', w.name, w.message);        }      }    }  }  return target;}EventEmitter.prototype.addListener = function addListener(type, listener) {  return _addListener(this, type, listener, false);};EventEmitter.prototype.on = EventEmitter.prototype.addListener;EventEmitter.prototype.prependListener =    function prependListener(type, listener) {      return _addListener(this, type, listener, true);    };function onceWrapper() {  if (!this.fired) {    this.target.removeListener(this.type, this.wrapFn);    this.fired = true;    switch (arguments.length) {      case 0:        return this.listener.call(this.target);      case 1:        return this.listener.call(this.target, arguments[0]);      case 2:        return this.listener.call(this.target, arguments[0], arguments[1]);      case 3:        return this.listener.call(this.target, arguments[0], arguments[1],            arguments[2]);      default:        var args = new Array(arguments.length);        for (var i = 0; i < args.length; ++i)          args[i] = arguments[i];        this.listener.apply(this.target, args);    }  }}function _onceWrap(target, type, listener) {  var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };  var wrapped = bind.call(onceWrapper, state);  wrapped.listener = listener;  state.wrapFn = wrapped;  return wrapped;}EventEmitter.prototype.once = function once(type, listener) {  if (typeof listener !== 'function')    throw new TypeError('"listener" argument must be a function');  this.on(type, _onceWrap(this, type, listener));  return this;};EventEmitter.prototype.prependOnceListener =    function prependOnceListener(type, listener) {      if (typeof listener !== 'function')        throw new TypeError('"listener" argument must be a function');      this.prependListener(type, _onceWrap(this, type, listener));      return this;    };// Emits a 'removeListener' event if and only if the listener was removed.EventEmitter.prototype.removeListener =    function removeListener(type, listener) {      var list, events, position, i, originalListener;      if (typeof listener !== 'function')        throw new TypeError('"listener" argument must be a function');      events = this._events;      if (!events)        return this;      list = events[type];      if (!list)        return this;      if (list === listener || list.listener === listener) {        if (--this._eventsCount === 0)          this._events = objectCreate(null);        else {          delete events[type];          if (events.removeListener)            this.emit('removeListener', type, list.listener || listener);        }      } else if (typeof list !== 'function') {        position = -1;        for (i = list.length - 1; i >= 0; i--) {          if (list[i] === listener || list[i].listener === listener) {            originalListener = list[i].listener;            position = i;            break;          }        }        if (position < 0)          return this;        if (position === 0)          list.shift();        else          spliceOne(list, position);        if (list.length === 1)          events[type] = list[0];        if (events.removeListener)          this.emit('removeListener', type, originalListener || listener);      }      return this;    };EventEmitter.prototype.removeAllListeners =    function removeAllListeners(type) {      var listeners, events, i;      events = this._events;      if (!events)        return this;      // not listening for removeListener, no need to emit      if (!events.removeListener) {        if (arguments.length === 0) {          this._events = objectCreate(null);          this._eventsCount = 0;        } else if (events[type]) {          if (--this._eventsCount === 0)            this._events = objectCreate(null);          else            delete events[type];        }        return this;      }      // emit removeListener for all listeners on all events      if (arguments.length === 0) {        var keys = objectKeys(events);        var key;        for (i = 0; i < keys.length; ++i) {          key = keys[i];          if (key === 'removeListener') continue;          this.removeAllListeners(key);        }        this.removeAllListeners('removeListener');        this._events = objectCreate(null);        this._eventsCount = 0;        return this;      }      listeners = events[type];      if (typeof listeners === 'function') {        this.removeListener(type, listeners);      } else if (listeners) {        // LIFO order        for (i = listeners.length - 1; i >= 0; i--) {          this.removeListener(type, listeners[i]);        }      }      return this;    };function _listeners(target, type, unwrap) {  var events = target._events;  if (!events)    return [];  var evlistener = events[type];  if (!evlistener)    return [];  if (typeof evlistener === 'function')    return unwrap ? [evlistener.listener || evlistener] : [evlistener];  return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);}EventEmitter.prototype.listeners = function listeners(type) {  return _listeners(this, type, true);};EventEmitter.prototype.rawListeners = function rawListeners(type) {  return _listeners(this, type, false);};EventEmitter.listenerCount = function(emitter, type) {  if (typeof emitter.listenerCount === 'function') {    return emitter.listenerCount(type);  } else {    return listenerCount.call(emitter, type);  }};EventEmitter.prototype.listenerCount = listenerCount;function listenerCount(type) {  var events = this._events;  if (events) {    var evlistener = events[type];    if (typeof evlistener === 'function') {      return 1;    } else if (evlistener) {      return evlistener.length;    }  }  return 0;}EventEmitter.prototype.eventNames = function eventNames() {  return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : [];};// About 1.5x faster than the two-arg version of Array#splice().function spliceOne(list, index) {  for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1)    list[i] = list[k];  list.pop();}function arrayClone(arr, n) {  var copy = new Array(n);  for (var i = 0; i < n; ++i)    copy[i] = arr[i];  return copy;}function unwrapListeners(arr) {  var ret = new Array(arr.length);  for (var i = 0; i < ret.length; ++i) {    ret[i] = arr[i].listener || arr[i];  }  return ret;}function objectCreatePolyfill(proto) {  var F = function() {};  F.prototype = proto;  return new F;}function objectKeysPolyfill(obj) {  var keys = [];  for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) {    keys.push(k);  }  return k;}function functionBindPolyfill(context) {  var fn = this;  return function () {    return fn.apply(context, arguments);  };}},{}],137:[function(require,module,exports){var Buffer = require('safe-buffer').Buffervar MD5 = require('md5.js')/* eslint-disable camelcase */function EVP_BytesToKey (password, salt, keyBits, ivLen) {  if (!Buffer.isBuffer(password)) password = Buffer.from(password, 'binary')  if (salt) {    if (!Buffer.isBuffer(salt)) salt = Buffer.from(salt, 'binary')    if (salt.length !== 8) throw new RangeError('salt should be Buffer with 8 byte length')  }  var keyLen = keyBits / 8  var key = Buffer.alloc(keyLen)  var iv = Buffer.alloc(ivLen || 0)  var tmp = Buffer.alloc(0)  while (keyLen > 0 || ivLen > 0) {    var hash = new MD5()    hash.update(tmp)    hash.update(password)    if (salt) hash.update(salt)    tmp = hash.digest()    var used = 0    if (keyLen > 0) {      var keyStart = key.length - keyLen      used = Math.min(keyLen, tmp.length)      tmp.copy(key, keyStart, 0, used)      keyLen -= used    }    if (used < tmp.length && ivLen > 0) {      var ivStart = iv.length - ivLen      var length = Math.min(ivLen, tmp.length - used)      tmp.copy(iv, ivStart, used, used + length)      ivLen -= length    }  }  tmp.fill(0)  return { key: key, iv: iv }}module.exports = EVP_BytesToKey},{"md5.js":194,"safe-buffer":247}],138:[function(require,module,exports){'use strict'var Buffer = require('safe-buffer').Buffervar Transform = require('stream').Transformvar inherits = require('inherits')function throwIfNotStringOrBuffer (val, prefix) {  if (!Buffer.isBuffer(val) && typeof val !== 'string') {    throw new TypeError(prefix + ' must be a string or a buffer')  }}function HashBase (blockSize) {  Transform.call(this)  this._block = Buffer.allocUnsafe(blockSize)  this._blockSize = blockSize  this._blockOffset = 0  this._length = [0, 0, 0, 0]  this._finalized = false}inherits(HashBase, Transform)HashBase.prototype._transform = function (chunk, encoding, callback) {  var error = null  try {    this.update(chunk, encoding)  } catch (err) {    error = err  }  callback(error)}HashBase.prototype._flush = function (callback) {  var error = null  try {    this.push(this.digest())  } catch (err) {    error = err  }  callback(error)}HashBase.prototype.update = function (data, encoding) {  throwIfNotStringOrBuffer(data, 'Data')  if (this._finalized) throw new Error('Digest already called')  if (!Buffer.isBuffer(data)) data = Buffer.from(data, encoding)  // consume data  var block = this._block  var offset = 0  while (this._blockOffset + data.length - offset >= this._blockSize) {    for (var i = this._blockOffset; i < this._blockSize;) block[i++] = data[offset++]    this._update()    this._blockOffset = 0  }  while (offset < data.length) block[this._blockOffset++] = data[offset++]  // update length  for (var j = 0, carry = data.length * 8; carry > 0; ++j) {    this._length[j] += carry    carry = (this._length[j] / 0x0100000000) | 0    if (carry > 0) this._length[j] -= 0x0100000000 * carry  }  return this}HashBase.prototype._update = function () {  throw new Error('_update is not implemented')}HashBase.prototype.digest = function (encoding) {  if (this._finalized) throw new Error('Digest already called')  this._finalized = true  var digest = this._digest()  if (encoding !== undefined) digest = digest.toString(encoding)  // reset state  this._block.fill(0)  this._blockOffset = 0  for (var i = 0; i < 4; ++i) this._length[i] = 0  return digest}HashBase.prototype._digest = function () {  throw new Error('_digest is not implemented')}module.exports = HashBase},{"inherits":154,"safe-buffer":247,"stream":257}],139:[function(require,module,exports){var hash = exports;hash.utils = require('./hash/utils');hash.common = require('./hash/common');hash.sha = require('./hash/sha');hash.ripemd = require('./hash/ripemd');hash.hmac = require('./hash/hmac');// Proxy hash functions to the main objecthash.sha1 = hash.sha.sha1;hash.sha256 = hash.sha.sha256;hash.sha224 = hash.sha.sha224;hash.sha384 = hash.sha.sha384;hash.sha512 = hash.sha.sha512;hash.ripemd160 = hash.ripemd.ripemd160;},{"./hash/common":140,"./hash/hmac":141,"./hash/ripemd":142,"./hash/sha":143,"./hash/utils":150}],140:[function(require,module,exports){'use strict';var utils = require('./utils');var assert = require('minimalistic-assert');function BlockHash() {  this.pending = null;  this.pendingTotal = 0;  this.blockSize = this.constructor.blockSize;  this.outSize = this.constructor.outSize;  this.hmacStrength = this.constructor.hmacStrength;  this.padLength = this.constructor.padLength / 8;  this.endian = 'big';  this._delta8 = this.blockSize / 8;  this._delta32 = this.blockSize / 32;}exports.BlockHash = BlockHash;BlockHash.prototype.update = function update(msg, enc) {  // Convert message to array, pad it, and join into 32bit blocks  msg = utils.toArray(msg, enc);  if (!this.pending)    this.pending = msg;  else    this.pending = this.pending.concat(msg);  this.pendingTotal += msg.length;  // Enough data, try updating  if (this.pending.length >= this._delta8) {    msg = this.pending;    // Process pending data in blocks    var r = msg.length % this._delta8;    this.pending = msg.slice(msg.length - r, msg.length);    if (this.pending.length === 0)      this.pending = null;    msg = utils.join32(msg, 0, msg.length - r, this.endian);    for (var i = 0; i < msg.length; i += this._delta32)      this._update(msg, i, i + this._delta32);  }  return this;};BlockHash.prototype.digest = function digest(enc) {  this.update(this._pad());  assert(this.pending === null);  return this._digest(enc);};BlockHash.prototype._pad = function pad() {  var len = this.pendingTotal;  var bytes = this._delta8;  var k = bytes - ((len + this.padLength) % bytes);  var res = new Array(k + this.padLength);  res[0] = 0x80;  for (var i = 1; i < k; i++)    res[i] = 0;  // Append length  len <<= 3;  if (this.endian === 'big') {    for (var t = 8; t < this.padLength; t++)      res[i++] = 0;    res[i++] = 0;    res[i++] = 0;    res[i++] = 0;    res[i++] = 0;    res[i++] = (len >>> 24) & 0xff;    res[i++] = (len >>> 16) & 0xff;    res[i++] = (len >>> 8) & 0xff;    res[i++] = len & 0xff;  } else {    res[i++] = len & 0xff;    res[i++] = (len >>> 8) & 0xff;    res[i++] = (len >>> 16) & 0xff;    res[i++] = (len >>> 24) & 0xff;    res[i++] = 0;    res[i++] = 0;    res[i++] = 0;    res[i++] = 0;    for (t = 8; t < this.padLength; t++)      res[i++] = 0;  }  return res;};},{"./utils":150,"minimalistic-assert":197}],141:[function(require,module,exports){'use strict';var utils = require('./utils');var assert = require('minimalistic-assert');function Hmac(hash, key, enc) {  if (!(this instanceof Hmac))    return new Hmac(hash, key, enc);  this.Hash = hash;  this.blockSize = hash.blockSize / 8;  this.outSize = hash.outSize / 8;  this.inner = null;  this.outer = null;  this._init(utils.toArray(key, enc));}module.exports = Hmac;Hmac.prototype._init = function init(key) {  // Shorten key, if needed  if (key.length > this.blockSize)    key = new this.Hash().update(key).digest();  assert(key.length <= this.blockSize);  // Add padding to key  for (var i = key.length; i < this.blockSize; i++)    key.push(0);  for (i = 0; i < key.length; i++)    key[i] ^= 0x36;  this.inner = new this.Hash().update(key);  // 0x36 ^ 0x5c = 0x6a  for (i = 0; i < key.length; i++)    key[i] ^= 0x6a;  this.outer = new this.Hash().update(key);};Hmac.prototype.update = function update(msg, enc) {  this.inner.update(msg, enc);  return this;};Hmac.prototype.digest = function digest(enc) {  this.outer.update(this.inner.digest());  return this.outer.digest(enc);};},{"./utils":150,"minimalistic-assert":197}],142:[function(require,module,exports){'use strict';var utils = require('./utils');var common = require('./common');var rotl32 = utils.rotl32;var sum32 = utils.sum32;var sum32_3 = utils.sum32_3;var sum32_4 = utils.sum32_4;var BlockHash = common.BlockHash;function RIPEMD160() {  if (!(this instanceof RIPEMD160))    return new RIPEMD160();  BlockHash.call(this);  this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ];  this.endian = 'little';}utils.inherits(RIPEMD160, BlockHash);exports.ripemd160 = RIPEMD160;RIPEMD160.blockSize = 512;RIPEMD160.outSize = 160;RIPEMD160.hmacStrength = 192;RIPEMD160.padLength = 64;RIPEMD160.prototype._update = function update(msg, start) {  var A = this.h[0];  var B = this.h[1];  var C = this.h[2];  var D = this.h[3];  var E = this.h[4];  var Ah = A;  var Bh = B;  var Ch = C;  var Dh = D;  var Eh = E;  for (var j = 0; j < 80; j++) {    var T = sum32(      rotl32(        sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)),        s[j]),      E);    A = E;    E = D;    D = rotl32(C, 10);    C = B;    B = T;    T = sum32(      rotl32(        sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)),        sh[j]),      Eh);    Ah = Eh;    Eh = Dh;    Dh = rotl32(Ch, 10);    Ch = Bh;    Bh = T;  }  T = sum32_3(this.h[1], C, Dh);  this.h[1] = sum32_3(this.h[2], D, Eh);  this.h[2] = sum32_3(this.h[3], E, Ah);  this.h[3] = sum32_3(this.h[4], A, Bh);  this.h[4] = sum32_3(this.h[0], B, Ch);  this.h[0] = T;};RIPEMD160.prototype._digest = function digest(enc) {  if (enc === 'hex')    return utils.toHex32(this.h, 'little');  else    return utils.split32(this.h, 'little');};function f(j, x, y, z) {  if (j <= 15)    return x ^ y ^ z;  else if (j <= 31)    return (x & y) | ((~x) & z);  else if (j <= 47)    return (x | (~y)) ^ z;  else if (j <= 63)    return (x & z) | (y & (~z));  else    return x ^ (y | (~z));}function K(j) {  if (j <= 15)    return 0x00000000;  else if (j <= 31)    return 0x5a827999;  else if (j <= 47)    return 0x6ed9eba1;  else if (j <= 63)    return 0x8f1bbcdc;  else    return 0xa953fd4e;}function Kh(j) {  if (j <= 15)    return 0x50a28be6;  else if (j <= 31)    return 0x5c4dd124;  else if (j <= 47)    return 0x6d703ef3;  else if (j <= 63)    return 0x7a6d76e9;  else    return 0x00000000;}var r = [  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,  7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,  3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,  1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,  4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13];var rh = [  5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,  6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,  15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,  8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,  12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11];var s = [  11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,  7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,  11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,  11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,  9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6];var sh = [  8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,  9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,  9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,  15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,  8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11];},{"./common":140,"./utils":150}],143:[function(require,module,exports){'use strict';exports.sha1 = require('./sha/1');exports.sha224 = require('./sha/224');exports.sha256 = require('./sha/256');exports.sha384 = require('./sha/384');exports.sha512 = require('./sha/512');},{"./sha/1":144,"./sha/224":145,"./sha/256":146,"./sha/384":147,"./sha/512":148}],144:[function(require,module,exports){'use strict';var utils = require('../utils');var common = require('../common');var shaCommon = require('./common');var rotl32 = utils.rotl32;var sum32 = utils.sum32;var sum32_5 = utils.sum32_5;var ft_1 = shaCommon.ft_1;var BlockHash = common.BlockHash;var sha1_K = [  0x5A827999, 0x6ED9EBA1,  0x8F1BBCDC, 0xCA62C1D6];function SHA1() {  if (!(this instanceof SHA1))    return new SHA1();  BlockHash.call(this);  this.h = [    0x67452301, 0xefcdab89, 0x98badcfe,    0x10325476, 0xc3d2e1f0 ];  this.W = new Array(80);}utils.inherits(SHA1, BlockHash);module.exports = SHA1;SHA1.blockSize = 512;SHA1.outSize = 160;SHA1.hmacStrength = 80;SHA1.padLength = 64;SHA1.prototype._update = function _update(msg, start) {  var W = this.W;  for (var i = 0; i < 16; i++)    W[i] = msg[start + i];  for(; i < W.length; i++)    W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);  var a = this.h[0];  var b = this.h[1];  var c = this.h[2];  var d = this.h[3];  var e = this.h[4];  for (i = 0; i < W.length; i++) {    var s = ~~(i / 20);    var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]);    e = d;    d = c;    c = rotl32(b, 30);    b = a;    a = t;  }  this.h[0] = sum32(this.h[0], a);  this.h[1] = sum32(this.h[1], b);  this.h[2] = sum32(this.h[2], c);  this.h[3] = sum32(this.h[3], d);  this.h[4] = sum32(this.h[4], e);};SHA1.prototype._digest = function digest(enc) {  if (enc === 'hex')    return utils.toHex32(this.h, 'big');  else    return utils.split32(this.h, 'big');};},{"../common":140,"../utils":150,"./common":149}],145:[function(require,module,exports){'use strict';var utils = require('../utils');var SHA256 = require('./256');function SHA224() {  if (!(this instanceof SHA224))    return new SHA224();  SHA256.call(this);  this.h = [    0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,    0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ];}utils.inherits(SHA224, SHA256);module.exports = SHA224;SHA224.blockSize = 512;SHA224.outSize = 224;SHA224.hmacStrength = 192;SHA224.padLength = 64;SHA224.prototype._digest = function digest(enc) {  // Just truncate output  if (enc === 'hex')    return utils.toHex32(this.h.slice(0, 7), 'big');  else    return utils.split32(this.h.slice(0, 7), 'big');};},{"../utils":150,"./256":146}],146:[function(require,module,exports){'use strict';var utils = require('../utils');var common = require('../common');var shaCommon = require('./common');var assert = require('minimalistic-assert');var sum32 = utils.sum32;var sum32_4 = utils.sum32_4;var sum32_5 = utils.sum32_5;var ch32 = shaCommon.ch32;var maj32 = shaCommon.maj32;var s0_256 = shaCommon.s0_256;var s1_256 = shaCommon.s1_256;var g0_256 = shaCommon.g0_256;var g1_256 = shaCommon.g1_256;var BlockHash = common.BlockHash;var sha256_K = [  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,  0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,  0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,  0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,  0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,  0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];function SHA256() {  if (!(this instanceof SHA256))    return new SHA256();  BlockHash.call(this);  this.h = [    0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,    0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19  ];  this.k = sha256_K;  this.W = new Array(64);}utils.inherits(SHA256, BlockHash);module.exports = SHA256;SHA256.blockSize = 512;SHA256.outSize = 256;SHA256.hmacStrength = 192;SHA256.padLength = 64;SHA256.prototype._update = function _update(msg, start) {  var W = this.W;  for (var i = 0; i < 16; i++)    W[i] = msg[start + i];  for (; i < W.length; i++)    W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]);  var a = this.h[0];  var b = this.h[1];  var c = this.h[2];  var d = this.h[3];  var e = this.h[4];  var f = this.h[5];  var g = this.h[6];  var h = this.h[7];  assert(this.k.length === W.length);  for (i = 0; i < W.length; i++) {    var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]);    var T2 = sum32(s0_256(a), maj32(a, b, c));    h = g;    g = f;    f = e;    e = sum32(d, T1);    d = c;    c = b;    b = a;    a = sum32(T1, T2);  }  this.h[0] = sum32(this.h[0], a);  this.h[1] = sum32(this.h[1], b);  this.h[2] = sum32(this.h[2], c);  this.h[3] = sum32(this.h[3], d);  this.h[4] = sum32(this.h[4], e);  this.h[5] = sum32(this.h[5], f);  this.h[6] = sum32(this.h[6], g);  this.h[7] = sum32(this.h[7], h);};SHA256.prototype._digest = function digest(enc) {  if (enc === 'hex')    return utils.toHex32(this.h, 'big');  else    return utils.split32(this.h, 'big');};},{"../common":140,"../utils":150,"./common":149,"minimalistic-assert":197}],147:[function(require,module,exports){'use strict';var utils = require('../utils');var SHA512 = require('./512');function SHA384() {  if (!(this instanceof SHA384))    return new SHA384();  SHA512.call(this);  this.h = [    0xcbbb9d5d, 0xc1059ed8,    0x629a292a, 0x367cd507,    0x9159015a, 0x3070dd17,    0x152fecd8, 0xf70e5939,    0x67332667, 0xffc00b31,    0x8eb44a87, 0x68581511,    0xdb0c2e0d, 0x64f98fa7,    0x47b5481d, 0xbefa4fa4 ];}utils.inherits(SHA384, SHA512);module.exports = SHA384;SHA384.blockSize = 1024;SHA384.outSize = 384;SHA384.hmacStrength = 192;SHA384.padLength = 128;SHA384.prototype._digest = function digest(enc) {  if (enc === 'hex')    return utils.toHex32(this.h.slice(0, 12), 'big');  else    return utils.split32(this.h.slice(0, 12), 'big');};},{"../utils":150,"./512":148}],148:[function(require,module,exports){'use strict';var utils = require('../utils');var common = require('../common');var assert = require('minimalistic-assert');var rotr64_hi = utils.rotr64_hi;var rotr64_lo = utils.rotr64_lo;var shr64_hi = utils.shr64_hi;var shr64_lo = utils.shr64_lo;var sum64 = utils.sum64;var sum64_hi = utils.sum64_hi;var sum64_lo = utils.sum64_lo;var sum64_4_hi = utils.sum64_4_hi;var sum64_4_lo = utils.sum64_4_lo;var sum64_5_hi = utils.sum64_5_hi;var sum64_5_lo = utils.sum64_5_lo;var BlockHash = common.BlockHash;var sha512_K = [  0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,  0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,  0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,  0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,  0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,  0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,  0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,  0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,  0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,  0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,  0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,  0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,  0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,  0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,  0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,  0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,  0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,  0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,  0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,  0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,  0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,  0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,  0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,  0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,  0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,  0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,  0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,  0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,  0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,  0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,  0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,  0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,  0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,  0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,  0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,  0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,  0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,  0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,  0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,  0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817];function SHA512() {  if (!(this instanceof SHA512))    return new SHA512();  BlockHash.call(this);  this.h = [    0x6a09e667, 0xf3bcc908,    0xbb67ae85, 0x84caa73b,    0x3c6ef372, 0xfe94f82b,    0xa54ff53a, 0x5f1d36f1,    0x510e527f, 0xade682d1,    0x9b05688c, 0x2b3e6c1f,    0x1f83d9ab, 0xfb41bd6b,    0x5be0cd19, 0x137e2179 ];  this.k = sha512_K;  this.W = new Array(160);}utils.inherits(SHA512, BlockHash);module.exports = SHA512;SHA512.blockSize = 1024;SHA512.outSize = 512;SHA512.hmacStrength = 192;SHA512.padLength = 128;SHA512.prototype._prepareBlock = function _prepareBlock(msg, start) {  var W = this.W;  // 32 x 32bit words  for (var i = 0; i < 32; i++)    W[i] = msg[start + i];  for (; i < W.length; i += 2) {    var c0_hi = g1_512_hi(W[i - 4], W[i - 3]);  // i - 2    var c0_lo = g1_512_lo(W[i - 4], W[i - 3]);    var c1_hi = W[i - 14];  // i - 7    var c1_lo = W[i - 13];    var c2_hi = g0_512_hi(W[i - 30], W[i - 29]);  // i - 15    var c2_lo = g0_512_lo(W[i - 30], W[i - 29]);    var c3_hi = W[i - 32];  // i - 16    var c3_lo = W[i - 31];    W[i] = sum64_4_hi(      c0_hi, c0_lo,      c1_hi, c1_lo,      c2_hi, c2_lo,      c3_hi, c3_lo);    W[i + 1] = sum64_4_lo(      c0_hi, c0_lo,      c1_hi, c1_lo,      c2_hi, c2_lo,      c3_hi, c3_lo);  }};SHA512.prototype._update = function _update(msg, start) {  this._prepareBlock(msg, start);  var W = this.W;  var ah = this.h[0];  var al = this.h[1];  var bh = this.h[2];  var bl = this.h[3];  var ch = this.h[4];  var cl = this.h[5];  var dh = this.h[6];  var dl = this.h[7];  var eh = this.h[8];  var el = this.h[9];  var fh = this.h[10];  var fl = this.h[11];  var gh = this.h[12];  var gl = this.h[13];  var hh = this.h[14];  var hl = this.h[15];  assert(this.k.length === W.length);  for (var i = 0; i < W.length; i += 2) {    var c0_hi = hh;    var c0_lo = hl;    var c1_hi = s1_512_hi(eh, el);    var c1_lo = s1_512_lo(eh, el);    var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl);    var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl);    var c3_hi = this.k[i];    var c3_lo = this.k[i + 1];    var c4_hi = W[i];    var c4_lo = W[i + 1];    var T1_hi = sum64_5_hi(      c0_hi, c0_lo,      c1_hi, c1_lo,      c2_hi, c2_lo,      c3_hi, c3_lo,      c4_hi, c4_lo);    var T1_lo = sum64_5_lo(      c0_hi, c0_lo,      c1_hi, c1_lo,      c2_hi, c2_lo,      c3_hi, c3_lo,      c4_hi, c4_lo);    c0_hi = s0_512_hi(ah, al);    c0_lo = s0_512_lo(ah, al);    c1_hi = maj64_hi(ah, al, bh, bl, ch, cl);    c1_lo = maj64_lo(ah, al, bh, bl, ch, cl);    var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo);    var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo);    hh = gh;    hl = gl;    gh = fh;    gl = fl;    fh = eh;    fl = el;    eh = sum64_hi(dh, dl, T1_hi, T1_lo);    el = sum64_lo(dl, dl, T1_hi, T1_lo);    dh = ch;    dl = cl;    ch = bh;    cl = bl;    bh = ah;    bl = al;    ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo);    al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo);  }  sum64(this.h, 0, ah, al);  sum64(this.h, 2, bh, bl);  sum64(this.h, 4, ch, cl);  sum64(this.h, 6, dh, dl);  sum64(this.h, 8, eh, el);  sum64(this.h, 10, fh, fl);  sum64(this.h, 12, gh, gl);  sum64(this.h, 14, hh, hl);};SHA512.prototype._digest = function digest(enc) {  if (enc === 'hex')    return utils.toHex32(this.h, 'big');  else    return utils.split32(this.h, 'big');};function ch64_hi(xh, xl, yh, yl, zh) {  var r = (xh & yh) ^ ((~xh) & zh);  if (r < 0)    r += 0x100000000;  return r;}function ch64_lo(xh, xl, yh, yl, zh, zl) {  var r = (xl & yl) ^ ((~xl) & zl);  if (r < 0)    r += 0x100000000;  return r;}function maj64_hi(xh, xl, yh, yl, zh) {  var r = (xh & yh) ^ (xh & zh) ^ (yh & zh);  if (r < 0)    r += 0x100000000;  return r;}function maj64_lo(xh, xl, yh, yl, zh, zl) {  var r = (xl & yl) ^ (xl & zl) ^ (yl & zl);  if (r < 0)    r += 0x100000000;  return r;}function s0_512_hi(xh, xl) {  var c0_hi = rotr64_hi(xh, xl, 28);  var c1_hi = rotr64_hi(xl, xh, 2);  // 34  var c2_hi = rotr64_hi(xl, xh, 7);  // 39  var r = c0_hi ^ c1_hi ^ c2_hi;  if (r < 0)    r += 0x100000000;  return r;}function s0_512_lo(xh, xl) {  var c0_lo = rotr64_lo(xh, xl, 28);  var c1_lo = rotr64_lo(xl, xh, 2);  // 34  var c2_lo = rotr64_lo(xl, xh, 7);  // 39  var r = c0_lo ^ c1_lo ^ c2_lo;  if (r < 0)    r += 0x100000000;  return r;}function s1_512_hi(xh, xl) {  var c0_hi = rotr64_hi(xh, xl, 14);  var c1_hi = rotr64_hi(xh, xl, 18);  var c2_hi = rotr64_hi(xl, xh, 9);  // 41  var r = c0_hi ^ c1_hi ^ c2_hi;  if (r < 0)    r += 0x100000000;  return r;}function s1_512_lo(xh, xl) {  var c0_lo = rotr64_lo(xh, xl, 14);  var c1_lo = rotr64_lo(xh, xl, 18);  var c2_lo = rotr64_lo(xl, xh, 9);  // 41  var r = c0_lo ^ c1_lo ^ c2_lo;  if (r < 0)    r += 0x100000000;  return r;}function g0_512_hi(xh, xl) {  var c0_hi = rotr64_hi(xh, xl, 1);  var c1_hi = rotr64_hi(xh, xl, 8);  var c2_hi = shr64_hi(xh, xl, 7);  var r = c0_hi ^ c1_hi ^ c2_hi;  if (r < 0)    r += 0x100000000;  return r;}function g0_512_lo(xh, xl) {  var c0_lo = rotr64_lo(xh, xl, 1);  var c1_lo = rotr64_lo(xh, xl, 8);  var c2_lo = shr64_lo(xh, xl, 7);  var r = c0_lo ^ c1_lo ^ c2_lo;  if (r < 0)    r += 0x100000000;  return r;}function g1_512_hi(xh, xl) {  var c0_hi = rotr64_hi(xh, xl, 19);  var c1_hi = rotr64_hi(xl, xh, 29);  // 61  var c2_hi = shr64_hi(xh, xl, 6);  var r = c0_hi ^ c1_hi ^ c2_hi;  if (r < 0)    r += 0x100000000;  return r;}function g1_512_lo(xh, xl) {  var c0_lo = rotr64_lo(xh, xl, 19);  var c1_lo = rotr64_lo(xl, xh, 29);  // 61  var c2_lo = shr64_lo(xh, xl, 6);  var r = c0_lo ^ c1_lo ^ c2_lo;  if (r < 0)    r += 0x100000000;  return r;}},{"../common":140,"../utils":150,"minimalistic-assert":197}],149:[function(require,module,exports){'use strict';var utils = require('../utils');var rotr32 = utils.rotr32;function ft_1(s, x, y, z) {  if (s === 0)    return ch32(x, y, z);  if (s === 1 || s === 3)    return p32(x, y, z);  if (s === 2)    return maj32(x, y, z);}exports.ft_1 = ft_1;function ch32(x, y, z) {  return (x & y) ^ ((~x) & z);}exports.ch32 = ch32;function maj32(x, y, z) {  return (x & y) ^ (x & z) ^ (y & z);}exports.maj32 = maj32;function p32(x, y, z) {  return x ^ y ^ z;}exports.p32 = p32;function s0_256(x) {  return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22);}exports.s0_256 = s0_256;function s1_256(x) {  return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25);}exports.s1_256 = s1_256;function g0_256(x) {  return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3);}exports.g0_256 = g0_256;function g1_256(x) {  return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10);}exports.g1_256 = g1_256;},{"../utils":150}],150:[function(require,module,exports){'use strict';var assert = require('minimalistic-assert');var inherits = require('inherits');exports.inherits = inherits;function isSurrogatePair(msg, i) {  if ((msg.charCodeAt(i) & 0xFC00) !== 0xD800) {    return false;  }  if (i < 0 || i + 1 >= msg.length) {    return false;  }  return (msg.charCodeAt(i + 1) & 0xFC00) === 0xDC00;}function toArray(msg, enc) {  if (Array.isArray(msg))    return msg.slice();  if (!msg)    return [];  var res = [];  if (typeof msg === 'string') {    if (!enc) {      // Inspired by stringToUtf8ByteArray() in closure-library by Google      // https://github.com/google/closure-library/blob/8598d87242af59aac233270742c8984e2b2bdbe0/closure/goog/crypt/crypt.js#L117-L143      // Apache License 2.0      // https://github.com/google/closure-library/blob/master/LICENSE      var p = 0;      for (var i = 0; i < msg.length; i++) {        var c = msg.charCodeAt(i);        if (c < 128) {          res[p++] = c;        } else if (c < 2048) {          res[p++] = (c >> 6) | 192;          res[p++] = (c & 63) | 128;        } else if (isSurrogatePair(msg, i)) {          c = 0x10000 + ((c & 0x03FF) << 10) + (msg.charCodeAt(++i) & 0x03FF);          res[p++] = (c >> 18) | 240;          res[p++] = ((c >> 12) & 63) | 128;          res[p++] = ((c >> 6) & 63) | 128;          res[p++] = (c & 63) | 128;        } else {          res[p++] = (c >> 12) | 224;          res[p++] = ((c >> 6) & 63) | 128;          res[p++] = (c & 63) | 128;        }      }    } else if (enc === 'hex') {      msg = msg.replace(/[^a-z0-9]+/ig, '');      if (msg.length % 2 !== 0)        msg = '0' + msg;      for (i = 0; i < msg.length; i += 2)        res.push(parseInt(msg[i] + msg[i + 1], 16));    }  } else {    for (i = 0; i < msg.length; i++)      res[i] = msg[i] | 0;  }  return res;}exports.toArray = toArray;function toHex(msg) {  var res = '';  for (var i = 0; i < msg.length; i++)    res += zero2(msg[i].toString(16));  return res;}exports.toHex = toHex;function htonl(w) {  var res = (w >>> 24) |            ((w >>> 8) & 0xff00) |            ((w << 8) & 0xff0000) |            ((w & 0xff) << 24);  return res >>> 0;}exports.htonl = htonl;function toHex32(msg, endian) {  var res = '';  for (var i = 0; i < msg.length; i++) {    var w = msg[i];    if (endian === 'little')      w = htonl(w);    res += zero8(w.toString(16));  }  return res;}exports.toHex32 = toHex32;function zero2(word) {  if (word.length === 1)    return '0' + word;  else    return word;}exports.zero2 = zero2;function zero8(word) {  if (word.length === 7)    return '0' + word;  else if (word.length === 6)    return '00' + word;  else if (word.length === 5)    return '000' + word;  else if (word.length === 4)    return '0000' + word;  else if (word.length === 3)    return '00000' + word;  else if (word.length === 2)    return '000000' + word;  else if (word.length === 1)    return '0000000' + word;  else    return word;}exports.zero8 = zero8;function join32(msg, start, end, endian) {  var len = end - start;  assert(len % 4 === 0);  var res = new Array(len / 4);  for (var i = 0, k = start; i < res.length; i++, k += 4) {    var w;    if (endian === 'big')      w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3];    else      w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k];    res[i] = w >>> 0;  }  return res;}exports.join32 = join32;function split32(msg, endian) {  var res = new Array(msg.length * 4);  for (var i = 0, k = 0; i < msg.length; i++, k += 4) {    var m = msg[i];    if (endian === 'big') {      res[k] = m >>> 24;      res[k + 1] = (m >>> 16) & 0xff;      res[k + 2] = (m >>> 8) & 0xff;      res[k + 3] = m & 0xff;    } else {      res[k + 3] = m >>> 24;      res[k + 2] = (m >>> 16) & 0xff;      res[k + 1] = (m >>> 8) & 0xff;      res[k] = m & 0xff;    }  }  return res;}exports.split32 = split32;function rotr32(w, b) {  return (w >>> b) | (w << (32 - b));}exports.rotr32 = rotr32;function rotl32(w, b) {  return (w << b) | (w >>> (32 - b));}exports.rotl32 = rotl32;function sum32(a, b) {  return (a + b) >>> 0;}exports.sum32 = sum32;function sum32_3(a, b, c) {  return (a + b + c) >>> 0;}exports.sum32_3 = sum32_3;function sum32_4(a, b, c, d) {  return (a + b + c + d) >>> 0;}exports.sum32_4 = sum32_4;function sum32_5(a, b, c, d, e) {  return (a + b + c + d + e) >>> 0;}exports.sum32_5 = sum32_5;function sum64(buf, pos, ah, al) {  var bh = buf[pos];  var bl = buf[pos + 1];  var lo = (al + bl) >>> 0;  var hi = (lo < al ? 1 : 0) + ah + bh;  buf[pos] = hi >>> 0;  buf[pos + 1] = lo;}exports.sum64 = sum64;function sum64_hi(ah, al, bh, bl) {  var lo = (al + bl) >>> 0;  var hi = (lo < al ? 1 : 0) + ah + bh;  return hi >>> 0;}exports.sum64_hi = sum64_hi;function sum64_lo(ah, al, bh, bl) {  var lo = al + bl;  return lo >>> 0;}exports.sum64_lo = sum64_lo;function sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) {  var carry = 0;  var lo = al;  lo = (lo + bl) >>> 0;  carry += lo < al ? 1 : 0;  lo = (lo + cl) >>> 0;  carry += lo < cl ? 1 : 0;  lo = (lo + dl) >>> 0;  carry += lo < dl ? 1 : 0;  var hi = ah + bh + ch + dh + carry;  return hi >>> 0;}exports.sum64_4_hi = sum64_4_hi;function sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) {  var lo = al + bl + cl + dl;  return lo >>> 0;}exports.sum64_4_lo = sum64_4_lo;function sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {  var carry = 0;  var lo = al;  lo = (lo + bl) >>> 0;  carry += lo < al ? 1 : 0;  lo = (lo + cl) >>> 0;  carry += lo < cl ? 1 : 0;  lo = (lo + dl) >>> 0;  carry += lo < dl ? 1 : 0;  lo = (lo + el) >>> 0;  carry += lo < el ? 1 : 0;  var hi = ah + bh + ch + dh + eh + carry;  return hi >>> 0;}exports.sum64_5_hi = sum64_5_hi;function sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {  var lo = al + bl + cl + dl + el;  return lo >>> 0;}exports.sum64_5_lo = sum64_5_lo;function rotr64_hi(ah, al, num) {  var r = (al << (32 - num)) | (ah >>> num);  return r >>> 0;}exports.rotr64_hi = rotr64_hi;function rotr64_lo(ah, al, num) {  var r = (ah << (32 - num)) | (al >>> num);  return r >>> 0;}exports.rotr64_lo = rotr64_lo;function shr64_hi(ah, al, num) {  return ah >>> num;}exports.shr64_hi = shr64_hi;function shr64_lo(ah, al, num) {  var r = (ah << (32 - num)) | (al >>> num);  return r >>> 0;}exports.shr64_lo = shr64_lo;},{"inherits":154,"minimalistic-assert":197}],151:[function(require,module,exports){'use strict';var hash = require('hash.js');var utils = require('minimalistic-crypto-utils');var assert = require('minimalistic-assert');function HmacDRBG(options) {  if (!(this instanceof HmacDRBG))    return new HmacDRBG(options);  this.hash = options.hash;  this.predResist = !!options.predResist;  this.outLen = this.hash.outSize;  this.minEntropy = options.minEntropy || this.hash.hmacStrength;  this._reseed = null;  this.reseedInterval = null;  this.K = null;  this.V = null;  var entropy = utils.toArray(options.entropy, options.entropyEnc || 'hex');  var nonce = utils.toArray(options.nonce, options.nonceEnc || 'hex');  var pers = utils.toArray(options.pers, options.persEnc || 'hex');  assert(entropy.length >= (this.minEntropy / 8),         'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');  this._init(entropy, nonce, pers);}module.exports = HmacDRBG;HmacDRBG.prototype._init = function init(entropy, nonce, pers) {  var seed = entropy.concat(nonce).concat(pers);  this.K = new Array(this.outLen / 8);  this.V = new Array(this.outLen / 8);  for (var i = 0; i < this.V.length; i++) {    this.K[i] = 0x00;    this.V[i] = 0x01;  }  this._update(seed);  this._reseed = 1;  this.reseedInterval = 0x1000000000000;  // 2^48};HmacDRBG.prototype._hmac = function hmac() {  return new hash.hmac(this.hash, this.K);};HmacDRBG.prototype._update = function update(seed) {  var kmac = this._hmac()                 .update(this.V)                 .update([ 0x00 ]);  if (seed)    kmac = kmac.update(seed);  this.K = kmac.digest();  this.V = this._hmac().update(this.V).digest();  if (!seed)    return;  this.K = this._hmac()               .update(this.V)               .update([ 0x01 ])               .update(seed)               .digest();  this.V = this._hmac().update(this.V).digest();};HmacDRBG.prototype.reseed = function reseed(entropy, entropyEnc, add, addEnc) {  // Optional entropy enc  if (typeof entropyEnc !== 'string') {    addEnc = add;    add = entropyEnc;    entropyEnc = null;  }  entropy = utils.toArray(entropy, entropyEnc);  add = utils.toArray(add, addEnc);  assert(entropy.length >= (this.minEntropy / 8),         'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');  this._update(entropy.concat(add || []));  this._reseed = 1;};HmacDRBG.prototype.generate = function generate(len, enc, add, addEnc) {  if (this._reseed > this.reseedInterval)    throw new Error('Reseed is required');  // Optional encoding  if (typeof enc !== 'string') {    addEnc = add;    add = enc;    enc = null;  }  // Optional additional data  if (add) {    add = utils.toArray(add, addEnc || 'hex');    this._update(add);  }  var temp = [];  while (temp.length < len) {    this.V = this._hmac().update(this.V).digest();    temp = temp.concat(this.V);  }  var res = temp.slice(0, len);  this._update(add);  this._reseed++;  return utils.encode(res, enc);};},{"hash.js":139,"minimalistic-assert":197,"minimalistic-crypto-utils":198}],152:[function(require,module,exports){exports.read = function (buffer, offset, isLE, mLen, nBytes) {  var e, m  var eLen = (nBytes * 8) - mLen - 1  var eMax = (1 << eLen) - 1  var eBias = eMax >> 1  var nBits = -7  var i = isLE ? (nBytes - 1) : 0  var d = isLE ? -1 : 1  var s = buffer[offset + i]  i += d  e = s & ((1 << (-nBits)) - 1)  s >>= (-nBits)  nBits += eLen  for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}  m = e & ((1 << (-nBits)) - 1)  e >>= (-nBits)  nBits += mLen  for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}  if (e === 0) {    e = 1 - eBias  } else if (e === eMax) {    return m ? NaN : ((s ? -1 : 1) * Infinity)  } else {    m = m + Math.pow(2, mLen)    e = e - eBias  }  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)}exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {  var e, m, c  var eLen = (nBytes * 8) - mLen - 1  var eMax = (1 << eLen) - 1  var eBias = eMax >> 1  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)  var i = isLE ? 0 : (nBytes - 1)  var d = isLE ? 1 : -1  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0  value = Math.abs(value)  if (isNaN(value) || value === Infinity) {    m = isNaN(value) ? 1 : 0    e = eMax  } else {    e = Math.floor(Math.log(value) / Math.LN2)    if (value * (c = Math.pow(2, -e)) < 1) {      e--      c *= 2    }    if (e + eBias >= 1) {      value += rt / c    } else {      value += rt * Math.pow(2, 1 - eBias)    }    if (value * c >= 2) {      e++      c /= 2    }    if (e + eBias >= eMax) {      m = 0      e = eMax    } else if (e + eBias >= 1) {      m = ((value * c) - 1) * Math.pow(2, mLen)      e = e + eBias    } else {      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)      e = 0    }  }  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}  e = (e << mLen) | m  eLen += mLen  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}  buffer[offset + i - d] |= s * 128}},{}],153:[function(require,module,exports){(function (global){'use strict';var Mutation = global.MutationObserver || global.WebKitMutationObserver;var scheduleDrain;{  if (Mutation) {    var called = 0;    var observer = new Mutation(nextTick);    var element = global.document.createTextNode('');    observer.observe(element, {      characterData: true    });    scheduleDrain = function () {      element.data = (called = ++called % 2);    };  } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') {    var channel = new global.MessageChannel();    channel.port1.onmessage = nextTick;    scheduleDrain = function () {      channel.port2.postMessage(0);    };  } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) {    scheduleDrain = function () {      // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted      // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.      var scriptEl = global.document.createElement('script');      scriptEl.onreadystatechange = function () {        nextTick();        scriptEl.onreadystatechange = null;        scriptEl.parentNode.removeChild(scriptEl);        scriptEl = null;      };      global.document.documentElement.appendChild(scriptEl);    };  } else {    scheduleDrain = function () {      setTimeout(nextTick, 0);    };  }}var draining;var queue = [];//named nextTick for less confusing stack tracesfunction nextTick() {  draining = true;  var i, oldQueue;  var len = queue.length;  while (len) {    oldQueue = queue;    queue = [];    i = -1;    while (++i < len) {      oldQueue[i]();    }    len = queue.length;  }  draining = false;}module.exports = immediate;function immediate(task) {  if (queue.push(task) === 1 && !draining) {    scheduleDrain();  }}}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})},{}],154:[function(require,module,exports){if (typeof Object.create === 'function') {  // implementation from standard node.js 'util' module  module.exports = function inherits(ctor, superCtor) {    ctor.super_ = superCtor    ctor.prototype = Object.create(superCtor.prototype, {      constructor: {        value: ctor,        enumerable: false,        writable: true,        configurable: true      }    });  };} else {  // old school shim for old browsers  module.exports = function inherits(ctor, superCtor) {    ctor.super_ = superCtor    var TempCtor = function () {}    TempCtor.prototype = superCtor.prototype    ctor.prototype = new TempCtor()    ctor.prototype.constructor = ctor  }}},{}],155:[function(require,module,exports){/*! * Determine if an object is a Buffer * * @author   Feross Aboukhadijeh <https://feross.org> * @license  MIT */// The _isBuffer check is for Safari 5-7 support, because it's missing// Object.prototype.constructor. Remove this eventuallymodule.exports = function (obj) {  return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)}function isBuffer (obj) {  return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)}// For Node v0.10 support. Remove this eventually.function isSlowBuffer (obj) {  return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))}},{}],156:[function(require,module,exports){var toString = {}.toString;module.exports = Array.isArray || function (arr) {  return toString.call(arr) == '[object Array]';};},{}],157:[function(require,module,exports){'use strict';var utils = require('./utils');var support = require('./support');// private propertyvar _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";// public method for encodingexports.encode = function(input) {    var output = [];    var chr1, chr2, chr3, enc1, enc2, enc3, enc4;    var i = 0, len = input.length, remainingBytes = len;    var isArray = utils.getTypeOf(input) !== "string";    while (i < input.length) {        remainingBytes = len - i;        if (!isArray) {            chr1 = input.charCodeAt(i++);            chr2 = i < len ? input.charCodeAt(i++) : 0;            chr3 = i < len ? input.charCodeAt(i++) : 0;        } else {            chr1 = input[i++];            chr2 = i < len ? input[i++] : 0;            chr3 = i < len ? input[i++] : 0;        }        enc1 = chr1 >> 2;        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);        enc3 = remainingBytes > 1 ? (((chr2 & 15) << 2) | (chr3 >> 6)) : 64;        enc4 = remainingBytes > 2 ? (chr3 & 63) : 64;        output.push(_keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4));    }    return output.join("");};// public method for decodingexports.decode = function(input) {    var chr1, chr2, chr3;    var enc1, enc2, enc3, enc4;    var i = 0, resultIndex = 0;    var dataUrlPrefix = "data:";    if (input.substr(0, dataUrlPrefix.length) === dataUrlPrefix) {        // This is a common error: people give a data url        // (data:image/png;base64,iVBOR...) with a {base64: true} and        // wonders why things don't work.        // We can detect that the string input looks like a data url but we        // *can't* be sure it is one: removing everything up to the comma would        // be too dangerous.        throw new Error("Invalid base64 input, it looks like a data url.");    }    input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");    var totalLength = input.length * 3 / 4;    if(input.charAt(input.length - 1) === _keyStr.charAt(64)) {        totalLength--;    }    if(input.charAt(input.length - 2) === _keyStr.charAt(64)) {        totalLength--;    }    if (totalLength % 1 !== 0) {        // totalLength is not an integer, the length does not match a valid        // base64 content. That can happen if:        // - the input is not a base64 content        // - the input is *almost* a base64 content, with a extra chars at the        //   beginning or at the end        // - the input uses a base64 variant (base64url for example)        throw new Error("Invalid base64 input, bad content length.");    }    var output;    if (support.uint8array) {        output = new Uint8Array(totalLength|0);    } else {        output = new Array(totalLength|0);    }    while (i < input.length) {        enc1 = _keyStr.indexOf(input.charAt(i++));        enc2 = _keyStr.indexOf(input.charAt(i++));        enc3 = _keyStr.indexOf(input.charAt(i++));        enc4 = _keyStr.indexOf(input.charAt(i++));        chr1 = (enc1 << 2) | (enc2 >> 4);        chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);        chr3 = ((enc3 & 3) << 6) | enc4;        output[resultIndex++] = chr1;        if (enc3 !== 64) {            output[resultIndex++] = chr2;        }        if (enc4 !== 64) {            output[resultIndex++] = chr3;        }    }    return output;};},{"./support":186,"./utils":188}],158:[function(require,module,exports){'use strict';var external = require("./external");var DataWorker = require('./stream/DataWorker');var DataLengthProbe = require('./stream/DataLengthProbe');var Crc32Probe = require('./stream/Crc32Probe');var DataLengthProbe = require('./stream/DataLengthProbe');/** * Represent a compressed object, with everything needed to decompress it. * @constructor * @param {number} compressedSize the size of the data compressed. * @param {number} uncompressedSize the size of the data after decompression. * @param {number} crc32 the crc32 of the decompressed file. * @param {object} compression the type of compression, see lib/compressions.js. * @param {String|ArrayBuffer|Uint8Array|Buffer} data the compressed data. */function CompressedObject(compressedSize, uncompressedSize, crc32, compression, data) {    this.compressedSize = compressedSize;    this.uncompressedSize = uncompressedSize;    this.crc32 = crc32;    this.compression = compression;    this.compressedContent = data;}CompressedObject.prototype = {    /**     * Create a worker to get the uncompressed content.     * @return {GenericWorker} the worker.     */    getContentWorker : function () {        var worker = new DataWorker(external.Promise.resolve(this.compressedContent))        .pipe(this.compression.uncompressWorker())        .pipe(new DataLengthProbe("data_length"));        var that = this;        worker.on("end", function () {            if(this.streamInfo['data_length'] !== that.uncompressedSize) {                throw new Error("Bug : uncompressed data size mismatch");            }        });        return worker;    },    /**     * Create a worker to get the compressed content.     * @return {GenericWorker} the worker.     */    getCompressedWorker : function () {        return new DataWorker(external.Promise.resolve(this.compressedContent))        .withStreamInfo("compressedSize", this.compressedSize)        .withStreamInfo("uncompressedSize", this.uncompressedSize)        .withStreamInfo("crc32", this.crc32)        .withStreamInfo("compression", this.compression)        ;    }};/** * Chain the given worker with other workers to compress the content with the * given compresion. * @param {GenericWorker} uncompressedWorker the worker to pipe. * @param {Object} compression the compression object. * @param {Object} compressionOptions the options to use when compressing. * @return {GenericWorker} the new worker compressing the content. */CompressedObject.createWorkerFrom = function (uncompressedWorker, compression, compressionOptions) {    return uncompressedWorker    .pipe(new Crc32Probe())    .pipe(new DataLengthProbe("uncompressedSize"))    .pipe(compression.compressWorker(compressionOptions))    .pipe(new DataLengthProbe("compressedSize"))    .withStreamInfo("compression", compression);};module.exports = CompressedObject;},{"./external":162,"./stream/Crc32Probe":181,"./stream/DataLengthProbe":182,"./stream/DataWorker":183}],159:[function(require,module,exports){'use strict';var GenericWorker = require("./stream/GenericWorker");exports.STORE = {    magic: "\x00\x00",    compressWorker : function (compressionOptions) {        return new GenericWorker("STORE compression");    },    uncompressWorker : function () {        return new GenericWorker("STORE decompression");    }};exports.DEFLATE = require('./flate');},{"./flate":163,"./stream/GenericWorker":184}],160:[function(require,module,exports){'use strict';var utils = require('./utils');/** * The following functions come from pako, from pako/lib/zlib/crc32.js * released under the MIT license, see pako https://github.com/nodeca/pako/ */// Use ordinary array, since untyped makes no boost herefunction makeTable() {    var c, table = [];    for(var n =0; n < 256; n++){        c = n;        for(var k =0; k < 8; k++){            c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));        }        table[n] = c;    }    return table;}// Create table on load. Just 255 signed longs. Not a problem.var crcTable = makeTable();function crc32(crc, buf, len, pos) {    var t = crcTable, end = pos + len;    crc = crc ^ (-1);    for (var i = pos; i < end; i++ ) {        crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF];    }    return (crc ^ (-1)); // >>> 0;}// That's all for the pako functions./** * Compute the crc32 of a string. * This is almost the same as the function crc32, but for strings. Using the * same function for the two use cases leads to horrible performances. * @param {Number} crc the starting value of the crc. * @param {String} str the string to use. * @param {Number} len the length of the string. * @param {Number} pos the starting position for the crc32 computation. * @return {Number} the computed crc32. */function crc32str(crc, str, len, pos) {    var t = crcTable, end = pos + len;    crc = crc ^ (-1);    for (var i = pos; i < end; i++ ) {        crc = (crc >>> 8) ^ t[(crc ^ str.charCodeAt(i)) & 0xFF];    }    return (crc ^ (-1)); // >>> 0;}module.exports = function crc32wrapper(input, crc) {    if (typeof input === "undefined" || !input.length) {        return 0;    }    var isArray = utils.getTypeOf(input) !== "string";    if(isArray) {        return crc32(crc|0, input, input.length, 0);    } else {        return crc32str(crc|0, input, input.length, 0);    }};},{"./utils":188}],161:[function(require,module,exports){'use strict';exports.base64 = false;exports.binary = false;exports.dir = false;exports.createFolders = true;exports.date = null;exports.compression = null;exports.compressionOptions = null;exports.comment = null;exports.unixPermissions = null;exports.dosPermissions = null;},{}],162:[function(require,module,exports){/* global Promise */'use strict';// load the global object first:// - it should be better integrated in the system (unhandledRejection in node)// - the environment may have a custom Promise implementation (see zone.js)var ES6Promise = null;if (typeof Promise !== "undefined") {    ES6Promise = Promise;} else {    ES6Promise = require("lie");}/** * Let the user use/change some implementations. */module.exports = {    Promise: ES6Promise};},{"lie":192}],163:[function(require,module,exports){'use strict';var USE_TYPEDARRAY = (typeof Uint8Array !== 'undefined') && (typeof Uint16Array !== 'undefined') && (typeof Uint32Array !== 'undefined');var pako = require("pako");var utils = require("./utils");var GenericWorker = require("./stream/GenericWorker");var ARRAY_TYPE = USE_TYPEDARRAY ? "uint8array" : "array";exports.magic = "\x08\x00";/** * Create a worker that uses pako to inflate/deflate. * @constructor * @param {String} action the name of the pako function to call : either "Deflate" or "Inflate". * @param {Object} options the options to use when (de)compressing. */function FlateWorker(action, options) {    GenericWorker.call(this, "FlateWorker/" + action);    this._pako = null;    this._pakoAction = action;    this._pakoOptions = options;    // the `meta` object from the last chunk received    // this allow this worker to pass around metadata    this.meta = {};}utils.inherits(FlateWorker, GenericWorker);/** * @see GenericWorker.processChunk */FlateWorker.prototype.processChunk = function (chunk) {    this.meta = chunk.meta;    if (this._pako === null) {        this._createPako();    }    this._pako.push(utils.transformTo(ARRAY_TYPE, chunk.data), false);};/** * @see GenericWorker.flush */FlateWorker.prototype.flush = function () {    GenericWorker.prototype.flush.call(this);    if (this._pako === null) {        this._createPako();    }    this._pako.push([], true);};/** * @see GenericWorker.cleanUp */FlateWorker.prototype.cleanUp = function () {    GenericWorker.prototype.cleanUp.call(this);    this._pako = null;};/** * Create the _pako object. * TODO: lazy-loading this object isn't the best solution but it's the * quickest. The best solution is to lazy-load the worker list. See also the * issue #446. */FlateWorker.prototype._createPako = function () {    this._pako = new pako[this._pakoAction]({        raw: true,        level: this._pakoOptions.level || -1 // default compression    });    var self = this;    this._pako.onData = function(data) {        self.push({            data : data,            meta : self.meta        });    };};exports.compressWorker = function (compressionOptions) {    return new FlateWorker("Deflate", compressionOptions);};exports.uncompressWorker = function () {    return new FlateWorker("Inflate", {});};},{"./stream/GenericWorker":184,"./utils":188,"pako":199}],164:[function(require,module,exports){'use strict';var utils = require('../utils');var GenericWorker = require('../stream/GenericWorker');var utf8 = require('../utf8');var crc32 = require('../crc32');var signature = require('../signature');/** * Transform an integer into a string in hexadecimal. * @private * @param {number} dec the number to convert. * @param {number} bytes the number of bytes to generate. * @returns {string} the result. */var decToHex = function(dec, bytes) {    var hex = "", i;    for (i = 0; i < bytes; i++) {        hex += String.fromCharCode(dec & 0xff);        dec = dec >>> 8;    }    return hex;};/** * Generate the UNIX part of the external file attributes. * @param {Object} unixPermissions the unix permissions or null. * @param {Boolean} isDir true if the entry is a directory, false otherwise. * @return {Number} a 32 bit integer. * * adapted from http://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute : * * TTTTsstrwxrwxrwx0000000000ADVSHR * ^^^^____________________________ file type, see zipinfo.c (UNX_*) *     ^^^_________________________ setuid, setgid, sticky *        ^^^^^^^^^________________ permissions *                 ^^^^^^^^^^______ not used ? *                           ^^^^^^ DOS attribute bits : Archive, Directory, Volume label, System file, Hidden, Read only */var generateUnixExternalFileAttr = function (unixPermissions, isDir) {    var result = unixPermissions;    if (!unixPermissions) {        // I can't use octal values in strict mode, hence the hexa.        //  040775 => 0x41fd        // 0100664 => 0x81b4        result = isDir ? 0x41fd : 0x81b4;    }    return (result & 0xFFFF) << 16;};/** * Generate the DOS part of the external file attributes. * @param {Object} dosPermissions the dos permissions or null. * @param {Boolean} isDir true if the entry is a directory, false otherwise. * @return {Number} a 32 bit integer. * * Bit 0     Read-Only * Bit 1     Hidden * Bit 2     System * Bit 3     Volume Label * Bit 4     Directory * Bit 5     Archive */var generateDosExternalFileAttr = function (dosPermissions, isDir) {    // the dir flag is already set for compatibility    return (dosPermissions || 0)  & 0x3F;};/** * Generate the various parts used in the construction of the final zip file. * @param {Object} streamInfo the hash with informations about the compressed file. * @param {Boolean} streamedContent is the content streamed ? * @param {Boolean} streamingEnded is the stream finished ? * @param {number} offset the current offset from the start of the zip file. * @param {String} platform let's pretend we are this platform (change platform dependents fields) * @param {Function} encodeFileName the function to encode the file name / comment. * @return {Object} the zip parts. */var generateZipParts = function(streamInfo, streamedContent, streamingEnded, offset, platform, encodeFileName) {    var file = streamInfo['file'],    compression = streamInfo['compression'],    useCustomEncoding = encodeFileName !== utf8.utf8encode,    encodedFileName = utils.transformTo("string", encodeFileName(file.name)),    utfEncodedFileName = utils.transformTo("string", utf8.utf8encode(file.name)),    comment = file.comment,    encodedComment = utils.transformTo("string", encodeFileName(comment)),    utfEncodedComment = utils.transformTo("string", utf8.utf8encode(comment)),    useUTF8ForFileName = utfEncodedFileName.length !== file.name.length,    useUTF8ForComment = utfEncodedComment.length !== comment.length,    dosTime,    dosDate,    extraFields = "",    unicodePathExtraField = "",    unicodeCommentExtraField = "",    dir = file.dir,    date = file.date;    var dataInfo = {        crc32 : 0,        compressedSize : 0,        uncompressedSize : 0    };    // if the content is streamed, the sizes/crc32 are only available AFTER    // the end of the stream.    if (!streamedContent || streamingEnded) {        dataInfo.crc32 = streamInfo['crc32'];        dataInfo.compressedSize = streamInfo['compressedSize'];        dataInfo.uncompressedSize = streamInfo['uncompressedSize'];    }    var bitflag = 0;    if (streamedContent) {        // Bit 3: the sizes/crc32 are set to zero in the local header.        // The correct values are put in the data descriptor immediately        // following the compressed data.        bitflag |= 0x0008;    }    if (!useCustomEncoding && (useUTF8ForFileName || useUTF8ForComment)) {        // Bit 11: Language encoding flag (EFS).        bitflag |= 0x0800;    }    var extFileAttr = 0;    var versionMadeBy = 0;    if (dir) {        // dos or unix, we set the dos dir flag        extFileAttr |= 0x00010;    }    if(platform === "UNIX") {        versionMadeBy = 0x031E; // UNIX, version 3.0        extFileAttr |= generateUnixExternalFileAttr(file.unixPermissions, dir);    } else { // DOS or other, fallback to DOS        versionMadeBy = 0x0014; // DOS, version 2.0        extFileAttr |= generateDosExternalFileAttr(file.dosPermissions, dir);    }    // date    // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html    // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html    // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html    dosTime = date.getUTCHours();    dosTime = dosTime << 6;    dosTime = dosTime | date.getUTCMinutes();    dosTime = dosTime << 5;    dosTime = dosTime | date.getUTCSeconds() / 2;    dosDate = date.getUTCFullYear() - 1980;    dosDate = dosDate << 4;    dosDate = dosDate | (date.getUTCMonth() + 1);    dosDate = dosDate << 5;    dosDate = dosDate | date.getUTCDate();    if (useUTF8ForFileName) {        // set the unicode path extra field. unzip needs at least one extra        // field to correctly handle unicode path, so using the path is as good        // as any other information. This could improve the situation with        // other archive managers too.        // This field is usually used without the utf8 flag, with a non        // unicode path in the header (winrar, winzip). This helps (a bit)        // with the messy Windows' default compressed folders feature but        // breaks on p7zip which doesn't seek the unicode path extra field.        // So for now, UTF-8 everywhere !        unicodePathExtraField =            // Version            decToHex(1, 1) +            // NameCRC32            decToHex(crc32(encodedFileName), 4) +            // UnicodeName            utfEncodedFileName;        extraFields +=            // Info-ZIP Unicode Path Extra Field            "\x75\x70" +            // size            decToHex(unicodePathExtraField.length, 2) +            // content            unicodePathExtraField;    }    if(useUTF8ForComment) {        unicodeCommentExtraField =            // Version            decToHex(1, 1) +            // CommentCRC32            decToHex(crc32(encodedComment), 4) +            // UnicodeName            utfEncodedComment;        extraFields +=            // Info-ZIP Unicode Path Extra Field            "\x75\x63" +            // size            decToHex(unicodeCommentExtraField.length, 2) +            // content            unicodeCommentExtraField;    }    var header = "";    // version needed to extract    header += "\x0A\x00";    // general purpose bit flag    header += decToHex(bitflag, 2);    // compression method    header += compression.magic;    // last mod file time    header += decToHex(dosTime, 2);    // last mod file date    header += decToHex(dosDate, 2);    // crc-32    header += decToHex(dataInfo.crc32, 4);    // compressed size    header += decToHex(dataInfo.compressedSize, 4);    // uncompressed size    header += decToHex(dataInfo.uncompressedSize, 4);    // file name length    header += decToHex(encodedFileName.length, 2);    // extra field length    header += decToHex(extraFields.length, 2);    var fileRecord = signature.LOCAL_FILE_HEADER + header + encodedFileName + extraFields;    var dirRecord = signature.CENTRAL_FILE_HEADER +        // version made by (00: DOS)        decToHex(versionMadeBy, 2) +        // file header (common to file and central directory)        header +        // file comment length        decToHex(encodedComment.length, 2) +        // disk number start        "\x00\x00" +        // internal file attributes TODO        "\x00\x00" +        // external file attributes        decToHex(extFileAttr, 4) +        // relative offset of local header        decToHex(offset, 4) +        // file name        encodedFileName +        // extra field        extraFields +        // file comment        encodedComment;    return {        fileRecord: fileRecord,        dirRecord: dirRecord    };};/** * Generate the EOCD record. * @param {Number} entriesCount the number of entries in the zip file. * @param {Number} centralDirLength the length (in bytes) of the central dir. * @param {Number} localDirLength the length (in bytes) of the local dir. * @param {String} comment the zip file comment as a binary string. * @param {Function} encodeFileName the function to encode the comment. * @return {String} the EOCD record. */var generateCentralDirectoryEnd = function (entriesCount, centralDirLength, localDirLength, comment, encodeFileName) {    var dirEnd = "";    var encodedComment = utils.transformTo("string", encodeFileName(comment));    // end of central dir signature    dirEnd = signature.CENTRAL_DIRECTORY_END +        // number of this disk        "\x00\x00" +        // number of the disk with the start of the central directory        "\x00\x00" +        // total number of entries in the central directory on this disk        decToHex(entriesCount, 2) +        // total number of entries in the central directory        decToHex(entriesCount, 2) +        // size of the central directory   4 bytes        decToHex(centralDirLength, 4) +        // offset of start of central directory with respect to the starting disk number        decToHex(localDirLength, 4) +        // .ZIP file comment length        decToHex(encodedComment.length, 2) +        // .ZIP file comment        encodedComment;    return dirEnd;};/** * Generate data descriptors for a file entry. * @param {Object} streamInfo the hash generated by a worker, containing informations * on the file entry. * @return {String} the data descriptors. */var generateDataDescriptors = function (streamInfo) {    var descriptor = "";    descriptor = signature.DATA_DESCRIPTOR +        // crc-32                          4 bytes        decToHex(streamInfo['crc32'], 4) +        // compressed size                 4 bytes        decToHex(streamInfo['compressedSize'], 4) +        // uncompressed size               4 bytes        decToHex(streamInfo['uncompressedSize'], 4);    return descriptor;};/** * A worker to concatenate other workers to create a zip file. * @param {Boolean} streamFiles `true` to stream the content of the files, * `false` to accumulate it. * @param {String} comment the comment to use. * @param {String} platform the platform to use, "UNIX" or "DOS". * @param {Function} encodeFileName the function to encode file names and comments. */function ZipFileWorker(streamFiles, comment, platform, encodeFileName) {    GenericWorker.call(this, "ZipFileWorker");    // The number of bytes written so far. This doesn't count accumulated chunks.    this.bytesWritten = 0;    // The comment of the zip file    this.zipComment = comment;    // The platform "generating" the zip file.    this.zipPlatform = platform;    // the function to encode file names and comments.    this.encodeFileName = encodeFileName;    // Should we stream the content of the files ?    this.streamFiles = streamFiles;    // If `streamFiles` is false, we will need to accumulate the content of the    // files to calculate sizes / crc32 (and write them *before* the content).    // This boolean indicates if we are accumulating chunks (it will change a lot    // during the lifetime of this worker).    this.accumulate = false;    // The buffer receiving chunks when accumulating content.    this.contentBuffer = [];    // The list of generated directory records.    this.dirRecords = [];    // The offset (in bytes) from the beginning of the zip file for the current source.    this.currentSourceOffset = 0;    // The total number of entries in this zip file.    this.entriesCount = 0;    // the name of the file currently being added, null when handling the end of the zip file.    // Used for the emited metadata.    this.currentFile = null;    this._sources = [];}utils.inherits(ZipFileWorker, GenericWorker);/** * @see GenericWorker.push */ZipFileWorker.prototype.push = function (chunk) {    var currentFilePercent = chunk.meta.percent || 0;    var entriesCount = this.entriesCount;    var remainingFiles = this._sources.length;    if(this.accumulate) {        this.contentBuffer.push(chunk);    } else {        this.bytesWritten += chunk.data.length;        GenericWorker.prototype.push.call(this, {            data : chunk.data,            meta : {                currentFile : this.currentFile,                percent : entriesCount ? (currentFilePercent + 100 * (entriesCount - remainingFiles - 1)) / entriesCount : 100            }        });    }};/** * The worker started a new source (an other worker). * @param {Object} streamInfo the streamInfo object from the new source. */ZipFileWorker.prototype.openedSource = function (streamInfo) {    this.currentSourceOffset = this.bytesWritten;    this.currentFile = streamInfo['file'].name;    var streamedContent = this.streamFiles && !streamInfo['file'].dir;    // don't stream folders (because they don't have any content)    if(streamedContent) {        var record = generateZipParts(streamInfo, streamedContent, false, this.currentSourceOffset, this.zipPlatform, this.encodeFileName);        this.push({            data : record.fileRecord,            meta : {percent:0}        });    } else {        // we need to wait for the whole file before pushing anything        this.accumulate = true;    }};/** * The worker finished a source (an other worker). * @param {Object} streamInfo the streamInfo object from the finished source. */ZipFileWorker.prototype.closedSource = function (streamInfo) {    this.accumulate = false;    var streamedContent = this.streamFiles && !streamInfo['file'].dir;    var record = generateZipParts(streamInfo, streamedContent, true, this.currentSourceOffset, this.zipPlatform, this.encodeFileName);    this.dirRecords.push(record.dirRecord);    if(streamedContent) {        // after the streamed file, we put data descriptors        this.push({            data : generateDataDescriptors(streamInfo),            meta : {percent:100}        });    } else {        // the content wasn't streamed, we need to push everything now        // first the file record, then the content        this.push({            data : record.fileRecord,            meta : {percent:0}        });        while(this.contentBuffer.length) {            this.push(this.contentBuffer.shift());        }    }    this.currentFile = null;};/** * @see GenericWorker.flush */ZipFileWorker.prototype.flush = function () {    var localDirLength = this.bytesWritten;    for(var i = 0; i < this.dirRecords.length; i++) {        this.push({            data : this.dirRecords[i],            meta : {percent:100}        });    }    var centralDirLength = this.bytesWritten - localDirLength;    var dirEnd = generateCentralDirectoryEnd(this.dirRecords.length, centralDirLength, localDirLength, this.zipComment, this.encodeFileName);    this.push({        data : dirEnd,        meta : {percent:100}    });};/** * Prepare the next source to be read. */ZipFileWorker.prototype.prepareNextSource = function () {    this.previous = this._sources.shift();    this.openedSource(this.previous.streamInfo);    if (this.isPaused) {        this.previous.pause();    } else {        this.previous.resume();    }};/** * @see GenericWorker.registerPrevious */ZipFileWorker.prototype.registerPrevious = function (previous) {    this._sources.push(previous);    var self = this;    previous.on('data', function (chunk) {        self.processChunk(chunk);    });    previous.on('end', function () {        self.closedSource(self.previous.streamInfo);        if(self._sources.length) {            self.prepareNextSource();        } else {            self.end();        }    });    previous.on('error', function (e) {        self.error(e);    });    return this;};/** * @see GenericWorker.resume */ZipFileWorker.prototype.resume = function () {    if(!GenericWorker.prototype.resume.call(this)) {        return false;    }    if (!this.previous && this._sources.length) {        this.prepareNextSource();        return true;    }    if (!this.previous && !this._sources.length && !this.generatedError) {        this.end();        return true;    }};/** * @see GenericWorker.error */ZipFileWorker.prototype.error = function (e) {    var sources = this._sources;    if(!GenericWorker.prototype.error.call(this, e)) {        return false;    }    for(var i = 0; i < sources.length; i++) {        try {            sources[i].error(e);        } catch(e) {            // the `error` exploded, nothing to do        }    }    return true;};/** * @see GenericWorker.lock */ZipFileWorker.prototype.lock = function () {    GenericWorker.prototype.lock.call(this);    var sources = this._sources;    for(var i = 0; i < sources.length; i++) {        sources[i].lock();    }};module.exports = ZipFileWorker;},{"../crc32":160,"../signature":179,"../stream/GenericWorker":184,"../utf8":187,"../utils":188}],165:[function(require,module,exports){'use strict';var compressions = require('../compressions');var ZipFileWorker = require('./ZipFileWorker');/** * Find the compression to use. * @param {String} fileCompression the compression defined at the file level, if any. * @param {String} zipCompression the compression defined at the load() level. * @return {Object} the compression object to use. */var getCompression = function (fileCompression, zipCompression) {    var compressionName = fileCompression || zipCompression;    var compression = compressions[compressionName];    if (!compression) {        throw new Error(compressionName + " is not a valid compression method !");    }    return compression;};/** * Create a worker to generate a zip file. * @param {JSZip} zip the JSZip instance at the right root level. * @param {Object} options to generate the zip file. * @param {String} comment the comment to use. */exports.generateWorker = function (zip, options, comment) {    var zipFileWorker = new ZipFileWorker(options.streamFiles, comment, options.platform, options.encodeFileName);    var entriesCount = 0;    try {        zip.forEach(function (relativePath, file) {            entriesCount++;            var compression = getCompression(file.options.compression, options.compression);            var compressionOptions = file.options.compressionOptions || options.compressionOptions || {};            var dir = file.dir, date = file.date;            file._compressWorker(compression, compressionOptions)            .withStreamInfo("file", {                name : relativePath,                dir : dir,                date : date,                comment : file.comment || "",                unixPermissions : file.unixPermissions,                dosPermissions : file.dosPermissions            })            .pipe(zipFileWorker);        });        zipFileWorker.entriesCount = entriesCount;    } catch (e) {        zipFileWorker.error(e);    }    return zipFileWorker;};},{"../compressions":159,"./ZipFileWorker":164}],166:[function(require,module,exports){'use strict';/** * Representation a of zip file in js * @constructor */function JSZip() {    // if this constructor is used without `new`, it adds `new` before itself:    if(!(this instanceof JSZip)) {        return new JSZip();    }    if(arguments.length) {        throw new Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide.");    }    // object containing the files :    // {    //   "folder/" : {...},    //   "folder/data.txt" : {...}    // }    this.files = {};    this.comment = null;    // Where we are in the hierarchy    this.root = "";    this.clone = function() {        var newObj = new JSZip();        for (var i in this) {            if (typeof this[i] !== "function") {                newObj[i] = this[i];            }        }        return newObj;    };}JSZip.prototype = require('./object');JSZip.prototype.loadAsync = require('./load');JSZip.support = require('./support');JSZip.defaults = require('./defaults');// TODO find a better way to handle this version,// a require('package.json').version doesn't work with webpack, see #327JSZip.version = "3.1.5";JSZip.loadAsync = function (content, options) {    return new JSZip().loadAsync(content, options);};JSZip.external = require("./external");module.exports = JSZip;},{"./defaults":161,"./external":162,"./load":167,"./object":171,"./support":186}],167:[function(require,module,exports){'use strict';var utils = require('./utils');var external = require("./external");var utf8 = require('./utf8');var utils = require('./utils');var ZipEntries = require('./zipEntries');var Crc32Probe = require('./stream/Crc32Probe');var nodejsUtils = require("./nodejsUtils");/** * Check the CRC32 of an entry. * @param {ZipEntry} zipEntry the zip entry to check. * @return {Promise} the result. */function checkEntryCRC32(zipEntry) {    return new external.Promise(function (resolve, reject) {        var worker = zipEntry.decompressed.getContentWorker().pipe(new Crc32Probe());        worker.on("error", function (e) {            reject(e);        })        .on("end", function () {            if (worker.streamInfo.crc32 !== zipEntry.decompressed.crc32) {                reject(new Error("Corrupted zip : CRC32 mismatch"));            } else {                resolve();            }        })        .resume();    });}module.exports = function(data, options) {    var zip = this;    options = utils.extend(options || {}, {        base64: false,        checkCRC32: false,        optimizedBinaryString: false,        createFolders: false,        decodeFileName: utf8.utf8decode    });    if (nodejsUtils.isNode && nodejsUtils.isStream(data)) {        return external.Promise.reject(new Error("JSZip can't accept a stream when loading a zip file."));    }    return utils.prepareContent("the loaded zip file", data, true, options.optimizedBinaryString, options.base64)    .then(function(data) {        var zipEntries = new ZipEntries(options);        zipEntries.load(data);        return zipEntries;    }).then(function checkCRC32(zipEntries) {        var promises = [external.Promise.resolve(zipEntries)];        var files = zipEntries.files;        if (options.checkCRC32) {            for (var i = 0; i < files.length; i++) {                promises.push(checkEntryCRC32(files[i]));            }        }        return external.Promise.all(promises);    }).then(function addFiles(results) {        var zipEntries = results.shift();        var files = zipEntries.files;        for (var i = 0; i < files.length; i++) {            var input = files[i];            zip.file(input.fileNameStr, input.decompressed, {                binary: true,                optimizedBinaryString: true,                date: input.date,                dir: input.dir,                comment : input.fileCommentStr.length ? input.fileCommentStr : null,                unixPermissions : input.unixPermissions,                dosPermissions : input.dosPermissions,                createFolders: options.createFolders            });        }        if (zipEntries.zipComment.length) {            zip.comment = zipEntries.zipComment;        }        return zip;    });};},{"./external":162,"./nodejsUtils":168,"./stream/Crc32Probe":181,"./utf8":187,"./utils":188,"./zipEntries":189}],168:[function(require,module,exports){(function (Buffer){'use strict';module.exports = {    /**     * True if this is running in Nodejs, will be undefined in a browser.     * In a browser, browserify won't include this file and the whole module     * will be resolved an empty object.     */    isNode : typeof Buffer !== "undefined",    /**     * Create a new nodejs Buffer from an existing content.     * @param {Object} data the data to pass to the constructor.     * @param {String} encoding the encoding to use.     * @return {Buffer} a new Buffer.     */    newBufferFrom: function(data, encoding) {        // XXX We can't use `Buffer.from` which comes from `Uint8Array.from`        // in nodejs v4 (< v.4.5). It's not the expected implementation (and        // has a different signature).        // see https://github.com/nodejs/node/issues/8053        // A condition on nodejs' version won't solve the issue as we don't        // control the Buffer polyfills that may or may not be used.        return new Buffer(data, encoding);    },    /**     * Create a new nodejs Buffer with the specified size.     * @param {Integer} size the size of the buffer.     * @return {Buffer} a new Buffer.     */    allocBuffer: function (size) {        if (Buffer.alloc) {            return Buffer.alloc(size);        } else {            return new Buffer(size);        }    },    /**     * Find out if an object is a Buffer.     * @param {Object} b the object to test.     * @return {Boolean} true if the object is a Buffer, false otherwise.     */    isBuffer : function(b){        return Buffer.isBuffer(b);    },    isStream : function (obj) {        return obj &&            typeof obj.on === "function" &&            typeof obj.pause === "function" &&            typeof obj.resume === "function";    }};}).call(this,require("buffer").Buffer)},{"buffer":79}],169:[function(require,module,exports){"use strict";var utils = require('../utils');var GenericWorker = require('../stream/GenericWorker');/** * A worker that use a nodejs stream as source. * @constructor * @param {String} filename the name of the file entry for this stream. * @param {Readable} stream the nodejs stream. */function NodejsStreamInputAdapter(filename, stream) {    GenericWorker.call(this, "Nodejs stream input adapter for " + filename);    this._upstreamEnded = false;    this._bindStream(stream);}utils.inherits(NodejsStreamInputAdapter, GenericWorker);/** * Prepare the stream and bind the callbacks on it. * Do this ASAP on node 0.10 ! A lazy binding doesn't always work. * @param {Stream} stream the nodejs stream to use. */NodejsStreamInputAdapter.prototype._bindStream = function (stream) {    var self = this;    this._stream = stream;    stream.pause();    stream    .on("data", function (chunk) {        self.push({            data: chunk,            meta : {                percent : 0            }        });    })    .on("error", function (e) {        if(self.isPaused) {            this.generatedError = e;        } else {            self.error(e);        }    })    .on("end", function () {        if(self.isPaused) {            self._upstreamEnded = true;        } else {            self.end();        }    });};NodejsStreamInputAdapter.prototype.pause = function () {    if(!GenericWorker.prototype.pause.call(this)) {        return false;    }    this._stream.pause();    return true;};NodejsStreamInputAdapter.prototype.resume = function () {    if(!GenericWorker.prototype.resume.call(this)) {        return false;    }    if(this._upstreamEnded) {        this.end();    } else {        this._stream.resume();    }    return true;};module.exports = NodejsStreamInputAdapter;},{"../stream/GenericWorker":184,"../utils":188}],170:[function(require,module,exports){'use strict';var Readable = require('readable-stream').Readable;var utils = require('../utils');utils.inherits(NodejsStreamOutputAdapter, Readable);/*** A nodejs stream using a worker as source.* @see the SourceWrapper in http://nodejs.org/api/stream.html* @constructor* @param {StreamHelper} helper the helper wrapping the worker* @param {Object} options the nodejs stream options* @param {Function} updateCb the update callback.*/function NodejsStreamOutputAdapter(helper, options, updateCb) {    Readable.call(this, options);    this._helper = helper;    var self = this;    helper.on("data", function (data, meta) {        if (!self.push(data)) {            self._helper.pause();        }        if(updateCb) {            updateCb(meta);        }    })    .on("error", function(e) {        self.emit('error', e);    })    .on("end", function () {        self.push(null);    });}NodejsStreamOutputAdapter.prototype._read = function() {    this._helper.resume();};module.exports = NodejsStreamOutputAdapter;},{"../utils":188,"readable-stream":172}],171:[function(require,module,exports){'use strict';var utf8 = require('./utf8');var utils = require('./utils');var GenericWorker = require('./stream/GenericWorker');var StreamHelper = require('./stream/StreamHelper');var defaults = require('./defaults');var CompressedObject = require('./compressedObject');var ZipObject = require('./zipObject');var generate = require("./generate");var nodejsUtils = require("./nodejsUtils");var NodejsStreamInputAdapter = require("./nodejs/NodejsStreamInputAdapter");/** * Add a file in the current folder. * @private * @param {string} name the name of the file * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file * @param {Object} originalOptions the options of the file * @return {Object} the new file. */var fileAdd = function(name, data, originalOptions) {    // be sure sub folders exist    var dataType = utils.getTypeOf(data),        parent;    /*     * Correct options.     */    var o = utils.extend(originalOptions || {}, defaults);    o.date = o.date || new Date();    if (o.compression !== null) {        o.compression = o.compression.toUpperCase();    }    if (typeof o.unixPermissions === "string") {        o.unixPermissions = parseInt(o.unixPermissions, 8);    }    // UNX_IFDIR  0040000 see zipinfo.c    if (o.unixPermissions && (o.unixPermissions & 0x4000)) {        o.dir = true;    }    // Bit 4    Directory    if (o.dosPermissions && (o.dosPermissions & 0x0010)) {        o.dir = true;    }    if (o.dir) {        name = forceTrailingSlash(name);    }    if (o.createFolders && (parent = parentFolder(name))) {        folderAdd.call(this, parent, true);    }    var isUnicodeString = dataType === "string" && o.binary === false && o.base64 === false;    if (!originalOptions || typeof originalOptions.binary === "undefined") {        o.binary = !isUnicodeString;    }    var isCompressedEmpty = (data instanceof CompressedObject) && data.uncompressedSize === 0;    if (isCompressedEmpty || o.dir || !data || data.length === 0) {        o.base64 = false;        o.binary = true;        data = "";        o.compression = "STORE";        dataType = "string";    }    /*     * Convert content to fit.     */    var zipObjectContent = null;    if (data instanceof CompressedObject || data instanceof GenericWorker) {        zipObjectContent = data;    } else if (nodejsUtils.isNode && nodejsUtils.isStream(data)) {        zipObjectContent = new NodejsStreamInputAdapter(name, data);    } else {        zipObjectContent = utils.prepareContent(name, data, o.binary, o.optimizedBinaryString, o.base64);    }    var object = new ZipObject(name, zipObjectContent, o);    this.files[name] = object;    /*    TODO: we can't throw an exception because we have async promises    (we can have a promise of a Date() for example) but returning a    promise is useless because file(name, data) returns the JSZip    object for chaining. Should we break that to allow the user    to catch the error ?    return external.Promise.resolve(zipObjectContent)    .then(function () {        return object;    });    */};/** * Find the parent folder of the path. * @private * @param {string} path the path to use * @return {string} the parent folder, or "" */var parentFolder = function (path) {    if (path.slice(-1) === '/') {        path = path.substring(0, path.length - 1);    }    var lastSlash = path.lastIndexOf('/');    return (lastSlash > 0) ? path.substring(0, lastSlash) : "";};/** * Returns the path with a slash at the end. * @private * @param {String} path the path to check. * @return {String} the path with a trailing slash. */var forceTrailingSlash = function(path) {    // Check the name ends with a /    if (path.slice(-1) !== "/") {        path += "/"; // IE doesn't like substr(-1)    }    return path;};/** * Add a (sub) folder in the current folder. * @private * @param {string} name the folder's name * @param {boolean=} [createFolders] If true, automatically create sub *  folders. Defaults to false. * @return {Object} the new folder. */var folderAdd = function(name, createFolders) {    createFolders = (typeof createFolders !== 'undefined') ? createFolders : defaults.createFolders;    name = forceTrailingSlash(name);    // Does this folder already exist?    if (!this.files[name]) {        fileAdd.call(this, name, null, {            dir: true,            createFolders: createFolders        });    }    return this.files[name];};/*** Cross-window, cross-Node-context regular expression detection* @param  {Object}  object Anything* @return {Boolean}        true if the object is a regular expression,* false otherwise*/function isRegExp(object) {    return Object.prototype.toString.call(object) === "[object RegExp]";}// return the actual prototype of JSZipvar out = {    /**     * @see loadAsync     */    load: function() {        throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.");    },    /**     * Call a callback function for each entry at this folder level.     * @param {Function} cb the callback function:     * function (relativePath, file) {...}     * It takes 2 arguments : the relative path and the file.     */    forEach: function(cb) {        var filename, relativePath, file;        for (filename in this.files) {            if (!this.files.hasOwnProperty(filename)) {                continue;            }            file = this.files[filename];            relativePath = filename.slice(this.root.length, filename.length);            if (relativePath && filename.slice(0, this.root.length) === this.root) { // the file is in the current root                cb(relativePath, file); // TODO reverse the parameters ? need to be clean AND consistent with the filter search fn...            }        }    },    /**     * Filter nested files/folders with the specified function.     * @param {Function} search the predicate to use :     * function (relativePath, file) {...}     * It takes 2 arguments : the relative path and the file.     * @return {Array} An array of matching elements.     */    filter: function(search) {        var result = [];        this.forEach(function (relativePath, entry) {            if (search(relativePath, entry)) { // the file matches the function                result.push(entry);            }        });        return result;    },    /**     * Add a file to the zip file, or search a file.     * @param   {string|RegExp} name The name of the file to add (if data is defined),     * the name of the file to find (if no data) or a regex to match files.     * @param   {String|ArrayBuffer|Uint8Array|Buffer} data  The file data, either raw or base64 encoded     * @param   {Object} o     File options     * @return  {JSZip|Object|Array} this JSZip object (when adding a file),     * a file (when searching by string) or an array of files (when searching by regex).     */    file: function(name, data, o) {        if (arguments.length === 1) {            if (isRegExp(name)) {                var regexp = name;                return this.filter(function(relativePath, file) {                    return !file.dir && regexp.test(relativePath);                });            }            else { // text                var obj = this.files[this.root + name];                if (obj && !obj.dir) {                    return obj;                } else {                    return null;                }            }        }        else { // more than one argument : we have data !            name = this.root + name;            fileAdd.call(this, name, data, o);        }        return this;    },    /**     * Add a directory to the zip file, or search.     * @param   {String|RegExp} arg The name of the directory to add, or a regex to search folders.     * @return  {JSZip} an object with the new directory as the root, or an array containing matching folders.     */    folder: function(arg) {        if (!arg) {            return this;        }        if (isRegExp(arg)) {            return this.filter(function(relativePath, file) {                return file.dir && arg.test(relativePath);            });        }        // else, name is a new folder        var name = this.root + arg;        var newFolder = folderAdd.call(this, name);        // Allow chaining by returning a new object with this folder as the root        var ret = this.clone();        ret.root = newFolder.name;        return ret;    },    /**     * Delete a file, or a directory and all sub-files, from the zip     * @param {string} name the name of the file to delete     * @return {JSZip} this JSZip object     */    remove: function(name) {        name = this.root + name;        var file = this.files[name];        if (!file) {            // Look for any folders            if (name.slice(-1) !== "/") {                name += "/";            }            file = this.files[name];        }        if (file && !file.dir) {            // file            delete this.files[name];        } else {            // maybe a folder, delete recursively            var kids = this.filter(function(relativePath, file) {                return file.name.slice(0, name.length) === name;            });            for (var i = 0; i < kids.length; i++) {                delete this.files[kids[i].name];            }        }        return this;    },    /**     * Generate the complete zip file     * @param {Object} options the options to generate the zip file :     * - compression, "STORE" by default.     * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob.     * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file     */    generate: function(options) {        throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.");    },    /**     * Generate the complete zip file as an internal stream.     * @param {Object} options the options to generate the zip file :     * - compression, "STORE" by default.     * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob.     * @return {StreamHelper} the streamed zip file.     */    generateInternalStream: function(options) {      var worker, opts = {};      try {          opts = utils.extend(options || {}, {              streamFiles: false,              compression: "STORE",              compressionOptions : null,              type: "",              platform: "DOS",              comment: null,              mimeType: 'application/zip',              encodeFileName: utf8.utf8encode          });          opts.type = opts.type.toLowerCase();          opts.compression = opts.compression.toUpperCase();          // "binarystring" is prefered but the internals use "string".          if(opts.type === "binarystring") {            opts.type = "string";          }          if (!opts.type) {            throw new Error("No output type specified.");          }          utils.checkSupport(opts.type);          // accept nodejs `process.platform`          if(              opts.platform === 'darwin' ||              opts.platform === 'freebsd' ||              opts.platform === 'linux' ||              opts.platform === 'sunos'          ) {              opts.platform = "UNIX";          }          if (opts.platform === 'win32') {              opts.platform = "DOS";          }          var comment = opts.comment || this.comment || "";          worker = generate.generateWorker(this, opts, comment);      } catch (e) {        worker = new GenericWorker("error");        worker.error(e);      }      return new StreamHelper(worker, opts.type || "string", opts.mimeType);    },    /**     * Generate the complete zip file asynchronously.     * @see generateInternalStream     */    generateAsync: function(options, onUpdate) {        return this.generateInternalStream(options).accumulate(onUpdate);    },    /**     * Generate the complete zip file asynchronously.     * @see generateInternalStream     */    generateNodeStream: function(options, onUpdate) {        options = options || {};        if (!options.type) {            options.type = "nodebuffer";        }        return this.generateInternalStream(options).toNodejsStream(onUpdate);    }};module.exports = out;},{"./compressedObject":158,"./defaults":161,"./generate":165,"./nodejs/NodejsStreamInputAdapter":169,"./nodejsUtils":168,"./stream/GenericWorker":184,"./stream/StreamHelper":185,"./utf8":187,"./utils":188,"./zipObject":191}],172:[function(require,module,exports){/* * This file is used by module bundlers (browserify/webpack/etc) when * including a stream implementation. We use "readable-stream" to get a * consistent behavior between nodejs versions but bundlers often have a shim * for "stream". Using this shim greatly improve the compatibility and greatly * reduce the final size of the bundle (only one stream implementation, not * two). */module.exports = require("stream");},{"stream":257}],173:[function(require,module,exports){'use strict';var DataReader = require('./DataReader');var utils = require('../utils');function ArrayReader(data) {    DataReader.call(this, data);	for(var i = 0; i < this.data.length; i++) {		data[i] = data[i] & 0xFF;	}}utils.inherits(ArrayReader, DataReader);/** * @see DataReader.byteAt */ArrayReader.prototype.byteAt = function(i) {    return this.data[this.zero + i];};/** * @see DataReader.lastIndexOfSignature */ArrayReader.prototype.lastIndexOfSignature = function(sig) {    var sig0 = sig.charCodeAt(0),        sig1 = sig.charCodeAt(1),        sig2 = sig.charCodeAt(2),        sig3 = sig.charCodeAt(3);    for (var i = this.length - 4; i >= 0; --i) {        if (this.data[i] === sig0 && this.data[i + 1] === sig1 && this.data[i + 2] === sig2 && this.data[i + 3] === sig3) {            return i - this.zero;        }    }    return -1;};/** * @see DataReader.readAndCheckSignature */ArrayReader.prototype.readAndCheckSignature = function (sig) {    var sig0 = sig.charCodeAt(0),        sig1 = sig.charCodeAt(1),        sig2 = sig.charCodeAt(2),        sig3 = sig.charCodeAt(3),        data = this.readData(4);    return sig0 === data[0] && sig1 === data[1] && sig2 === data[2] && sig3 === data[3];};/** * @see DataReader.readData */ArrayReader.prototype.readData = function(size) {    this.checkOffset(size);    if(size === 0) {        return [];    }    var result = this.data.slice(this.zero + this.index, this.zero + this.index + size);    this.index += size;    return result;};module.exports = ArrayReader;},{"../utils":188,"./DataReader":174}],174:[function(require,module,exports){'use strict';var utils = require('../utils');function DataReader(data) {    this.data = data; // type : see implementation    this.length = data.length;    this.index = 0;    this.zero = 0;}DataReader.prototype = {    /**     * Check that the offset will not go too far.     * @param {string} offset the additional offset to check.     * @throws {Error} an Error if the offset is out of bounds.     */    checkOffset: function(offset) {        this.checkIndex(this.index + offset);    },    /**     * Check that the specified index will not be too far.     * @param {string} newIndex the index to check.     * @throws {Error} an Error if the index is out of bounds.     */    checkIndex: function(newIndex) {        if (this.length < this.zero + newIndex || newIndex < 0) {            throw new Error("End of data reached (data length = " + this.length + ", asked index = " + (newIndex) + "). Corrupted zip ?");        }    },    /**     * Change the index.     * @param {number} newIndex The new index.     * @throws {Error} if the new index is out of the data.     */    setIndex: function(newIndex) {        this.checkIndex(newIndex);        this.index = newIndex;    },    /**     * Skip the next n bytes.     * @param {number} n the number of bytes to skip.     * @throws {Error} if the new index is out of the data.     */    skip: function(n) {        this.setIndex(this.index + n);    },    /**     * Get the byte at the specified index.     * @param {number} i the index to use.     * @return {number} a byte.     */    byteAt: function(i) {        // see implementations    },    /**     * Get the next number with a given byte size.     * @param {number} size the number of bytes to read.     * @return {number} the corresponding number.     */    readInt: function(size) {        var result = 0,            i;        this.checkOffset(size);        for (i = this.index + size - 1; i >= this.index; i--) {            result = (result << 8) + this.byteAt(i);        }        this.index += size;        return result;    },    /**     * Get the next string with a given byte size.     * @param {number} size the number of bytes to read.     * @return {string} the corresponding string.     */    readString: function(size) {        return utils.transformTo("string", this.readData(size));    },    /**     * Get raw data without conversion, <size> bytes.     * @param {number} size the number of bytes to read.     * @return {Object} the raw data, implementation specific.     */    readData: function(size) {        // see implementations    },    /**     * Find the last occurence of a zip signature (4 bytes).     * @param {string} sig the signature to find.     * @return {number} the index of the last occurence, -1 if not found.     */    lastIndexOfSignature: function(sig) {        // see implementations    },    /**     * Read the signature (4 bytes) at the current position and compare it with sig.     * @param {string} sig the expected signature     * @return {boolean} true if the signature matches, false otherwise.     */    readAndCheckSignature: function(sig) {        // see implementations    },    /**     * Get the next date.     * @return {Date} the date.     */    readDate: function() {        var dostime = this.readInt(4);        return new Date(Date.UTC(        ((dostime >> 25) & 0x7f) + 1980, // year        ((dostime >> 21) & 0x0f) - 1, // month        (dostime >> 16) & 0x1f, // day        (dostime >> 11) & 0x1f, // hour        (dostime >> 5) & 0x3f, // minute        (dostime & 0x1f) << 1)); // second    }};module.exports = DataReader;},{"../utils":188}],175:[function(require,module,exports){'use strict';var Uint8ArrayReader = require('./Uint8ArrayReader');var utils = require('../utils');function NodeBufferReader(data) {    Uint8ArrayReader.call(this, data);}utils.inherits(NodeBufferReader, Uint8ArrayReader);/** * @see DataReader.readData */NodeBufferReader.prototype.readData = function(size) {    this.checkOffset(size);    var result = this.data.slice(this.zero + this.index, this.zero + this.index + size);    this.index += size;    return result;};module.exports = NodeBufferReader;},{"../utils":188,"./Uint8ArrayReader":177}],176:[function(require,module,exports){'use strict';var DataReader = require('./DataReader');var utils = require('../utils');function StringReader(data) {    DataReader.call(this, data);}utils.inherits(StringReader, DataReader);/** * @see DataReader.byteAt */StringReader.prototype.byteAt = function(i) {    return this.data.charCodeAt(this.zero + i);};/** * @see DataReader.lastIndexOfSignature */StringReader.prototype.lastIndexOfSignature = function(sig) {    return this.data.lastIndexOf(sig) - this.zero;};/** * @see DataReader.readAndCheckSignature */StringReader.prototype.readAndCheckSignature = function (sig) {    var data = this.readData(4);    return sig === data;};/** * @see DataReader.readData */StringReader.prototype.readData = function(size) {    this.checkOffset(size);    // this will work because the constructor applied the "& 0xff" mask.    var result = this.data.slice(this.zero + this.index, this.zero + this.index + size);    this.index += size;    return result;};module.exports = StringReader;},{"../utils":188,"./DataReader":174}],177:[function(require,module,exports){'use strict';var ArrayReader = require('./ArrayReader');var utils = require('../utils');function Uint8ArrayReader(data) {    ArrayReader.call(this, data);}utils.inherits(Uint8ArrayReader, ArrayReader);/** * @see DataReader.readData */Uint8ArrayReader.prototype.readData = function(size) {    this.checkOffset(size);    if(size === 0) {        // in IE10, when using subarray(idx, idx), we get the array [0x00] instead of [].        return new Uint8Array(0);    }    var result = this.data.subarray(this.zero + this.index, this.zero + this.index + size);    this.index += size;    return result;};module.exports = Uint8ArrayReader;},{"../utils":188,"./ArrayReader":173}],178:[function(require,module,exports){'use strict';var utils = require('../utils');var support = require('../support');var ArrayReader = require('./ArrayReader');var StringReader = require('./StringReader');var NodeBufferReader = require('./NodeBufferReader');var Uint8ArrayReader = require('./Uint8ArrayReader');/** * Create a reader adapted to the data. * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data to read. * @return {DataReader} the data reader. */module.exports = function (data) {    var type = utils.getTypeOf(data);    utils.checkSupport(type);    if (type === "string" && !support.uint8array) {        return new StringReader(data);    }    if (type === "nodebuffer") {        return new NodeBufferReader(data);    }    if (support.uint8array) {        return new Uint8ArrayReader(utils.transformTo("uint8array", data));    }    return new ArrayReader(utils.transformTo("array", data));};},{"../support":186,"../utils":188,"./ArrayReader":173,"./NodeBufferReader":175,"./StringReader":176,"./Uint8ArrayReader":177}],179:[function(require,module,exports){'use strict';exports.LOCAL_FILE_HEADER = "PK\x03\x04";exports.CENTRAL_FILE_HEADER = "PK\x01\x02";exports.CENTRAL_DIRECTORY_END = "PK\x05\x06";exports.ZIP64_CENTRAL_DIRECTORY_LOCATOR = "PK\x06\x07";exports.ZIP64_CENTRAL_DIRECTORY_END = "PK\x06\x06";exports.DATA_DESCRIPTOR = "PK\x07\x08";},{}],180:[function(require,module,exports){'use strict';var GenericWorker = require('./GenericWorker');var utils = require('../utils');/** * A worker which convert chunks to a specified type. * @constructor * @param {String} destType the destination type. */function ConvertWorker(destType) {    GenericWorker.call(this, "ConvertWorker to " + destType);    this.destType = destType;}utils.inherits(ConvertWorker, GenericWorker);/** * @see GenericWorker.processChunk */ConvertWorker.prototype.processChunk = function (chunk) {    this.push({        data : utils.transformTo(this.destType, chunk.data),        meta : chunk.meta    });};module.exports = ConvertWorker;},{"../utils":188,"./GenericWorker":184}],181:[function(require,module,exports){'use strict';var GenericWorker = require('./GenericWorker');var crc32 = require('../crc32');var utils = require('../utils');/** * A worker which calculate the crc32 of the data flowing through. * @constructor */function Crc32Probe() {    GenericWorker.call(this, "Crc32Probe");    this.withStreamInfo("crc32", 0);}utils.inherits(Crc32Probe, GenericWorker);/** * @see GenericWorker.processChunk */Crc32Probe.prototype.processChunk = function (chunk) {    this.streamInfo.crc32 = crc32(chunk.data, this.streamInfo.crc32 || 0);    this.push(chunk);};module.exports = Crc32Probe;},{"../crc32":160,"../utils":188,"./GenericWorker":184}],182:[function(require,module,exports){'use strict';var utils = require('../utils');var GenericWorker = require('./GenericWorker');/** * A worker which calculate the total length of the data flowing through. * @constructor * @param {String} propName the name used to expose the length */function DataLengthProbe(propName) {    GenericWorker.call(this, "DataLengthProbe for " + propName);    this.propName = propName;    this.withStreamInfo(propName, 0);}utils.inherits(DataLengthProbe, GenericWorker);/** * @see GenericWorker.processChunk */DataLengthProbe.prototype.processChunk = function (chunk) {    if(chunk) {        var length = this.streamInfo[this.propName] || 0;        this.streamInfo[this.propName] = length + chunk.data.length;    }    GenericWorker.prototype.processChunk.call(this, chunk);};module.exports = DataLengthProbe;},{"../utils":188,"./GenericWorker":184}],183:[function(require,module,exports){'use strict';var utils = require('../utils');var GenericWorker = require('./GenericWorker');// the size of the generated chunks// TODO expose this as a public variablevar DEFAULT_BLOCK_SIZE = 16 * 1024;/** * A worker that reads a content and emits chunks. * @constructor * @param {Promise} dataP the promise of the data to split */function DataWorker(dataP) {    GenericWorker.call(this, "DataWorker");    var self = this;    this.dataIsReady = false;    this.index = 0;    this.max = 0;    this.data = null;    this.type = "";    this._tickScheduled = false;    dataP.then(function (data) {        self.dataIsReady = true;        self.data = data;        self.max = data && data.length || 0;        self.type = utils.getTypeOf(data);        if(!self.isPaused) {            self._tickAndRepeat();        }    }, function (e) {        self.error(e);    });}utils.inherits(DataWorker, GenericWorker);/** * @see GenericWorker.cleanUp */DataWorker.prototype.cleanUp = function () {    GenericWorker.prototype.cleanUp.call(this);    this.data = null;};/** * @see GenericWorker.resume */DataWorker.prototype.resume = function () {    if(!GenericWorker.prototype.resume.call(this)) {        return false;    }    if (!this._tickScheduled && this.dataIsReady) {        this._tickScheduled = true;        utils.delay(this._tickAndRepeat, [], this);    }    return true;};/** * Trigger a tick a schedule an other call to this function. */DataWorker.prototype._tickAndRepeat = function() {    this._tickScheduled = false;    if(this.isPaused || this.isFinished) {        return;    }    this._tick();    if(!this.isFinished) {        utils.delay(this._tickAndRepeat, [], this);        this._tickScheduled = true;    }};/** * Read and push a chunk. */DataWorker.prototype._tick = function() {    if(this.isPaused || this.isFinished) {        return false;    }    var size = DEFAULT_BLOCK_SIZE;    var data = null, nextIndex = Math.min(this.max, this.index + size);    if (this.index >= this.max) {        // EOF        return this.end();    } else {        switch(this.type) {            case "string":                data = this.data.substring(this.index, nextIndex);            break;            case "uint8array":                data = this.data.subarray(this.index, nextIndex);            break;            case "array":            case "nodebuffer":                data = this.data.slice(this.index, nextIndex);            break;        }        this.index = nextIndex;        return this.push({            data : data,            meta : {                percent : this.max ? this.index / this.max * 100 : 0            }        });    }};module.exports = DataWorker;},{"../utils":188,"./GenericWorker":184}],184:[function(require,module,exports){'use strict';/** * A worker that does nothing but passing chunks to the next one. This is like * a nodejs stream but with some differences. On the good side : * - it works on IE 6-9 without any issue / polyfill * - it weights less than the full dependencies bundled with browserify * - it forwards errors (no need to declare an error handler EVERYWHERE) * * A chunk is an object with 2 attributes : `meta` and `data`. The former is an * object containing anything (`percent` for example), see each worker for more * details. The latter is the real data (String, Uint8Array, etc). * * @constructor * @param {String} name the name of the stream (mainly used for debugging purposes) */function GenericWorker(name) {    // the name of the worker    this.name = name || "default";    // an object containing metadata about the workers chain    this.streamInfo = {};    // an error which happened when the worker was paused    this.generatedError = null;    // an object containing metadata to be merged by this worker into the general metadata    this.extraStreamInfo = {};    // true if the stream is paused (and should not do anything), false otherwise    this.isPaused = true;    // true if the stream is finished (and should not do anything), false otherwise    this.isFinished = false;    // true if the stream is locked to prevent further structure updates (pipe), false otherwise    this.isLocked = false;    // the event listeners    this._listeners = {        'data':[],        'end':[],        'error':[]    };    // the previous worker, if any    this.previous = null;}GenericWorker.prototype = {    /**     * Push a chunk to the next workers.     * @param {Object} chunk the chunk to push     */    push : function (chunk) {        this.emit("data", chunk);    },    /**     * End the stream.     * @return {Boolean} true if this call ended the worker, false otherwise.     */    end : function () {        if (this.isFinished) {            return false;        }        this.flush();        try {            this.emit("end");            this.cleanUp();            this.isFinished = true;        } catch (e) {            this.emit("error", e);        }        return true;    },    /**     * End the stream with an error.     * @param {Error} e the error which caused the premature end.     * @return {Boolean} true if this call ended the worker with an error, false otherwise.     */    error : function (e) {        if (this.isFinished) {            return false;        }        if(this.isPaused) {            this.generatedError = e;        } else {            this.isFinished = true;            this.emit("error", e);            // in the workers chain exploded in the middle of the chain,            // the error event will go downward but we also need to notify            // workers upward that there has been an error.            if(this.previous) {                this.previous.error(e);            }            this.cleanUp();        }        return true;    },    /**     * Add a callback on an event.     * @param {String} name the name of the event (data, end, error)     * @param {Function} listener the function to call when the event is triggered     * @return {GenericWorker} the current object for chainability     */    on : function (name, listener) {        this._listeners[name].push(listener);        return this;    },    /**     * Clean any references when a worker is ending.     */    cleanUp : function () {        this.streamInfo = this.generatedError = this.extraStreamInfo = null;        this._listeners = [];    },    /**     * Trigger an event. This will call registered callback with the provided arg.     * @param {String} name the name of the event (data, end, error)     * @param {Object} arg the argument to call the callback with.     */    emit : function (name, arg) {        if (this._listeners[name]) {            for(var i = 0; i < this._listeners[name].length; i++) {                this._listeners[name][i].call(this, arg);            }        }    },    /**     * Chain a worker with an other.     * @param {Worker} next the worker receiving events from the current one.     * @return {worker} the next worker for chainability     */    pipe : function (next) {        return next.registerPrevious(this);    },    /**     * Same as `pipe` in the other direction.     * Using an API with `pipe(next)` is very easy.     * Implementing the API with the point of view of the next one registering     * a source is easier, see the ZipFileWorker.     * @param {Worker} previous the previous worker, sending events to this one     * @return {Worker} the current worker for chainability     */    registerPrevious : function (previous) {        if (this.isLocked) {            throw new Error("The stream '" + this + "' has already been used.");        }        // sharing the streamInfo...        this.streamInfo = previous.streamInfo;        // ... and adding our own bits        this.mergeStreamInfo();        this.previous =  previous;        var self = this;        previous.on('data', function (chunk) {            self.processChunk(chunk);        });        previous.on('end', function () {            self.end();        });        previous.on('error', function (e) {            self.error(e);        });        return this;    },    /**     * Pause the stream so it doesn't send events anymore.     * @return {Boolean} true if this call paused the worker, false otherwise.     */    pause : function () {        if(this.isPaused || this.isFinished) {            return false;        }        this.isPaused = true;        if(this.previous) {            this.previous.pause();        }        return true;    },    /**     * Resume a paused stream.     * @return {Boolean} true if this call resumed the worker, false otherwise.     */    resume : function () {        if(!this.isPaused || this.isFinished) {            return false;        }        this.isPaused = false;        // if true, the worker tried to resume but failed        var withError = false;        if(this.generatedError) {            this.error(this.generatedError);            withError = true;        }        if(this.previous) {            this.previous.resume();        }        return !withError;    },    /**     * Flush any remaining bytes as the stream is ending.     */    flush : function () {},    /**     * Process a chunk. This is usually the method overridden.     * @param {Object} chunk the chunk to process.     */    processChunk : function(chunk) {        this.push(chunk);    },    /**     * Add a key/value to be added in the workers chain streamInfo once activated.     * @param {String} key the key to use     * @param {Object} value the associated value     * @return {Worker} the current worker for chainability     */    withStreamInfo : function (key, value) {        this.extraStreamInfo[key] = value;        this.mergeStreamInfo();        return this;    },    /**     * Merge this worker's streamInfo into the chain's streamInfo.     */    mergeStreamInfo : function () {        for(var key in this.extraStreamInfo) {            if (!this.extraStreamInfo.hasOwnProperty(key)) {                continue;            }            this.streamInfo[key] = this.extraStreamInfo[key];        }    },    /**     * Lock the stream to prevent further updates on the workers chain.     * After calling this method, all calls to pipe will fail.     */    lock: function () {        if (this.isLocked) {            throw new Error("The stream '" + this + "' has already been used.");        }        this.isLocked = true;        if (this.previous) {            this.previous.lock();        }    },    /**     *     * Pretty print the workers chain.     */    toString : function () {        var me = "Worker " + this.name;        if (this.previous) {            return this.previous + " -> " + me;        } else {            return me;        }    }};module.exports = GenericWorker;},{}],185:[function(require,module,exports){(function (Buffer){'use strict';var utils = require('../utils');var ConvertWorker = require('./ConvertWorker');var GenericWorker = require('./GenericWorker');var base64 = require('../base64');var support = require("../support");var external = require("../external");var NodejsStreamOutputAdapter = null;if (support.nodestream) {    try {        NodejsStreamOutputAdapter = require('../nodejs/NodejsStreamOutputAdapter');    } catch(e) {}}/** * Apply the final transformation of the data. If the user wants a Blob for * example, it's easier to work with an U8intArray and finally do the * ArrayBuffer/Blob conversion. * @param {String} type the name of the final type * @param {String|Uint8Array|Buffer} content the content to transform * @param {String} mimeType the mime type of the content, if applicable. * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the content in the right format. */function transformZipOutput(type, content, mimeType) {    switch(type) {        case "blob" :            return utils.newBlob(utils.transformTo("arraybuffer", content), mimeType);        case "base64" :            return base64.encode(content);        default :            return utils.transformTo(type, content);    }}/** * Concatenate an array of data of the given type. * @param {String} type the type of the data in the given array. * @param {Array} dataArray the array containing the data chunks to concatenate * @return {String|Uint8Array|Buffer} the concatenated data * @throws Error if the asked type is unsupported */function concat (type, dataArray) {    var i, index = 0, res = null, totalLength = 0;    for(i = 0; i < dataArray.length; i++) {        totalLength += dataArray[i].length;    }    switch(type) {        case "string":            return dataArray.join("");          case "array":            return Array.prototype.concat.apply([], dataArray);        case "uint8array":            res = new Uint8Array(totalLength);            for(i = 0; i < dataArray.length; i++) {                res.set(dataArray[i], index);                index += dataArray[i].length;            }            return res;        case "nodebuffer":            return Buffer.concat(dataArray);        default:            throw new Error("concat : unsupported type '"  + type + "'");    }}/** * Listen a StreamHelper, accumulate its content and concatenate it into a * complete block. * @param {StreamHelper} helper the helper to use. * @param {Function} updateCallback a callback called on each update. Called * with one arg : * - the metadata linked to the update received. * @return Promise the promise for the accumulation. */function accumulate(helper, updateCallback) {    return new external.Promise(function (resolve, reject){        var dataArray = [];        var chunkType = helper._internalType,            resultType = helper._outputType,            mimeType = helper._mimeType;        helper        .on('data', function (data, meta) {            dataArray.push(data);            if(updateCallback) {                updateCallback(meta);            }        })        .on('error', function(err) {            dataArray = [];            reject(err);        })        .on('end', function (){            try {                var result = transformZipOutput(resultType, concat(chunkType, dataArray), mimeType);                resolve(result);            } catch (e) {                reject(e);            }            dataArray = [];        })        .resume();    });}/** * An helper to easily use workers outside of JSZip. * @constructor * @param {Worker} worker the worker to wrap * @param {String} outputType the type of data expected by the use * @param {String} mimeType the mime type of the content, if applicable. */function StreamHelper(worker, outputType, mimeType) {    var internalType = outputType;    switch(outputType) {        case "blob":        case "arraybuffer":            internalType = "uint8array";        break;        case "base64":            internalType = "string";        break;    }    try {        // the type used internally        this._internalType = internalType;        // the type used to output results        this._outputType = outputType;        // the mime type        this._mimeType = mimeType;        utils.checkSupport(internalType);        this._worker = worker.pipe(new ConvertWorker(internalType));        // the last workers can be rewired without issues but we need to        // prevent any updates on previous workers.        worker.lock();    } catch(e) {        this._worker = new GenericWorker("error");        this._worker.error(e);    }}StreamHelper.prototype = {    /**     * Listen a StreamHelper, accumulate its content and concatenate it into a     * complete block.     * @param {Function} updateCb the update callback.     * @return Promise the promise for the accumulation.     */    accumulate : function (updateCb) {        return accumulate(this, updateCb);    },    /**     * Add a listener on an event triggered on a stream.     * @param {String} evt the name of the event     * @param {Function} fn the listener     * @return {StreamHelper} the current helper.     */    on : function (evt, fn) {        var self = this;        if(evt === "data") {            this._worker.on(evt, function (chunk) {                fn.call(self, chunk.data, chunk.meta);            });        } else {            this._worker.on(evt, function () {                utils.delay(fn, arguments, self);            });        }        return this;    },    /**     * Resume the flow of chunks.     * @return {StreamHelper} the current helper.     */    resume : function () {        utils.delay(this._worker.resume, [], this._worker);        return this;    },    /**     * Pause the flow of chunks.     * @return {StreamHelper} the current helper.     */    pause : function () {        this._worker.pause();        return this;    },    /**     * Return a nodejs stream for this helper.     * @param {Function} updateCb the update callback.     * @return {NodejsStreamOutputAdapter} the nodejs stream.     */    toNodejsStream : function (updateCb) {        utils.checkSupport("nodestream");        if (this._outputType !== "nodebuffer") {            // an object stream containing blob/arraybuffer/uint8array/string            // is strange and I don't know if it would be useful.            // I you find this comment and have a good usecase, please open a            // bug report !            throw new Error(this._outputType + " is not supported by this method");        }        return new NodejsStreamOutputAdapter(this, {            objectMode : this._outputType !== "nodebuffer"        }, updateCb);    }};module.exports = StreamHelper;}).call(this,require("buffer").Buffer)},{"../base64":157,"../external":162,"../nodejs/NodejsStreamOutputAdapter":170,"../support":186,"../utils":188,"./ConvertWorker":180,"./GenericWorker":184,"buffer":79}],186:[function(require,module,exports){(function (Buffer){'use strict';exports.base64 = true;exports.array = true;exports.string = true;exports.arraybuffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined";exports.nodebuffer = typeof Buffer !== "undefined";// contains true if JSZip can read/generate Uint8Array, false otherwise.exports.uint8array = typeof Uint8Array !== "undefined";if (typeof ArrayBuffer === "undefined") {    exports.blob = false;}else {    var buffer = new ArrayBuffer(0);    try {        exports.blob = new Blob([buffer], {            type: "application/zip"        }).size === 0;    }    catch (e) {        try {            var Builder = self.BlobBuilder || self.WebKitBlobBuilder || self.MozBlobBuilder || self.MSBlobBuilder;            var builder = new Builder();            builder.append(buffer);            exports.blob = builder.getBlob('application/zip').size === 0;        }        catch (e) {            exports.blob = false;        }    }}try {    exports.nodestream = !!require('readable-stream').Readable;} catch(e) {    exports.nodestream = false;}}).call(this,require("buffer").Buffer)},{"buffer":79,"readable-stream":172}],187:[function(require,module,exports){'use strict';var utils = require('./utils');var support = require('./support');var nodejsUtils = require('./nodejsUtils');var GenericWorker = require('./stream/GenericWorker');/** * The following functions come from pako, from pako/lib/utils/strings * released under the MIT license, see pako https://github.com/nodeca/pako/ */// Table with utf8 lengths (calculated by first byte of sequence)// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS,// because max possible codepoint is 0x10ffffvar _utf8len = new Array(256);for (var i=0; i<256; i++) {  _utf8len[i] = (i >= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1);}_utf8len[254]=_utf8len[254]=1; // Invalid sequence start// convert string to array (typed, when possible)var string2buf = function (str) {    var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0;    // count binary size    for (m_pos = 0; m_pos < str_len; m_pos++) {        c = str.charCodeAt(m_pos);        if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) {            c2 = str.charCodeAt(m_pos+1);            if ((c2 & 0xfc00) === 0xdc00) {                c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);                m_pos++;            }        }        buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4;    }    // allocate buffer    if (support.uint8array) {        buf = new Uint8Array(buf_len);    } else {        buf = new Array(buf_len);    }    // convert    for (i=0, m_pos = 0; i < buf_len; m_pos++) {        c = str.charCodeAt(m_pos);        if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) {            c2 = str.charCodeAt(m_pos+1);            if ((c2 & 0xfc00) === 0xdc00) {                c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);                m_pos++;            }        }        if (c < 0x80) {            /* one byte */            buf[i++] = c;        } else if (c < 0x800) {            /* two bytes */            buf[i++] = 0xC0 | (c >>> 6);            buf[i++] = 0x80 | (c & 0x3f);        } else if (c < 0x10000) {            /* three bytes */            buf[i++] = 0xE0 | (c >>> 12);            buf[i++] = 0x80 | (c >>> 6 & 0x3f);            buf[i++] = 0x80 | (c & 0x3f);        } else {            /* four bytes */            buf[i++] = 0xf0 | (c >>> 18);            buf[i++] = 0x80 | (c >>> 12 & 0x3f);            buf[i++] = 0x80 | (c >>> 6 & 0x3f);            buf[i++] = 0x80 | (c & 0x3f);        }    }    return buf;};// Calculate max possible position in utf8 buffer,// that will not break sequence. If that's not possible// - (very small limits) return max size as is.//// buf[] - utf8 bytes array// max   - length limit (mandatory);var utf8border = function(buf, max) {    var pos;    max = max || buf.length;    if (max > buf.length) { max = buf.length; }    // go back from last position, until start of sequence found    pos = max-1;    while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; }    // Fuckup - very small and broken sequence,    // return max, because we should return something anyway.    if (pos < 0) { return max; }    // If we came to start of buffer - that means vuffer is too small,    // return max too.    if (pos === 0) { return max; }    return (pos + _utf8len[buf[pos]] > max) ? pos : max;};// convert array to stringvar buf2string = function (buf) {    var str, i, out, c, c_len;    var len = buf.length;    // Reserve max possible length (2 words per char)    // NB: by unknown reasons, Array is significantly faster for    //     String.fromCharCode.apply than Uint16Array.    var utf16buf = new Array(len*2);    for (out=0, i=0; i<len;) {        c = buf[i++];        // quick process ascii        if (c < 0x80) { utf16buf[out++] = c; continue; }        c_len = _utf8len[c];        // skip 5 & 6 byte codes        if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len-1; continue; }        // apply mask on first byte        c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07;        // join the rest        while (c_len > 1 && i < len) {            c = (c << 6) | (buf[i++] & 0x3f);            c_len--;        }        // terminated by end of string?        if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; }        if (c < 0x10000) {            utf16buf[out++] = c;        } else {            c -= 0x10000;            utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff);            utf16buf[out++] = 0xdc00 | (c & 0x3ff);        }    }    // shrinkBuf(utf16buf, out)    if (utf16buf.length !== out) {        if(utf16buf.subarray) {            utf16buf = utf16buf.subarray(0, out);        } else {            utf16buf.length = out;        }    }    // return String.fromCharCode.apply(null, utf16buf);    return utils.applyFromCharCode(utf16buf);};// That's all for the pako functions./** * Transform a javascript string into an array (typed if possible) of bytes, * UTF-8 encoded. * @param {String} str the string to encode * @return {Array|Uint8Array|Buffer} the UTF-8 encoded string. */exports.utf8encode = function utf8encode(str) {    if (support.nodebuffer) {        return nodejsUtils.newBufferFrom(str, "utf-8");    }    return string2buf(str);};/** * Transform a bytes array (or a representation) representing an UTF-8 encoded * string into a javascript string. * @param {Array|Uint8Array|Buffer} buf the data de decode * @return {String} the decoded string. */exports.utf8decode = function utf8decode(buf) {    if (support.nodebuffer) {        return utils.transformTo("nodebuffer", buf).toString("utf-8");    }    buf = utils.transformTo(support.uint8array ? "uint8array" : "array", buf);    return buf2string(buf);};/** * A worker to decode utf8 encoded binary chunks into string chunks. * @constructor */function Utf8DecodeWorker() {    GenericWorker.call(this, "utf-8 decode");    // the last bytes if a chunk didn't end with a complete codepoint.    this.leftOver = null;}utils.inherits(Utf8DecodeWorker, GenericWorker);/** * @see GenericWorker.processChunk */Utf8DecodeWorker.prototype.processChunk = function (chunk) {    var data = utils.transformTo(support.uint8array ? "uint8array" : "array", chunk.data);    // 1st step, re-use what's left of the previous chunk    if (this.leftOver && this.leftOver.length) {        if(support.uint8array) {            var previousData = data;            data = new Uint8Array(previousData.length + this.leftOver.length);            data.set(this.leftOver, 0);            data.set(previousData, this.leftOver.length);        } else {            data = this.leftOver.concat(data);        }        this.leftOver = null;    }    var nextBoundary = utf8border(data);    var usableData = data;    if (nextBoundary !== data.length) {        if (support.uint8array) {            usableData = data.subarray(0, nextBoundary);            this.leftOver = data.subarray(nextBoundary, data.length);        } else {            usableData = data.slice(0, nextBoundary);            this.leftOver = data.slice(nextBoundary, data.length);        }    }    this.push({        data : exports.utf8decode(usableData),        meta : chunk.meta    });};/** * @see GenericWorker.flush */Utf8DecodeWorker.prototype.flush = function () {    if(this.leftOver && this.leftOver.length) {        this.push({            data : exports.utf8decode(this.leftOver),            meta : {}        });        this.leftOver = null;    }};exports.Utf8DecodeWorker = Utf8DecodeWorker;/** * A worker to endcode string chunks into utf8 encoded binary chunks. * @constructor */function Utf8EncodeWorker() {    GenericWorker.call(this, "utf-8 encode");}utils.inherits(Utf8EncodeWorker, GenericWorker);/** * @see GenericWorker.processChunk */Utf8EncodeWorker.prototype.processChunk = function (chunk) {    this.push({        data : exports.utf8encode(chunk.data),        meta : chunk.meta    });};exports.Utf8EncodeWorker = Utf8EncodeWorker;},{"./nodejsUtils":168,"./stream/GenericWorker":184,"./support":186,"./utils":188}],188:[function(require,module,exports){'use strict';var support = require('./support');var base64 = require('./base64');var nodejsUtils = require('./nodejsUtils');var setImmediate = require('core-js/library/fn/set-immediate');var external = require("./external");/** * Convert a string that pass as a "binary string": it should represent a byte * array but may have > 255 char codes. Be sure to take only the first byte * and returns the byte array. * @param {String} str the string to transform. * @return {Array|Uint8Array} the string in a binary format. */function string2binary(str) {    var result = null;    if (support.uint8array) {      result = new Uint8Array(str.length);    } else {      result = new Array(str.length);    }    return stringToArrayLike(str, result);}/** * Create a new blob with the given content and the given type. * @param {String|ArrayBuffer} part the content to put in the blob. DO NOT use * an Uint8Array because the stock browser of android 4 won't accept it (it * will be silently converted to a string, "[object Uint8Array]"). * * Use only ONE part to build the blob to avoid a memory leak in IE11 / Edge: * when a large amount of Array is used to create the Blob, the amount of * memory consumed is nearly 100 times the original data amount. * * @param {String} type the mime type of the blob. * @return {Blob} the created blob. */exports.newBlob = function(part, type) {    exports.checkSupport("blob");    try {        // Blob constructor        return new Blob([part], {            type: type        });    }    catch (e) {        try {            // deprecated, browser only, old way            var Builder = self.BlobBuilder || self.WebKitBlobBuilder || self.MozBlobBuilder || self.MSBlobBuilder;            var builder = new Builder();            builder.append(part);            return builder.getBlob(type);        }        catch (e) {            // well, fuck ?!            throw new Error("Bug : can't construct the Blob.");        }    }};/** * The identity function. * @param {Object} input the input. * @return {Object} the same input. */function identity(input) {    return input;}/** * Fill in an array with a string. * @param {String} str the string to use. * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to fill in (will be mutated). * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated array. */function stringToArrayLike(str, array) {    for (var i = 0; i < str.length; ++i) {        array[i] = str.charCodeAt(i) & 0xFF;    }    return array;}/** * An helper for the function arrayLikeToString. * This contains static informations and functions that * can be optimized by the browser JIT compiler. */var arrayToStringHelper = {    /**     * Transform an array of int into a string, chunk by chunk.     * See the performances notes on arrayLikeToString.     * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform.     * @param {String} type the type of the array.     * @param {Integer} chunk the chunk size.     * @return {String} the resulting string.     * @throws Error if the chunk is too big for the stack.     */    stringifyByChunk: function(array, type, chunk) {        var result = [], k = 0, len = array.length;        // shortcut        if (len <= chunk) {            return String.fromCharCode.apply(null, array);        }        while (k < len) {            if (type === "array" || type === "nodebuffer") {                result.push(String.fromCharCode.apply(null, array.slice(k, Math.min(k + chunk, len))));            }            else {                result.push(String.fromCharCode.apply(null, array.subarray(k, Math.min(k + chunk, len))));            }            k += chunk;        }        return result.join("");    },    /**     * Call String.fromCharCode on every item in the array.     * This is the naive implementation, which generate A LOT of intermediate string.     * This should be used when everything else fail.     * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform.     * @return {String} the result.     */    stringifyByChar: function(array){        var resultStr = "";        for(var i = 0; i < array.length; i++) {            resultStr += String.fromCharCode(array[i]);        }        return resultStr;    },    applyCanBeUsed : {        /**         * true if the browser accepts to use String.fromCharCode on Uint8Array         */        uint8array : (function () {            try {                return support.uint8array && String.fromCharCode.apply(null, new Uint8Array(1)).length === 1;            } catch (e) {                return false;            }        })(),        /**         * true if the browser accepts to use String.fromCharCode on nodejs Buffer.         */        nodebuffer : (function () {            try {                return support.nodebuffer && String.fromCharCode.apply(null, nodejsUtils.allocBuffer(1)).length === 1;            } catch (e) {                return false;            }        })()    }};/** * Transform an array-like object to a string. * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. * @return {String} the result. */function arrayLikeToString(array) {    // Performances notes :    // --------------------    // String.fromCharCode.apply(null, array) is the fastest, see    // see http://jsperf.com/converting-a-uint8array-to-a-string/2    // but the stack is limited (and we can get huge arrays !).    //    // result += String.fromCharCode(array[i]); generate too many strings !    //    // This code is inspired by http://jsperf.com/arraybuffer-to-string-apply-performance/2    // TODO : we now have workers that split the work. Do we still need that ?    var chunk = 65536,        type = exports.getTypeOf(array),        canUseApply = true;    if (type === "uint8array") {        canUseApply = arrayToStringHelper.applyCanBeUsed.uint8array;    } else if (type === "nodebuffer") {        canUseApply = arrayToStringHelper.applyCanBeUsed.nodebuffer;    }    if (canUseApply) {        while (chunk > 1) {            try {                return arrayToStringHelper.stringifyByChunk(array, type, chunk);            } catch (e) {                chunk = Math.floor(chunk / 2);            }        }    }    // no apply or chunk error : slow and painful algorithm    // default browser on android 4.*    return arrayToStringHelper.stringifyByChar(array);}exports.applyFromCharCode = arrayLikeToString;/** * Copy the data from an array-like to an other array-like. * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayFrom the origin array. * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayTo the destination array which will be mutated. * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated destination array. */function arrayLikeToArrayLike(arrayFrom, arrayTo) {    for (var i = 0; i < arrayFrom.length; i++) {        arrayTo[i] = arrayFrom[i];    }    return arrayTo;}// a matrix containing functions to transform everything into everything.var transform = {};// string to ?transform["string"] = {    "string": identity,    "array": function(input) {        return stringToArrayLike(input, new Array(input.length));    },    "arraybuffer": function(input) {        return transform["string"]["uint8array"](input).buffer;    },    "uint8array": function(input) {        return stringToArrayLike(input, new Uint8Array(input.length));    },    "nodebuffer": function(input) {        return stringToArrayLike(input, nodejsUtils.allocBuffer(input.length));    }};// array to ?transform["array"] = {    "string": arrayLikeToString,    "array": identity,    "arraybuffer": function(input) {        return (new Uint8Array(input)).buffer;    },    "uint8array": function(input) {        return new Uint8Array(input);    },    "nodebuffer": function(input) {        return nodejsUtils.newBufferFrom(input);    }};// arraybuffer to ?transform["arraybuffer"] = {    "string": function(input) {        return arrayLikeToString(new Uint8Array(input));    },    "array": function(input) {        return arrayLikeToArrayLike(new Uint8Array(input), new Array(input.byteLength));    },    "arraybuffer": identity,    "uint8array": function(input) {        return new Uint8Array(input);    },    "nodebuffer": function(input) {        return nodejsUtils.newBufferFrom(new Uint8Array(input));    }};// uint8array to ?transform["uint8array"] = {    "string": arrayLikeToString,    "array": function(input) {        return arrayLikeToArrayLike(input, new Array(input.length));    },    "arraybuffer": function(input) {        return input.buffer;    },    "uint8array": identity,    "nodebuffer": function(input) {        return nodejsUtils.newBufferFrom(input);    }};// nodebuffer to ?transform["nodebuffer"] = {    "string": arrayLikeToString,    "array": function(input) {        return arrayLikeToArrayLike(input, new Array(input.length));    },    "arraybuffer": function(input) {        return transform["nodebuffer"]["uint8array"](input).buffer;    },    "uint8array": function(input) {        return arrayLikeToArrayLike(input, new Uint8Array(input.length));    },    "nodebuffer": identity};/** * Transform an input into any type. * The supported output type are : string, array, uint8array, arraybuffer, nodebuffer. * If no output type is specified, the unmodified input will be returned. * @param {String} outputType the output type. * @param {String|Array|ArrayBuffer|Uint8Array|Buffer} input the input to convert. * @throws {Error} an Error if the browser doesn't support the requested output type. */exports.transformTo = function(outputType, input) {    if (!input) {        // undefined, null, etc        // an empty string won't harm.        input = "";    }    if (!outputType) {        return input;    }    exports.checkSupport(outputType);    var inputType = exports.getTypeOf(input);    var result = transform[inputType][outputType](input);    return result;};/** * Return the type of the input. * The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer. * @param {Object} input the input to identify. * @return {String} the (lowercase) type of the input. */exports.getTypeOf = function(input) {    if (typeof input === "string") {        return "string";    }    if (Object.prototype.toString.call(input) === "[object Array]") {        return "array";    }    if (support.nodebuffer && nodejsUtils.isBuffer(input)) {        return "nodebuffer";    }    if (support.uint8array && input instanceof Uint8Array) {        return "uint8array";    }    if (support.arraybuffer && input instanceof ArrayBuffer) {        return "arraybuffer";    }};/** * Throw an exception if the type is not supported. * @param {String} type the type to check. * @throws {Error} an Error if the browser doesn't support the requested type. */exports.checkSupport = function(type) {    var supported = support[type.toLowerCase()];    if (!supported) {        throw new Error(type + " is not supported by this platform");    }};exports.MAX_VALUE_16BITS = 65535;exports.MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1/** * Prettify a string read as binary. * @param {string} str the string to prettify. * @return {string} a pretty string. */exports.pretty = function(str) {    var res = '',        code, i;    for (i = 0; i < (str || "").length; i++) {        code = str.charCodeAt(i);        res += '\\x' + (code < 16 ? "0" : "") + code.toString(16).toUpperCase();    }    return res;};/** * Defer the call of a function. * @param {Function} callback the function to call asynchronously. * @param {Array} args the arguments to give to the callback. */exports.delay = function(callback, args, self) {    setImmediate(function () {        callback.apply(self || null, args || []);    });};/** * Extends a prototype with an other, without calling a constructor with * side effects. Inspired by nodejs' `utils.inherits` * @param {Function} ctor the constructor to augment * @param {Function} superCtor the parent constructor to use */exports.inherits = function (ctor, superCtor) {    var Obj = function() {};    Obj.prototype = superCtor.prototype;    ctor.prototype = new Obj();};/** * Merge the objects passed as parameters into a new one. * @private * @param {...Object} var_args All objects to merge. * @return {Object} a new object with the data of the others. */exports.extend = function() {    var result = {}, i, attr;    for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers        for (attr in arguments[i]) {            if (arguments[i].hasOwnProperty(attr) && typeof result[attr] === "undefined") {                result[attr] = arguments[i][attr];            }        }    }    return result;};/** * Transform arbitrary content into a Promise. * @param {String} name a name for the content being processed. * @param {Object} inputData the content to process. * @param {Boolean} isBinary true if the content is not an unicode string * @param {Boolean} isOptimizedBinaryString true if the string content only has one byte per character. * @param {Boolean} isBase64 true if the string content is encoded with base64. * @return {Promise} a promise in a format usable by JSZip. */exports.prepareContent = function(name, inputData, isBinary, isOptimizedBinaryString, isBase64) {    // if inputData is already a promise, this flatten it.    var promise = external.Promise.resolve(inputData).then(function(data) {                        var isBlob = support.blob && (data instanceof Blob || ['[object File]', '[object Blob]'].indexOf(Object.prototype.toString.call(data)) !== -1);        if (isBlob && typeof FileReader !== "undefined") {            return new external.Promise(function (resolve, reject) {                var reader = new FileReader();                reader.onload = function(e) {                    resolve(e.target.result);                };                reader.onerror = function(e) {                    reject(e.target.error);                };                reader.readAsArrayBuffer(data);            });        } else {            return data;        }    });    return promise.then(function(data) {        var dataType = exports.getTypeOf(data);        if (!dataType) {            return external.Promise.reject(                new Error("Can't read the data of '" + name + "'. Is it " +                          "in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?")            );        }        // special case : it's way easier to work with Uint8Array than with ArrayBuffer        if (dataType === "arraybuffer") {            data = exports.transformTo("uint8array", data);        } else if (dataType === "string") {            if (isBase64) {                data = base64.decode(data);            }            else if (isBinary) {                // optimizedBinaryString === true means that the file has already been filtered with a 0xFF mask                if (isOptimizedBinaryString !== true) {                    // this is a string, not in a base64 format.                    // Be sure that this is a correct "binary string"                    data = string2binary(data);                }            }        }        return data;    });};},{"./base64":157,"./external":162,"./nodejsUtils":168,"./support":186,"core-js/library/fn/set-immediate":82}],189:[function(require,module,exports){'use strict';var readerFor = require('./reader/readerFor');var utils = require('./utils');var sig = require('./signature');var ZipEntry = require('./zipEntry');var utf8 = require('./utf8');var support = require('./support');//  class ZipEntries {{{/** * All the entries in the zip file. * @constructor * @param {Object} loadOptions Options for loading the stream. */function ZipEntries(loadOptions) {    this.files = [];    this.loadOptions = loadOptions;}ZipEntries.prototype = {    /**     * Check that the reader is on the specified signature.     * @param {string} expectedSignature the expected signature.     * @throws {Error} if it is an other signature.     */    checkSignature: function(expectedSignature) {        if (!this.reader.readAndCheckSignature(expectedSignature)) {            this.reader.index -= 4;            var signature = this.reader.readString(4);            throw new Error("Corrupted zip or bug: unexpected signature " + "(" + utils.pretty(signature) + ", expected " + utils.pretty(expectedSignature) + ")");        }    },    /**     * Check if the given signature is at the given index.     * @param {number} askedIndex the index to check.     * @param {string} expectedSignature the signature to expect.     * @return {boolean} true if the signature is here, false otherwise.     */    isSignature: function(askedIndex, expectedSignature) {        var currentIndex = this.reader.index;        this.reader.setIndex(askedIndex);        var signature = this.reader.readString(4);        var result = signature === expectedSignature;        this.reader.setIndex(currentIndex);        return result;    },    /**     * Read the end of the central directory.     */    readBlockEndOfCentral: function() {        this.diskNumber = this.reader.readInt(2);        this.diskWithCentralDirStart = this.reader.readInt(2);        this.centralDirRecordsOnThisDisk = this.reader.readInt(2);        this.centralDirRecords = this.reader.readInt(2);        this.centralDirSize = this.reader.readInt(4);        this.centralDirOffset = this.reader.readInt(4);        this.zipCommentLength = this.reader.readInt(2);        // warning : the encoding depends of the system locale        // On a linux machine with LANG=en_US.utf8, this field is utf8 encoded.        // On a windows machine, this field is encoded with the localized windows code page.        var zipComment = this.reader.readData(this.zipCommentLength);        var decodeParamType = support.uint8array ? "uint8array" : "array";        // To get consistent behavior with the generation part, we will assume that        // this is utf8 encoded unless specified otherwise.        var decodeContent = utils.transformTo(decodeParamType, zipComment);        this.zipComment = this.loadOptions.decodeFileName(decodeContent);    },    /**     * Read the end of the Zip 64 central directory.     * Not merged with the method readEndOfCentral :     * The end of central can coexist with its Zip64 brother,     * I don't want to read the wrong number of bytes !     */    readBlockZip64EndOfCentral: function() {        this.zip64EndOfCentralSize = this.reader.readInt(8);        this.reader.skip(4);        // this.versionMadeBy = this.reader.readString(2);        // this.versionNeeded = this.reader.readInt(2);        this.diskNumber = this.reader.readInt(4);        this.diskWithCentralDirStart = this.reader.readInt(4);        this.centralDirRecordsOnThisDisk = this.reader.readInt(8);        this.centralDirRecords = this.reader.readInt(8);        this.centralDirSize = this.reader.readInt(8);        this.centralDirOffset = this.reader.readInt(8);        this.zip64ExtensibleData = {};        var extraDataSize = this.zip64EndOfCentralSize - 44,            index = 0,            extraFieldId,            extraFieldLength,            extraFieldValue;        while (index < extraDataSize) {            extraFieldId = this.reader.readInt(2);            extraFieldLength = this.reader.readInt(4);            extraFieldValue = this.reader.readData(extraFieldLength);            this.zip64ExtensibleData[extraFieldId] = {                id: extraFieldId,                length: extraFieldLength,                value: extraFieldValue            };        }    },    /**     * Read the end of the Zip 64 central directory locator.     */    readBlockZip64EndOfCentralLocator: function() {        this.diskWithZip64CentralDirStart = this.reader.readInt(4);        this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8);        this.disksCount = this.reader.readInt(4);        if (this.disksCount > 1) {            throw new Error("Multi-volumes zip are not supported");        }    },    /**     * Read the local files, based on the offset read in the central part.     */    readLocalFiles: function() {        var i, file;        for (i = 0; i < this.files.length; i++) {            file = this.files[i];            this.reader.setIndex(file.localHeaderOffset);            this.checkSignature(sig.LOCAL_FILE_HEADER);            file.readLocalPart(this.reader);            file.handleUTF8();            file.processAttributes();        }    },    /**     * Read the central directory.     */    readCentralDir: function() {        var file;        this.reader.setIndex(this.centralDirOffset);        while (this.reader.readAndCheckSignature(sig.CENTRAL_FILE_HEADER)) {            file = new ZipEntry({                zip64: this.zip64            }, this.loadOptions);            file.readCentralPart(this.reader);            this.files.push(file);        }        if (this.centralDirRecords !== this.files.length) {            if (this.centralDirRecords !== 0 && this.files.length === 0) {                // We expected some records but couldn't find ANY.                // This is really suspicious, as if something went wrong.                throw new Error("Corrupted zip or bug: expected " + this.centralDirRecords + " records in central dir, got " + this.files.length);            } else {                // We found some records but not all.                // Something is wrong but we got something for the user: no error here.                // console.warn("expected", this.centralDirRecords, "records in central dir, got", this.files.length);            }        }    },    /**     * Read the end of central directory.     */    readEndOfCentral: function() {        var offset = this.reader.lastIndexOfSignature(sig.CENTRAL_DIRECTORY_END);        if (offset < 0) {            // Check if the content is a truncated zip or complete garbage.            // A "LOCAL_FILE_HEADER" is not required at the beginning (auto            // extractible zip for example) but it can give a good hint.            // If an ajax request was used without responseType, we will also            // get unreadable data.            var isGarbage = !this.isSignature(0, sig.LOCAL_FILE_HEADER);            if (isGarbage) {                throw new Error("Can't find end of central directory : is this a zip file ? " +                                "If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html");            } else {                throw new Error("Corrupted zip: can't find end of central directory");            }        }        this.reader.setIndex(offset);        var endOfCentralDirOffset = offset;        this.checkSignature(sig.CENTRAL_DIRECTORY_END);        this.readBlockEndOfCentral();        /* extract from the zip spec :            4)  If one of the fields in the end of central directory                record is too small to hold required data, the field                should be set to -1 (0xFFFF or 0xFFFFFFFF) and the                ZIP64 format record should be created.            5)  The end of central directory record and the                Zip64 end of central directory locator record must                reside on the same disk when splitting or spanning                an archive.         */        if (this.diskNumber === utils.MAX_VALUE_16BITS || this.diskWithCentralDirStart === utils.MAX_VALUE_16BITS || this.centralDirRecordsOnThisDisk === utils.MAX_VALUE_16BITS || this.centralDirRecords === utils.MAX_VALUE_16BITS || this.centralDirSize === utils.MAX_VALUE_32BITS || this.centralDirOffset === utils.MAX_VALUE_32BITS) {            this.zip64 = true;            /*            Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from            the zip file can fit into a 32bits integer. This cannot be solved : JavaScript represents            all numbers as 64-bit double precision IEEE 754 floating point numbers.            So, we have 53bits for integers and bitwise operations treat everything as 32bits.            see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators            and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5            */            // should look for a zip64 EOCD locator            offset = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR);            if (offset < 0) {                throw new Error("Corrupted zip: can't find the ZIP64 end of central directory locator");            }            this.reader.setIndex(offset);            this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR);            this.readBlockZip64EndOfCentralLocator();            // now the zip64 EOCD record            if (!this.isSignature(this.relativeOffsetEndOfZip64CentralDir, sig.ZIP64_CENTRAL_DIRECTORY_END)) {                // console.warn("ZIP64 end of central directory not where expected.");                this.relativeOffsetEndOfZip64CentralDir = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_END);                if (this.relativeOffsetEndOfZip64CentralDir < 0) {                    throw new Error("Corrupted zip: can't find the ZIP64 end of central directory");                }            }            this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir);            this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_END);            this.readBlockZip64EndOfCentral();        }        var expectedEndOfCentralDirOffset = this.centralDirOffset + this.centralDirSize;        if (this.zip64) {            expectedEndOfCentralDirOffset += 20; // end of central dir 64 locator            expectedEndOfCentralDirOffset += 12 /* should not include the leading 12 bytes */ + this.zip64EndOfCentralSize;        }        var extraBytes = endOfCentralDirOffset - expectedEndOfCentralDirOffset;        if (extraBytes > 0) {            // console.warn(extraBytes, "extra bytes at beginning or within zipfile");            if (this.isSignature(endOfCentralDirOffset, sig.CENTRAL_FILE_HEADER)) {                // The offsets seem wrong, but we have something at the specified offset.                // So… we keep it.            } else {                // the offset is wrong, update the "zero" of the reader                // this happens if data has been prepended (crx files for example)                this.reader.zero = extraBytes;            }        } else if (extraBytes < 0) {            throw new Error("Corrupted zip: missing " + Math.abs(extraBytes) + " bytes.");        }    },    prepareReader: function(data) {        this.reader = readerFor(data);    },    /**     * Read a zip file and create ZipEntries.     * @param {String|ArrayBuffer|Uint8Array|Buffer} data the binary string representing a zip file.     */    load: function(data) {        this.prepareReader(data);        this.readEndOfCentral();        this.readCentralDir();        this.readLocalFiles();    }};// }}} end of ZipEntriesmodule.exports = ZipEntries;},{"./reader/readerFor":178,"./signature":179,"./support":186,"./utf8":187,"./utils":188,"./zipEntry":190}],190:[function(require,module,exports){'use strict';var readerFor = require('./reader/readerFor');var utils = require('./utils');var CompressedObject = require('./compressedObject');var crc32fn = require('./crc32');var utf8 = require('./utf8');var compressions = require('./compressions');var support = require('./support');var MADE_BY_DOS = 0x00;var MADE_BY_UNIX = 0x03;/** * Find a compression registered in JSZip. * @param {string} compressionMethod the method magic to find. * @return {Object|null} the JSZip compression object, null if none found. */var findCompression = function(compressionMethod) {    for (var method in compressions) {        if (!compressions.hasOwnProperty(method)) {            continue;        }        if (compressions[method].magic === compressionMethod) {            return compressions[method];        }    }    return null;};// class ZipEntry {{{/** * An entry in the zip file. * @constructor * @param {Object} options Options of the current file. * @param {Object} loadOptions Options for loading the stream. */function ZipEntry(options, loadOptions) {    this.options = options;    this.loadOptions = loadOptions;}ZipEntry.prototype = {    /**     * say if the file is encrypted.     * @return {boolean} true if the file is encrypted, false otherwise.     */    isEncrypted: function() {        // bit 1 is set        return (this.bitFlag & 0x0001) === 0x0001;    },    /**     * say if the file has utf-8 filename/comment.     * @return {boolean} true if the filename/comment is in utf-8, false otherwise.     */    useUTF8: function() {        // bit 11 is set        return (this.bitFlag & 0x0800) === 0x0800;    },    /**     * Read the local part of a zip file and add the info in this object.     * @param {DataReader} reader the reader to use.     */    readLocalPart: function(reader) {        var compression, localExtraFieldsLength;        // we already know everything from the central dir !        // If the central dir data are false, we are doomed.        // On the bright side, the local part is scary  : zip64, data descriptors, both, etc.        // The less data we get here, the more reliable this should be.        // Let's skip the whole header and dash to the data !        reader.skip(22);        // in some zip created on windows, the filename stored in the central dir contains \ instead of /.        // Strangely, the filename here is OK.        // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes        // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators...        // Search "unzip mismatching "local" filename continuing with "central" filename version" on        // the internet.        //        // I think I see the logic here : the central directory is used to display        // content and the local directory is used to extract the files. Mixing / and \        // may be used to display \ to windows users and use / when extracting the files.        // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394        this.fileNameLength = reader.readInt(2);        localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir        // the fileName is stored as binary data, the handleUTF8 method will take care of the encoding.        this.fileName = reader.readData(this.fileNameLength);        reader.skip(localExtraFieldsLength);        if (this.compressedSize === -1 || this.uncompressedSize === -1) {            throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " + "(compressedSize === -1 || uncompressedSize === -1)");        }        compression = findCompression(this.compressionMethod);        if (compression === null) { // no compression found            throw new Error("Corrupted zip : compression " + utils.pretty(this.compressionMethod) + " unknown (inner file : " + utils.transformTo("string", this.fileName) + ")");        }        this.decompressed = new CompressedObject(this.compressedSize, this.uncompressedSize, this.crc32, compression, reader.readData(this.compressedSize));    },    /**     * Read the central part of a zip file and add the info in this object.     * @param {DataReader} reader the reader to use.     */    readCentralPart: function(reader) {        this.versionMadeBy = reader.readInt(2);        reader.skip(2);        // this.versionNeeded = reader.readInt(2);        this.bitFlag = reader.readInt(2);        this.compressionMethod = reader.readString(2);        this.date = reader.readDate();        this.crc32 = reader.readInt(4);        this.compressedSize = reader.readInt(4);        this.uncompressedSize = reader.readInt(4);        var fileNameLength = reader.readInt(2);        this.extraFieldsLength = reader.readInt(2);        this.fileCommentLength = reader.readInt(2);        this.diskNumberStart = reader.readInt(2);        this.internalFileAttributes = reader.readInt(2);        this.externalFileAttributes = reader.readInt(4);        this.localHeaderOffset = reader.readInt(4);        if (this.isEncrypted()) {            throw new Error("Encrypted zip are not supported");        }        // will be read in the local part, see the comments there        reader.skip(fileNameLength);        this.readExtraFields(reader);        this.parseZIP64ExtraField(reader);        this.fileComment = reader.readData(this.fileCommentLength);    },    /**     * Parse the external file attributes and get the unix/dos permissions.     */    processAttributes: function () {        this.unixPermissions = null;        this.dosPermissions = null;        var madeBy = this.versionMadeBy >> 8;        // Check if we have the DOS directory flag set.        // We look for it in the DOS and UNIX permissions        // but some unknown platform could set it as a compatibility flag.        this.dir = this.externalFileAttributes & 0x0010 ? true : false;        if(madeBy === MADE_BY_DOS) {            // first 6 bits (0 to 5)            this.dosPermissions = this.externalFileAttributes & 0x3F;        }        if(madeBy === MADE_BY_UNIX) {            this.unixPermissions = (this.externalFileAttributes >> 16) & 0xFFFF;            // the octal permissions are in (this.unixPermissions & 0x01FF).toString(8);        }        // fail safe : if the name ends with a / it probably means a folder        if (!this.dir && this.fileNameStr.slice(-1) === '/') {            this.dir = true;        }    },    /**     * Parse the ZIP64 extra field and merge the info in the current ZipEntry.     * @param {DataReader} reader the reader to use.     */    parseZIP64ExtraField: function(reader) {        if (!this.extraFields[0x0001]) {            return;        }        // should be something, preparing the extra reader        var extraReader = readerFor(this.extraFields[0x0001].value);        // I really hope that these 64bits integer can fit in 32 bits integer, because js        // won't let us have more.        if (this.uncompressedSize === utils.MAX_VALUE_32BITS) {            this.uncompressedSize = extraReader.readInt(8);        }        if (this.compressedSize === utils.MAX_VALUE_32BITS) {            this.compressedSize = extraReader.readInt(8);        }        if (this.localHeaderOffset === utils.MAX_VALUE_32BITS) {            this.localHeaderOffset = extraReader.readInt(8);        }        if (this.diskNumberStart === utils.MAX_VALUE_32BITS) {            this.diskNumberStart = extraReader.readInt(4);        }    },    /**     * Read the central part of a zip file and add the info in this object.     * @param {DataReader} reader the reader to use.     */    readExtraFields: function(reader) {        var end = reader.index + this.extraFieldsLength,            extraFieldId,            extraFieldLength,            extraFieldValue;        if (!this.extraFields) {            this.extraFields = {};        }        while (reader.index < end) {            extraFieldId = reader.readInt(2);            extraFieldLength = reader.readInt(2);            extraFieldValue = reader.readData(extraFieldLength);            this.extraFields[extraFieldId] = {                id: extraFieldId,                length: extraFieldLength,                value: extraFieldValue            };        }    },    /**     * Apply an UTF8 transformation if needed.     */    handleUTF8: function() {        var decodeParamType = support.uint8array ? "uint8array" : "array";        if (this.useUTF8()) {            this.fileNameStr = utf8.utf8decode(this.fileName);            this.fileCommentStr = utf8.utf8decode(this.fileComment);        } else {            var upath = this.findExtraFieldUnicodePath();            if (upath !== null) {                this.fileNameStr = upath;            } else {                // ASCII text or unsupported code page                var fileNameByteArray =  utils.transformTo(decodeParamType, this.fileName);                this.fileNameStr = this.loadOptions.decodeFileName(fileNameByteArray);            }            var ucomment = this.findExtraFieldUnicodeComment();            if (ucomment !== null) {                this.fileCommentStr = ucomment;            } else {                // ASCII text or unsupported code page                var commentByteArray =  utils.transformTo(decodeParamType, this.fileComment);                this.fileCommentStr = this.loadOptions.decodeFileName(commentByteArray);            }        }    },    /**     * Find the unicode path declared in the extra field, if any.     * @return {String} the unicode path, null otherwise.     */    findExtraFieldUnicodePath: function() {        var upathField = this.extraFields[0x7075];        if (upathField) {            var extraReader = readerFor(upathField.value);            // wrong version            if (extraReader.readInt(1) !== 1) {                return null;            }            // the crc of the filename changed, this field is out of date.            if (crc32fn(this.fileName) !== extraReader.readInt(4)) {                return null;            }            return utf8.utf8decode(extraReader.readData(upathField.length - 5));        }        return null;    },    /**     * Find the unicode comment declared in the extra field, if any.     * @return {String} the unicode comment, null otherwise.     */    findExtraFieldUnicodeComment: function() {        var ucommentField = this.extraFields[0x6375];        if (ucommentField) {            var extraReader = readerFor(ucommentField.value);            // wrong version            if (extraReader.readInt(1) !== 1) {                return null;            }            // the crc of the comment changed, this field is out of date.            if (crc32fn(this.fileComment) !== extraReader.readInt(4)) {                return null;            }            return utf8.utf8decode(extraReader.readData(ucommentField.length - 5));        }        return null;    }};module.exports = ZipEntry;},{"./compressedObject":158,"./compressions":159,"./crc32":160,"./reader/readerFor":178,"./support":186,"./utf8":187,"./utils":188}],191:[function(require,module,exports){'use strict';var StreamHelper = require('./stream/StreamHelper');var DataWorker = require('./stream/DataWorker');var utf8 = require('./utf8');var CompressedObject = require('./compressedObject');var GenericWorker = require('./stream/GenericWorker');/** * A simple object representing a file in the zip file. * @constructor * @param {string} name the name of the file * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data * @param {Object} options the options of the file */var ZipObject = function(name, data, options) {    this.name = name;    this.dir = options.dir;    this.date = options.date;    this.comment = options.comment;    this.unixPermissions = options.unixPermissions;    this.dosPermissions = options.dosPermissions;    this._data = data;    this._dataBinary = options.binary;    // keep only the compression    this.options = {        compression : options.compression,        compressionOptions : options.compressionOptions    };};ZipObject.prototype = {    /**     * Create an internal stream for the content of this object.     * @param {String} type the type of each chunk.     * @return StreamHelper the stream.     */    internalStream: function (type) {        var result = null, outputType = "string";        try {            if (!type) {                throw new Error("No output type specified.");            }            outputType = type.toLowerCase();            var askUnicodeString = outputType === "string" || outputType === "text";            if (outputType === "binarystring" || outputType === "text") {                outputType = "string";            }            result = this._decompressWorker();            var isUnicodeString = !this._dataBinary;            if (isUnicodeString && !askUnicodeString) {                result = result.pipe(new utf8.Utf8EncodeWorker());            }            if (!isUnicodeString && askUnicodeString) {                result = result.pipe(new utf8.Utf8DecodeWorker());            }        } catch (e) {            result = new GenericWorker("error");            result.error(e);        }        return new StreamHelper(result, outputType, "");    },    /**     * Prepare the content in the asked type.     * @param {String} type the type of the result.     * @param {Function} onUpdate a function to call on each internal update.     * @return Promise the promise of the result.     */    async: function (type, onUpdate) {        return this.internalStream(type).accumulate(onUpdate);    },    /**     * Prepare the content as a nodejs stream.     * @param {String} type the type of each chunk.     * @param {Function} onUpdate a function to call on each internal update.     * @return Stream the stream.     */    nodeStream: function (type, onUpdate) {        return this.internalStream(type || "nodebuffer").toNodejsStream(onUpdate);    },    /**     * Return a worker for the compressed content.     * @private     * @param {Object} compression the compression object to use.     * @param {Object} compressionOptions the options to use when compressing.     * @return Worker the worker.     */    _compressWorker: function (compression, compressionOptions) {        if (            this._data instanceof CompressedObject &&            this._data.compression.magic === compression.magic        ) {            return this._data.getCompressedWorker();        } else {            var result = this._decompressWorker();            if(!this._dataBinary) {                result = result.pipe(new utf8.Utf8EncodeWorker());            }            return CompressedObject.createWorkerFrom(result, compression, compressionOptions);        }    },    /**     * Return a worker for the decompressed content.     * @private     * @return Worker the worker.     */    _decompressWorker : function () {        if (this._data instanceof CompressedObject) {            return this._data.getContentWorker();        } else if (this._data instanceof GenericWorker) {            return this._data;        } else {            return new DataWorker(this._data);        }    }};var removedMethods = ["asText", "asBinary", "asNodeBuffer", "asUint8Array", "asArrayBuffer"];var removedFn = function () {    throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.");};for(var i = 0; i < removedMethods.length; i++) {    ZipObject.prototype[removedMethods[i]] = removedFn;}module.exports = ZipObject;},{"./compressedObject":158,"./stream/DataWorker":183,"./stream/GenericWorker":184,"./stream/StreamHelper":185,"./utf8":187}],192:[function(require,module,exports){'use strict';var immediate = require('immediate');/* istanbul ignore next */function INTERNAL() {}var handlers = {};var REJECTED = ['REJECTED'];var FULFILLED = ['FULFILLED'];var PENDING = ['PENDING'];module.exports = Promise;function Promise(resolver) {  if (typeof resolver !== 'function') {    throw new TypeError('resolver must be a function');  }  this.state = PENDING;  this.queue = [];  this.outcome = void 0;  if (resolver !== INTERNAL) {    safelyResolveThenable(this, resolver);  }}Promise.prototype["catch"] = function (onRejected) {  return this.then(null, onRejected);};Promise.prototype.then = function (onFulfilled, onRejected) {  if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||    typeof onRejected !== 'function' && this.state === REJECTED) {    return this;  }  var promise = new this.constructor(INTERNAL);  if (this.state !== PENDING) {    var resolver = this.state === FULFILLED ? onFulfilled : onRejected;    unwrap(promise, resolver, this.outcome);  } else {    this.queue.push(new QueueItem(promise, onFulfilled, onRejected));  }  return promise;};function QueueItem(promise, onFulfilled, onRejected) {  this.promise = promise;  if (typeof onFulfilled === 'function') {    this.onFulfilled = onFulfilled;    this.callFulfilled = this.otherCallFulfilled;  }  if (typeof onRejected === 'function') {    this.onRejected = onRejected;    this.callRejected = this.otherCallRejected;  }}QueueItem.prototype.callFulfilled = function (value) {  handlers.resolve(this.promise, value);};QueueItem.prototype.otherCallFulfilled = function (value) {  unwrap(this.promise, this.onFulfilled, value);};QueueItem.prototype.callRejected = function (value) {  handlers.reject(this.promise, value);};QueueItem.prototype.otherCallRejected = function (value) {  unwrap(this.promise, this.onRejected, value);};function unwrap(promise, func, value) {  immediate(function () {    var returnValue;    try {      returnValue = func(value);    } catch (e) {      return handlers.reject(promise, e);    }    if (returnValue === promise) {      handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));    } else {      handlers.resolve(promise, returnValue);    }  });}handlers.resolve = function (self, value) {  var result = tryCatch(getThen, value);  if (result.status === 'error') {    return handlers.reject(self, result.value);  }  var thenable = result.value;  if (thenable) {    safelyResolveThenable(self, thenable);  } else {    self.state = FULFILLED;    self.outcome = value;    var i = -1;    var len = self.queue.length;    while (++i < len) {      self.queue[i].callFulfilled(value);    }  }  return self;};handlers.reject = function (self, error) {  self.state = REJECTED;  self.outcome = error;  var i = -1;  var len = self.queue.length;  while (++i < len) {    self.queue[i].callRejected(error);  }  return self;};function getThen(obj) {  // Make sure we only access the accessor once as required by the spec  var then = obj && obj.then;  if (obj && (typeof obj === 'object' || typeof obj === 'function') && typeof then === 'function') {    return function appyThen() {      then.apply(obj, arguments);    };  }}function safelyResolveThenable(self, thenable) {  // Either fulfill, reject or reject with error  var called = false;  function onError(value) {    if (called) {      return;    }    called = true;    handlers.reject(self, value);  }  function onSuccess(value) {    if (called) {      return;    }    called = true;    handlers.resolve(self, value);  }  function tryToUnwrap() {    thenable(onSuccess, onError);  }  var result = tryCatch(tryToUnwrap);  if (result.status === 'error') {    onError(result.value);  }}function tryCatch(func, value) {  var out = {};  try {    out.value = func(value);    out.status = 'success';  } catch (e) {    out.status = 'error';    out.value = e;  }  return out;}Promise.resolve = resolve;function resolve(value) {  if (value instanceof this) {    return value;  }  return handlers.resolve(new this(INTERNAL), value);}Promise.reject = reject;function reject(reason) {  var promise = new this(INTERNAL);  return handlers.reject(promise, reason);}Promise.all = all;function all(iterable) {  var self = this;  if (Object.prototype.toString.call(iterable) !== '[object Array]') {    return this.reject(new TypeError('must be an array'));  }  var len = iterable.length;  var called = false;  if (!len) {    return this.resolve([]);  }  var values = new Array(len);  var resolved = 0;  var i = -1;  var promise = new this(INTERNAL);  while (++i < len) {    allResolver(iterable[i], i);  }  return promise;  function allResolver(value, i) {    self.resolve(value).then(resolveFromAll, function (error) {      if (!called) {        called = true;        handlers.reject(promise, error);      }    });    function resolveFromAll(outValue) {      values[i] = outValue;      if (++resolved === len && !called) {        called = true;        handlers.resolve(promise, values);      }    }  }}Promise.race = race;function race(iterable) {  var self = this;  if (Object.prototype.toString.call(iterable) !== '[object Array]') {    return this.reject(new TypeError('must be an array'));  }  var len = iterable.length;  var called = false;  if (!len) {    return this.resolve([]);  }  var i = -1;  var promise = new this(INTERNAL);  while (++i < len) {    resolver(iterable[i]);  }  return promise;  function resolver(value) {    self.resolve(value).then(function (response) {      if (!called) {        called = true;        handlers.resolve(promise, response);      }    }, function (error) {      if (!called) {        called = true;        handlers.reject(promise, error);      }    });  }}},{"immediate":153}],193:[function(require,module,exports){(function (global){/** * @license * Lodash <https://lodash.com/> * Copyright JS Foundation and other contributors <https://js.foundation/> * Released under MIT license <https://lodash.com/license> * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE> * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors */;(function() {  /** Used as a safe reference for `undefined` in pre-ES5 environments. */  var undefined;  /** Used as the semantic version number. */  var VERSION = '4.17.11';  /** Used as the size to enable large array optimizations. */  var LARGE_ARRAY_SIZE = 200;  /** Error message constants. */  var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',      FUNC_ERROR_TEXT = 'Expected a function';  /** Used to stand-in for `undefined` hash values. */  var HASH_UNDEFINED = '__lodash_hash_undefined__';  /** Used as the maximum memoize cache size. */  var MAX_MEMOIZE_SIZE = 500;  /** Used as the internal argument placeholder. */  var PLACEHOLDER = '__lodash_placeholder__';  /** Used to compose bitmasks for cloning. */  var CLONE_DEEP_FLAG = 1,      CLONE_FLAT_FLAG = 2,      CLONE_SYMBOLS_FLAG = 4;  /** Used to compose bitmasks for value comparisons. */  var COMPARE_PARTIAL_FLAG = 1,      COMPARE_UNORDERED_FLAG = 2;  /** Used to compose bitmasks for function metadata. */  var WRAP_BIND_FLAG = 1,      WRAP_BIND_KEY_FLAG = 2,      WRAP_CURRY_BOUND_FLAG = 4,      WRAP_CURRY_FLAG = 8,      WRAP_CURRY_RIGHT_FLAG = 16,      WRAP_PARTIAL_FLAG = 32,      WRAP_PARTIAL_RIGHT_FLAG = 64,      WRAP_ARY_FLAG = 128,      WRAP_REARG_FLAG = 256,      WRAP_FLIP_FLAG = 512;  /** Used as default options for `_.truncate`. */  var DEFAULT_TRUNC_LENGTH = 30,      DEFAULT_TRUNC_OMISSION = '...';  /** Used to detect hot functions by number of calls within a span of milliseconds. */  var HOT_COUNT = 800,      HOT_SPAN = 16;  /** Used to indicate the type of lazy iteratees. */  var LAZY_FILTER_FLAG = 1,      LAZY_MAP_FLAG = 2,      LAZY_WHILE_FLAG = 3;  /** Used as references for various `Number` constants. */  var INFINITY = 1 / 0,      MAX_SAFE_INTEGER = 9007199254740991,      MAX_INTEGER = 1.7976931348623157e+308,      NAN = 0 / 0;  /** Used as references for the maximum length and index of an array. */  var MAX_ARRAY_LENGTH = 4294967295,      MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,      HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;  /** Used to associate wrap methods with their bit flags. */  var wrapFlags = [    ['ary', WRAP_ARY_FLAG],    ['bind', WRAP_BIND_FLAG],    ['bindKey', WRAP_BIND_KEY_FLAG],    ['curry', WRAP_CURRY_FLAG],    ['curryRight', WRAP_CURRY_RIGHT_FLAG],    ['flip', WRAP_FLIP_FLAG],    ['partial', WRAP_PARTIAL_FLAG],    ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],    ['rearg', WRAP_REARG_FLAG]  ];  /** `Object#toString` result references. */  var argsTag = '[object Arguments]',      arrayTag = '[object Array]',      asyncTag = '[object AsyncFunction]',      boolTag = '[object Boolean]',      dateTag = '[object Date]',      domExcTag = '[object DOMException]',      errorTag = '[object Error]',      funcTag = '[object Function]',      genTag = '[object GeneratorFunction]',      mapTag = '[object Map]',      numberTag = '[object Number]',      nullTag = '[object Null]',      objectTag = '[object Object]',      promiseTag = '[object Promise]',      proxyTag = '[object Proxy]',      regexpTag = '[object RegExp]',      setTag = '[object Set]',      stringTag = '[object String]',      symbolTag = '[object Symbol]',      undefinedTag = '[object Undefined]',      weakMapTag = '[object WeakMap]',      weakSetTag = '[object WeakSet]';  var arrayBufferTag = '[object ArrayBuffer]',      dataViewTag = '[object DataView]',      float32Tag = '[object Float32Array]',      float64Tag = '[object Float64Array]',      int8Tag = '[object Int8Array]',      int16Tag = '[object Int16Array]',      int32Tag = '[object Int32Array]',      uint8Tag = '[object Uint8Array]',      uint8ClampedTag = '[object Uint8ClampedArray]',      uint16Tag = '[object Uint16Array]',      uint32Tag = '[object Uint32Array]';  /** Used to match empty string literals in compiled template source. */  var reEmptyStringLeading = /\b__p \+= '';/g,      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;  /** Used to match HTML entities and HTML characters. */  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,      reUnescapedHtml = /[&<>"']/g,      reHasEscapedHtml = RegExp(reEscapedHtml.source),      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);  /** Used to match template delimiters. */  var reEscape = /<%-([\s\S]+?)%>/g,      reEvaluate = /<%([\s\S]+?)%>/g,      reInterpolate = /<%=([\s\S]+?)%>/g;  /** Used to match property names within property paths. */  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,      reIsPlainProp = /^\w*$/,      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;  /**   * Used to match `RegExp`   * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).   */  var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,      reHasRegExpChar = RegExp(reRegExpChar.source);  /** Used to match leading and trailing whitespace. */  var reTrim = /^\s+|\s+$/g,      reTrimStart = /^\s+/,      reTrimEnd = /\s+$/;  /** Used to match wrap detail comments. */  var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,      reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,      reSplitDetails = /,? & /;  /** Used to match words composed of alphanumeric characters. */  var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;  /** Used to match backslashes in property paths. */  var reEscapeChar = /\\(\\)?/g;  /**   * Used to match   * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).   */  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;  /** Used to match `RegExp` flags from their coerced string values. */  var reFlags = /\w*$/;  /** Used to detect bad signed hexadecimal string values. */  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;  /** Used to detect binary string values. */  var reIsBinary = /^0b[01]+$/i;  /** Used to detect host constructors (Safari). */  var reIsHostCtor = /^\[object .+?Constructor\]$/;  /** Used to detect octal string values. */  var reIsOctal = /^0o[0-7]+$/i;  /** Used to detect unsigned integer values. */  var reIsUint = /^(?:0|[1-9]\d*)$/;  /** Used to match Latin Unicode letters (excluding mathematical operators). */  var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;  /** Used to ensure capturing order of template delimiters. */  var reNoMatch = /($^)/;  /** Used to match unescaped characters in compiled string literals. */  var reUnescapedString = /['\n\r\u2028\u2029\\]/g;  /** Used to compose unicode character classes. */  var rsAstralRange = '\\ud800-\\udfff',      rsComboMarksRange = '\\u0300-\\u036f',      reComboHalfMarksRange = '\\ufe20-\\ufe2f',      rsComboSymbolsRange = '\\u20d0-\\u20ff',      rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,      rsDingbatRange = '\\u2700-\\u27bf',      rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',      rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',      rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',      rsPunctuationRange = '\\u2000-\\u206f',      rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',      rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',      rsVarRange = '\\ufe0e\\ufe0f',      rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;  /** Used to compose unicode capture groups. */  var rsApos = "['\u2019]",      rsAstral = '[' + rsAstralRange + ']',      rsBreak = '[' + rsBreakRange + ']',      rsCombo = '[' + rsComboRange + ']',      rsDigits = '\\d+',      rsDingbat = '[' + rsDingbatRange + ']',      rsLower = '[' + rsLowerRange + ']',      rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',      rsFitz = '\\ud83c[\\udffb-\\udfff]',      rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',      rsNonAstral = '[^' + rsAstralRange + ']',      rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',      rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',      rsUpper = '[' + rsUpperRange + ']',      rsZWJ = '\\u200d';  /** Used to compose unicode regexes. */  var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',      rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',      rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',      rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',      reOptMod = rsModifier + '?',      rsOptVar = '[' + rsVarRange + ']?',      rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',      rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])',      rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])',      rsSeq = rsOptVar + reOptMod + rsOptJoin,      rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,      rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';  /** Used to match apostrophes. */  var reApos = RegExp(rsApos, 'g');  /**   * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and   * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).   */  var reComboMark = RegExp(rsCombo, 'g');  /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */  var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');  /** Used to match complex or compound words. */  var reUnicodeWord = RegExp([    rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',    rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',    rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,    rsUpper + '+' + rsOptContrUpper,    rsOrdUpper,    rsOrdLower,    rsDigits,    rsEmoji  ].join('|'), 'g');  /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */  var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');  /** Used to detect strings that need a more robust regexp to match words. */  var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;  /** Used to assign default `context` object properties. */  var contextProps = [    'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',    'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',    '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'  ];  /** Used to make template sourceURLs easier to identify. */  var templateCounter = -1;  /** Used to identify `toStringTag` values of typed arrays. */  var typedArrayTags = {};  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =  typedArrayTags[uint32Tag] = true;  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =  typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =  typedArrayTags[errorTag] = typedArrayTags[funcTag] =  typedArrayTags[mapTag] = typedArrayTags[numberTag] =  typedArrayTags[objectTag] = typedArrayTags[regexpTag] =  typedArrayTags[setTag] = typedArrayTags[stringTag] =  typedArrayTags[weakMapTag] = false;  /** Used to identify `toStringTag` values supported by `_.clone`. */  var cloneableTags = {};  cloneableTags[argsTag] = cloneableTags[arrayTag] =  cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =  cloneableTags[boolTag] = cloneableTags[dateTag] =  cloneableTags[float32Tag] = cloneableTags[float64Tag] =  cloneableTags[int8Tag] = cloneableTags[int16Tag] =  cloneableTags[int32Tag] = cloneableTags[mapTag] =  cloneableTags[numberTag] = cloneableTags[objectTag] =  cloneableTags[regexpTag] = cloneableTags[setTag] =  cloneableTags[stringTag] = cloneableTags[symbolTag] =  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;  cloneableTags[errorTag] = cloneableTags[funcTag] =  cloneableTags[weakMapTag] = false;  /** Used to map Latin Unicode letters to basic Latin letters. */  var deburredLetters = {    // Latin-1 Supplement block.    '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',    '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',    '\xc7': 'C',  '\xe7': 'c',    '\xd0': 'D',  '\xf0': 'd',    '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',    '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',    '\xcc': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',    '\xec': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',    '\xd1': 'N',  '\xf1': 'n',    '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',    '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',    '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',    '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',    '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',    '\xc6': 'Ae', '\xe6': 'ae',    '\xde': 'Th', '\xfe': 'th',    '\xdf': 'ss',    // Latin Extended-A block.    '\u0100': 'A',  '\u0102': 'A', '\u0104': 'A',    '\u0101': 'a',  '\u0103': 'a', '\u0105': 'a',    '\u0106': 'C',  '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',    '\u0107': 'c',  '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',    '\u010e': 'D',  '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',    '\u0112': 'E',  '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',    '\u0113': 'e',  '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',    '\u011c': 'G',  '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',    '\u011d': 'g',  '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',    '\u0124': 'H',  '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',    '\u0128': 'I',  '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',    '\u0129': 'i',  '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',    '\u0134': 'J',  '\u0135': 'j',    '\u0136': 'K',  '\u0137': 'k', '\u0138': 'k',    '\u0139': 'L',  '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',    '\u013a': 'l',  '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',    '\u0143': 'N',  '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',    '\u0144': 'n',  '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',    '\u014c': 'O',  '\u014e': 'O', '\u0150': 'O',    '\u014d': 'o',  '\u014f': 'o', '\u0151': 'o',    '\u0154': 'R',  '\u0156': 'R', '\u0158': 'R',    '\u0155': 'r',  '\u0157': 'r', '\u0159': 'r',    '\u015a': 'S',  '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',    '\u015b': 's',  '\u015d': 's', '\u015f': 's', '\u0161': 's',    '\u0162': 'T',  '\u0164': 'T', '\u0166': 'T',    '\u0163': 't',  '\u0165': 't', '\u0167': 't',    '\u0168': 'U',  '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',    '\u0169': 'u',  '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',    '\u0174': 'W',  '\u0175': 'w',    '\u0176': 'Y',  '\u0177': 'y', '\u0178': 'Y',    '\u0179': 'Z',  '\u017b': 'Z', '\u017d': 'Z',    '\u017a': 'z',  '\u017c': 'z', '\u017e': 'z',    '\u0132': 'IJ', '\u0133': 'ij',    '\u0152': 'Oe', '\u0153': 'oe',    '\u0149': "'n", '\u017f': 's'  };  /** Used to map characters to HTML entities. */  var htmlEscapes = {    '&': '&',    '<': '<',    '>': '>',    '"': '"',    "'": '''  };  /** Used to map HTML entities to characters. */  var htmlUnescapes = {    '&': '&',    '<': '<',    '>': '>',    '"': '"',    ''': "'"  };  /** Used to escape characters for inclusion in compiled string literals. */  var stringEscapes = {    '\\': '\\',    "'": "'",    '\n': 'n',    '\r': 'r',    '\u2028': 'u2028',    '\u2029': 'u2029'  };  /** Built-in method references without a dependency on `root`. */  var freeParseFloat = parseFloat,      freeParseInt = parseInt;  /** Detect free variable `global` from Node.js. */  var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;  /** Detect free variable `self`. */  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;  /** Used as a reference to the global object. */  var root = freeGlobal || freeSelf || Function('return this')();  /** Detect free variable `exports`. */  var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;  /** Detect free variable `module`. */  var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;  /** Detect the popular CommonJS extension `module.exports`. */  var moduleExports = freeModule && freeModule.exports === freeExports;  /** Detect free variable `process` from Node.js. */  var freeProcess = moduleExports && freeGlobal.process;  /** Used to access faster Node.js helpers. */  var nodeUtil = (function() {    try {      // Use `util.types` for Node.js 10+.      var types = freeModule && freeModule.require && freeModule.require('util').types;      if (types) {        return types;      }      // Legacy `process.binding('util')` for Node.js < 10.      return freeProcess && freeProcess.binding && freeProcess.binding('util');    } catch (e) {}  }());  /* Node.js helper references. */  var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,      nodeIsDate = nodeUtil && nodeUtil.isDate,      nodeIsMap = nodeUtil && nodeUtil.isMap,      nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,      nodeIsSet = nodeUtil && nodeUtil.isSet,      nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;  /*--------------------------------------------------------------------------*/  /**   * A faster alternative to `Function#apply`, this function invokes `func`   * with the `this` binding of `thisArg` and the arguments of `args`.   *   * @private   * @param {Function} func The function to invoke.   * @param {*} thisArg The `this` binding of `func`.   * @param {Array} args The arguments to invoke `func` with.   * @returns {*} Returns the result of `func`.   */  function apply(func, thisArg, args) {    switch (args.length) {      case 0: return func.call(thisArg);      case 1: return func.call(thisArg, args[0]);      case 2: return func.call(thisArg, args[0], args[1]);      case 3: return func.call(thisArg, args[0], args[1], args[2]);    }    return func.apply(thisArg, args);  }  /**   * A specialized version of `baseAggregator` for arrays.   *   * @private   * @param {Array} [array] The array to iterate over.   * @param {Function} setter The function to set `accumulator` values.   * @param {Function} iteratee The iteratee to transform keys.   * @param {Object} accumulator The initial aggregated object.   * @returns {Function} Returns `accumulator`.   */  function arrayAggregator(array, setter, iteratee, accumulator) {    var index = -1,        length = array == null ? 0 : array.length;    while (++index < length) {      var value = array[index];      setter(accumulator, value, iteratee(value), array);    }    return accumulator;  }  /**   * A specialized version of `_.forEach` for arrays without support for   * iteratee shorthands.   *   * @private   * @param {Array} [array] The array to iterate over.   * @param {Function} iteratee The function invoked per iteration.   * @returns {Array} Returns `array`.   */  function arrayEach(array, iteratee) {    var index = -1,        length = array == null ? 0 : array.length;    while (++index < length) {      if (iteratee(array[index], index, array) === false) {        break;      }    }    return array;  }  /**   * A specialized version of `_.forEachRight` for arrays without support for   * iteratee shorthands.   *   * @private   * @param {Array} [array] The array to iterate over.   * @param {Function} iteratee The function invoked per iteration.   * @returns {Array} Returns `array`.   */  function arrayEachRight(array, iteratee) {    var length = array == null ? 0 : array.length;    while (length--) {      if (iteratee(array[length], length, array) === false) {        break;      }    }    return array;  }  /**   * A specialized version of `_.every` for arrays without support for   * iteratee shorthands.   *   * @private   * @param {Array} [array] The array to iterate over.   * @param {Function} predicate The function invoked per iteration.   * @returns {boolean} Returns `true` if all elements pass the predicate check,   *  else `false`.   */  function arrayEvery(array, predicate) {    var index = -1,        length = array == null ? 0 : array.length;    while (++index < length) {      if (!predicate(array[index], index, array)) {        return false;      }    }    return true;  }  /**   * A specialized version of `_.filter` for arrays without support for   * iteratee shorthands.   *   * @private   * @param {Array} [array] The array to iterate over.   * @param {Function} predicate The function invoked per iteration.   * @returns {Array} Returns the new filtered array.   */  function arrayFilter(array, predicate) {    var index = -1,        length = array == null ? 0 : array.length,        resIndex = 0,        result = [];    while (++index < length) {      var value = array[index];      if (predicate(value, index, array)) {        result[resIndex++] = value;      }    }    return result;  }  /**   * A specialized version of `_.includes` for arrays without support for   * specifying an index to search from.   *   * @private   * @param {Array} [array] The array to inspect.   * @param {*} target The value to search for.   * @returns {boolean} Returns `true` if `target` is found, else `false`.   */  function arrayIncludes(array, value) {    var length = array == null ? 0 : array.length;    return !!length && baseIndexOf(array, value, 0) > -1;  }  /**   * This function is like `arrayIncludes` except that it accepts a comparator.   *   * @private   * @param {Array} [array] The array to inspect.   * @param {*} target The value to search for.   * @param {Function} comparator The comparator invoked per element.   * @returns {boolean} Returns `true` if `target` is found, else `false`.   */  function arrayIncludesWith(array, value, comparator) {    var index = -1,        length = array == null ? 0 : array.length;    while (++index < length) {      if (comparator(value, array[index])) {        return true;      }    }    return false;  }  /**   * A specialized version of `_.map` for arrays without support for iteratee   * shorthands.   *   * @private   * @param {Array} [array] The array to iterate over.   * @param {Function} iteratee The function invoked per iteration.   * @returns {Array} Returns the new mapped array.   */  function arrayMap(array, iteratee) {    var index = -1,        length = array == null ? 0 : array.length,        result = Array(length);    while (++index < length) {      result[index] = iteratee(array[index], index, array);    }    return result;  }  /**   * Appends the elements of `values` to `array`.   *   * @private   * @param {Array} array The array to modify.   * @param {Array} values The values to append.   * @returns {Array} Returns `array`.   */  function arrayPush(array, values) {    var index = -1,        length = values.length,        offset = array.length;    while (++index < length) {      array[offset + index] = values[index];    }    return array;  }  /**   * A specialized version of `_.reduce` for arrays without support for   * iteratee shorthands.   *   * @private   * @param {Array} [array] The array to iterate over.   * @param {Function} iteratee The function invoked per iteration.   * @param {*} [accumulator] The initial value.   * @param {boolean} [initAccum] Specify using the first element of `array` as   *  the initial value.   * @returns {*} Returns the accumulated value.   */  function arrayReduce(array, iteratee, accumulator, initAccum) {    var index = -1,        length = array == null ? 0 : array.length;    if (initAccum && length) {      accumulator = array[++index];    }    while (++index < length) {      accumulator = iteratee(accumulator, array[index], index, array);    }    return accumulator;  }  /**   * A specialized version of `_.reduceRight` for arrays without support for   * iteratee shorthands.   *   * @private   * @param {Array} [array] The array to iterate over.   * @param {Function} iteratee The function invoked per iteration.   * @param {*} [accumulator] The initial value.   * @param {boolean} [initAccum] Specify using the last element of `array` as   *  the initial value.   * @returns {*} Returns the accumulated value.   */  function arrayReduceRight(array, iteratee, accumulator, initAccum) {    var length = array == null ? 0 : array.length;    if (initAccum && length) {      accumulator = array[--length];    }    while (length--) {      accumulator = iteratee(accumulator, array[length], length, array);    }    return accumulator;  }  /**   * A specialized version of `_.some` for arrays without support for iteratee   * shorthands.   *   * @private   * @param {Array} [array] The array to iterate over.   * @param {Function} predicate The function invoked per iteration.   * @returns {boolean} Returns `true` if any element passes the predicate check,   *  else `false`.   */  function arraySome(array, predicate) {    var index = -1,        length = array == null ? 0 : array.length;    while (++index < length) {      if (predicate(array[index], index, array)) {        return true;      }    }    return false;  }  /**   * Gets the size of an ASCII `string`.   *   * @private   * @param {string} string The string inspect.   * @returns {number} Returns the string size.   */  var asciiSize = baseProperty('length');  /**   * Converts an ASCII `string` to an array.   *   * @private   * @param {string} string The string to convert.   * @returns {Array} Returns the converted array.   */  function asciiToArray(string) {    return string.split('');  }  /**   * Splits an ASCII `string` into an array of its words.   *   * @private   * @param {string} The string to inspect.   * @returns {Array} Returns the words of `string`.   */  function asciiWords(string) {    return string.match(reAsciiWord) || [];  }  /**   * The base implementation of methods like `_.findKey` and `_.findLastKey`,   * without support for iteratee shorthands, which iterates over `collection`   * using `eachFunc`.   *   * @private   * @param {Array|Object} collection The collection to inspect.   * @param {Function} predicate The function invoked per iteration.   * @param {Function} eachFunc The function to iterate over `collection`.   * @returns {*} Returns the found element or its key, else `undefined`.   */  function baseFindKey(collection, predicate, eachFunc) {    var result;    eachFunc(collection, function(value, key, collection) {      if (predicate(value, key, collection)) {        result = key;        return false;      }    });    return result;  }  /**   * The base implementation of `_.findIndex` and `_.findLastIndex` without   * support for iteratee shorthands.   *   * @private   * @param {Array} array The array to inspect.   * @param {Function} predicate The function invoked per iteration.   * @param {number} fromIndex The index to search from.   * @param {boolean} [fromRight] Specify iterating from right to left.   * @returns {number} Returns the index of the matched value, else `-1`.   */  function baseFindIndex(array, predicate, fromIndex, fromRight) {    var length = array.length,        index = fromIndex + (fromRight ? 1 : -1);    while ((fromRight ? index-- : ++index < length)) {      if (predicate(array[index], index, array)) {        return index;      }    }    return -1;  }  /**   * The base implementation of `_.indexOf` without `fromIndex` bounds checks.   *   * @private   * @param {Array} array The array to inspect.   * @param {*} value The value to search for.   * @param {number} fromIndex The index to search from.   * @returns {number} Returns the index of the matched value, else `-1`.   */  function baseIndexOf(array, value, fromIndex) {    return value === value      ? strictIndexOf(array, value, fromIndex)      : baseFindIndex(array, baseIsNaN, fromIndex);  }  /**   * This function is like `baseIndexOf` except that it accepts a comparator.   *   * @private   * @param {Array} array The array to inspect.   * @param {*} value The value to search for.   * @param {number} fromIndex The index to search from.   * @param {Function} comparator The comparator invoked per element.   * @returns {number} Returns the index of the matched value, else `-1`.   */  function baseIndexOfWith(array, value, fromIndex, comparator) {    var index = fromIndex - 1,        length = array.length;    while (++index < length) {      if (comparator(array[index], value)) {        return index;      }    }    return -1;  }  /**   * The base implementation of `_.isNaN` without support for number objects.   *   * @private   * @param {*} value The value to check.   * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.   */  function baseIsNaN(value) {    return value !== value;  }  /**   * The base implementation of `_.mean` and `_.meanBy` without support for   * iteratee shorthands.   *   * @private   * @param {Array} array The array to iterate over.   * @param {Function} iteratee The function invoked per iteration.   * @returns {number} Returns the mean.   */  function baseMean(array, iteratee) {    var length = array == null ? 0 : array.length;    return length ? (baseSum(array, iteratee) / length) : NAN;  }  /**   * The base implementation of `_.property` without support for deep paths.   *   * @private   * @param {string} key The key of the property to get.   * @returns {Function} Returns the new accessor function.   */  function baseProperty(key) {    return function(object) {      return object == null ? undefined : object[key];    };  }  /**   * The base implementation of `_.propertyOf` without support for deep paths.   *   * @private   * @param {Object} object The object to query.   * @returns {Function} Returns the new accessor function.   */  function basePropertyOf(object) {    return function(key) {      return object == null ? undefined : object[key];    };  }  /**   * The base implementation of `_.reduce` and `_.reduceRight`, without support   * for iteratee shorthands, which iterates over `collection` using `eachFunc`.   *   * @private   * @param {Array|Object} collection The collection to iterate over.   * @param {Function} iteratee The function invoked per iteration.   * @param {*} accumulator The initial value.   * @param {boolean} initAccum Specify using the first or last element of   *  `collection` as the initial value.   * @param {Function} eachFunc The function to iterate over `collection`.   * @returns {*} Returns the accumulated value.   */  function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {    eachFunc(collection, function(value, index, collection) {      accumulator = initAccum        ? (initAccum = false, value)        : iteratee(accumulator, value, index, collection);    });    return accumulator;  }  /**   * The base implementation of `_.sortBy` which uses `comparer` to define the   * sort order of `array` and replaces criteria objects with their corresponding   * values.   *   * @private   * @param {Array} array The array to sort.   * @param {Function} comparer The function to define sort order.   * @returns {Array} Returns `array`.   */  function baseSortBy(array, comparer) {    var length = array.length;    array.sort(comparer);    while (length--) {      array[length] = array[length].value;    }    return array;  }  /**   * The base implementation of `_.sum` and `_.sumBy` without support for   * iteratee shorthands.   *   * @private   * @param {Array} array The array to iterate over.   * @param {Function} iteratee The function invoked per iteration.   * @returns {number} Returns the sum.   */  function baseSum(array, iteratee) {    var result,        index = -1,        length = array.length;    while (++index < length) {      var current = iteratee(array[index]);      if (current !== undefined) {        result = result === undefined ? current : (result + current);      }    }    return result;  }  /**   * The base implementation of `_.times` without support for iteratee shorthands   * or max array length checks.   *   * @private   * @param {number} n The number of times to invoke `iteratee`.   * @param {Function} iteratee The function invoked per iteration.   * @returns {Array} Returns the array of results.   */  function baseTimes(n, iteratee) {    var index = -1,        result = Array(n);    while (++index < n) {      result[index] = iteratee(index);    }    return result;  }  /**   * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array   * of key-value pairs for `object` corresponding to the property names of `props`.   *   * @private   * @param {Object} object The object to query.   * @param {Array} props The property names to get values for.   * @returns {Object} Returns the key-value pairs.   */  function baseToPairs(object, props) {    return arrayMap(props, function(key) {      return [key, object[key]];    });  }  /**   * The base implementation of `_.unary` without support for storing metadata.   *   * @private   * @param {Function} func The function to cap arguments for.   * @returns {Function} Returns the new capped function.   */  function baseUnary(func) {    return function(value) {      return func(value);    };  }  /**   * The base implementation of `_.values` and `_.valuesIn` which creates an   * array of `object` property values corresponding to the property names   * of `props`.   *   * @private   * @param {Object} object The object to query.   * @param {Array} props The property names to get values for.   * @returns {Object} Returns the array of property values.   */  function baseValues(object, props) {    return arrayMap(props, function(key) {      return object[key];    });  }  /**   * Checks if a `cache` value for `key` exists.   *   * @private   * @param {Object} cache The cache to query.   * @param {string} key The key of the entry to check.   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.   */  function cacheHas(cache, key) {    return cache.has(key);  }  /**   * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol   * that is not found in the character symbols.   *   * @private   * @param {Array} strSymbols The string symbols to inspect.   * @param {Array} chrSymbols The character symbols to find.   * @returns {number} Returns the index of the first unmatched string symbol.   */  function charsStartIndex(strSymbols, chrSymbols) {    var index = -1,        length = strSymbols.length;    while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}    return index;  }  /**   * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol   * that is not found in the character symbols.   *   * @private   * @param {Array} strSymbols The string symbols to inspect.   * @param {Array} chrSymbols The character symbols to find.   * @returns {number} Returns the index of the last unmatched string symbol.   */  function charsEndIndex(strSymbols, chrSymbols) {    var index = strSymbols.length;    while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}    return index;  }  /**   * Gets the number of `placeholder` occurrences in `array`.   *   * @private   * @param {Array} array The array to inspect.   * @param {*} placeholder The placeholder to search for.   * @returns {number} Returns the placeholder count.   */  function countHolders(array, placeholder) {    var length = array.length,        result = 0;    while (length--) {      if (array[length] === placeholder) {        ++result;      }    }    return result;  }  /**   * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A   * letters to basic Latin letters.   *   * @private   * @param {string} letter The matched letter to deburr.   * @returns {string} Returns the deburred letter.   */  var deburrLetter = basePropertyOf(deburredLetters);  /**   * Used by `_.escape` to convert characters to HTML entities.   *   * @private   * @param {string} chr The matched character to escape.   * @returns {string} Returns the escaped character.   */  var escapeHtmlChar = basePropertyOf(htmlEscapes);  /**   * Used by `_.template` to escape characters for inclusion in compiled string literals.   *   * @private   * @param {string} chr The matched character to escape.   * @returns {string} Returns the escaped character.   */  function escapeStringChar(chr) {    return '\\' + stringEscapes[chr];  }  /**   * Gets the value at `key` of `object`.   *   * @private   * @param {Object} [object] The object to query.   * @param {string} key The key of the property to get.   * @returns {*} Returns the property value.   */  function getValue(object, key) {    return object == null ? undefined : object[key];  }  /**   * Checks if `string` contains Unicode symbols.   *   * @private   * @param {string} string The string to inspect.   * @returns {boolean} Returns `true` if a symbol is found, else `false`.   */  function hasUnicode(string) {    return reHasUnicode.test(string);  }  /**   * Checks if `string` contains a word composed of Unicode symbols.   *   * @private   * @param {string} string The string to inspect.   * @returns {boolean} Returns `true` if a word is found, else `false`.   */  function hasUnicodeWord(string) {    return reHasUnicodeWord.test(string);  }  /**   * Converts `iterator` to an array.   *   * @private   * @param {Object} iterator The iterator to convert.   * @returns {Array} Returns the converted array.   */  function iteratorToArray(iterator) {    var data,        result = [];    while (!(data = iterator.next()).done) {      result.push(data.value);    }    return result;  }  /**   * Converts `map` to its key-value pairs.   *   * @private   * @param {Object} map The map to convert.   * @returns {Array} Returns the key-value pairs.   */  function mapToArray(map) {    var index = -1,        result = Array(map.size);    map.forEach(function(value, key) {      result[++index] = [key, value];    });    return result;  }  /**   * Creates a unary function that invokes `func` with its argument transformed.   *   * @private   * @param {Function} func The function to wrap.   * @param {Function} transform The argument transform.   * @returns {Function} Returns the new function.   */  function overArg(func, transform) {    return function(arg) {      return func(transform(arg));    };  }  /**   * Replaces all `placeholder` elements in `array` with an internal placeholder   * and returns an array of their indexes.   *   * @private   * @param {Array} array The array to modify.   * @param {*} placeholder The placeholder to replace.   * @returns {Array} Returns the new array of placeholder indexes.   */  function replaceHolders(array, placeholder) {    var index = -1,        length = array.length,        resIndex = 0,        result = [];    while (++index < length) {      var value = array[index];      if (value === placeholder || value === PLACEHOLDER) {        array[index] = PLACEHOLDER;        result[resIndex++] = index;      }    }    return result;  }  /**   * Converts `set` to an array of its values.   *   * @private   * @param {Object} set The set to convert.   * @returns {Array} Returns the values.   */  function setToArray(set) {    var index = -1,        result = Array(set.size);    set.forEach(function(value) {      result[++index] = value;    });    return result;  }  /**   * Converts `set` to its value-value pairs.   *   * @private   * @param {Object} set The set to convert.   * @returns {Array} Returns the value-value pairs.   */  function setToPairs(set) {    var index = -1,        result = Array(set.size);    set.forEach(function(value) {      result[++index] = [value, value];    });    return result;  }  /**   * A specialized version of `_.indexOf` which performs strict equality   * comparisons of values, i.e. `===`.   *   * @private   * @param {Array} array The array to inspect.   * @param {*} value The value to search for.   * @param {number} fromIndex The index to search from.   * @returns {number} Returns the index of the matched value, else `-1`.   */  function strictIndexOf(array, value, fromIndex) {    var index = fromIndex - 1,        length = array.length;    while (++index < length) {      if (array[index] === value) {        return index;      }    }    return -1;  }  /**   * A specialized version of `_.lastIndexOf` which performs strict equality   * comparisons of values, i.e. `===`.   *   * @private   * @param {Array} array The array to inspect.   * @param {*} value The value to search for.   * @param {number} fromIndex The index to search from.   * @returns {number} Returns the index of the matched value, else `-1`.   */  function strictLastIndexOf(array, value, fromIndex) {    var index = fromIndex + 1;    while (index--) {      if (array[index] === value) {        return index;      }    }    return index;  }  /**   * Gets the number of symbols in `string`.   *   * @private   * @param {string} string The string to inspect.   * @returns {number} Returns the string size.   */  function stringSize(string) {    return hasUnicode(string)      ? unicodeSize(string)      : asciiSize(string);  }  /**   * Converts `string` to an array.   *   * @private   * @param {string} string The string to convert.   * @returns {Array} Returns the converted array.   */  function stringToArray(string) {    return hasUnicode(string)      ? unicodeToArray(string)      : asciiToArray(string);  }  /**   * Used by `_.unescape` to convert HTML entities to characters.   *   * @private   * @param {string} chr The matched character to unescape.   * @returns {string} Returns the unescaped character.   */  var unescapeHtmlChar = basePropertyOf(htmlUnescapes);  /**   * Gets the size of a Unicode `string`.   *   * @private   * @param {string} string The string inspect.   * @returns {number} Returns the string size.   */  function unicodeSize(string) {    var result = reUnicode.lastIndex = 0;    while (reUnicode.test(string)) {      ++result;    }    return result;  }  /**   * Converts a Unicode `string` to an array.   *   * @private   * @param {string} string The string to convert.   * @returns {Array} Returns the converted array.   */  function unicodeToArray(string) {    return string.match(reUnicode) || [];  }  /**   * Splits a Unicode `string` into an array of its words.   *   * @private   * @param {string} The string to inspect.   * @returns {Array} Returns the words of `string`.   */  function unicodeWords(string) {    return string.match(reUnicodeWord) || [];  }  /*--------------------------------------------------------------------------*/  /**   * Create a new pristine `lodash` function using the `context` object.   *   * @static   * @memberOf _   * @since 1.1.0   * @category Util   * @param {Object} [context=root] The context object.   * @returns {Function} Returns a new `lodash` function.   * @example   *   * _.mixin({ 'foo': _.constant('foo') });   *   * var lodash = _.runInContext();   * lodash.mixin({ 'bar': lodash.constant('bar') });   *   * _.isFunction(_.foo);   * // => true   * _.isFunction(_.bar);   * // => false   *   * lodash.isFunction(lodash.foo);   * // => false   * lodash.isFunction(lodash.bar);   * // => true   *   * // Create a suped-up `defer` in Node.js.   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;   */  var runInContext = (function runInContext(context) {    context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));    /** Built-in constructor references. */    var Array = context.Array,        Date = context.Date,        Error = context.Error,        Function = context.Function,        Math = context.Math,        Object = context.Object,        RegExp = context.RegExp,        String = context.String,        TypeError = context.TypeError;    /** Used for built-in method references. */    var arrayProto = Array.prototype,        funcProto = Function.prototype,        objectProto = Object.prototype;    /** Used to detect overreaching core-js shims. */    var coreJsData = context['__core-js_shared__'];    /** Used to resolve the decompiled source of functions. */    var funcToString = funcProto.toString;    /** Used to check objects for own properties. */    var hasOwnProperty = objectProto.hasOwnProperty;    /** Used to generate unique IDs. */    var idCounter = 0;    /** Used to detect methods masquerading as native. */    var maskSrcKey = (function() {      var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');      return uid ? ('Symbol(src)_1.' + uid) : '';    }());    /**     * Used to resolve the     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)     * of values.     */    var nativeObjectToString = objectProto.toString;    /** Used to infer the `Object` constructor. */    var objectCtorString = funcToString.call(Object);    /** Used to restore the original `_` reference in `_.noConflict`. */    var oldDash = root._;    /** Used to detect if a method is native. */    var reIsNative = RegExp('^' +      funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')      .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'    );    /** Built-in value references. */    var Buffer = moduleExports ? context.Buffer : undefined,        Symbol = context.Symbol,        Uint8Array = context.Uint8Array,        allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,        getPrototype = overArg(Object.getPrototypeOf, Object),        objectCreate = Object.create,        propertyIsEnumerable = objectProto.propertyIsEnumerable,        splice = arrayProto.splice,        spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,        symIterator = Symbol ? Symbol.iterator : undefined,        symToStringTag = Symbol ? Symbol.toStringTag : undefined;    var defineProperty = (function() {      try {        var func = getNative(Object, 'defineProperty');        func({}, '', {});        return func;      } catch (e) {}    }());    /** Mocked built-ins. */    var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,        ctxNow = Date && Date.now !== root.Date.now && Date.now,        ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;    /* Built-in method references for those with the same name as other `lodash` methods. */    var nativeCeil = Math.ceil,        nativeFloor = Math.floor,        nativeGetSymbols = Object.getOwnPropertySymbols,        nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,        nativeIsFinite = context.isFinite,        nativeJoin = arrayProto.join,        nativeKeys = overArg(Object.keys, Object),        nativeMax = Math.max,        nativeMin = Math.min,        nativeNow = Date.now,        nativeParseInt = context.parseInt,        nativeRandom = Math.random,        nativeReverse = arrayProto.reverse;    /* Built-in method references that are verified to be native. */    var DataView = getNative(context, 'DataView'),        Map = getNative(context, 'Map'),        Promise = getNative(context, 'Promise'),        Set = getNative(context, 'Set'),        WeakMap = getNative(context, 'WeakMap'),        nativeCreate = getNative(Object, 'create');    /** Used to store function metadata. */    var metaMap = WeakMap && new WeakMap;    /** Used to lookup unminified function names. */    var realNames = {};    /** Used to detect maps, sets, and weakmaps. */    var dataViewCtorString = toSource(DataView),        mapCtorString = toSource(Map),        promiseCtorString = toSource(Promise),        setCtorString = toSource(Set),        weakMapCtorString = toSource(WeakMap);    /** Used to convert symbols to primitives and strings. */    var symbolProto = Symbol ? Symbol.prototype : undefined,        symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,        symbolToString = symbolProto ? symbolProto.toString : undefined;    /*------------------------------------------------------------------------*/    /**     * Creates a `lodash` object which wraps `value` to enable implicit method     * chain sequences. Methods that operate on and return arrays, collections,     * and functions can be chained together. Methods that retrieve a single value     * or may return a primitive value will automatically end the chain sequence     * and return the unwrapped value. Otherwise, the value must be unwrapped     * with `_#value`.     *     * Explicit chain sequences, which must be unwrapped with `_#value`, may be     * enabled using `_.chain`.     *     * The execution of chained methods is lazy, that is, it's deferred until     * `_#value` is implicitly or explicitly called.     *     * Lazy evaluation allows several methods to support shortcut fusion.     * Shortcut fusion is an optimization to merge iteratee calls; this avoids     * the creation of intermediate arrays and can greatly reduce the number of     * iteratee executions. Sections of a chain sequence qualify for shortcut     * fusion if the section is applied to an array and iteratees accept only     * one argument. The heuristic for whether a section qualifies for shortcut     * fusion is subject to change.     *     * Chaining is supported in custom builds as long as the `_#value` method is     * directly or indirectly included in the build.     *     * In addition to lodash methods, wrappers have `Array` and `String` methods.     *     * The wrapper `Array` methods are:     * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`     *     * The wrapper `String` methods are:     * `replace` and `split`     *     * The wrapper methods that support shortcut fusion are:     * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,     * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,     * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`     *     * The chainable wrapper methods are:     * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,     * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,     * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,     * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,     * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,     * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,     * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,     * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,     * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,     * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,     * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,     * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,     * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,     * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,     * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,     * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,     * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,     * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,     * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,     * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,     * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,     * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,     * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,     * `zipObject`, `zipObjectDeep`, and `zipWith`     *     * The wrapper methods that are **not** chainable by default are:     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,     * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,     * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,     * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,     * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,     * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,     * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,     * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,     * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,     * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,     * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,     * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,     * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,     * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,     * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,     * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,     * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,     * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,     * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,     * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,     * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,     * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,     * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,     * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,     * `upperFirst`, `value`, and `words`     *     * @name _     * @constructor     * @category Seq     * @param {*} value The value to wrap in a `lodash` instance.     * @returns {Object} Returns the new `lodash` wrapper instance.     * @example     *     * function square(n) {     *   return n * n;     * }     *     * var wrapped = _([1, 2, 3]);     *     * // Returns an unwrapped value.     * wrapped.reduce(_.add);     * // => 6     *     * // Returns a wrapped value.     * var squares = wrapped.map(square);     *     * _.isArray(squares);     * // => false     *     * _.isArray(squares.value());     * // => true     */    function lodash(value) {      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {        if (value instanceof LodashWrapper) {          return value;        }        if (hasOwnProperty.call(value, '__wrapped__')) {          return wrapperClone(value);        }      }      return new LodashWrapper(value);    }    /**     * The base implementation of `_.create` without support for assigning     * properties to the created object.     *     * @private     * @param {Object} proto The object to inherit from.     * @returns {Object} Returns the new object.     */    var baseCreate = (function() {      function object() {}      return function(proto) {        if (!isObject(proto)) {          return {};        }        if (objectCreate) {          return objectCreate(proto);        }        object.prototype = proto;        var result = new object;        object.prototype = undefined;        return result;      };    }());    /**     * The function whose prototype chain sequence wrappers inherit from.     *     * @private     */    function baseLodash() {      // No operation performed.    }    /**     * The base constructor for creating `lodash` wrapper objects.     *     * @private     * @param {*} value The value to wrap.     * @param {boolean} [chainAll] Enable explicit method chain sequences.     */    function LodashWrapper(value, chainAll) {      this.__wrapped__ = value;      this.__actions__ = [];      this.__chain__ = !!chainAll;      this.__index__ = 0;      this.__values__ = undefined;    }    /**     * By default, the template delimiters used by lodash are like those in     * embedded Ruby (ERB) as well as ES2015 template strings. Change the     * following template settings to use alternative delimiters.     *     * @static     * @memberOf _     * @type {Object}     */    lodash.templateSettings = {      /**       * Used to detect `data` property values to be HTML-escaped.       *       * @memberOf _.templateSettings       * @type {RegExp}       */      'escape': reEscape,      /**       * Used to detect code to be evaluated.       *       * @memberOf _.templateSettings       * @type {RegExp}       */      'evaluate': reEvaluate,      /**       * Used to detect `data` property values to inject.       *       * @memberOf _.templateSettings       * @type {RegExp}       */      'interpolate': reInterpolate,      /**       * Used to reference the data object in the template text.       *       * @memberOf _.templateSettings       * @type {string}       */      'variable': '',      /**       * Used to import variables into the compiled template.       *       * @memberOf _.templateSettings       * @type {Object}       */      'imports': {        /**         * A reference to the `lodash` function.         *         * @memberOf _.templateSettings.imports         * @type {Function}         */        '_': lodash      }    };    // Ensure wrappers are instances of `baseLodash`.    lodash.prototype = baseLodash.prototype;    lodash.prototype.constructor = lodash;    LodashWrapper.prototype = baseCreate(baseLodash.prototype);    LodashWrapper.prototype.constructor = LodashWrapper;    /*------------------------------------------------------------------------*/    /**     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.     *     * @private     * @constructor     * @param {*} value The value to wrap.     */    function LazyWrapper(value) {      this.__wrapped__ = value;      this.__actions__ = [];      this.__dir__ = 1;      this.__filtered__ = false;      this.__iteratees__ = [];      this.__takeCount__ = MAX_ARRAY_LENGTH;      this.__views__ = [];    }    /**     * Creates a clone of the lazy wrapper object.     *     * @private     * @name clone     * @memberOf LazyWrapper     * @returns {Object} Returns the cloned `LazyWrapper` object.     */    function lazyClone() {      var result = new LazyWrapper(this.__wrapped__);      result.__actions__ = copyArray(this.__actions__);      result.__dir__ = this.__dir__;      result.__filtered__ = this.__filtered__;      result.__iteratees__ = copyArray(this.__iteratees__);      result.__takeCount__ = this.__takeCount__;      result.__views__ = copyArray(this.__views__);      return result;    }    /**     * Reverses the direction of lazy iteration.     *     * @private     * @name reverse     * @memberOf LazyWrapper     * @returns {Object} Returns the new reversed `LazyWrapper` object.     */    function lazyReverse() {      if (this.__filtered__) {        var result = new LazyWrapper(this);        result.__dir__ = -1;        result.__filtered__ = true;      } else {        result = this.clone();        result.__dir__ *= -1;      }      return result;    }    /**     * Extracts the unwrapped value from its lazy wrapper.     *     * @private     * @name value     * @memberOf LazyWrapper     * @returns {*} Returns the unwrapped value.     */    function lazyValue() {      var array = this.__wrapped__.value(),          dir = this.__dir__,          isArr = isArray(array),          isRight = dir < 0,          arrLength = isArr ? array.length : 0,          view = getView(0, arrLength, this.__views__),          start = view.start,          end = view.end,          length = end - start,          index = isRight ? end : (start - 1),          iteratees = this.__iteratees__,          iterLength = iteratees.length,          resIndex = 0,          takeCount = nativeMin(length, this.__takeCount__);      if (!isArr || (!isRight && arrLength == length && takeCount == length)) {        return baseWrapperValue(array, this.__actions__);      }      var result = [];      outer:      while (length-- && resIndex < takeCount) {        index += dir;        var iterIndex = -1,            value = array[index];        while (++iterIndex < iterLength) {          var data = iteratees[iterIndex],              iteratee = data.iteratee,              type = data.type,              computed = iteratee(value);          if (type == LAZY_MAP_FLAG) {            value = computed;          } else if (!computed) {            if (type == LAZY_FILTER_FLAG) {              continue outer;            } else {              break outer;            }          }        }        result[resIndex++] = value;      }      return result;    }    // Ensure `LazyWrapper` is an instance of `baseLodash`.    LazyWrapper.prototype = baseCreate(baseLodash.prototype);    LazyWrapper.prototype.constructor = LazyWrapper;    /*------------------------------------------------------------------------*/    /**     * Creates a hash object.     *     * @private     * @constructor     * @param {Array} [entries] The key-value pairs to cache.     */    function Hash(entries) {      var index = -1,          length = entries == null ? 0 : entries.length;      this.clear();      while (++index < length) {        var entry = entries[index];        this.set(entry[0], entry[1]);      }    }    /**     * Removes all key-value entries from the hash.     *     * @private     * @name clear     * @memberOf Hash     */    function hashClear() {      this.__data__ = nativeCreate ? nativeCreate(null) : {};      this.size = 0;    }    /**     * Removes `key` and its value from the hash.     *     * @private     * @name delete     * @memberOf Hash     * @param {Object} hash The hash to modify.     * @param {string} key The key of the value to remove.     * @returns {boolean} Returns `true` if the entry was removed, else `false`.     */    function hashDelete(key) {      var result = this.has(key) && delete this.__data__[key];      this.size -= result ? 1 : 0;      return result;    }    /**     * Gets the hash value for `key`.     *     * @private     * @name get     * @memberOf Hash     * @param {string} key The key of the value to get.     * @returns {*} Returns the entry value.     */    function hashGet(key) {      var data = this.__data__;      if (nativeCreate) {        var result = data[key];        return result === HASH_UNDEFINED ? undefined : result;      }      return hasOwnProperty.call(data, key) ? data[key] : undefined;    }    /**     * Checks if a hash value for `key` exists.     *     * @private     * @name has     * @memberOf Hash     * @param {string} key The key of the entry to check.     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.     */    function hashHas(key) {      var data = this.__data__;      return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);    }    /**     * Sets the hash `key` to `value`.     *     * @private     * @name set     * @memberOf Hash     * @param {string} key The key of the value to set.     * @param {*} value The value to set.     * @returns {Object} Returns the hash instance.     */    function hashSet(key, value) {      var data = this.__data__;      this.size += this.has(key) ? 0 : 1;      data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;      return this;    }    // Add methods to `Hash`.    Hash.prototype.clear = hashClear;    Hash.prototype['delete'] = hashDelete;    Hash.prototype.get = hashGet;    Hash.prototype.has = hashHas;    Hash.prototype.set = hashSet;    /*------------------------------------------------------------------------*/    /**     * Creates an list cache object.     *     * @private     * @constructor     * @param {Array} [entries] The key-value pairs to cache.     */    function ListCache(entries) {      var index = -1,          length = entries == null ? 0 : entries.length;      this.clear();      while (++index < length) {        var entry = entries[index];        this.set(entry[0], entry[1]);      }    }    /**     * Removes all key-value entries from the list cache.     *     * @private     * @name clear     * @memberOf ListCache     */    function listCacheClear() {      this.__data__ = [];      this.size = 0;    }    /**     * Removes `key` and its value from the list cache.     *     * @private     * @name delete     * @memberOf ListCache     * @param {string} key The key of the value to remove.     * @returns {boolean} Returns `true` if the entry was removed, else `false`.     */    function listCacheDelete(key) {      var data = this.__data__,          index = assocIndexOf(data, key);      if (index < 0) {        return false;      }      var lastIndex = data.length - 1;      if (index == lastIndex) {        data.pop();      } else {        splice.call(data, index, 1);      }      --this.size;      return true;    }    /**     * Gets the list cache value for `key`.     *     * @private     * @name get     * @memberOf ListCache     * @param {string} key The key of the value to get.     * @returns {*} Returns the entry value.     */    function listCacheGet(key) {      var data = this.__data__,          index = assocIndexOf(data, key);      return index < 0 ? undefined : data[index][1];    }    /**     * Checks if a list cache value for `key` exists.     *     * @private     * @name has     * @memberOf ListCache     * @param {string} key The key of the entry to check.     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.     */    function listCacheHas(key) {      return assocIndexOf(this.__data__, key) > -1;    }    /**     * Sets the list cache `key` to `value`.     *     * @private     * @name set     * @memberOf ListCache     * @param {string} key The key of the value to set.     * @param {*} value The value to set.     * @returns {Object} Returns the list cache instance.     */    function listCacheSet(key, value) {      var data = this.__data__,          index = assocIndexOf(data, key);      if (index < 0) {        ++this.size;        data.push([key, value]);      } else {        data[index][1] = value;      }      return this;    }    // Add methods to `ListCache`.    ListCache.prototype.clear = listCacheClear;    ListCache.prototype['delete'] = listCacheDelete;    ListCache.prototype.get = listCacheGet;    ListCache.prototype.has = listCacheHas;    ListCache.prototype.set = listCacheSet;    /*------------------------------------------------------------------------*/    /**     * Creates a map cache object to store key-value pairs.     *     * @private     * @constructor     * @param {Array} [entries] The key-value pairs to cache.     */    function MapCache(entries) {      var index = -1,          length = entries == null ? 0 : entries.length;      this.clear();      while (++index < length) {        var entry = entries[index];        this.set(entry[0], entry[1]);      }    }    /**     * Removes all key-value entries from the map.     *     * @private     * @name clear     * @memberOf MapCache     */    function mapCacheClear() {      this.size = 0;      this.__data__ = {        'hash': new Hash,        'map': new (Map || ListCache),        'string': new Hash      };    }    /**     * Removes `key` and its value from the map.     *     * @private     * @name delete     * @memberOf MapCache     * @param {string} key The key of the value to remove.     * @returns {boolean} Returns `true` if the entry was removed, else `false`.     */    function mapCacheDelete(key) {      var result = getMapData(this, key)['delete'](key);      this.size -= result ? 1 : 0;      return result;    }    /**     * Gets the map value for `key`.     *     * @private     * @name get     * @memberOf MapCache     * @param {string} key The key of the value to get.     * @returns {*} Returns the entry value.     */    function mapCacheGet(key) {      return getMapData(this, key).get(key);    }    /**     * Checks if a map value for `key` exists.     *     * @private     * @name has     * @memberOf MapCache     * @param {string} key The key of the entry to check.     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.     */    function mapCacheHas(key) {      return getMapData(this, key).has(key);    }    /**     * Sets the map `key` to `value`.     *     * @private     * @name set     * @memberOf MapCache     * @param {string} key The key of the value to set.     * @param {*} value The value to set.     * @returns {Object} Returns the map cache instance.     */    function mapCacheSet(key, value) {      var data = getMapData(this, key),          size = data.size;      data.set(key, value);      this.size += data.size == size ? 0 : 1;      return this;    }    // Add methods to `MapCache`.    MapCache.prototype.clear = mapCacheClear;    MapCache.prototype['delete'] = mapCacheDelete;    MapCache.prototype.get = mapCacheGet;    MapCache.prototype.has = mapCacheHas;    MapCache.prototype.set = mapCacheSet;    /*------------------------------------------------------------------------*/    /**     *     * Creates an array cache object to store unique values.     *     * @private     * @constructor     * @param {Array} [values] The values to cache.     */    function SetCache(values) {      var index = -1,          length = values == null ? 0 : values.length;      this.__data__ = new MapCache;      while (++index < length) {        this.add(values[index]);      }    }    /**     * Adds `value` to the array cache.     *     * @private     * @name add     * @memberOf SetCache     * @alias push     * @param {*} value The value to cache.     * @returns {Object} Returns the cache instance.     */    function setCacheAdd(value) {      this.__data__.set(value, HASH_UNDEFINED);      return this;    }    /**     * Checks if `value` is in the array cache.     *     * @private     * @name has     * @memberOf SetCache     * @param {*} value The value to search for.     * @returns {number} Returns `true` if `value` is found, else `false`.     */    function setCacheHas(value) {      return this.__data__.has(value);    }    // Add methods to `SetCache`.    SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;    SetCache.prototype.has = setCacheHas;    /*------------------------------------------------------------------------*/    /**     * Creates a stack cache object to store key-value pairs.     *     * @private     * @constructor     * @param {Array} [entries] The key-value pairs to cache.     */    function Stack(entries) {      var data = this.__data__ = new ListCache(entries);      this.size = data.size;    }    /**     * Removes all key-value entries from the stack.     *     * @private     * @name clear     * @memberOf Stack     */    function stackClear() {      this.__data__ = new ListCache;      this.size = 0;    }    /**     * Removes `key` and its value from the stack.     *     * @private     * @name delete     * @memberOf Stack     * @param {string} key The key of the value to remove.     * @returns {boolean} Returns `true` if the entry was removed, else `false`.     */    function stackDelete(key) {      var data = this.__data__,          result = data['delete'](key);      this.size = data.size;      return result;    }    /**     * Gets the stack value for `key`.     *     * @private     * @name get     * @memberOf Stack     * @param {string} key The key of the value to get.     * @returns {*} Returns the entry value.     */    function stackGet(key) {      return this.__data__.get(key);    }    /**     * Checks if a stack value for `key` exists.     *     * @private     * @name has     * @memberOf Stack     * @param {string} key The key of the entry to check.     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.     */    function stackHas(key) {      return this.__data__.has(key);    }    /**     * Sets the stack `key` to `value`.     *     * @private     * @name set     * @memberOf Stack     * @param {string} key The key of the value to set.     * @param {*} value The value to set.     * @returns {Object} Returns the stack cache instance.     */    function stackSet(key, value) {      var data = this.__data__;      if (data instanceof ListCache) {        var pairs = data.__data__;        if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {          pairs.push([key, value]);          this.size = ++data.size;          return this;        }        data = this.__data__ = new MapCache(pairs);      }      data.set(key, value);      this.size = data.size;      return this;    }    // Add methods to `Stack`.    Stack.prototype.clear = stackClear;    Stack.prototype['delete'] = stackDelete;    Stack.prototype.get = stackGet;    Stack.prototype.has = stackHas;    Stack.prototype.set = stackSet;    /*------------------------------------------------------------------------*/    /**     * Creates an array of the enumerable property names of the array-like `value`.     *     * @private     * @param {*} value The value to query.     * @param {boolean} inherited Specify returning inherited property names.     * @returns {Array} Returns the array of property names.     */    function arrayLikeKeys(value, inherited) {      var isArr = isArray(value),          isArg = !isArr && isArguments(value),          isBuff = !isArr && !isArg && isBuffer(value),          isType = !isArr && !isArg && !isBuff && isTypedArray(value),          skipIndexes = isArr || isArg || isBuff || isType,          result = skipIndexes ? baseTimes(value.length, String) : [],          length = result.length;      for (var key in value) {        if ((inherited || hasOwnProperty.call(value, key)) &&            !(skipIndexes && (               // Safari 9 has enumerable `arguments.length` in strict mode.               key == 'length' ||               // Node.js 0.10 has enumerable non-index properties on buffers.               (isBuff && (key == 'offset' || key == 'parent')) ||               // PhantomJS 2 has enumerable non-index properties on typed arrays.               (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||               // Skip index properties.               isIndex(key, length)            ))) {          result.push(key);        }      }      return result;    }    /**     * A specialized version of `_.sample` for arrays.     *     * @private     * @param {Array} array The array to sample.     * @returns {*} Returns the random element.     */    function arraySample(array) {      var length = array.length;      return length ? array[baseRandom(0, length - 1)] : undefined;    }    /**     * A specialized version of `_.sampleSize` for arrays.     *     * @private     * @param {Array} array The array to sample.     * @param {number} n The number of elements to sample.     * @returns {Array} Returns the random elements.     */    function arraySampleSize(array, n) {      return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));    }    /**     * A specialized version of `_.shuffle` for arrays.     *     * @private     * @param {Array} array The array to shuffle.     * @returns {Array} Returns the new shuffled array.     */    function arrayShuffle(array) {      return shuffleSelf(copyArray(array));    }    /**     * This function is like `assignValue` except that it doesn't assign     * `undefined` values.     *     * @private     * @param {Object} object The object to modify.     * @param {string} key The key of the property to assign.     * @param {*} value The value to assign.     */    function assignMergeValue(object, key, value) {      if ((value !== undefined && !eq(object[key], value)) ||          (value === undefined && !(key in object))) {        baseAssignValue(object, key, value);      }    }    /**     * Assigns `value` to `key` of `object` if the existing value is not equivalent     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)     * for equality comparisons.     *     * @private     * @param {Object} object The object to modify.     * @param {string} key The key of the property to assign.     * @param {*} value The value to assign.     */    function assignValue(object, key, value) {      var objValue = object[key];      if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||          (value === undefined && !(key in object))) {        baseAssignValue(object, key, value);      }    }    /**     * Gets the index at which the `key` is found in `array` of key-value pairs.     *     * @private     * @param {Array} array The array to inspect.     * @param {*} key The key to search for.     * @returns {number} Returns the index of the matched value, else `-1`.     */    function assocIndexOf(array, key) {      var length = array.length;      while (length--) {        if (eq(array[length][0], key)) {          return length;        }      }      return -1;    }    /**     * Aggregates elements of `collection` on `accumulator` with keys transformed     * by `iteratee` and values set by `setter`.     *     * @private     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} setter The function to set `accumulator` values.     * @param {Function} iteratee The iteratee to transform keys.     * @param {Object} accumulator The initial aggregated object.     * @returns {Function} Returns `accumulator`.     */    function baseAggregator(collection, setter, iteratee, accumulator) {      baseEach(collection, function(value, key, collection) {        setter(accumulator, value, iteratee(value), collection);      });      return accumulator;    }    /**     * The base implementation of `_.assign` without support for multiple sources     * or `customizer` functions.     *     * @private     * @param {Object} object The destination object.     * @param {Object} source The source object.     * @returns {Object} Returns `object`.     */    function baseAssign(object, source) {      return object && copyObject(source, keys(source), object);    }    /**     * The base implementation of `_.assignIn` without support for multiple sources     * or `customizer` functions.     *     * @private     * @param {Object} object The destination object.     * @param {Object} source The source object.     * @returns {Object} Returns `object`.     */    function baseAssignIn(object, source) {      return object && copyObject(source, keysIn(source), object);    }    /**     * The base implementation of `assignValue` and `assignMergeValue` without     * value checks.     *     * @private     * @param {Object} object The object to modify.     * @param {string} key The key of the property to assign.     * @param {*} value The value to assign.     */    function baseAssignValue(object, key, value) {      if (key == '__proto__' && defineProperty) {        defineProperty(object, key, {          'configurable': true,          'enumerable': true,          'value': value,          'writable': true        });      } else {        object[key] = value;      }    }    /**     * The base implementation of `_.at` without support for individual paths.     *     * @private     * @param {Object} object The object to iterate over.     * @param {string[]} paths The property paths to pick.     * @returns {Array} Returns the picked elements.     */    function baseAt(object, paths) {      var index = -1,          length = paths.length,          result = Array(length),          skip = object == null;      while (++index < length) {        result[index] = skip ? undefined : get(object, paths[index]);      }      return result;    }    /**     * The base implementation of `_.clamp` which doesn't coerce arguments.     *     * @private     * @param {number} number The number to clamp.     * @param {number} [lower] The lower bound.     * @param {number} upper The upper bound.     * @returns {number} Returns the clamped number.     */    function baseClamp(number, lower, upper) {      if (number === number) {        if (upper !== undefined) {          number = number <= upper ? number : upper;        }        if (lower !== undefined) {          number = number >= lower ? number : lower;        }      }      return number;    }    /**     * The base implementation of `_.clone` and `_.cloneDeep` which tracks     * traversed objects.     *     * @private     * @param {*} value The value to clone.     * @param {boolean} bitmask The bitmask flags.     *  1 - Deep clone     *  2 - Flatten inherited properties     *  4 - Clone symbols     * @param {Function} [customizer] The function to customize cloning.     * @param {string} [key] The key of `value`.     * @param {Object} [object] The parent object of `value`.     * @param {Object} [stack] Tracks traversed objects and their clone counterparts.     * @returns {*} Returns the cloned value.     */    function baseClone(value, bitmask, customizer, key, object, stack) {      var result,          isDeep = bitmask & CLONE_DEEP_FLAG,          isFlat = bitmask & CLONE_FLAT_FLAG,          isFull = bitmask & CLONE_SYMBOLS_FLAG;      if (customizer) {        result = object ? customizer(value, key, object, stack) : customizer(value);      }      if (result !== undefined) {        return result;      }      if (!isObject(value)) {        return value;      }      var isArr = isArray(value);      if (isArr) {        result = initCloneArray(value);        if (!isDeep) {          return copyArray(value, result);        }      } else {        var tag = getTag(value),            isFunc = tag == funcTag || tag == genTag;        if (isBuffer(value)) {          return cloneBuffer(value, isDeep);        }        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {          result = (isFlat || isFunc) ? {} : initCloneObject(value);          if (!isDeep) {            return isFlat              ? copySymbolsIn(value, baseAssignIn(result, value))              : copySymbols(value, baseAssign(result, value));          }        } else {          if (!cloneableTags[tag]) {            return object ? value : {};          }          result = initCloneByTag(value, tag, isDeep);        }      }      // Check for circular references and return its corresponding clone.      stack || (stack = new Stack);      var stacked = stack.get(value);      if (stacked) {        return stacked;      }      stack.set(value, result);      if (isSet(value)) {        value.forEach(function(subValue) {          result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));        });        return result;      }      if (isMap(value)) {        value.forEach(function(subValue, key) {          result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));        });        return result;      }      var keysFunc = isFull        ? (isFlat ? getAllKeysIn : getAllKeys)        : (isFlat ? keysIn : keys);      var props = isArr ? undefined : keysFunc(value);      arrayEach(props || value, function(subValue, key) {        if (props) {          key = subValue;          subValue = value[key];        }        // Recursively populate clone (susceptible to call stack limits).        assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));      });      return result;    }    /**     * The base implementation of `_.conforms` which doesn't clone `source`.     *     * @private     * @param {Object} source The object of property predicates to conform to.     * @returns {Function} Returns the new spec function.     */    function baseConforms(source) {      var props = keys(source);      return function(object) {        return baseConformsTo(object, source, props);      };    }    /**     * The base implementation of `_.conformsTo` which accepts `props` to check.     *     * @private     * @param {Object} object The object to inspect.     * @param {Object} source The object of property predicates to conform to.     * @returns {boolean} Returns `true` if `object` conforms, else `false`.     */    function baseConformsTo(object, source, props) {      var length = props.length;      if (object == null) {        return !length;      }      object = Object(object);      while (length--) {        var key = props[length],            predicate = source[key],            value = object[key];        if ((value === undefined && !(key in object)) || !predicate(value)) {          return false;        }      }      return true;    }    /**     * The base implementation of `_.delay` and `_.defer` which accepts `args`     * to provide to `func`.     *     * @private     * @param {Function} func The function to delay.     * @param {number} wait The number of milliseconds to delay invocation.     * @param {Array} args The arguments to provide to `func`.     * @returns {number|Object} Returns the timer id or timeout object.     */    function baseDelay(func, wait, args) {      if (typeof func != 'function') {        throw new TypeError(FUNC_ERROR_TEXT);      }      return setTimeout(function() { func.apply(undefined, args); }, wait);    }    /**     * The base implementation of methods like `_.difference` without support     * for excluding multiple arrays or iteratee shorthands.     *     * @private     * @param {Array} array The array to inspect.     * @param {Array} values The values to exclude.     * @param {Function} [iteratee] The iteratee invoked per element.     * @param {Function} [comparator] The comparator invoked per element.     * @returns {Array} Returns the new array of filtered values.     */    function baseDifference(array, values, iteratee, comparator) {      var index = -1,          includes = arrayIncludes,          isCommon = true,          length = array.length,          result = [],          valuesLength = values.length;      if (!length) {        return result;      }      if (iteratee) {        values = arrayMap(values, baseUnary(iteratee));      }      if (comparator) {        includes = arrayIncludesWith;        isCommon = false;      }      else if (values.length >= LARGE_ARRAY_SIZE) {        includes = cacheHas;        isCommon = false;        values = new SetCache(values);      }      outer:      while (++index < length) {        var value = array[index],            computed = iteratee == null ? value : iteratee(value);        value = (comparator || value !== 0) ? value : 0;        if (isCommon && computed === computed) {          var valuesIndex = valuesLength;          while (valuesIndex--) {            if (values[valuesIndex] === computed) {              continue outer;            }          }          result.push(value);        }        else if (!includes(values, computed, comparator)) {          result.push(value);        }      }      return result;    }    /**     * The base implementation of `_.forEach` without support for iteratee shorthands.     *     * @private     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @returns {Array|Object} Returns `collection`.     */    var baseEach = createBaseEach(baseForOwn);    /**     * The base implementation of `_.forEachRight` without support for iteratee shorthands.     *     * @private     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @returns {Array|Object} Returns `collection`.     */    var baseEachRight = createBaseEach(baseForOwnRight, true);    /**     * The base implementation of `_.every` without support for iteratee shorthands.     *     * @private     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} predicate The function invoked per iteration.     * @returns {boolean} Returns `true` if all elements pass the predicate check,     *  else `false`     */    function baseEvery(collection, predicate) {      var result = true;      baseEach(collection, function(value, index, collection) {        result = !!predicate(value, index, collection);        return result;      });      return result;    }    /**     * The base implementation of methods like `_.max` and `_.min` which accepts a     * `comparator` to determine the extremum value.     *     * @private     * @param {Array} array The array to iterate over.     * @param {Function} iteratee The iteratee invoked per iteration.     * @param {Function} comparator The comparator used to compare values.     * @returns {*} Returns the extremum value.     */    function baseExtremum(array, iteratee, comparator) {      var index = -1,          length = array.length;      while (++index < length) {        var value = array[index],            current = iteratee(value);        if (current != null && (computed === undefined              ? (current === current && !isSymbol(current))              : comparator(current, computed)            )) {          var computed = current,              result = value;        }      }      return result;    }    /**     * The base implementation of `_.fill` without an iteratee call guard.     *     * @private     * @param {Array} array The array to fill.     * @param {*} value The value to fill `array` with.     * @param {number} [start=0] The start position.     * @param {number} [end=array.length] The end position.     * @returns {Array} Returns `array`.     */    function baseFill(array, value, start, end) {      var length = array.length;      start = toInteger(start);      if (start < 0) {        start = -start > length ? 0 : (length + start);      }      end = (end === undefined || end > length) ? length : toInteger(end);      if (end < 0) {        end += length;      }      end = start > end ? 0 : toLength(end);      while (start < end) {        array[start++] = value;      }      return array;    }    /**     * The base implementation of `_.filter` without support for iteratee shorthands.     *     * @private     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} predicate The function invoked per iteration.     * @returns {Array} Returns the new filtered array.     */    function baseFilter(collection, predicate) {      var result = [];      baseEach(collection, function(value, index, collection) {        if (predicate(value, index, collection)) {          result.push(value);        }      });      return result;    }    /**     * The base implementation of `_.flatten` with support for restricting flattening.     *     * @private     * @param {Array} array The array to flatten.     * @param {number} depth The maximum recursion depth.     * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.     * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.     * @param {Array} [result=[]] The initial result value.     * @returns {Array} Returns the new flattened array.     */    function baseFlatten(array, depth, predicate, isStrict, result) {      var index = -1,          length = array.length;      predicate || (predicate = isFlattenable);      result || (result = []);      while (++index < length) {        var value = array[index];        if (depth > 0 && predicate(value)) {          if (depth > 1) {            // Recursively flatten arrays (susceptible to call stack limits).            baseFlatten(value, depth - 1, predicate, isStrict, result);          } else {            arrayPush(result, value);          }        } else if (!isStrict) {          result[result.length] = value;        }      }      return result;    }    /**     * The base implementation of `baseForOwn` which iterates over `object`     * properties returned by `keysFunc` and invokes `iteratee` for each property.     * Iteratee functions may exit iteration early by explicitly returning `false`.     *     * @private     * @param {Object} object The object to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @param {Function} keysFunc The function to get the keys of `object`.     * @returns {Object} Returns `object`.     */    var baseFor = createBaseFor();    /**     * This function is like `baseFor` except that it iterates over properties     * in the opposite order.     *     * @private     * @param {Object} object The object to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @param {Function} keysFunc The function to get the keys of `object`.     * @returns {Object} Returns `object`.     */    var baseForRight = createBaseFor(true);    /**     * The base implementation of `_.forOwn` without support for iteratee shorthands.     *     * @private     * @param {Object} object The object to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @returns {Object} Returns `object`.     */    function baseForOwn(object, iteratee) {      return object && baseFor(object, iteratee, keys);    }    /**     * The base implementation of `_.forOwnRight` without support for iteratee shorthands.     *     * @private     * @param {Object} object The object to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @returns {Object} Returns `object`.     */    function baseForOwnRight(object, iteratee) {      return object && baseForRight(object, iteratee, keys);    }    /**     * The base implementation of `_.functions` which creates an array of     * `object` function property names filtered from `props`.     *     * @private     * @param {Object} object The object to inspect.     * @param {Array} props The property names to filter.     * @returns {Array} Returns the function names.     */    function baseFunctions(object, props) {      return arrayFilter(props, function(key) {        return isFunction(object[key]);      });    }    /**     * The base implementation of `_.get` without support for default values.     *     * @private     * @param {Object} object The object to query.     * @param {Array|string} path The path of the property to get.     * @returns {*} Returns the resolved value.     */    function baseGet(object, path) {      path = castPath(path, object);      var index = 0,          length = path.length;      while (object != null && index < length) {        object = object[toKey(path[index++])];      }      return (index && index == length) ? object : undefined;    }    /**     * The base implementation of `getAllKeys` and `getAllKeysIn` which uses     * `keysFunc` and `symbolsFunc` to get the enumerable property names and     * symbols of `object`.     *     * @private     * @param {Object} object The object to query.     * @param {Function} keysFunc The function to get the keys of `object`.     * @param {Function} symbolsFunc The function to get the symbols of `object`.     * @returns {Array} Returns the array of property names and symbols.     */    function baseGetAllKeys(object, keysFunc, symbolsFunc) {      var result = keysFunc(object);      return isArray(object) ? result : arrayPush(result, symbolsFunc(object));    }    /**     * The base implementation of `getTag` without fallbacks for buggy environments.     *     * @private     * @param {*} value The value to query.     * @returns {string} Returns the `toStringTag`.     */    function baseGetTag(value) {      if (value == null) {        return value === undefined ? undefinedTag : nullTag;      }      return (symToStringTag && symToStringTag in Object(value))        ? getRawTag(value)        : objectToString(value);    }    /**     * The base implementation of `_.gt` which doesn't coerce arguments.     *     * @private     * @param {*} value The value to compare.     * @param {*} other The other value to compare.     * @returns {boolean} Returns `true` if `value` is greater than `other`,     *  else `false`.     */    function baseGt(value, other) {      return value > other;    }    /**     * The base implementation of `_.has` without support for deep paths.     *     * @private     * @param {Object} [object] The object to query.     * @param {Array|string} key The key to check.     * @returns {boolean} Returns `true` if `key` exists, else `false`.     */    function baseHas(object, key) {      return object != null && hasOwnProperty.call(object, key);    }    /**     * The base implementation of `_.hasIn` without support for deep paths.     *     * @private     * @param {Object} [object] The object to query.     * @param {Array|string} key The key to check.     * @returns {boolean} Returns `true` if `key` exists, else `false`.     */    function baseHasIn(object, key) {      return object != null && key in Object(object);    }    /**     * The base implementation of `_.inRange` which doesn't coerce arguments.     *     * @private     * @param {number} number The number to check.     * @param {number} start The start of the range.     * @param {number} end The end of the range.     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.     */    function baseInRange(number, start, end) {      return number >= nativeMin(start, end) && number < nativeMax(start, end);    }    /**     * The base implementation of methods like `_.intersection`, without support     * for iteratee shorthands, that accepts an array of arrays to inspect.     *     * @private     * @param {Array} arrays The arrays to inspect.     * @param {Function} [iteratee] The iteratee invoked per element.     * @param {Function} [comparator] The comparator invoked per element.     * @returns {Array} Returns the new array of shared values.     */    function baseIntersection(arrays, iteratee, comparator) {      var includes = comparator ? arrayIncludesWith : arrayIncludes,          length = arrays[0].length,          othLength = arrays.length,          othIndex = othLength,          caches = Array(othLength),          maxLength = Infinity,          result = [];      while (othIndex--) {        var array = arrays[othIndex];        if (othIndex && iteratee) {          array = arrayMap(array, baseUnary(iteratee));        }        maxLength = nativeMin(array.length, maxLength);        caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))          ? new SetCache(othIndex && array)          : undefined;      }      array = arrays[0];      var index = -1,          seen = caches[0];      outer:      while (++index < length && result.length < maxLength) {        var value = array[index],            computed = iteratee ? iteratee(value) : value;        value = (comparator || value !== 0) ? value : 0;        if (!(seen              ? cacheHas(seen, computed)              : includes(result, computed, comparator)            )) {          othIndex = othLength;          while (--othIndex) {            var cache = caches[othIndex];            if (!(cache                  ? cacheHas(cache, computed)                  : includes(arrays[othIndex], computed, comparator))                ) {              continue outer;            }          }          if (seen) {            seen.push(computed);          }          result.push(value);        }      }      return result;    }    /**     * The base implementation of `_.invert` and `_.invertBy` which inverts     * `object` with values transformed by `iteratee` and set by `setter`.     *     * @private     * @param {Object} object The object to iterate over.     * @param {Function} setter The function to set `accumulator` values.     * @param {Function} iteratee The iteratee to transform values.     * @param {Object} accumulator The initial inverted object.     * @returns {Function} Returns `accumulator`.     */    function baseInverter(object, setter, iteratee, accumulator) {      baseForOwn(object, function(value, key, object) {        setter(accumulator, iteratee(value), key, object);      });      return accumulator;    }    /**     * The base implementation of `_.invoke` without support for individual     * method arguments.     *     * @private     * @param {Object} object The object to query.     * @param {Array|string} path The path of the method to invoke.     * @param {Array} args The arguments to invoke the method with.     * @returns {*} Returns the result of the invoked method.     */    function baseInvoke(object, path, args) {      path = castPath(path, object);      object = parent(object, path);      var func = object == null ? object : object[toKey(last(path))];      return func == null ? undefined : apply(func, object, args);    }    /**     * The base implementation of `_.isArguments`.     *     * @private     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is an `arguments` object,     */    function baseIsArguments(value) {      return isObjectLike(value) && baseGetTag(value) == argsTag;    }    /**     * The base implementation of `_.isArrayBuffer` without Node.js optimizations.     *     * @private     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.     */    function baseIsArrayBuffer(value) {      return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;    }    /**     * The base implementation of `_.isDate` without Node.js optimizations.     *     * @private     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.     */    function baseIsDate(value) {      return isObjectLike(value) && baseGetTag(value) == dateTag;    }    /**     * The base implementation of `_.isEqual` which supports partial comparisons     * and tracks traversed objects.     *     * @private     * @param {*} value The value to compare.     * @param {*} other The other value to compare.     * @param {boolean} bitmask The bitmask flags.     *  1 - Unordered comparison     *  2 - Partial comparison     * @param {Function} [customizer] The function to customize comparisons.     * @param {Object} [stack] Tracks traversed `value` and `other` objects.     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.     */    function baseIsEqual(value, other, bitmask, customizer, stack) {      if (value === other) {        return true;      }      if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {        return value !== value && other !== other;      }      return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);    }    /**     * A specialized version of `baseIsEqual` for arrays and objects which performs     * deep comparisons and tracks traversed objects enabling objects with circular     * references to be compared.     *     * @private     * @param {Object} object The object to compare.     * @param {Object} other The other object to compare.     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.     * @param {Function} customizer The function to customize comparisons.     * @param {Function} equalFunc The function to determine equivalents of values.     * @param {Object} [stack] Tracks traversed `object` and `other` objects.     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.     */    function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {      var objIsArr = isArray(object),          othIsArr = isArray(other),          objTag = objIsArr ? arrayTag : getTag(object),          othTag = othIsArr ? arrayTag : getTag(other);      objTag = objTag == argsTag ? objectTag : objTag;      othTag = othTag == argsTag ? objectTag : othTag;      var objIsObj = objTag == objectTag,          othIsObj = othTag == objectTag,          isSameTag = objTag == othTag;      if (isSameTag && isBuffer(object)) {        if (!isBuffer(other)) {          return false;        }        objIsArr = true;        objIsObj = false;      }      if (isSameTag && !objIsObj) {        stack || (stack = new Stack);        return (objIsArr || isTypedArray(object))          ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)          : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);      }      if (!(bitmask & COMPARE_PARTIAL_FLAG)) {        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');        if (objIsWrapped || othIsWrapped) {          var objUnwrapped = objIsWrapped ? object.value() : object,              othUnwrapped = othIsWrapped ? other.value() : other;          stack || (stack = new Stack);          return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);        }      }      if (!isSameTag) {        return false;      }      stack || (stack = new Stack);      return equalObjects(object, other, bitmask, customizer, equalFunc, stack);    }    /**     * The base implementation of `_.isMap` without Node.js optimizations.     *     * @private     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a map, else `false`.     */    function baseIsMap(value) {      return isObjectLike(value) && getTag(value) == mapTag;    }    /**     * The base implementation of `_.isMatch` without support for iteratee shorthands.     *     * @private     * @param {Object} object The object to inspect.     * @param {Object} source The object of property values to match.     * @param {Array} matchData The property names, values, and compare flags to match.     * @param {Function} [customizer] The function to customize comparisons.     * @returns {boolean} Returns `true` if `object` is a match, else `false`.     */    function baseIsMatch(object, source, matchData, customizer) {      var index = matchData.length,          length = index,          noCustomizer = !customizer;      if (object == null) {        return !length;      }      object = Object(object);      while (index--) {        var data = matchData[index];        if ((noCustomizer && data[2])              ? data[1] !== object[data[0]]              : !(data[0] in object)            ) {          return false;        }      }      while (++index < length) {        data = matchData[index];        var key = data[0],            objValue = object[key],            srcValue = data[1];        if (noCustomizer && data[2]) {          if (objValue === undefined && !(key in object)) {            return false;          }        } else {          var stack = new Stack;          if (customizer) {            var result = customizer(objValue, srcValue, key, object, source, stack);          }          if (!(result === undefined                ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)                : result              )) {            return false;          }        }      }      return true;    }    /**     * The base implementation of `_.isNative` without bad shim checks.     *     * @private     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a native function,     *  else `false`.     */    function baseIsNative(value) {      if (!isObject(value) || isMasked(value)) {        return false;      }      var pattern = isFunction(value) ? reIsNative : reIsHostCtor;      return pattern.test(toSource(value));    }    /**     * The base implementation of `_.isRegExp` without Node.js optimizations.     *     * @private     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.     */    function baseIsRegExp(value) {      return isObjectLike(value) && baseGetTag(value) == regexpTag;    }    /**     * The base implementation of `_.isSet` without Node.js optimizations.     *     * @private     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a set, else `false`.     */    function baseIsSet(value) {      return isObjectLike(value) && getTag(value) == setTag;    }    /**     * The base implementation of `_.isTypedArray` without Node.js optimizations.     *     * @private     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.     */    function baseIsTypedArray(value) {      return isObjectLike(value) &&        isLength(value.length) && !!typedArrayTags[baseGetTag(value)];    }    /**     * The base implementation of `_.iteratee`.     *     * @private     * @param {*} [value=_.identity] The value to convert to an iteratee.     * @returns {Function} Returns the iteratee.     */    function baseIteratee(value) {      // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.      // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.      if (typeof value == 'function') {        return value;      }      if (value == null) {        return identity;      }      if (typeof value == 'object') {        return isArray(value)          ? baseMatchesProperty(value[0], value[1])          : baseMatches(value);      }      return property(value);    }    /**     * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.     *     * @private     * @param {Object} object The object to query.     * @returns {Array} Returns the array of property names.     */    function baseKeys(object) {      if (!isPrototype(object)) {        return nativeKeys(object);      }      var result = [];      for (var key in Object(object)) {        if (hasOwnProperty.call(object, key) && key != 'constructor') {          result.push(key);        }      }      return result;    }    /**     * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.     *     * @private     * @param {Object} object The object to query.     * @returns {Array} Returns the array of property names.     */    function baseKeysIn(object) {      if (!isObject(object)) {        return nativeKeysIn(object);      }      var isProto = isPrototype(object),          result = [];      for (var key in object) {        if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {          result.push(key);        }      }      return result;    }    /**     * The base implementation of `_.lt` which doesn't coerce arguments.     *     * @private     * @param {*} value The value to compare.     * @param {*} other The other value to compare.     * @returns {boolean} Returns `true` if `value` is less than `other`,     *  else `false`.     */    function baseLt(value, other) {      return value < other;    }    /**     * The base implementation of `_.map` without support for iteratee shorthands.     *     * @private     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} iteratee The function invoked per iteration.     * @returns {Array} Returns the new mapped array.     */    function baseMap(collection, iteratee) {      var index = -1,          result = isArrayLike(collection) ? Array(collection.length) : [];      baseEach(collection, function(value, key, collection) {        result[++index] = iteratee(value, key, collection);      });      return result;    }    /**     * The base implementation of `_.matches` which doesn't clone `source`.     *     * @private     * @param {Object} source The object of property values to match.     * @returns {Function} Returns the new spec function.     */    function baseMatches(source) {      var matchData = getMatchData(source);      if (matchData.length == 1 && matchData[0][2]) {        return matchesStrictComparable(matchData[0][0], matchData[0][1]);      }      return function(object) {        return object === source || baseIsMatch(object, source, matchData);      };    }    /**     * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.     *     * @private     * @param {string} path The path of the property to get.     * @param {*} srcValue The value to match.     * @returns {Function} Returns the new spec function.     */    function baseMatchesProperty(path, srcValue) {      if (isKey(path) && isStrictComparable(srcValue)) {        return matchesStrictComparable(toKey(path), srcValue);      }      return function(object) {        var objValue = get(object, path);        return (objValue === undefined && objValue === srcValue)          ? hasIn(object, path)          : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);      };    }    /**     * The base implementation of `_.merge` without support for multiple sources.     *     * @private     * @param {Object} object The destination object.     * @param {Object} source The source object.     * @param {number} srcIndex The index of `source`.     * @param {Function} [customizer] The function to customize merged values.     * @param {Object} [stack] Tracks traversed source values and their merged     *  counterparts.     */    function baseMerge(object, source, srcIndex, customizer, stack) {      if (object === source) {        return;      }      baseFor(source, function(srcValue, key) {        if (isObject(srcValue)) {          stack || (stack = new Stack);          baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);        }        else {          var newValue = customizer            ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)            : undefined;          if (newValue === undefined) {            newValue = srcValue;          }          assignMergeValue(object, key, newValue);        }      }, keysIn);    }    /**     * A specialized version of `baseMerge` for arrays and objects which performs     * deep merges and tracks traversed objects enabling objects with circular     * references to be merged.     *     * @private     * @param {Object} object The destination object.     * @param {Object} source The source object.     * @param {string} key The key of the value to merge.     * @param {number} srcIndex The index of `source`.     * @param {Function} mergeFunc The function to merge values.     * @param {Function} [customizer] The function to customize assigned values.     * @param {Object} [stack] Tracks traversed source values and their merged     *  counterparts.     */    function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {      var objValue = safeGet(object, key),          srcValue = safeGet(source, key),          stacked = stack.get(srcValue);      if (stacked) {        assignMergeValue(object, key, stacked);        return;      }      var newValue = customizer        ? customizer(objValue, srcValue, (key + ''), object, source, stack)        : undefined;      var isCommon = newValue === undefined;      if (isCommon) {        var isArr = isArray(srcValue),            isBuff = !isArr && isBuffer(srcValue),            isTyped = !isArr && !isBuff && isTypedArray(srcValue);        newValue = srcValue;        if (isArr || isBuff || isTyped) {          if (isArray(objValue)) {            newValue = objValue;          }          else if (isArrayLikeObject(objValue)) {            newValue = copyArray(objValue);          }          else if (isBuff) {            isCommon = false;            newValue = cloneBuffer(srcValue, true);          }          else if (isTyped) {            isCommon = false;            newValue = cloneTypedArray(srcValue, true);          }          else {            newValue = [];          }        }        else if (isPlainObject(srcValue) || isArguments(srcValue)) {          newValue = objValue;          if (isArguments(objValue)) {            newValue = toPlainObject(objValue);          }          else if (!isObject(objValue) || isFunction(objValue)) {            newValue = initCloneObject(srcValue);          }        }        else {          isCommon = false;        }      }      if (isCommon) {        // Recursively merge objects and arrays (susceptible to call stack limits).        stack.set(srcValue, newValue);        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);        stack['delete'](srcValue);      }      assignMergeValue(object, key, newValue);    }    /**     * The base implementation of `_.nth` which doesn't coerce arguments.     *     * @private     * @param {Array} array The array to query.     * @param {number} n The index of the element to return.     * @returns {*} Returns the nth element of `array`.     */    function baseNth(array, n) {      var length = array.length;      if (!length) {        return;      }      n += n < 0 ? length : 0;      return isIndex(n, length) ? array[n] : undefined;    }    /**     * The base implementation of `_.orderBy` without param guards.     *     * @private     * @param {Array|Object} collection The collection to iterate over.     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.     * @param {string[]} orders The sort orders of `iteratees`.     * @returns {Array} Returns the new sorted array.     */    function baseOrderBy(collection, iteratees, orders) {      var index = -1;      iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));      var result = baseMap(collection, function(value, key, collection) {        var criteria = arrayMap(iteratees, function(iteratee) {          return iteratee(value);        });        return { 'criteria': criteria, 'index': ++index, 'value': value };      });      return baseSortBy(result, function(object, other) {        return compareMultiple(object, other, orders);      });    }    /**     * The base implementation of `_.pick` without support for individual     * property identifiers.     *     * @private     * @param {Object} object The source object.     * @param {string[]} paths The property paths to pick.     * @returns {Object} Returns the new object.     */    function basePick(object, paths) {      return basePickBy(object, paths, function(value, path) {        return hasIn(object, path);      });    }    /**     * The base implementation of  `_.pickBy` without support for iteratee shorthands.     *     * @private     * @param {Object} object The source object.     * @param {string[]} paths The property paths to pick.     * @param {Function} predicate The function invoked per property.     * @returns {Object} Returns the new object.     */    function basePickBy(object, paths, predicate) {      var index = -1,          length = paths.length,          result = {};      while (++index < length) {        var path = paths[index],            value = baseGet(object, path);        if (predicate(value, path)) {          baseSet(result, castPath(path, object), value);        }      }      return result;    }    /**     * A specialized version of `baseProperty` which supports deep paths.     *     * @private     * @param {Array|string} path The path of the property to get.     * @returns {Function} Returns the new accessor function.     */    function basePropertyDeep(path) {      return function(object) {        return baseGet(object, path);      };    }    /**     * The base implementation of `_.pullAllBy` without support for iteratee     * shorthands.     *     * @private     * @param {Array} array The array to modify.     * @param {Array} values The values to remove.     * @param {Function} [iteratee] The iteratee invoked per element.     * @param {Function} [comparator] The comparator invoked per element.     * @returns {Array} Returns `array`.     */    function basePullAll(array, values, iteratee, comparator) {      var indexOf = comparator ? baseIndexOfWith : baseIndexOf,          index = -1,          length = values.length,          seen = array;      if (array === values) {        values = copyArray(values);      }      if (iteratee) {        seen = arrayMap(array, baseUnary(iteratee));      }      while (++index < length) {        var fromIndex = 0,            value = values[index],            computed = iteratee ? iteratee(value) : value;        while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {          if (seen !== array) {            splice.call(seen, fromIndex, 1);          }          splice.call(array, fromIndex, 1);        }      }      return array;    }    /**     * The base implementation of `_.pullAt` without support for individual     * indexes or capturing the removed elements.     *     * @private     * @param {Array} array The array to modify.     * @param {number[]} indexes The indexes of elements to remove.     * @returns {Array} Returns `array`.     */    function basePullAt(array, indexes) {      var length = array ? indexes.length : 0,          lastIndex = length - 1;      while (length--) {        var index = indexes[length];        if (length == lastIndex || index !== previous) {          var previous = index;          if (isIndex(index)) {            splice.call(array, index, 1);          } else {            baseUnset(array, index);          }        }      }      return array;    }    /**     * The base implementation of `_.random` without support for returning     * floating-point numbers.     *     * @private     * @param {number} lower The lower bound.     * @param {number} upper The upper bound.     * @returns {number} Returns the random number.     */    function baseRandom(lower, upper) {      return lower + nativeFloor(nativeRandom() * (upper - lower + 1));    }    /**     * The base implementation of `_.range` and `_.rangeRight` which doesn't     * coerce arguments.     *     * @private     * @param {number} start The start of the range.     * @param {number} end The end of the range.     * @param {number} step The value to increment or decrement by.     * @param {boolean} [fromRight] Specify iterating from right to left.     * @returns {Array} Returns the range of numbers.     */    function baseRange(start, end, step, fromRight) {      var index = -1,          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),          result = Array(length);      while (length--) {        result[fromRight ? length : ++index] = start;        start += step;      }      return result;    }    /**     * The base implementation of `_.repeat` which doesn't coerce arguments.     *     * @private     * @param {string} string The string to repeat.     * @param {number} n The number of times to repeat the string.     * @returns {string} Returns the repeated string.     */    function baseRepeat(string, n) {      var result = '';      if (!string || n < 1 || n > MAX_SAFE_INTEGER) {        return result;      }      // Leverage the exponentiation by squaring algorithm for a faster repeat.      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.      do {        if (n % 2) {          result += string;        }        n = nativeFloor(n / 2);        if (n) {          string += string;        }      } while (n);      return result;    }    /**     * The base implementation of `_.rest` which doesn't validate or coerce arguments.     *     * @private     * @param {Function} func The function to apply a rest parameter to.     * @param {number} [start=func.length-1] The start position of the rest parameter.     * @returns {Function} Returns the new function.     */    function baseRest(func, start) {      return setToString(overRest(func, start, identity), func + '');    }    /**     * The base implementation of `_.sample`.     *     * @private     * @param {Array|Object} collection The collection to sample.     * @returns {*} Returns the random element.     */    function baseSample(collection) {      return arraySample(values(collection));    }    /**     * The base implementation of `_.sampleSize` without param guards.     *     * @private     * @param {Array|Object} collection The collection to sample.     * @param {number} n The number of elements to sample.     * @returns {Array} Returns the random elements.     */    function baseSampleSize(collection, n) {      var array = values(collection);      return shuffleSelf(array, baseClamp(n, 0, array.length));    }    /**     * The base implementation of `_.set`.     *     * @private     * @param {Object} object The object to modify.     * @param {Array|string} path The path of the property to set.     * @param {*} value The value to set.     * @param {Function} [customizer] The function to customize path creation.     * @returns {Object} Returns `object`.     */    function baseSet(object, path, value, customizer) {      if (!isObject(object)) {        return object;      }      path = castPath(path, object);      var index = -1,          length = path.length,          lastIndex = length - 1,          nested = object;      while (nested != null && ++index < length) {        var key = toKey(path[index]),            newValue = value;        if (index != lastIndex) {          var objValue = nested[key];          newValue = customizer ? customizer(objValue, key, nested) : undefined;          if (newValue === undefined) {            newValue = isObject(objValue)              ? objValue              : (isIndex(path[index + 1]) ? [] : {});          }        }        assignValue(nested, key, newValue);        nested = nested[key];      }      return object;    }    /**     * The base implementation of `setData` without support for hot loop shorting.     *     * @private     * @param {Function} func The function to associate metadata with.     * @param {*} data The metadata.     * @returns {Function} Returns `func`.     */    var baseSetData = !metaMap ? identity : function(func, data) {      metaMap.set(func, data);      return func;    };    /**     * The base implementation of `setToString` without support for hot loop shorting.     *     * @private     * @param {Function} func The function to modify.     * @param {Function} string The `toString` result.     * @returns {Function} Returns `func`.     */    var baseSetToString = !defineProperty ? identity : function(func, string) {      return defineProperty(func, 'toString', {        'configurable': true,        'enumerable': false,        'value': constant(string),        'writable': true      });    };    /**     * The base implementation of `_.shuffle`.     *     * @private     * @param {Array|Object} collection The collection to shuffle.     * @returns {Array} Returns the new shuffled array.     */    function baseShuffle(collection) {      return shuffleSelf(values(collection));    }    /**     * The base implementation of `_.slice` without an iteratee call guard.     *     * @private     * @param {Array} array The array to slice.     * @param {number} [start=0] The start position.     * @param {number} [end=array.length] The end position.     * @returns {Array} Returns the slice of `array`.     */    function baseSlice(array, start, end) {      var index = -1,          length = array.length;      if (start < 0) {        start = -start > length ? 0 : (length + start);      }      end = end > length ? length : end;      if (end < 0) {        end += length;      }      length = start > end ? 0 : ((end - start) >>> 0);      start >>>= 0;      var result = Array(length);      while (++index < length) {        result[index] = array[index + start];      }      return result;    }    /**     * The base implementation of `_.some` without support for iteratee shorthands.     *     * @private     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} predicate The function invoked per iteration.     * @returns {boolean} Returns `true` if any element passes the predicate check,     *  else `false`.     */    function baseSome(collection, predicate) {      var result;      baseEach(collection, function(value, index, collection) {        result = predicate(value, index, collection);        return !result;      });      return !!result;    }    /**     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which     * performs a binary search of `array` to determine the index at which `value`     * should be inserted into `array` in order to maintain its sort order.     *     * @private     * @param {Array} array The sorted array to inspect.     * @param {*} value The value to evaluate.     * @param {boolean} [retHighest] Specify returning the highest qualified index.     * @returns {number} Returns the index at which `value` should be inserted     *  into `array`.     */    function baseSortedIndex(array, value, retHighest) {      var low = 0,          high = array == null ? low : array.length;      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {        while (low < high) {          var mid = (low + high) >>> 1,              computed = array[mid];          if (computed !== null && !isSymbol(computed) &&              (retHighest ? (computed <= value) : (computed < value))) {            low = mid + 1;          } else {            high = mid;          }        }        return high;      }      return baseSortedIndexBy(array, value, identity, retHighest);    }    /**     * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`     * which invokes `iteratee` for `value` and each element of `array` to compute     * their sort ranking. The iteratee is invoked with one argument; (value).     *     * @private     * @param {Array} array The sorted array to inspect.     * @param {*} value The value to evaluate.     * @param {Function} iteratee The iteratee invoked per element.     * @param {boolean} [retHighest] Specify returning the highest qualified index.     * @returns {number} Returns the index at which `value` should be inserted     *  into `array`.     */    function baseSortedIndexBy(array, value, iteratee, retHighest) {      value = iteratee(value);      var low = 0,          high = array == null ? 0 : array.length,          valIsNaN = value !== value,          valIsNull = value === null,          valIsSymbol = isSymbol(value),          valIsUndefined = value === undefined;      while (low < high) {        var mid = nativeFloor((low + high) / 2),            computed = iteratee(array[mid]),            othIsDefined = computed !== undefined,            othIsNull = computed === null,            othIsReflexive = computed === computed,            othIsSymbol = isSymbol(computed);        if (valIsNaN) {          var setLow = retHighest || othIsReflexive;        } else if (valIsUndefined) {          setLow = othIsReflexive && (retHighest || othIsDefined);        } else if (valIsNull) {          setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);        } else if (valIsSymbol) {          setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);        } else if (othIsNull || othIsSymbol) {          setLow = false;        } else {          setLow = retHighest ? (computed <= value) : (computed < value);        }        if (setLow) {          low = mid + 1;        } else {          high = mid;        }      }      return nativeMin(high, MAX_ARRAY_INDEX);    }    /**     * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without     * support for iteratee shorthands.     *     * @private     * @param {Array} array The array to inspect.     * @param {Function} [iteratee] The iteratee invoked per element.     * @returns {Array} Returns the new duplicate free array.     */    function baseSortedUniq(array, iteratee) {      var index = -1,          length = array.length,          resIndex = 0,          result = [];      while (++index < length) {        var value = array[index],            computed = iteratee ? iteratee(value) : value;        if (!index || !eq(computed, seen)) {          var seen = computed;          result[resIndex++] = value === 0 ? 0 : value;        }      }      return result;    }    /**     * The base implementation of `_.toNumber` which doesn't ensure correct     * conversions of binary, hexadecimal, or octal string values.     *     * @private     * @param {*} value The value to process.     * @returns {number} Returns the number.     */    function baseToNumber(value) {      if (typeof value == 'number') {        return value;      }      if (isSymbol(value)) {        return NAN;      }      return +value;    }    /**     * The base implementation of `_.toString` which doesn't convert nullish     * values to empty strings.     *     * @private     * @param {*} value The value to process.     * @returns {string} Returns the string.     */    function baseToString(value) {      // Exit early for strings to avoid a performance hit in some environments.      if (typeof value == 'string') {        return value;      }      if (isArray(value)) {        // Recursively convert values (susceptible to call stack limits).        return arrayMap(value, baseToString) + '';      }      if (isSymbol(value)) {        return symbolToString ? symbolToString.call(value) : '';      }      var result = (value + '');      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;    }    /**     * The base implementation of `_.uniqBy` without support for iteratee shorthands.     *     * @private     * @param {Array} array The array to inspect.     * @param {Function} [iteratee] The iteratee invoked per element.     * @param {Function} [comparator] The comparator invoked per element.     * @returns {Array} Returns the new duplicate free array.     */    function baseUniq(array, iteratee, comparator) {      var index = -1,          includes = arrayIncludes,          length = array.length,          isCommon = true,          result = [],          seen = result;      if (comparator) {        isCommon = false;        includes = arrayIncludesWith;      }      else if (length >= LARGE_ARRAY_SIZE) {        var set = iteratee ? null : createSet(array);        if (set) {          return setToArray(set);        }        isCommon = false;        includes = cacheHas;        seen = new SetCache;      }      else {        seen = iteratee ? [] : result;      }      outer:      while (++index < length) {        var value = array[index],            computed = iteratee ? iteratee(value) : value;        value = (comparator || value !== 0) ? value : 0;        if (isCommon && computed === computed) {          var seenIndex = seen.length;          while (seenIndex--) {            if (seen[seenIndex] === computed) {              continue outer;            }          }          if (iteratee) {            seen.push(computed);          }          result.push(value);        }        else if (!includes(seen, computed, comparator)) {          if (seen !== result) {            seen.push(computed);          }          result.push(value);        }      }      return result;    }    /**     * The base implementation of `_.unset`.     *     * @private     * @param {Object} object The object to modify.     * @param {Array|string} path The property path to unset.     * @returns {boolean} Returns `true` if the property is deleted, else `false`.     */    function baseUnset(object, path) {      path = castPath(path, object);      object = parent(object, path);      return object == null || delete object[toKey(last(path))];    }    /**     * The base implementation of `_.update`.     *     * @private     * @param {Object} object The object to modify.     * @param {Array|string} path The path of the property to update.     * @param {Function} updater The function to produce the updated value.     * @param {Function} [customizer] The function to customize path creation.     * @returns {Object} Returns `object`.     */    function baseUpdate(object, path, updater, customizer) {      return baseSet(object, path, updater(baseGet(object, path)), customizer);    }    /**     * The base implementation of methods like `_.dropWhile` and `_.takeWhile`     * without support for iteratee shorthands.     *     * @private     * @param {Array} array The array to query.     * @param {Function} predicate The function invoked per iteration.     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.     * @param {boolean} [fromRight] Specify iterating from right to left.     * @returns {Array} Returns the slice of `array`.     */    function baseWhile(array, predicate, isDrop, fromRight) {      var length = array.length,          index = fromRight ? length : -1;      while ((fromRight ? index-- : ++index < length) &&        predicate(array[index], index, array)) {}      return isDrop        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));    }    /**     * The base implementation of `wrapperValue` which returns the result of     * performing a sequence of actions on the unwrapped `value`, where each     * successive action is supplied the return value of the previous.     *     * @private     * @param {*} value The unwrapped value.     * @param {Array} actions Actions to perform to resolve the unwrapped value.     * @returns {*} Returns the resolved value.     */    function baseWrapperValue(value, actions) {      var result = value;      if (result instanceof LazyWrapper) {        result = result.value();      }      return arrayReduce(actions, function(result, action) {        return action.func.apply(action.thisArg, arrayPush([result], action.args));      }, result);    }    /**     * The base implementation of methods like `_.xor`, without support for     * iteratee shorthands, that accepts an array of arrays to inspect.     *     * @private     * @param {Array} arrays The arrays to inspect.     * @param {Function} [iteratee] The iteratee invoked per element.     * @param {Function} [comparator] The comparator invoked per element.     * @returns {Array} Returns the new array of values.     */    function baseXor(arrays, iteratee, comparator) {      var length = arrays.length;      if (length < 2) {        return length ? baseUniq(arrays[0]) : [];      }      var index = -1,          result = Array(length);      while (++index < length) {        var array = arrays[index],            othIndex = -1;        while (++othIndex < length) {          if (othIndex != index) {            result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);          }        }      }      return baseUniq(baseFlatten(result, 1), iteratee, comparator);    }    /**     * This base implementation of `_.zipObject` which assigns values using `assignFunc`.     *     * @private     * @param {Array} props The property identifiers.     * @param {Array} values The property values.     * @param {Function} assignFunc The function to assign values.     * @returns {Object} Returns the new object.     */    function baseZipObject(props, values, assignFunc) {      var index = -1,          length = props.length,          valsLength = values.length,          result = {};      while (++index < length) {        var value = index < valsLength ? values[index] : undefined;        assignFunc(result, props[index], value);      }      return result;    }    /**     * Casts `value` to an empty array if it's not an array like object.     *     * @private     * @param {*} value The value to inspect.     * @returns {Array|Object} Returns the cast array-like object.     */    function castArrayLikeObject(value) {      return isArrayLikeObject(value) ? value : [];    }    /**     * Casts `value` to `identity` if it's not a function.     *     * @private     * @param {*} value The value to inspect.     * @returns {Function} Returns cast function.     */    function castFunction(value) {      return typeof value == 'function' ? value : identity;    }    /**     * Casts `value` to a path array if it's not one.     *     * @private     * @param {*} value The value to inspect.     * @param {Object} [object] The object to query keys on.     * @returns {Array} Returns the cast property path array.     */    function castPath(value, object) {      if (isArray(value)) {        return value;      }      return isKey(value, object) ? [value] : stringToPath(toString(value));    }    /**     * A `baseRest` alias which can be replaced with `identity` by module     * replacement plugins.     *     * @private     * @type {Function}     * @param {Function} func The function to apply a rest parameter to.     * @returns {Function} Returns the new function.     */    var castRest = baseRest;    /**     * Casts `array` to a slice if it's needed.     *     * @private     * @param {Array} array The array to inspect.     * @param {number} start The start position.     * @param {number} [end=array.length] The end position.     * @returns {Array} Returns the cast slice.     */    function castSlice(array, start, end) {      var length = array.length;      end = end === undefined ? length : end;      return (!start && end >= length) ? array : baseSlice(array, start, end);    }    /**     * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).     *     * @private     * @param {number|Object} id The timer id or timeout object of the timer to clear.     */    var clearTimeout = ctxClearTimeout || function(id) {      return root.clearTimeout(id);    };    /**     * Creates a clone of  `buffer`.     *     * @private     * @param {Buffer} buffer The buffer to clone.     * @param {boolean} [isDeep] Specify a deep clone.     * @returns {Buffer} Returns the cloned buffer.     */    function cloneBuffer(buffer, isDeep) {      if (isDeep) {        return buffer.slice();      }      var length = buffer.length,          result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);      buffer.copy(result);      return result;    }    /**     * Creates a clone of `arrayBuffer`.     *     * @private     * @param {ArrayBuffer} arrayBuffer The array buffer to clone.     * @returns {ArrayBuffer} Returns the cloned array buffer.     */    function cloneArrayBuffer(arrayBuffer) {      var result = new arrayBuffer.constructor(arrayBuffer.byteLength);      new Uint8Array(result).set(new Uint8Array(arrayBuffer));      return result;    }    /**     * Creates a clone of `dataView`.     *     * @private     * @param {Object} dataView The data view to clone.     * @param {boolean} [isDeep] Specify a deep clone.     * @returns {Object} Returns the cloned data view.     */    function cloneDataView(dataView, isDeep) {      var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;      return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);    }    /**     * Creates a clone of `regexp`.     *     * @private     * @param {Object} regexp The regexp to clone.     * @returns {Object} Returns the cloned regexp.     */    function cloneRegExp(regexp) {      var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));      result.lastIndex = regexp.lastIndex;      return result;    }    /**     * Creates a clone of the `symbol` object.     *     * @private     * @param {Object} symbol The symbol object to clone.     * @returns {Object} Returns the cloned symbol object.     */    function cloneSymbol(symbol) {      return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};    }    /**     * Creates a clone of `typedArray`.     *     * @private     * @param {Object} typedArray The typed array to clone.     * @param {boolean} [isDeep] Specify a deep clone.     * @returns {Object} Returns the cloned typed array.     */    function cloneTypedArray(typedArray, isDeep) {      var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;      return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);    }    /**     * Compares values to sort them in ascending order.     *     * @private     * @param {*} value The value to compare.     * @param {*} other The other value to compare.     * @returns {number} Returns the sort order indicator for `value`.     */    function compareAscending(value, other) {      if (value !== other) {        var valIsDefined = value !== undefined,            valIsNull = value === null,            valIsReflexive = value === value,            valIsSymbol = isSymbol(value);        var othIsDefined = other !== undefined,            othIsNull = other === null,            othIsReflexive = other === other,            othIsSymbol = isSymbol(other);        if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||            (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||            (valIsNull && othIsDefined && othIsReflexive) ||            (!valIsDefined && othIsReflexive) ||            !valIsReflexive) {          return 1;        }        if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||            (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||            (othIsNull && valIsDefined && valIsReflexive) ||            (!othIsDefined && valIsReflexive) ||            !othIsReflexive) {          return -1;        }      }      return 0;    }    /**     * Used by `_.orderBy` to compare multiple properties of a value to another     * and stable sort them.     *     * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,     * specify an order of "desc" for descending or "asc" for ascending sort order     * of corresponding values.     *     * @private     * @param {Object} object The object to compare.     * @param {Object} other The other object to compare.     * @param {boolean[]|string[]} orders The order to sort by for each property.     * @returns {number} Returns the sort order indicator for `object`.     */    function compareMultiple(object, other, orders) {      var index = -1,          objCriteria = object.criteria,          othCriteria = other.criteria,          length = objCriteria.length,          ordersLength = orders.length;      while (++index < length) {        var result = compareAscending(objCriteria[index], othCriteria[index]);        if (result) {          if (index >= ordersLength) {            return result;          }          var order = orders[index];          return result * (order == 'desc' ? -1 : 1);        }      }      // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications      // that causes it, under certain circumstances, to provide the same value for      // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247      // for more details.      //      // This also ensures a stable sort in V8 and other engines.      // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.      return object.index - other.index;    }    /**     * Creates an array that is the composition of partially applied arguments,     * placeholders, and provided arguments into a single array of arguments.     *     * @private     * @param {Array} args The provided arguments.     * @param {Array} partials The arguments to prepend to those provided.     * @param {Array} holders The `partials` placeholder indexes.     * @params {boolean} [isCurried] Specify composing for a curried function.     * @returns {Array} Returns the new array of composed arguments.     */    function composeArgs(args, partials, holders, isCurried) {      var argsIndex = -1,          argsLength = args.length,          holdersLength = holders.length,          leftIndex = -1,          leftLength = partials.length,          rangeLength = nativeMax(argsLength - holdersLength, 0),          result = Array(leftLength + rangeLength),          isUncurried = !isCurried;      while (++leftIndex < leftLength) {        result[leftIndex] = partials[leftIndex];      }      while (++argsIndex < holdersLength) {        if (isUncurried || argsIndex < argsLength) {          result[holders[argsIndex]] = args[argsIndex];        }      }      while (rangeLength--) {        result[leftIndex++] = args[argsIndex++];      }      return result;    }    /**     * This function is like `composeArgs` except that the arguments composition     * is tailored for `_.partialRight`.     *     * @private     * @param {Array} args The provided arguments.     * @param {Array} partials The arguments to append to those provided.     * @param {Array} holders The `partials` placeholder indexes.     * @params {boolean} [isCurried] Specify composing for a curried function.     * @returns {Array} Returns the new array of composed arguments.     */    function composeArgsRight(args, partials, holders, isCurried) {      var argsIndex = -1,          argsLength = args.length,          holdersIndex = -1,          holdersLength = holders.length,          rightIndex = -1,          rightLength = partials.length,          rangeLength = nativeMax(argsLength - holdersLength, 0),          result = Array(rangeLength + rightLength),          isUncurried = !isCurried;      while (++argsIndex < rangeLength) {        result[argsIndex] = args[argsIndex];      }      var offset = argsIndex;      while (++rightIndex < rightLength) {        result[offset + rightIndex] = partials[rightIndex];      }      while (++holdersIndex < holdersLength) {        if (isUncurried || argsIndex < argsLength) {          result[offset + holders[holdersIndex]] = args[argsIndex++];        }      }      return result;    }    /**     * Copies the values of `source` to `array`.     *     * @private     * @param {Array} source The array to copy values from.     * @param {Array} [array=[]] The array to copy values to.     * @returns {Array} Returns `array`.     */    function copyArray(source, array) {      var index = -1,          length = source.length;      array || (array = Array(length));      while (++index < length) {        array[index] = source[index];      }      return array;    }    /**     * Copies properties of `source` to `object`.     *     * @private     * @param {Object} source The object to copy properties from.     * @param {Array} props The property identifiers to copy.     * @param {Object} [object={}] The object to copy properties to.     * @param {Function} [customizer] The function to customize copied values.     * @returns {Object} Returns `object`.     */    function copyObject(source, props, object, customizer) {      var isNew = !object;      object || (object = {});      var index = -1,          length = props.length;      while (++index < length) {        var key = props[index];        var newValue = customizer          ? customizer(object[key], source[key], key, object, source)          : undefined;        if (newValue === undefined) {          newValue = source[key];        }        if (isNew) {          baseAssignValue(object, key, newValue);        } else {          assignValue(object, key, newValue);        }      }      return object;    }    /**     * Copies own symbols of `source` to `object`.     *     * @private     * @param {Object} source The object to copy symbols from.     * @param {Object} [object={}] The object to copy symbols to.     * @returns {Object} Returns `object`.     */    function copySymbols(source, object) {      return copyObject(source, getSymbols(source), object);    }    /**     * Copies own and inherited symbols of `source` to `object`.     *     * @private     * @param {Object} source The object to copy symbols from.     * @param {Object} [object={}] The object to copy symbols to.     * @returns {Object} Returns `object`.     */    function copySymbolsIn(source, object) {      return copyObject(source, getSymbolsIn(source), object);    }    /**     * Creates a function like `_.groupBy`.     *     * @private     * @param {Function} setter The function to set accumulator values.     * @param {Function} [initializer] The accumulator object initializer.     * @returns {Function} Returns the new aggregator function.     */    function createAggregator(setter, initializer) {      return function(collection, iteratee) {        var func = isArray(collection) ? arrayAggregator : baseAggregator,            accumulator = initializer ? initializer() : {};        return func(collection, setter, getIteratee(iteratee, 2), accumulator);      };    }    /**     * Creates a function like `_.assign`.     *     * @private     * @param {Function} assigner The function to assign values.     * @returns {Function} Returns the new assigner function.     */    function createAssigner(assigner) {      return baseRest(function(object, sources) {        var index = -1,            length = sources.length,            customizer = length > 1 ? sources[length - 1] : undefined,            guard = length > 2 ? sources[2] : undefined;        customizer = (assigner.length > 3 && typeof customizer == 'function')          ? (length--, customizer)          : undefined;        if (guard && isIterateeCall(sources[0], sources[1], guard)) {          customizer = length < 3 ? undefined : customizer;          length = 1;        }        object = Object(object);        while (++index < length) {          var source = sources[index];          if (source) {            assigner(object, source, index, customizer);          }        }        return object;      });    }    /**     * Creates a `baseEach` or `baseEachRight` function.     *     * @private     * @param {Function} eachFunc The function to iterate over a collection.     * @param {boolean} [fromRight] Specify iterating from right to left.     * @returns {Function} Returns the new base function.     */    function createBaseEach(eachFunc, fromRight) {      return function(collection, iteratee) {        if (collection == null) {          return collection;        }        if (!isArrayLike(collection)) {          return eachFunc(collection, iteratee);        }        var length = collection.length,            index = fromRight ? length : -1,            iterable = Object(collection);        while ((fromRight ? index-- : ++index < length)) {          if (iteratee(iterable[index], index, iterable) === false) {            break;          }        }        return collection;      };    }    /**     * Creates a base function for methods like `_.forIn` and `_.forOwn`.     *     * @private     * @param {boolean} [fromRight] Specify iterating from right to left.     * @returns {Function} Returns the new base function.     */    function createBaseFor(fromRight) {      return function(object, iteratee, keysFunc) {        var index = -1,            iterable = Object(object),            props = keysFunc(object),            length = props.length;        while (length--) {          var key = props[fromRight ? length : ++index];          if (iteratee(iterable[key], key, iterable) === false) {            break;          }        }        return object;      };    }    /**     * Creates a function that wraps `func` to invoke it with the optional `this`     * binding of `thisArg`.     *     * @private     * @param {Function} func The function to wrap.     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.     * @param {*} [thisArg] The `this` binding of `func`.     * @returns {Function} Returns the new wrapped function.     */    function createBind(func, bitmask, thisArg) {      var isBind = bitmask & WRAP_BIND_FLAG,          Ctor = createCtor(func);      function wrapper() {        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;        return fn.apply(isBind ? thisArg : this, arguments);      }      return wrapper;    }    /**     * Creates a function like `_.lowerFirst`.     *     * @private     * @param {string} methodName The name of the `String` case method to use.     * @returns {Function} Returns the new case function.     */    function createCaseFirst(methodName) {      return function(string) {        string = toString(string);        var strSymbols = hasUnicode(string)          ? stringToArray(string)          : undefined;        var chr = strSymbols          ? strSymbols[0]          : string.charAt(0);        var trailing = strSymbols          ? castSlice(strSymbols, 1).join('')          : string.slice(1);        return chr[methodName]() + trailing;      };    }    /**     * Creates a function like `_.camelCase`.     *     * @private     * @param {Function} callback The function to combine each word.     * @returns {Function} Returns the new compounder function.     */    function createCompounder(callback) {      return function(string) {        return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');      };    }    /**     * Creates a function that produces an instance of `Ctor` regardless of     * whether it was invoked as part of a `new` expression or by `call` or `apply`.     *     * @private     * @param {Function} Ctor The constructor to wrap.     * @returns {Function} Returns the new wrapped function.     */    function createCtor(Ctor) {      return function() {        // Use a `switch` statement to work with class constructors. See        // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist        // for more details.        var args = arguments;        switch (args.length) {          case 0: return new Ctor;          case 1: return new Ctor(args[0]);          case 2: return new Ctor(args[0], args[1]);          case 3: return new Ctor(args[0], args[1], args[2]);          case 4: return new Ctor(args[0], args[1], args[2], args[3]);          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);        }        var thisBinding = baseCreate(Ctor.prototype),            result = Ctor.apply(thisBinding, args);        // Mimic the constructor's `return` behavior.        // See https://es5.github.io/#x13.2.2 for more details.        return isObject(result) ? result : thisBinding;      };    }    /**     * Creates a function that wraps `func` to enable currying.     *     * @private     * @param {Function} func The function to wrap.     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.     * @param {number} arity The arity of `func`.     * @returns {Function} Returns the new wrapped function.     */    function createCurry(func, bitmask, arity) {      var Ctor = createCtor(func);      function wrapper() {        var length = arguments.length,            args = Array(length),            index = length,            placeholder = getHolder(wrapper);        while (index--) {          args[index] = arguments[index];        }        var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)          ? []          : replaceHolders(args, placeholder);        length -= holders.length;        if (length < arity) {          return createRecurry(            func, bitmask, createHybrid, wrapper.placeholder, undefined,            args, holders, undefined, undefined, arity - length);        }        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;        return apply(fn, this, args);      }      return wrapper;    }    /**     * Creates a `_.find` or `_.findLast` function.     *     * @private     * @param {Function} findIndexFunc The function to find the collection index.     * @returns {Function} Returns the new find function.     */    function createFind(findIndexFunc) {      return function(collection, predicate, fromIndex) {        var iterable = Object(collection);        if (!isArrayLike(collection)) {          var iteratee = getIteratee(predicate, 3);          collection = keys(collection);          predicate = function(key) { return iteratee(iterable[key], key, iterable); };        }        var index = findIndexFunc(collection, predicate, fromIndex);        return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;      };    }    /**     * Creates a `_.flow` or `_.flowRight` function.     *     * @private     * @param {boolean} [fromRight] Specify iterating from right to left.     * @returns {Function} Returns the new flow function.     */    function createFlow(fromRight) {      return flatRest(function(funcs) {        var length = funcs.length,            index = length,            prereq = LodashWrapper.prototype.thru;        if (fromRight) {          funcs.reverse();        }        while (index--) {          var func = funcs[index];          if (typeof func != 'function') {            throw new TypeError(FUNC_ERROR_TEXT);          }          if (prereq && !wrapper && getFuncName(func) == 'wrapper') {            var wrapper = new LodashWrapper([], true);          }        }        index = wrapper ? index : length;        while (++index < length) {          func = funcs[index];          var funcName = getFuncName(func),              data = funcName == 'wrapper' ? getData(func) : undefined;          if (data && isLaziable(data[0]) &&                data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&                !data[4].length && data[9] == 1              ) {            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);          } else {            wrapper = (func.length == 1 && isLaziable(func))              ? wrapper[funcName]()              : wrapper.thru(func);          }        }        return function() {          var args = arguments,              value = args[0];          if (wrapper && args.length == 1 && isArray(value)) {            return wrapper.plant(value).value();          }          var index = 0,              result = length ? funcs[index].apply(this, args) : value;          while (++index < length) {            result = funcs[index].call(this, result);          }          return result;        };      });    }    /**     * Creates a function that wraps `func` to invoke it with optional `this`     * binding of `thisArg`, partial application, and currying.     *     * @private     * @param {Function|string} func The function or method name to wrap.     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.     * @param {*} [thisArg] The `this` binding of `func`.     * @param {Array} [partials] The arguments to prepend to those provided to     *  the new function.     * @param {Array} [holders] The `partials` placeholder indexes.     * @param {Array} [partialsRight] The arguments to append to those provided     *  to the new function.     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.     * @param {Array} [argPos] The argument positions of the new function.     * @param {number} [ary] The arity cap of `func`.     * @param {number} [arity] The arity of `func`.     * @returns {Function} Returns the new wrapped function.     */    function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {      var isAry = bitmask & WRAP_ARY_FLAG,          isBind = bitmask & WRAP_BIND_FLAG,          isBindKey = bitmask & WRAP_BIND_KEY_FLAG,          isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),          isFlip = bitmask & WRAP_FLIP_FLAG,          Ctor = isBindKey ? undefined : createCtor(func);      function wrapper() {        var length = arguments.length,            args = Array(length),            index = length;        while (index--) {          args[index] = arguments[index];        }        if (isCurried) {          var placeholder = getHolder(wrapper),              holdersCount = countHolders(args, placeholder);        }        if (partials) {          args = composeArgs(args, partials, holders, isCurried);        }        if (partialsRight) {          args = composeArgsRight(args, partialsRight, holdersRight, isCurried);        }        length -= holdersCount;        if (isCurried && length < arity) {          var newHolders = replaceHolders(args, placeholder);          return createRecurry(            func, bitmask, createHybrid, wrapper.placeholder, thisArg,            args, newHolders, argPos, ary, arity - length          );        }        var thisBinding = isBind ? thisArg : this,            fn = isBindKey ? thisBinding[func] : func;        length = args.length;        if (argPos) {          args = reorder(args, argPos);        } else if (isFlip && length > 1) {          args.reverse();        }        if (isAry && ary < length) {          args.length = ary;        }        if (this && this !== root && this instanceof wrapper) {          fn = Ctor || createCtor(fn);        }        return fn.apply(thisBinding, args);      }      return wrapper;    }    /**     * Creates a function like `_.invertBy`.     *     * @private     * @param {Function} setter The function to set accumulator values.     * @param {Function} toIteratee The function to resolve iteratees.     * @returns {Function} Returns the new inverter function.     */    function createInverter(setter, toIteratee) {      return function(object, iteratee) {        return baseInverter(object, setter, toIteratee(iteratee), {});      };    }    /**     * Creates a function that performs a mathematical operation on two values.     *     * @private     * @param {Function} operator The function to perform the operation.     * @param {number} [defaultValue] The value used for `undefined` arguments.     * @returns {Function} Returns the new mathematical operation function.     */    function createMathOperation(operator, defaultValue) {      return function(value, other) {        var result;        if (value === undefined && other === undefined) {          return defaultValue;        }        if (value !== undefined) {          result = value;        }        if (other !== undefined) {          if (result === undefined) {            return other;          }          if (typeof value == 'string' || typeof other == 'string') {            value = baseToString(value);            other = baseToString(other);          } else {            value = baseToNumber(value);            other = baseToNumber(other);          }          result = operator(value, other);        }        return result;      };    }    /**     * Creates a function like `_.over`.     *     * @private     * @param {Function} arrayFunc The function to iterate over iteratees.     * @returns {Function} Returns the new over function.     */    function createOver(arrayFunc) {      return flatRest(function(iteratees) {        iteratees = arrayMap(iteratees, baseUnary(getIteratee()));        return baseRest(function(args) {          var thisArg = this;          return arrayFunc(iteratees, function(iteratee) {            return apply(iteratee, thisArg, args);          });        });      });    }    /**     * Creates the padding for `string` based on `length`. The `chars` string     * is truncated if the number of characters exceeds `length`.     *     * @private     * @param {number} length The padding length.     * @param {string} [chars=' '] The string used as padding.     * @returns {string} Returns the padding for `string`.     */    function createPadding(length, chars) {      chars = chars === undefined ? ' ' : baseToString(chars);      var charsLength = chars.length;      if (charsLength < 2) {        return charsLength ? baseRepeat(chars, length) : chars;      }      var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));      return hasUnicode(chars)        ? castSlice(stringToArray(result), 0, length).join('')        : result.slice(0, length);    }    /**     * Creates a function that wraps `func` to invoke it with the `this` binding     * of `thisArg` and `partials` prepended to the arguments it receives.     *     * @private     * @param {Function} func The function to wrap.     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.     * @param {*} thisArg The `this` binding of `func`.     * @param {Array} partials The arguments to prepend to those provided to     *  the new function.     * @returns {Function} Returns the new wrapped function.     */    function createPartial(func, bitmask, thisArg, partials) {      var isBind = bitmask & WRAP_BIND_FLAG,          Ctor = createCtor(func);      function wrapper() {        var argsIndex = -1,            argsLength = arguments.length,            leftIndex = -1,            leftLength = partials.length,            args = Array(leftLength + argsLength),            fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;        while (++leftIndex < leftLength) {          args[leftIndex] = partials[leftIndex];        }        while (argsLength--) {          args[leftIndex++] = arguments[++argsIndex];        }        return apply(fn, isBind ? thisArg : this, args);      }      return wrapper;    }    /**     * Creates a `_.range` or `_.rangeRight` function.     *     * @private     * @param {boolean} [fromRight] Specify iterating from right to left.     * @returns {Function} Returns the new range function.     */    function createRange(fromRight) {      return function(start, end, step) {        if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {          end = step = undefined;        }        // Ensure the sign of `-0` is preserved.        start = toFinite(start);        if (end === undefined) {          end = start;          start = 0;        } else {          end = toFinite(end);        }        step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);        return baseRange(start, end, step, fromRight);      };    }    /**     * Creates a function that performs a relational operation on two values.     *     * @private     * @param {Function} operator The function to perform the operation.     * @returns {Function} Returns the new relational operation function.     */    function createRelationalOperation(operator) {      return function(value, other) {        if (!(typeof value == 'string' && typeof other == 'string')) {          value = toNumber(value);          other = toNumber(other);        }        return operator(value, other);      };    }    /**     * Creates a function that wraps `func` to continue currying.     *     * @private     * @param {Function} func The function to wrap.     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.     * @param {Function} wrapFunc The function to create the `func` wrapper.     * @param {*} placeholder The placeholder value.     * @param {*} [thisArg] The `this` binding of `func`.     * @param {Array} [partials] The arguments to prepend to those provided to     *  the new function.     * @param {Array} [holders] The `partials` placeholder indexes.     * @param {Array} [argPos] The argument positions of the new function.     * @param {number} [ary] The arity cap of `func`.     * @param {number} [arity] The arity of `func`.     * @returns {Function} Returns the new wrapped function.     */    function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {      var isCurry = bitmask & WRAP_CURRY_FLAG,          newHolders = isCurry ? holders : undefined,          newHoldersRight = isCurry ? undefined : holders,          newPartials = isCurry ? partials : undefined,          newPartialsRight = isCurry ? undefined : partials;      bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);      bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);      if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {        bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);      }      var newData = [        func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,        newHoldersRight, argPos, ary, arity      ];      var result = wrapFunc.apply(undefined, newData);      if (isLaziable(func)) {        setData(result, newData);      }      result.placeholder = placeholder;      return setWrapToString(result, func, bitmask);    }    /**     * Creates a function like `_.round`.     *     * @private     * @param {string} methodName The name of the `Math` method to use when rounding.     * @returns {Function} Returns the new round function.     */    function createRound(methodName) {      var func = Math[methodName];      return function(number, precision) {        number = toNumber(number);        precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);        if (precision) {          // Shift with exponential notation to avoid floating-point issues.          // See [MDN](https://mdn.io/round#Examples) for more details.          var pair = (toString(number) + 'e').split('e'),              value = func(pair[0] + 'e' + (+pair[1] + precision));          pair = (toString(value) + 'e').split('e');          return +(pair[0] + 'e' + (+pair[1] - precision));        }        return func(number);      };    }    /**     * Creates a set object of `values`.     *     * @private     * @param {Array} values The values to add to the set.     * @returns {Object} Returns the new set.     */    var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {      return new Set(values);    };    /**     * Creates a `_.toPairs` or `_.toPairsIn` function.     *     * @private     * @param {Function} keysFunc The function to get the keys of a given object.     * @returns {Function} Returns the new pairs function.     */    function createToPairs(keysFunc) {      return function(object) {        var tag = getTag(object);        if (tag == mapTag) {          return mapToArray(object);        }        if (tag == setTag) {          return setToPairs(object);        }        return baseToPairs(object, keysFunc(object));      };    }    /**     * Creates a function that either curries or invokes `func` with optional     * `this` binding and partially applied arguments.     *     * @private     * @param {Function|string} func The function or method name to wrap.     * @param {number} bitmask The bitmask flags.     *    1 - `_.bind`     *    2 - `_.bindKey`     *    4 - `_.curry` or `_.curryRight` of a bound function     *    8 - `_.curry`     *   16 - `_.curryRight`     *   32 - `_.partial`     *   64 - `_.partialRight`     *  128 - `_.rearg`     *  256 - `_.ary`     *  512 - `_.flip`     * @param {*} [thisArg] The `this` binding of `func`.     * @param {Array} [partials] The arguments to be partially applied.     * @param {Array} [holders] The `partials` placeholder indexes.     * @param {Array} [argPos] The argument positions of the new function.     * @param {number} [ary] The arity cap of `func`.     * @param {number} [arity] The arity of `func`.     * @returns {Function} Returns the new wrapped function.     */    function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {      var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;      if (!isBindKey && typeof func != 'function') {        throw new TypeError(FUNC_ERROR_TEXT);      }      var length = partials ? partials.length : 0;      if (!length) {        bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);        partials = holders = undefined;      }      ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);      arity = arity === undefined ? arity : toInteger(arity);      length -= holders ? holders.length : 0;      if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {        var partialsRight = partials,            holdersRight = holders;        partials = holders = undefined;      }      var data = isBindKey ? undefined : getData(func);      var newData = [        func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,        argPos, ary, arity      ];      if (data) {        mergeData(newData, data);      }      func = newData[0];      bitmask = newData[1];      thisArg = newData[2];      partials = newData[3];      holders = newData[4];      arity = newData[9] = newData[9] === undefined        ? (isBindKey ? 0 : func.length)        : nativeMax(newData[9] - length, 0);      if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {        bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);      }      if (!bitmask || bitmask == WRAP_BIND_FLAG) {        var result = createBind(func, bitmask, thisArg);      } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {        result = createCurry(func, bitmask, arity);      } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {        result = createPartial(func, bitmask, thisArg, partials);      } else {        result = createHybrid.apply(undefined, newData);      }      var setter = data ? baseSetData : setData;      return setWrapToString(setter(result, newData), func, bitmask);    }    /**     * Used by `_.defaults` to customize its `_.assignIn` use to assign properties     * of source objects to the destination object for all destination properties     * that resolve to `undefined`.     *     * @private     * @param {*} objValue The destination value.     * @param {*} srcValue The source value.     * @param {string} key The key of the property to assign.     * @param {Object} object The parent object of `objValue`.     * @returns {*} Returns the value to assign.     */    function customDefaultsAssignIn(objValue, srcValue, key, object) {      if (objValue === undefined ||          (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {        return srcValue;      }      return objValue;    }    /**     * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source     * objects into destination objects that are passed thru.     *     * @private     * @param {*} objValue The destination value.     * @param {*} srcValue The source value.     * @param {string} key The key of the property to merge.     * @param {Object} object The parent object of `objValue`.     * @param {Object} source The parent object of `srcValue`.     * @param {Object} [stack] Tracks traversed source values and their merged     *  counterparts.     * @returns {*} Returns the value to assign.     */    function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {      if (isObject(objValue) && isObject(srcValue)) {        // Recursively merge objects and arrays (susceptible to call stack limits).        stack.set(srcValue, objValue);        baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);        stack['delete'](srcValue);      }      return objValue;    }    /**     * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain     * objects.     *     * @private     * @param {*} value The value to inspect.     * @param {string} key The key of the property to inspect.     * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.     */    function customOmitClone(value) {      return isPlainObject(value) ? undefined : value;    }    /**     * A specialized version of `baseIsEqualDeep` for arrays with support for     * partial deep comparisons.     *     * @private     * @param {Array} array The array to compare.     * @param {Array} other The other array to compare.     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.     * @param {Function} customizer The function to customize comparisons.     * @param {Function} equalFunc The function to determine equivalents of values.     * @param {Object} stack Tracks traversed `array` and `other` objects.     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.     */    function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,          arrLength = array.length,          othLength = other.length;      if (arrLength != othLength && !(isPartial && othLength > arrLength)) {        return false;      }      // Assume cyclic values are equal.      var stacked = stack.get(array);      if (stacked && stack.get(other)) {        return stacked == other;      }      var index = -1,          result = true,          seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;      stack.set(array, other);      stack.set(other, array);      // Ignore non-index properties.      while (++index < arrLength) {        var arrValue = array[index],            othValue = other[index];        if (customizer) {          var compared = isPartial            ? customizer(othValue, arrValue, index, other, array, stack)            : customizer(arrValue, othValue, index, array, other, stack);        }        if (compared !== undefined) {          if (compared) {            continue;          }          result = false;          break;        }        // Recursively compare arrays (susceptible to call stack limits).        if (seen) {          if (!arraySome(other, function(othValue, othIndex) {                if (!cacheHas(seen, othIndex) &&                    (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {                  return seen.push(othIndex);                }              })) {            result = false;            break;          }        } else if (!(              arrValue === othValue ||                equalFunc(arrValue, othValue, bitmask, customizer, stack)            )) {          result = false;          break;        }      }      stack['delete'](array);      stack['delete'](other);      return result;    }    /**     * A specialized version of `baseIsEqualDeep` for comparing objects of     * the same `toStringTag`.     *     * **Note:** This function only supports comparing values with tags of     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.     *     * @private     * @param {Object} object The object to compare.     * @param {Object} other The other object to compare.     * @param {string} tag The `toStringTag` of the objects to compare.     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.     * @param {Function} customizer The function to customize comparisons.     * @param {Function} equalFunc The function to determine equivalents of values.     * @param {Object} stack Tracks traversed `object` and `other` objects.     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.     */    function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {      switch (tag) {        case dataViewTag:          if ((object.byteLength != other.byteLength) ||              (object.byteOffset != other.byteOffset)) {            return false;          }          object = object.buffer;          other = other.buffer;        case arrayBufferTag:          if ((object.byteLength != other.byteLength) ||              !equalFunc(new Uint8Array(object), new Uint8Array(other))) {            return false;          }          return true;        case boolTag:        case dateTag:        case numberTag:          // Coerce booleans to `1` or `0` and dates to milliseconds.          // Invalid dates are coerced to `NaN`.          return eq(+object, +other);        case errorTag:          return object.name == other.name && object.message == other.message;        case regexpTag:        case stringTag:          // Coerce regexes to strings and treat strings, primitives and objects,          // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring          // for more details.          return object == (other + '');        case mapTag:          var convert = mapToArray;        case setTag:          var isPartial = bitmask & COMPARE_PARTIAL_FLAG;          convert || (convert = setToArray);          if (object.size != other.size && !isPartial) {            return false;          }          // Assume cyclic values are equal.          var stacked = stack.get(object);          if (stacked) {            return stacked == other;          }          bitmask |= COMPARE_UNORDERED_FLAG;          // Recursively compare objects (susceptible to call stack limits).          stack.set(object, other);          var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);          stack['delete'](object);          return result;        case symbolTag:          if (symbolValueOf) {            return symbolValueOf.call(object) == symbolValueOf.call(other);          }      }      return false;    }    /**     * A specialized version of `baseIsEqualDeep` for objects with support for     * partial deep comparisons.     *     * @private     * @param {Object} object The object to compare.     * @param {Object} other The other object to compare.     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.     * @param {Function} customizer The function to customize comparisons.     * @param {Function} equalFunc The function to determine equivalents of values.     * @param {Object} stack Tracks traversed `object` and `other` objects.     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.     */    function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,          objProps = getAllKeys(object),          objLength = objProps.length,          othProps = getAllKeys(other),          othLength = othProps.length;      if (objLength != othLength && !isPartial) {        return false;      }      var index = objLength;      while (index--) {        var key = objProps[index];        if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {          return false;        }      }      // Assume cyclic values are equal.      var stacked = stack.get(object);      if (stacked && stack.get(other)) {        return stacked == other;      }      var result = true;      stack.set(object, other);      stack.set(other, object);      var skipCtor = isPartial;      while (++index < objLength) {        key = objProps[index];        var objValue = object[key],            othValue = other[key];        if (customizer) {          var compared = isPartial            ? customizer(othValue, objValue, key, other, object, stack)            : customizer(objValue, othValue, key, object, other, stack);        }        // Recursively compare objects (susceptible to call stack limits).        if (!(compared === undefined              ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))              : compared            )) {          result = false;          break;        }        skipCtor || (skipCtor = key == 'constructor');      }      if (result && !skipCtor) {        var objCtor = object.constructor,            othCtor = other.constructor;        // Non `Object` object instances with different constructors are not equal.        if (objCtor != othCtor &&            ('constructor' in object && 'constructor' in other) &&            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&              typeof othCtor == 'function' && othCtor instanceof othCtor)) {          result = false;        }      }      stack['delete'](object);      stack['delete'](other);      return result;    }    /**     * A specialized version of `baseRest` which flattens the rest array.     *     * @private     * @param {Function} func The function to apply a rest parameter to.     * @returns {Function} Returns the new function.     */    function flatRest(func) {      return setToString(overRest(func, undefined, flatten), func + '');    }    /**     * Creates an array of own enumerable property names and symbols of `object`.     *     * @private     * @param {Object} object The object to query.     * @returns {Array} Returns the array of property names and symbols.     */    function getAllKeys(object) {      return baseGetAllKeys(object, keys, getSymbols);    }    /**     * Creates an array of own and inherited enumerable property names and     * symbols of `object`.     *     * @private     * @param {Object} object The object to query.     * @returns {Array} Returns the array of property names and symbols.     */    function getAllKeysIn(object) {      return baseGetAllKeys(object, keysIn, getSymbolsIn);    }    /**     * Gets metadata for `func`.     *     * @private     * @param {Function} func The function to query.     * @returns {*} Returns the metadata for `func`.     */    var getData = !metaMap ? noop : function(func) {      return metaMap.get(func);    };    /**     * Gets the name of `func`.     *     * @private     * @param {Function} func The function to query.     * @returns {string} Returns the function name.     */    function getFuncName(func) {      var result = (func.name + ''),          array = realNames[result],          length = hasOwnProperty.call(realNames, result) ? array.length : 0;      while (length--) {        var data = array[length],            otherFunc = data.func;        if (otherFunc == null || otherFunc == func) {          return data.name;        }      }      return result;    }    /**     * Gets the argument placeholder value for `func`.     *     * @private     * @param {Function} func The function to inspect.     * @returns {*} Returns the placeholder value.     */    function getHolder(func) {      var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;      return object.placeholder;    }    /**     * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,     * this function returns the custom method, otherwise it returns `baseIteratee`.     * If arguments are provided, the chosen function is invoked with them and     * its result is returned.     *     * @private     * @param {*} [value] The value to convert to an iteratee.     * @param {number} [arity] The arity of the created iteratee.     * @returns {Function} Returns the chosen function or its result.     */    function getIteratee() {      var result = lodash.iteratee || iteratee;      result = result === iteratee ? baseIteratee : result;      return arguments.length ? result(arguments[0], arguments[1]) : result;    }    /**     * Gets the data for `map`.     *     * @private     * @param {Object} map The map to query.     * @param {string} key The reference key.     * @returns {*} Returns the map data.     */    function getMapData(map, key) {      var data = map.__data__;      return isKeyable(key)        ? data[typeof key == 'string' ? 'string' : 'hash']        : data.map;    }    /**     * Gets the property names, values, and compare flags of `object`.     *     * @private     * @param {Object} object The object to query.     * @returns {Array} Returns the match data of `object`.     */    function getMatchData(object) {      var result = keys(object),          length = result.length;      while (length--) {        var key = result[length],            value = object[key];        result[length] = [key, value, isStrictComparable(value)];      }      return result;    }    /**     * Gets the native function at `key` of `object`.     *     * @private     * @param {Object} object The object to query.     * @param {string} key The key of the method to get.     * @returns {*} Returns the function if it's native, else `undefined`.     */    function getNative(object, key) {      var value = getValue(object, key);      return baseIsNative(value) ? value : undefined;    }    /**     * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.     *     * @private     * @param {*} value The value to query.     * @returns {string} Returns the raw `toStringTag`.     */    function getRawTag(value) {      var isOwn = hasOwnProperty.call(value, symToStringTag),          tag = value[symToStringTag];      try {        value[symToStringTag] = undefined;        var unmasked = true;      } catch (e) {}      var result = nativeObjectToString.call(value);      if (unmasked) {        if (isOwn) {          value[symToStringTag] = tag;        } else {          delete value[symToStringTag];        }      }      return result;    }    /**     * Creates an array of the own enumerable symbols of `object`.     *     * @private     * @param {Object} object The object to query.     * @returns {Array} Returns the array of symbols.     */    var getSymbols = !nativeGetSymbols ? stubArray : function(object) {      if (object == null) {        return [];      }      object = Object(object);      return arrayFilter(nativeGetSymbols(object), function(symbol) {        return propertyIsEnumerable.call(object, symbol);      });    };    /**     * Creates an array of the own and inherited enumerable symbols of `object`.     *     * @private     * @param {Object} object The object to query.     * @returns {Array} Returns the array of symbols.     */    var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {      var result = [];      while (object) {        arrayPush(result, getSymbols(object));        object = getPrototype(object);      }      return result;    };    /**     * Gets the `toStringTag` of `value`.     *     * @private     * @param {*} value The value to query.     * @returns {string} Returns the `toStringTag`.     */    var getTag = baseGetTag;    // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.    if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||        (Map && getTag(new Map) != mapTag) ||        (Promise && getTag(Promise.resolve()) != promiseTag) ||        (Set && getTag(new Set) != setTag) ||        (WeakMap && getTag(new WeakMap) != weakMapTag)) {      getTag = function(value) {        var result = baseGetTag(value),            Ctor = result == objectTag ? value.constructor : undefined,            ctorString = Ctor ? toSource(Ctor) : '';        if (ctorString) {          switch (ctorString) {            case dataViewCtorString: return dataViewTag;            case mapCtorString: return mapTag;            case promiseCtorString: return promiseTag;            case setCtorString: return setTag;            case weakMapCtorString: return weakMapTag;          }        }        return result;      };    }    /**     * Gets the view, applying any `transforms` to the `start` and `end` positions.     *     * @private     * @param {number} start The start of the view.     * @param {number} end The end of the view.     * @param {Array} transforms The transformations to apply to the view.     * @returns {Object} Returns an object containing the `start` and `end`     *  positions of the view.     */    function getView(start, end, transforms) {      var index = -1,          length = transforms.length;      while (++index < length) {        var data = transforms[index],            size = data.size;        switch (data.type) {          case 'drop':      start += size; break;          case 'dropRight': end -= size; break;          case 'take':      end = nativeMin(end, start + size); break;          case 'takeRight': start = nativeMax(start, end - size); break;        }      }      return { 'start': start, 'end': end };    }    /**     * Extracts wrapper details from the `source` body comment.     *     * @private     * @param {string} source The source to inspect.     * @returns {Array} Returns the wrapper details.     */    function getWrapDetails(source) {      var match = source.match(reWrapDetails);      return match ? match[1].split(reSplitDetails) : [];    }    /**     * Checks if `path` exists on `object`.     *     * @private     * @param {Object} object The object to query.     * @param {Array|string} path The path to check.     * @param {Function} hasFunc The function to check properties.     * @returns {boolean} Returns `true` if `path` exists, else `false`.     */    function hasPath(object, path, hasFunc) {      path = castPath(path, object);      var index = -1,          length = path.length,          result = false;      while (++index < length) {        var key = toKey(path[index]);        if (!(result = object != null && hasFunc(object, key))) {          break;        }        object = object[key];      }      if (result || ++index != length) {        return result;      }      length = object == null ? 0 : object.length;      return !!length && isLength(length) && isIndex(key, length) &&        (isArray(object) || isArguments(object));    }    /**     * Initializes an array clone.     *     * @private     * @param {Array} array The array to clone.     * @returns {Array} Returns the initialized clone.     */    function initCloneArray(array) {      var length = array.length,          result = new array.constructor(length);      // Add properties assigned by `RegExp#exec`.      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {        result.index = array.index;        result.input = array.input;      }      return result;    }    /**     * Initializes an object clone.     *     * @private     * @param {Object} object The object to clone.     * @returns {Object} Returns the initialized clone.     */    function initCloneObject(object) {      return (typeof object.constructor == 'function' && !isPrototype(object))        ? baseCreate(getPrototype(object))        : {};    }    /**     * Initializes an object clone based on its `toStringTag`.     *     * **Note:** This function only supports cloning values with tags of     * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.     *     * @private     * @param {Object} object The object to clone.     * @param {string} tag The `toStringTag` of the object to clone.     * @param {boolean} [isDeep] Specify a deep clone.     * @returns {Object} Returns the initialized clone.     */    function initCloneByTag(object, tag, isDeep) {      var Ctor = object.constructor;      switch (tag) {        case arrayBufferTag:          return cloneArrayBuffer(object);        case boolTag:        case dateTag:          return new Ctor(+object);        case dataViewTag:          return cloneDataView(object, isDeep);        case float32Tag: case float64Tag:        case int8Tag: case int16Tag: case int32Tag:        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:          return cloneTypedArray(object, isDeep);        case mapTag:          return new Ctor;        case numberTag:        case stringTag:          return new Ctor(object);        case regexpTag:          return cloneRegExp(object);        case setTag:          return new Ctor;        case symbolTag:          return cloneSymbol(object);      }    }    /**     * Inserts wrapper `details` in a comment at the top of the `source` body.     *     * @private     * @param {string} source The source to modify.     * @returns {Array} details The details to insert.     * @returns {string} Returns the modified source.     */    function insertWrapDetails(source, details) {      var length = details.length;      if (!length) {        return source;      }      var lastIndex = length - 1;      details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];      details = details.join(length > 2 ? ', ' : ' ');      return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');    }    /**     * Checks if `value` is a flattenable `arguments` object or array.     *     * @private     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.     */    function isFlattenable(value) {      return isArray(value) || isArguments(value) ||        !!(spreadableSymbol && value && value[spreadableSymbol]);    }    /**     * Checks if `value` is a valid array-like index.     *     * @private     * @param {*} value The value to check.     * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.     * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.     */    function isIndex(value, length) {      var type = typeof value;      length = length == null ? MAX_SAFE_INTEGER : length;      return !!length &&        (type == 'number' ||          (type != 'symbol' && reIsUint.test(value))) &&            (value > -1 && value % 1 == 0 && value < length);    }    /**     * Checks if the given arguments are from an iteratee call.     *     * @private     * @param {*} value The potential iteratee value argument.     * @param {*} index The potential iteratee index or key argument.     * @param {*} object The potential iteratee object argument.     * @returns {boolean} Returns `true` if the arguments are from an iteratee call,     *  else `false`.     */    function isIterateeCall(value, index, object) {      if (!isObject(object)) {        return false;      }      var type = typeof index;      if (type == 'number'            ? (isArrayLike(object) && isIndex(index, object.length))            : (type == 'string' && index in object)          ) {        return eq(object[index], value);      }      return false;    }    /**     * Checks if `value` is a property name and not a property path.     *     * @private     * @param {*} value The value to check.     * @param {Object} [object] The object to query keys on.     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.     */    function isKey(value, object) {      if (isArray(value)) {        return false;      }      var type = typeof value;      if (type == 'number' || type == 'symbol' || type == 'boolean' ||          value == null || isSymbol(value)) {        return true;      }      return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||        (object != null && value in Object(object));    }    /**     * Checks if `value` is suitable for use as unique object key.     *     * @private     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is suitable, else `false`.     */    function isKeyable(value) {      var type = typeof value;      return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')        ? (value !== '__proto__')        : (value === null);    }    /**     * Checks if `func` has a lazy counterpart.     *     * @private     * @param {Function} func The function to check.     * @returns {boolean} Returns `true` if `func` has a lazy counterpart,     *  else `false`.     */    function isLaziable(func) {      var funcName = getFuncName(func),          other = lodash[funcName];      if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {        return false;      }      if (func === other) {        return true;      }      var data = getData(other);      return !!data && func === data[0];    }    /**     * Checks if `func` has its source masked.     *     * @private     * @param {Function} func The function to check.     * @returns {boolean} Returns `true` if `func` is masked, else `false`.     */    function isMasked(func) {      return !!maskSrcKey && (maskSrcKey in func);    }    /**     * Checks if `func` is capable of being masked.     *     * @private     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `func` is maskable, else `false`.     */    var isMaskable = coreJsData ? isFunction : stubFalse;    /**     * Checks if `value` is likely a prototype object.     *     * @private     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.     */    function isPrototype(value) {      var Ctor = value && value.constructor,          proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;      return value === proto;    }    /**     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.     *     * @private     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` if suitable for strict     *  equality comparisons, else `false`.     */    function isStrictComparable(value) {      return value === value && !isObject(value);    }    /**     * A specialized version of `matchesProperty` for source values suitable     * for strict equality comparisons, i.e. `===`.     *     * @private     * @param {string} key The key of the property to get.     * @param {*} srcValue The value to match.     * @returns {Function} Returns the new spec function.     */    function matchesStrictComparable(key, srcValue) {      return function(object) {        if (object == null) {          return false;        }        return object[key] === srcValue &&          (srcValue !== undefined || (key in Object(object)));      };    }    /**     * A specialized version of `_.memoize` which clears the memoized function's     * cache when it exceeds `MAX_MEMOIZE_SIZE`.     *     * @private     * @param {Function} func The function to have its output memoized.     * @returns {Function} Returns the new memoized function.     */    function memoizeCapped(func) {      var result = memoize(func, function(key) {        if (cache.size === MAX_MEMOIZE_SIZE) {          cache.clear();        }        return key;      });      var cache = result.cache;      return result;    }    /**     * Merges the function metadata of `source` into `data`.     *     * Merging metadata reduces the number of wrappers used to invoke a function.     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`     * may be applied regardless of execution order. Methods like `_.ary` and     * `_.rearg` modify function arguments, making the order in which they are     * executed important, preventing the merging of metadata. However, we make     * an exception for a safe combined case where curried functions have `_.ary`     * and or `_.rearg` applied.     *     * @private     * @param {Array} data The destination metadata.     * @param {Array} source The source metadata.     * @returns {Array} Returns `data`.     */    function mergeData(data, source) {      var bitmask = data[1],          srcBitmask = source[1],          newBitmask = bitmask | srcBitmask,          isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);      var isCombo =        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||        ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));      // Exit early if metadata can't be merged.      if (!(isCommon || isCombo)) {        return data;      }      // Use source `thisArg` if available.      if (srcBitmask & WRAP_BIND_FLAG) {        data[2] = source[2];        // Set when currying a bound function.        newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;      }      // Compose partial arguments.      var value = source[3];      if (value) {        var partials = data[3];        data[3] = partials ? composeArgs(partials, value, source[4]) : value;        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];      }      // Compose partial right arguments.      value = source[5];      if (value) {        partials = data[5];        data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];      }      // Use source `argPos` if available.      value = source[7];      if (value) {        data[7] = value;      }      // Use source `ary` if it's smaller.      if (srcBitmask & WRAP_ARY_FLAG) {        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);      }      // Use source `arity` if one is not provided.      if (data[9] == null) {        data[9] = source[9];      }      // Use source `func` and merge bitmasks.      data[0] = source[0];      data[1] = newBitmask;      return data;    }    /**     * This function is like     * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)     * except that it includes inherited enumerable properties.     *     * @private     * @param {Object} object The object to query.     * @returns {Array} Returns the array of property names.     */    function nativeKeysIn(object) {      var result = [];      if (object != null) {        for (var key in Object(object)) {          result.push(key);        }      }      return result;    }    /**     * Converts `value` to a string using `Object.prototype.toString`.     *     * @private     * @param {*} value The value to convert.     * @returns {string} Returns the converted string.     */    function objectToString(value) {      return nativeObjectToString.call(value);    }    /**     * A specialized version of `baseRest` which transforms the rest array.     *     * @private     * @param {Function} func The function to apply a rest parameter to.     * @param {number} [start=func.length-1] The start position of the rest parameter.     * @param {Function} transform The rest array transform.     * @returns {Function} Returns the new function.     */    function overRest(func, start, transform) {      start = nativeMax(start === undefined ? (func.length - 1) : start, 0);      return function() {        var args = arguments,            index = -1,            length = nativeMax(args.length - start, 0),            array = Array(length);        while (++index < length) {          array[index] = args[start + index];        }        index = -1;        var otherArgs = Array(start + 1);        while (++index < start) {          otherArgs[index] = args[index];        }        otherArgs[start] = transform(array);        return apply(func, this, otherArgs);      };    }    /**     * Gets the parent value at `path` of `object`.     *     * @private     * @param {Object} object The object to query.     * @param {Array} path The path to get the parent value of.     * @returns {*} Returns the parent value.     */    function parent(object, path) {      return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));    }    /**     * Reorder `array` according to the specified indexes where the element at     * the first index is assigned as the first element, the element at     * the second index is assigned as the second element, and so on.     *     * @private     * @param {Array} array The array to reorder.     * @param {Array} indexes The arranged array indexes.     * @returns {Array} Returns `array`.     */    function reorder(array, indexes) {      var arrLength = array.length,          length = nativeMin(indexes.length, arrLength),          oldArray = copyArray(array);      while (length--) {        var index = indexes[length];        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;      }      return array;    }    /**     * Gets the value at `key`, unless `key` is "__proto__".     *     * @private     * @param {Object} object The object to query.     * @param {string} key The key of the property to get.     * @returns {*} Returns the property value.     */    function safeGet(object, key) {      if (key == '__proto__') {        return;      }      return object[key];    }    /**     * Sets metadata for `func`.     *     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short     * period of time, it will trip its breaker and transition to an identity     * function to avoid garbage collection pauses in V8. See     * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)     * for more details.     *     * @private     * @param {Function} func The function to associate metadata with.     * @param {*} data The metadata.     * @returns {Function} Returns `func`.     */    var setData = shortOut(baseSetData);    /**     * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).     *     * @private     * @param {Function} func The function to delay.     * @param {number} wait The number of milliseconds to delay invocation.     * @returns {number|Object} Returns the timer id or timeout object.     */    var setTimeout = ctxSetTimeout || function(func, wait) {      return root.setTimeout(func, wait);    };    /**     * Sets the `toString` method of `func` to return `string`.     *     * @private     * @param {Function} func The function to modify.     * @param {Function} string The `toString` result.     * @returns {Function} Returns `func`.     */    var setToString = shortOut(baseSetToString);    /**     * Sets the `toString` method of `wrapper` to mimic the source of `reference`     * with wrapper details in a comment at the top of the source body.     *     * @private     * @param {Function} wrapper The function to modify.     * @param {Function} reference The reference function.     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.     * @returns {Function} Returns `wrapper`.     */    function setWrapToString(wrapper, reference, bitmask) {      var source = (reference + '');      return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));    }    /**     * Creates a function that'll short out and invoke `identity` instead     * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`     * milliseconds.     *     * @private     * @param {Function} func The function to restrict.     * @returns {Function} Returns the new shortable function.     */    function shortOut(func) {      var count = 0,          lastCalled = 0;      return function() {        var stamp = nativeNow(),            remaining = HOT_SPAN - (stamp - lastCalled);        lastCalled = stamp;        if (remaining > 0) {          if (++count >= HOT_COUNT) {            return arguments[0];          }        } else {          count = 0;        }        return func.apply(undefined, arguments);      };    }    /**     * A specialized version of `_.shuffle` which mutates and sets the size of `array`.     *     * @private     * @param {Array} array The array to shuffle.     * @param {number} [size=array.length] The size of `array`.     * @returns {Array} Returns `array`.     */    function shuffleSelf(array, size) {      var index = -1,          length = array.length,          lastIndex = length - 1;      size = size === undefined ? length : size;      while (++index < size) {        var rand = baseRandom(index, lastIndex),            value = array[rand];        array[rand] = array[index];        array[index] = value;      }      array.length = size;      return array;    }    /**     * Converts `string` to a property path array.     *     * @private     * @param {string} string The string to convert.     * @returns {Array} Returns the property path array.     */    var stringToPath = memoizeCapped(function(string) {      var result = [];      if (string.charCodeAt(0) === 46 /* . */) {        result.push('');      }      string.replace(rePropName, function(match, number, quote, subString) {        result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));      });      return result;    });    /**     * Converts `value` to a string key if it's not a string or symbol.     *     * @private     * @param {*} value The value to inspect.     * @returns {string|symbol} Returns the key.     */    function toKey(value) {      if (typeof value == 'string' || isSymbol(value)) {        return value;      }      var result = (value + '');      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;    }    /**     * Converts `func` to its source code.     *     * @private     * @param {Function} func The function to convert.     * @returns {string} Returns the source code.     */    function toSource(func) {      if (func != null) {        try {          return funcToString.call(func);        } catch (e) {}        try {          return (func + '');        } catch (e) {}      }      return '';    }    /**     * Updates wrapper `details` based on `bitmask` flags.     *     * @private     * @returns {Array} details The details to modify.     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.     * @returns {Array} Returns `details`.     */    function updateWrapDetails(details, bitmask) {      arrayEach(wrapFlags, function(pair) {        var value = '_.' + pair[0];        if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {          details.push(value);        }      });      return details.sort();    }    /**     * Creates a clone of `wrapper`.     *     * @private     * @param {Object} wrapper The wrapper to clone.     * @returns {Object} Returns the cloned wrapper.     */    function wrapperClone(wrapper) {      if (wrapper instanceof LazyWrapper) {        return wrapper.clone();      }      var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);      result.__actions__ = copyArray(wrapper.__actions__);      result.__index__  = wrapper.__index__;      result.__values__ = wrapper.__values__;      return result;    }    /*------------------------------------------------------------------------*/    /**     * Creates an array of elements split into groups the length of `size`.     * If `array` can't be split evenly, the final chunk will be the remaining     * elements.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Array     * @param {Array} array The array to process.     * @param {number} [size=1] The length of each chunk     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.     * @returns {Array} Returns the new array of chunks.     * @example     *     * _.chunk(['a', 'b', 'c', 'd'], 2);     * // => [['a', 'b'], ['c', 'd']]     *     * _.chunk(['a', 'b', 'c', 'd'], 3);     * // => [['a', 'b', 'c'], ['d']]     */    function chunk(array, size, guard) {      if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {        size = 1;      } else {        size = nativeMax(toInteger(size), 0);      }      var length = array == null ? 0 : array.length;      if (!length || size < 1) {        return [];      }      var index = 0,          resIndex = 0,          result = Array(nativeCeil(length / size));      while (index < length) {        result[resIndex++] = baseSlice(array, index, (index += size));      }      return result;    }    /**     * Creates an array with all falsey values removed. The values `false`, `null`,     * `0`, `""`, `undefined`, and `NaN` are falsey.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Array     * @param {Array} array The array to compact.     * @returns {Array} Returns the new array of filtered values.     * @example     *     * _.compact([0, 1, false, 2, '', 3]);     * // => [1, 2, 3]     */    function compact(array) {      var index = -1,          length = array == null ? 0 : array.length,          resIndex = 0,          result = [];      while (++index < length) {        var value = array[index];        if (value) {          result[resIndex++] = value;        }      }      return result;    }    /**     * Creates a new array concatenating `array` with any additional arrays     * and/or values.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {Array} array The array to concatenate.     * @param {...*} [values] The values to concatenate.     * @returns {Array} Returns the new concatenated array.     * @example     *     * var array = [1];     * var other = _.concat(array, 2, [3], [[4]]);     *     * console.log(other);     * // => [1, 2, 3, [4]]     *     * console.log(array);     * // => [1]     */    function concat() {      var length = arguments.length;      if (!length) {        return [];      }      var args = Array(length - 1),          array = arguments[0],          index = length;      while (index--) {        args[index - 1] = arguments[index];      }      return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));    }    /**     * Creates an array of `array` values not included in the other given arrays     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)     * for equality comparisons. The order and references of result values are     * determined by the first array.     *     * **Note:** Unlike `_.pullAll`, this method returns a new array.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Array     * @param {Array} array The array to inspect.     * @param {...Array} [values] The values to exclude.     * @returns {Array} Returns the new array of filtered values.     * @see _.without, _.xor     * @example     *     * _.difference([2, 1], [2, 3]);     * // => [1]     */    var difference = baseRest(function(array, values) {      return isArrayLikeObject(array)        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))        : [];    });    /**     * This method is like `_.difference` except that it accepts `iteratee` which     * is invoked for each element of `array` and `values` to generate the criterion     * by which they're compared. The order and references of result values are     * determined by the first array. The iteratee is invoked with one argument:     * (value).     *     * **Note:** Unlike `_.pullAllBy`, this method returns a new array.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {Array} array The array to inspect.     * @param {...Array} [values] The values to exclude.     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.     * @returns {Array} Returns the new array of filtered values.     * @example     *     * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);     * // => [1.2]     *     * // The `_.property` iteratee shorthand.     * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');     * // => [{ 'x': 2 }]     */    var differenceBy = baseRest(function(array, values) {      var iteratee = last(values);      if (isArrayLikeObject(iteratee)) {        iteratee = undefined;      }      return isArrayLikeObject(array)        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))        : [];    });    /**     * This method is like `_.difference` except that it accepts `comparator`     * which is invoked to compare elements of `array` to `values`. The order and     * references of result values are determined by the first array. The comparator     * is invoked with two arguments: (arrVal, othVal).     *     * **Note:** Unlike `_.pullAllWith`, this method returns a new array.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {Array} array The array to inspect.     * @param {...Array} [values] The values to exclude.     * @param {Function} [comparator] The comparator invoked per element.     * @returns {Array} Returns the new array of filtered values.     * @example     *     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];     *     * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);     * // => [{ 'x': 2, 'y': 1 }]     */    var differenceWith = baseRest(function(array, values) {      var comparator = last(values);      if (isArrayLikeObject(comparator)) {        comparator = undefined;      }      return isArrayLikeObject(array)        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)        : [];    });    /**     * Creates a slice of `array` with `n` elements dropped from the beginning.     *     * @static     * @memberOf _     * @since 0.5.0     * @category Array     * @param {Array} array The array to query.     * @param {number} [n=1] The number of elements to drop.     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.     * @returns {Array} Returns the slice of `array`.     * @example     *     * _.drop([1, 2, 3]);     * // => [2, 3]     *     * _.drop([1, 2, 3], 2);     * // => [3]     *     * _.drop([1, 2, 3], 5);     * // => []     *     * _.drop([1, 2, 3], 0);     * // => [1, 2, 3]     */    function drop(array, n, guard) {      var length = array == null ? 0 : array.length;      if (!length) {        return [];      }      n = (guard || n === undefined) ? 1 : toInteger(n);      return baseSlice(array, n < 0 ? 0 : n, length);    }    /**     * Creates a slice of `array` with `n` elements dropped from the end.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Array     * @param {Array} array The array to query.     * @param {number} [n=1] The number of elements to drop.     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.     * @returns {Array} Returns the slice of `array`.     * @example     *     * _.dropRight([1, 2, 3]);     * // => [1, 2]     *     * _.dropRight([1, 2, 3], 2);     * // => [1]     *     * _.dropRight([1, 2, 3], 5);     * // => []     *     * _.dropRight([1, 2, 3], 0);     * // => [1, 2, 3]     */    function dropRight(array, n, guard) {      var length = array == null ? 0 : array.length;      if (!length) {        return [];      }      n = (guard || n === undefined) ? 1 : toInteger(n);      n = length - n;      return baseSlice(array, 0, n < 0 ? 0 : n);    }    /**     * Creates a slice of `array` excluding elements dropped from the end.     * Elements are dropped until `predicate` returns falsey. The predicate is     * invoked with three arguments: (value, index, array).     *     * @static     * @memberOf _     * @since 3.0.0     * @category Array     * @param {Array} array The array to query.     * @param {Function} [predicate=_.identity] The function invoked per iteration.     * @returns {Array} Returns the slice of `array`.     * @example     *     * var users = [     *   { 'user': 'barney',  'active': true },     *   { 'user': 'fred',    'active': false },     *   { 'user': 'pebbles', 'active': false }     * ];     *     * _.dropRightWhile(users, function(o) { return !o.active; });     * // => objects for ['barney']     *     * // The `_.matches` iteratee shorthand.     * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });     * // => objects for ['barney', 'fred']     *     * // The `_.matchesProperty` iteratee shorthand.     * _.dropRightWhile(users, ['active', false]);     * // => objects for ['barney']     *     * // The `_.property` iteratee shorthand.     * _.dropRightWhile(users, 'active');     * // => objects for ['barney', 'fred', 'pebbles']     */    function dropRightWhile(array, predicate) {      return (array && array.length)        ? baseWhile(array, getIteratee(predicate, 3), true, true)        : [];    }    /**     * Creates a slice of `array` excluding elements dropped from the beginning.     * Elements are dropped until `predicate` returns falsey. The predicate is     * invoked with three arguments: (value, index, array).     *     * @static     * @memberOf _     * @since 3.0.0     * @category Array     * @param {Array} array The array to query.     * @param {Function} [predicate=_.identity] The function invoked per iteration.     * @returns {Array} Returns the slice of `array`.     * @example     *     * var users = [     *   { 'user': 'barney',  'active': false },     *   { 'user': 'fred',    'active': false },     *   { 'user': 'pebbles', 'active': true }     * ];     *     * _.dropWhile(users, function(o) { return !o.active; });     * // => objects for ['pebbles']     *     * // The `_.matches` iteratee shorthand.     * _.dropWhile(users, { 'user': 'barney', 'active': false });     * // => objects for ['fred', 'pebbles']     *     * // The `_.matchesProperty` iteratee shorthand.     * _.dropWhile(users, ['active', false]);     * // => objects for ['pebbles']     *     * // The `_.property` iteratee shorthand.     * _.dropWhile(users, 'active');     * // => objects for ['barney', 'fred', 'pebbles']     */    function dropWhile(array, predicate) {      return (array && array.length)        ? baseWhile(array, getIteratee(predicate, 3), true)        : [];    }    /**     * Fills elements of `array` with `value` from `start` up to, but not     * including, `end`.     *     * **Note:** This method mutates `array`.     *     * @static     * @memberOf _     * @since 3.2.0     * @category Array     * @param {Array} array The array to fill.     * @param {*} value The value to fill `array` with.     * @param {number} [start=0] The start position.     * @param {number} [end=array.length] The end position.     * @returns {Array} Returns `array`.     * @example     *     * var array = [1, 2, 3];     *     * _.fill(array, 'a');     * console.log(array);     * // => ['a', 'a', 'a']     *     * _.fill(Array(3), 2);     * // => [2, 2, 2]     *     * _.fill([4, 6, 8, 10], '*', 1, 3);     * // => [4, '*', '*', 10]     */    function fill(array, value, start, end) {      var length = array == null ? 0 : array.length;      if (!length) {        return [];      }      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {        start = 0;        end = length;      }      return baseFill(array, value, start, end);    }    /**     * This method is like `_.find` except that it returns the index of the first     * element `predicate` returns truthy for instead of the element itself.     *     * @static     * @memberOf _     * @since 1.1.0     * @category Array     * @param {Array} array The array to inspect.     * @param {Function} [predicate=_.identity] The function invoked per iteration.     * @param {number} [fromIndex=0] The index to search from.     * @returns {number} Returns the index of the found element, else `-1`.     * @example     *     * var users = [     *   { 'user': 'barney',  'active': false },     *   { 'user': 'fred',    'active': false },     *   { 'user': 'pebbles', 'active': true }     * ];     *     * _.findIndex(users, function(o) { return o.user == 'barney'; });     * // => 0     *     * // The `_.matches` iteratee shorthand.     * _.findIndex(users, { 'user': 'fred', 'active': false });     * // => 1     *     * // The `_.matchesProperty` iteratee shorthand.     * _.findIndex(users, ['active', false]);     * // => 0     *     * // The `_.property` iteratee shorthand.     * _.findIndex(users, 'active');     * // => 2     */    function findIndex(array, predicate, fromIndex) {      var length = array == null ? 0 : array.length;      if (!length) {        return -1;      }      var index = fromIndex == null ? 0 : toInteger(fromIndex);      if (index < 0) {        index = nativeMax(length + index, 0);      }      return baseFindIndex(array, getIteratee(predicate, 3), index);    }    /**     * This method is like `_.findIndex` except that it iterates over elements     * of `collection` from right to left.     *     * @static     * @memberOf _     * @since 2.0.0     * @category Array     * @param {Array} array The array to inspect.     * @param {Function} [predicate=_.identity] The function invoked per iteration.     * @param {number} [fromIndex=array.length-1] The index to search from.     * @returns {number} Returns the index of the found element, else `-1`.     * @example     *     * var users = [     *   { 'user': 'barney',  'active': true },     *   { 'user': 'fred',    'active': false },     *   { 'user': 'pebbles', 'active': false }     * ];     *     * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });     * // => 2     *     * // The `_.matches` iteratee shorthand.     * _.findLastIndex(users, { 'user': 'barney', 'active': true });     * // => 0     *     * // The `_.matchesProperty` iteratee shorthand.     * _.findLastIndex(users, ['active', false]);     * // => 2     *     * // The `_.property` iteratee shorthand.     * _.findLastIndex(users, 'active');     * // => 0     */    function findLastIndex(array, predicate, fromIndex) {      var length = array == null ? 0 : array.length;      if (!length) {        return -1;      }      var index = length - 1;      if (fromIndex !== undefined) {        index = toInteger(fromIndex);        index = fromIndex < 0          ? nativeMax(length + index, 0)          : nativeMin(index, length - 1);      }      return baseFindIndex(array, getIteratee(predicate, 3), index, true);    }    /**     * Flattens `array` a single level deep.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Array     * @param {Array} array The array to flatten.     * @returns {Array} Returns the new flattened array.     * @example     *     * _.flatten([1, [2, [3, [4]], 5]]);     * // => [1, 2, [3, [4]], 5]     */    function flatten(array) {      var length = array == null ? 0 : array.length;      return length ? baseFlatten(array, 1) : [];    }    /**     * Recursively flattens `array`.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Array     * @param {Array} array The array to flatten.     * @returns {Array} Returns the new flattened array.     * @example     *     * _.flattenDeep([1, [2, [3, [4]], 5]]);     * // => [1, 2, 3, 4, 5]     */    function flattenDeep(array) {      var length = array == null ? 0 : array.length;      return length ? baseFlatten(array, INFINITY) : [];    }    /**     * Recursively flatten `array` up to `depth` times.     *     * @static     * @memberOf _     * @since 4.4.0     * @category Array     * @param {Array} array The array to flatten.     * @param {number} [depth=1] The maximum recursion depth.     * @returns {Array} Returns the new flattened array.     * @example     *     * var array = [1, [2, [3, [4]], 5]];     *     * _.flattenDepth(array, 1);     * // => [1, 2, [3, [4]], 5]     *     * _.flattenDepth(array, 2);     * // => [1, 2, 3, [4], 5]     */    function flattenDepth(array, depth) {      var length = array == null ? 0 : array.length;      if (!length) {        return [];      }      depth = depth === undefined ? 1 : toInteger(depth);      return baseFlatten(array, depth);    }    /**     * The inverse of `_.toPairs`; this method returns an object composed     * from key-value `pairs`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {Array} pairs The key-value pairs.     * @returns {Object} Returns the new object.     * @example     *     * _.fromPairs([['a', 1], ['b', 2]]);     * // => { 'a': 1, 'b': 2 }     */    function fromPairs(pairs) {      var index = -1,          length = pairs == null ? 0 : pairs.length,          result = {};      while (++index < length) {        var pair = pairs[index];        result[pair[0]] = pair[1];      }      return result;    }    /**     * Gets the first element of `array`.     *     * @static     * @memberOf _     * @since 0.1.0     * @alias first     * @category Array     * @param {Array} array The array to query.     * @returns {*} Returns the first element of `array`.     * @example     *     * _.head([1, 2, 3]);     * // => 1     *     * _.head([]);     * // => undefined     */    function head(array) {      return (array && array.length) ? array[0] : undefined;    }    /**     * Gets the index at which the first occurrence of `value` is found in `array`     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)     * for equality comparisons. If `fromIndex` is negative, it's used as the     * offset from the end of `array`.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Array     * @param {Array} array The array to inspect.     * @param {*} value The value to search for.     * @param {number} [fromIndex=0] The index to search from.     * @returns {number} Returns the index of the matched value, else `-1`.     * @example     *     * _.indexOf([1, 2, 1, 2], 2);     * // => 1     *     * // Search from the `fromIndex`.     * _.indexOf([1, 2, 1, 2], 2, 2);     * // => 3     */    function indexOf(array, value, fromIndex) {      var length = array == null ? 0 : array.length;      if (!length) {        return -1;      }      var index = fromIndex == null ? 0 : toInteger(fromIndex);      if (index < 0) {        index = nativeMax(length + index, 0);      }      return baseIndexOf(array, value, index);    }    /**     * Gets all but the last element of `array`.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Array     * @param {Array} array The array to query.     * @returns {Array} Returns the slice of `array`.     * @example     *     * _.initial([1, 2, 3]);     * // => [1, 2]     */    function initial(array) {      var length = array == null ? 0 : array.length;      return length ? baseSlice(array, 0, -1) : [];    }    /**     * Creates an array of unique values that are included in all given arrays     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)     * for equality comparisons. The order and references of result values are     * determined by the first array.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Array     * @param {...Array} [arrays] The arrays to inspect.     * @returns {Array} Returns the new array of intersecting values.     * @example     *     * _.intersection([2, 1], [2, 3]);     * // => [2]     */    var intersection = baseRest(function(arrays) {      var mapped = arrayMap(arrays, castArrayLikeObject);      return (mapped.length && mapped[0] === arrays[0])        ? baseIntersection(mapped)        : [];    });    /**     * This method is like `_.intersection` except that it accepts `iteratee`     * which is invoked for each element of each `arrays` to generate the criterion     * by which they're compared. The order and references of result values are     * determined by the first array. The iteratee is invoked with one argument:     * (value).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {...Array} [arrays] The arrays to inspect.     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.     * @returns {Array} Returns the new array of intersecting values.     * @example     *     * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);     * // => [2.1]     *     * // The `_.property` iteratee shorthand.     * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');     * // => [{ 'x': 1 }]     */    var intersectionBy = baseRest(function(arrays) {      var iteratee = last(arrays),          mapped = arrayMap(arrays, castArrayLikeObject);      if (iteratee === last(mapped)) {        iteratee = undefined;      } else {        mapped.pop();      }      return (mapped.length && mapped[0] === arrays[0])        ? baseIntersection(mapped, getIteratee(iteratee, 2))        : [];    });    /**     * This method is like `_.intersection` except that it accepts `comparator`     * which is invoked to compare elements of `arrays`. The order and references     * of result values are determined by the first array. The comparator is     * invoked with two arguments: (arrVal, othVal).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {...Array} [arrays] The arrays to inspect.     * @param {Function} [comparator] The comparator invoked per element.     * @returns {Array} Returns the new array of intersecting values.     * @example     *     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];     *     * _.intersectionWith(objects, others, _.isEqual);     * // => [{ 'x': 1, 'y': 2 }]     */    var intersectionWith = baseRest(function(arrays) {      var comparator = last(arrays),          mapped = arrayMap(arrays, castArrayLikeObject);      comparator = typeof comparator == 'function' ? comparator : undefined;      if (comparator) {        mapped.pop();      }      return (mapped.length && mapped[0] === arrays[0])        ? baseIntersection(mapped, undefined, comparator)        : [];    });    /**     * Converts all elements in `array` into a string separated by `separator`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {Array} array The array to convert.     * @param {string} [separator=','] The element separator.     * @returns {string} Returns the joined string.     * @example     *     * _.join(['a', 'b', 'c'], '~');     * // => 'a~b~c'     */    function join(array, separator) {      return array == null ? '' : nativeJoin.call(array, separator);    }    /**     * Gets the last element of `array`.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Array     * @param {Array} array The array to query.     * @returns {*} Returns the last element of `array`.     * @example     *     * _.last([1, 2, 3]);     * // => 3     */    function last(array) {      var length = array == null ? 0 : array.length;      return length ? array[length - 1] : undefined;    }    /**     * This method is like `_.indexOf` except that it iterates over elements of     * `array` from right to left.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Array     * @param {Array} array The array to inspect.     * @param {*} value The value to search for.     * @param {number} [fromIndex=array.length-1] The index to search from.     * @returns {number} Returns the index of the matched value, else `-1`.     * @example     *     * _.lastIndexOf([1, 2, 1, 2], 2);     * // => 3     *     * // Search from the `fromIndex`.     * _.lastIndexOf([1, 2, 1, 2], 2, 2);     * // => 1     */    function lastIndexOf(array, value, fromIndex) {      var length = array == null ? 0 : array.length;      if (!length) {        return -1;      }      var index = length;      if (fromIndex !== undefined) {        index = toInteger(fromIndex);        index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);      }      return value === value        ? strictLastIndexOf(array, value, index)        : baseFindIndex(array, baseIsNaN, index, true);    }    /**     * Gets the element at index `n` of `array`. If `n` is negative, the nth     * element from the end is returned.     *     * @static     * @memberOf _     * @since 4.11.0     * @category Array     * @param {Array} array The array to query.     * @param {number} [n=0] The index of the element to return.     * @returns {*} Returns the nth element of `array`.     * @example     *     * var array = ['a', 'b', 'c', 'd'];     *     * _.nth(array, 1);     * // => 'b'     *     * _.nth(array, -2);     * // => 'c';     */    function nth(array, n) {      return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;    }    /**     * Removes all given values from `array` using     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)     * for equality comparisons.     *     * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`     * to remove elements from an array by predicate.     *     * @static     * @memberOf _     * @since 2.0.0     * @category Array     * @param {Array} array The array to modify.     * @param {...*} [values] The values to remove.     * @returns {Array} Returns `array`.     * @example     *     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];     *     * _.pull(array, 'a', 'c');     * console.log(array);     * // => ['b', 'b']     */    var pull = baseRest(pullAll);    /**     * This method is like `_.pull` except that it accepts an array of values to remove.     *     * **Note:** Unlike `_.difference`, this method mutates `array`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {Array} array The array to modify.     * @param {Array} values The values to remove.     * @returns {Array} Returns `array`.     * @example     *     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];     *     * _.pullAll(array, ['a', 'c']);     * console.log(array);     * // => ['b', 'b']     */    function pullAll(array, values) {      return (array && array.length && values && values.length)        ? basePullAll(array, values)        : array;    }    /**     * This method is like `_.pullAll` except that it accepts `iteratee` which is     * invoked for each element of `array` and `values` to generate the criterion     * by which they're compared. The iteratee is invoked with one argument: (value).     *     * **Note:** Unlike `_.differenceBy`, this method mutates `array`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {Array} array The array to modify.     * @param {Array} values The values to remove.     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.     * @returns {Array} Returns `array`.     * @example     *     * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];     *     * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');     * console.log(array);     * // => [{ 'x': 2 }]     */    function pullAllBy(array, values, iteratee) {      return (array && array.length && values && values.length)        ? basePullAll(array, values, getIteratee(iteratee, 2))        : array;    }    /**     * This method is like `_.pullAll` except that it accepts `comparator` which     * is invoked to compare elements of `array` to `values`. The comparator is     * invoked with two arguments: (arrVal, othVal).     *     * **Note:** Unlike `_.differenceWith`, this method mutates `array`.     *     * @static     * @memberOf _     * @since 4.6.0     * @category Array     * @param {Array} array The array to modify.     * @param {Array} values The values to remove.     * @param {Function} [comparator] The comparator invoked per element.     * @returns {Array} Returns `array`.     * @example     *     * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];     *     * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);     * console.log(array);     * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]     */    function pullAllWith(array, values, comparator) {      return (array && array.length && values && values.length)        ? basePullAll(array, values, undefined, comparator)        : array;    }    /**     * Removes elements from `array` corresponding to `indexes` and returns an     * array of removed elements.     *     * **Note:** Unlike `_.at`, this method mutates `array`.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Array     * @param {Array} array The array to modify.     * @param {...(number|number[])} [indexes] The indexes of elements to remove.     * @returns {Array} Returns the new array of removed elements.     * @example     *     * var array = ['a', 'b', 'c', 'd'];     * var pulled = _.pullAt(array, [1, 3]);     *     * console.log(array);     * // => ['a', 'c']     *     * console.log(pulled);     * // => ['b', 'd']     */    var pullAt = flatRest(function(array, indexes) {      var length = array == null ? 0 : array.length,          result = baseAt(array, indexes);      basePullAt(array, arrayMap(indexes, function(index) {        return isIndex(index, length) ? +index : index;      }).sort(compareAscending));      return result;    });    /**     * Removes all elements from `array` that `predicate` returns truthy for     * and returns an array of the removed elements. The predicate is invoked     * with three arguments: (value, index, array).     *     * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`     * to pull elements from an array by value.     *     * @static     * @memberOf _     * @since 2.0.0     * @category Array     * @param {Array} array The array to modify.     * @param {Function} [predicate=_.identity] The function invoked per iteration.     * @returns {Array} Returns the new array of removed elements.     * @example     *     * var array = [1, 2, 3, 4];     * var evens = _.remove(array, function(n) {     *   return n % 2 == 0;     * });     *     * console.log(array);     * // => [1, 3]     *     * console.log(evens);     * // => [2, 4]     */    function remove(array, predicate) {      var result = [];      if (!(array && array.length)) {        return result;      }      var index = -1,          indexes = [],          length = array.length;      predicate = getIteratee(predicate, 3);      while (++index < length) {        var value = array[index];        if (predicate(value, index, array)) {          result.push(value);          indexes.push(index);        }      }      basePullAt(array, indexes);      return result;    }    /**     * Reverses `array` so that the first element becomes the last, the second     * element becomes the second to last, and so on.     *     * **Note:** This method mutates `array` and is based on     * [`Array#reverse`](https://mdn.io/Array/reverse).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {Array} array The array to modify.     * @returns {Array} Returns `array`.     * @example     *     * var array = [1, 2, 3];     *     * _.reverse(array);     * // => [3, 2, 1]     *     * console.log(array);     * // => [3, 2, 1]     */    function reverse(array) {      return array == null ? array : nativeReverse.call(array);    }    /**     * Creates a slice of `array` from `start` up to, but not including, `end`.     *     * **Note:** This method is used instead of     * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are     * returned.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Array     * @param {Array} array The array to slice.     * @param {number} [start=0] The start position.     * @param {number} [end=array.length] The end position.     * @returns {Array} Returns the slice of `array`.     */    function slice(array, start, end) {      var length = array == null ? 0 : array.length;      if (!length) {        return [];      }      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {        start = 0;        end = length;      }      else {        start = start == null ? 0 : toInteger(start);        end = end === undefined ? length : toInteger(end);      }      return baseSlice(array, start, end);    }    /**     * Uses a binary search to determine the lowest index at which `value`     * should be inserted into `array` in order to maintain its sort order.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Array     * @param {Array} array The sorted array to inspect.     * @param {*} value The value to evaluate.     * @returns {number} Returns the index at which `value` should be inserted     *  into `array`.     * @example     *     * _.sortedIndex([30, 50], 40);     * // => 1     */    function sortedIndex(array, value) {      return baseSortedIndex(array, value);    }    /**     * This method is like `_.sortedIndex` except that it accepts `iteratee`     * which is invoked for `value` and each element of `array` to compute their     * sort ranking. The iteratee is invoked with one argument: (value).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {Array} array The sorted array to inspect.     * @param {*} value The value to evaluate.     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.     * @returns {number} Returns the index at which `value` should be inserted     *  into `array`.     * @example     *     * var objects = [{ 'x': 4 }, { 'x': 5 }];     *     * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });     * // => 0     *     * // The `_.property` iteratee shorthand.     * _.sortedIndexBy(objects, { 'x': 4 }, 'x');     * // => 0     */    function sortedIndexBy(array, value, iteratee) {      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));    }    /**     * This method is like `_.indexOf` except that it performs a binary     * search on a sorted `array`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {Array} array The array to inspect.     * @param {*} value The value to search for.     * @returns {number} Returns the index of the matched value, else `-1`.     * @example     *     * _.sortedIndexOf([4, 5, 5, 5, 6], 5);     * // => 1     */    function sortedIndexOf(array, value) {      var length = array == null ? 0 : array.length;      if (length) {        var index = baseSortedIndex(array, value);        if (index < length && eq(array[index], value)) {          return index;        }      }      return -1;    }    /**     * This method is like `_.sortedIndex` except that it returns the highest     * index at which `value` should be inserted into `array` in order to     * maintain its sort order.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Array     * @param {Array} array The sorted array to inspect.     * @param {*} value The value to evaluate.     * @returns {number} Returns the index at which `value` should be inserted     *  into `array`.     * @example     *     * _.sortedLastIndex([4, 5, 5, 5, 6], 5);     * // => 4     */    function sortedLastIndex(array, value) {      return baseSortedIndex(array, value, true);    }    /**     * This method is like `_.sortedLastIndex` except that it accepts `iteratee`     * which is invoked for `value` and each element of `array` to compute their     * sort ranking. The iteratee is invoked with one argument: (value).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {Array} array The sorted array to inspect.     * @param {*} value The value to evaluate.     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.     * @returns {number} Returns the index at which `value` should be inserted     *  into `array`.     * @example     *     * var objects = [{ 'x': 4 }, { 'x': 5 }];     *     * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });     * // => 1     *     * // The `_.property` iteratee shorthand.     * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');     * // => 1     */    function sortedLastIndexBy(array, value, iteratee) {      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);    }    /**     * This method is like `_.lastIndexOf` except that it performs a binary     * search on a sorted `array`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {Array} array The array to inspect.     * @param {*} value The value to search for.     * @returns {number} Returns the index of the matched value, else `-1`.     * @example     *     * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);     * // => 3     */    function sortedLastIndexOf(array, value) {      var length = array == null ? 0 : array.length;      if (length) {        var index = baseSortedIndex(array, value, true) - 1;        if (eq(array[index], value)) {          return index;        }      }      return -1;    }    /**     * This method is like `_.uniq` except that it's designed and optimized     * for sorted arrays.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {Array} array The array to inspect.     * @returns {Array} Returns the new duplicate free array.     * @example     *     * _.sortedUniq([1, 1, 2]);     * // => [1, 2]     */    function sortedUniq(array) {      return (array && array.length)        ? baseSortedUniq(array)        : [];    }    /**     * This method is like `_.uniqBy` except that it's designed and optimized     * for sorted arrays.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {Array} array The array to inspect.     * @param {Function} [iteratee] The iteratee invoked per element.     * @returns {Array} Returns the new duplicate free array.     * @example     *     * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);     * // => [1.1, 2.3]     */    function sortedUniqBy(array, iteratee) {      return (array && array.length)        ? baseSortedUniq(array, getIteratee(iteratee, 2))        : [];    }    /**     * Gets all but the first element of `array`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {Array} array The array to query.     * @returns {Array} Returns the slice of `array`.     * @example     *     * _.tail([1, 2, 3]);     * // => [2, 3]     */    function tail(array) {      var length = array == null ? 0 : array.length;      return length ? baseSlice(array, 1, length) : [];    }    /**     * Creates a slice of `array` with `n` elements taken from the beginning.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Array     * @param {Array} array The array to query.     * @param {number} [n=1] The number of elements to take.     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.     * @returns {Array} Returns the slice of `array`.     * @example     *     * _.take([1, 2, 3]);     * // => [1]     *     * _.take([1, 2, 3], 2);     * // => [1, 2]     *     * _.take([1, 2, 3], 5);     * // => [1, 2, 3]     *     * _.take([1, 2, 3], 0);     * // => []     */    function take(array, n, guard) {      if (!(array && array.length)) {        return [];      }      n = (guard || n === undefined) ? 1 : toInteger(n);      return baseSlice(array, 0, n < 0 ? 0 : n);    }    /**     * Creates a slice of `array` with `n` elements taken from the end.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Array     * @param {Array} array The array to query.     * @param {number} [n=1] The number of elements to take.     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.     * @returns {Array} Returns the slice of `array`.     * @example     *     * _.takeRight([1, 2, 3]);     * // => [3]     *     * _.takeRight([1, 2, 3], 2);     * // => [2, 3]     *     * _.takeRight([1, 2, 3], 5);     * // => [1, 2, 3]     *     * _.takeRight([1, 2, 3], 0);     * // => []     */    function takeRight(array, n, guard) {      var length = array == null ? 0 : array.length;      if (!length) {        return [];      }      n = (guard || n === undefined) ? 1 : toInteger(n);      n = length - n;      return baseSlice(array, n < 0 ? 0 : n, length);    }    /**     * Creates a slice of `array` with elements taken from the end. Elements are     * taken until `predicate` returns falsey. The predicate is invoked with     * three arguments: (value, index, array).     *     * @static     * @memberOf _     * @since 3.0.0     * @category Array     * @param {Array} array The array to query.     * @param {Function} [predicate=_.identity] The function invoked per iteration.     * @returns {Array} Returns the slice of `array`.     * @example     *     * var users = [     *   { 'user': 'barney',  'active': true },     *   { 'user': 'fred',    'active': false },     *   { 'user': 'pebbles', 'active': false }     * ];     *     * _.takeRightWhile(users, function(o) { return !o.active; });     * // => objects for ['fred', 'pebbles']     *     * // The `_.matches` iteratee shorthand.     * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });     * // => objects for ['pebbles']     *     * // The `_.matchesProperty` iteratee shorthand.     * _.takeRightWhile(users, ['active', false]);     * // => objects for ['fred', 'pebbles']     *     * // The `_.property` iteratee shorthand.     * _.takeRightWhile(users, 'active');     * // => []     */    function takeRightWhile(array, predicate) {      return (array && array.length)        ? baseWhile(array, getIteratee(predicate, 3), false, true)        : [];    }    /**     * Creates a slice of `array` with elements taken from the beginning. Elements     * are taken until `predicate` returns falsey. The predicate is invoked with     * three arguments: (value, index, array).     *     * @static     * @memberOf _     * @since 3.0.0     * @category Array     * @param {Array} array The array to query.     * @param {Function} [predicate=_.identity] The function invoked per iteration.     * @returns {Array} Returns the slice of `array`.     * @example     *     * var users = [     *   { 'user': 'barney',  'active': false },     *   { 'user': 'fred',    'active': false },     *   { 'user': 'pebbles', 'active': true }     * ];     *     * _.takeWhile(users, function(o) { return !o.active; });     * // => objects for ['barney', 'fred']     *     * // The `_.matches` iteratee shorthand.     * _.takeWhile(users, { 'user': 'barney', 'active': false });     * // => objects for ['barney']     *     * // The `_.matchesProperty` iteratee shorthand.     * _.takeWhile(users, ['active', false]);     * // => objects for ['barney', 'fred']     *     * // The `_.property` iteratee shorthand.     * _.takeWhile(users, 'active');     * // => []     */    function takeWhile(array, predicate) {      return (array && array.length)        ? baseWhile(array, getIteratee(predicate, 3))        : [];    }    /**     * Creates an array of unique values, in order, from all given arrays using     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)     * for equality comparisons.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Array     * @param {...Array} [arrays] The arrays to inspect.     * @returns {Array} Returns the new array of combined values.     * @example     *     * _.union([2], [1, 2]);     * // => [2, 1]     */    var union = baseRest(function(arrays) {      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));    });    /**     * This method is like `_.union` except that it accepts `iteratee` which is     * invoked for each element of each `arrays` to generate the criterion by     * which uniqueness is computed. Result values are chosen from the first     * array in which the value occurs. The iteratee is invoked with one argument:     * (value).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {...Array} [arrays] The arrays to inspect.     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.     * @returns {Array} Returns the new array of combined values.     * @example     *     * _.unionBy([2.1], [1.2, 2.3], Math.floor);     * // => [2.1, 1.2]     *     * // The `_.property` iteratee shorthand.     * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');     * // => [{ 'x': 1 }, { 'x': 2 }]     */    var unionBy = baseRest(function(arrays) {      var iteratee = last(arrays);      if (isArrayLikeObject(iteratee)) {        iteratee = undefined;      }      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));    });    /**     * This method is like `_.union` except that it accepts `comparator` which     * is invoked to compare elements of `arrays`. Result values are chosen from     * the first array in which the value occurs. The comparator is invoked     * with two arguments: (arrVal, othVal).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {...Array} [arrays] The arrays to inspect.     * @param {Function} [comparator] The comparator invoked per element.     * @returns {Array} Returns the new array of combined values.     * @example     *     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];     *     * _.unionWith(objects, others, _.isEqual);     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]     */    var unionWith = baseRest(function(arrays) {      var comparator = last(arrays);      comparator = typeof comparator == 'function' ? comparator : undefined;      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);    });    /**     * Creates a duplicate-free version of an array, using     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)     * for equality comparisons, in which only the first occurrence of each element     * is kept. The order of result values is determined by the order they occur     * in the array.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Array     * @param {Array} array The array to inspect.     * @returns {Array} Returns the new duplicate free array.     * @example     *     * _.uniq([2, 1, 2]);     * // => [2, 1]     */    function uniq(array) {      return (array && array.length) ? baseUniq(array) : [];    }    /**     * This method is like `_.uniq` except that it accepts `iteratee` which is     * invoked for each element in `array` to generate the criterion by which     * uniqueness is computed. The order of result values is determined by the     * order they occur in the array. The iteratee is invoked with one argument:     * (value).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {Array} array The array to inspect.     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.     * @returns {Array} Returns the new duplicate free array.     * @example     *     * _.uniqBy([2.1, 1.2, 2.3], Math.floor);     * // => [2.1, 1.2]     *     * // The `_.property` iteratee shorthand.     * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');     * // => [{ 'x': 1 }, { 'x': 2 }]     */    function uniqBy(array, iteratee) {      return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];    }    /**     * This method is like `_.uniq` except that it accepts `comparator` which     * is invoked to compare elements of `array`. The order of result values is     * determined by the order they occur in the array.The comparator is invoked     * with two arguments: (arrVal, othVal).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {Array} array The array to inspect.     * @param {Function} [comparator] The comparator invoked per element.     * @returns {Array} Returns the new duplicate free array.     * @example     *     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];     *     * _.uniqWith(objects, _.isEqual);     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]     */    function uniqWith(array, comparator) {      comparator = typeof comparator == 'function' ? comparator : undefined;      return (array && array.length) ? baseUniq(array, undefined, comparator) : [];    }    /**     * This method is like `_.zip` except that it accepts an array of grouped     * elements and creates an array regrouping the elements to their pre-zip     * configuration.     *     * @static     * @memberOf _     * @since 1.2.0     * @category Array     * @param {Array} array The array of grouped elements to process.     * @returns {Array} Returns the new array of regrouped elements.     * @example     *     * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);     * // => [['a', 1, true], ['b', 2, false]]     *     * _.unzip(zipped);     * // => [['a', 'b'], [1, 2], [true, false]]     */    function unzip(array) {      if (!(array && array.length)) {        return [];      }      var length = 0;      array = arrayFilter(array, function(group) {        if (isArrayLikeObject(group)) {          length = nativeMax(group.length, length);          return true;        }      });      return baseTimes(length, function(index) {        return arrayMap(array, baseProperty(index));      });    }    /**     * This method is like `_.unzip` except that it accepts `iteratee` to specify     * how regrouped values should be combined. The iteratee is invoked with the     * elements of each group: (...group).     *     * @static     * @memberOf _     * @since 3.8.0     * @category Array     * @param {Array} array The array of grouped elements to process.     * @param {Function} [iteratee=_.identity] The function to combine     *  regrouped values.     * @returns {Array} Returns the new array of regrouped elements.     * @example     *     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);     * // => [[1, 10, 100], [2, 20, 200]]     *     * _.unzipWith(zipped, _.add);     * // => [3, 30, 300]     */    function unzipWith(array, iteratee) {      if (!(array && array.length)) {        return [];      }      var result = unzip(array);      if (iteratee == null) {        return result;      }      return arrayMap(result, function(group) {        return apply(iteratee, undefined, group);      });    }    /**     * Creates an array excluding all given values using     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)     * for equality comparisons.     *     * **Note:** Unlike `_.pull`, this method returns a new array.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Array     * @param {Array} array The array to inspect.     * @param {...*} [values] The values to exclude.     * @returns {Array} Returns the new array of filtered values.     * @see _.difference, _.xor     * @example     *     * _.without([2, 1, 2, 3], 1, 2);     * // => [3]     */    var without = baseRest(function(array, values) {      return isArrayLikeObject(array)        ? baseDifference(array, values)        : [];    });    /**     * Creates an array of unique values that is the     * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)     * of the given arrays. The order of result values is determined by the order     * they occur in the arrays.     *     * @static     * @memberOf _     * @since 2.4.0     * @category Array     * @param {...Array} [arrays] The arrays to inspect.     * @returns {Array} Returns the new array of filtered values.     * @see _.difference, _.without     * @example     *     * _.xor([2, 1], [2, 3]);     * // => [1, 3]     */    var xor = baseRest(function(arrays) {      return baseXor(arrayFilter(arrays, isArrayLikeObject));    });    /**     * This method is like `_.xor` except that it accepts `iteratee` which is     * invoked for each element of each `arrays` to generate the criterion by     * which by which they're compared. The order of result values is determined     * by the order they occur in the arrays. The iteratee is invoked with one     * argument: (value).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {...Array} [arrays] The arrays to inspect.     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.     * @returns {Array} Returns the new array of filtered values.     * @example     *     * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);     * // => [1.2, 3.4]     *     * // The `_.property` iteratee shorthand.     * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');     * // => [{ 'x': 2 }]     */    var xorBy = baseRest(function(arrays) {      var iteratee = last(arrays);      if (isArrayLikeObject(iteratee)) {        iteratee = undefined;      }      return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));    });    /**     * This method is like `_.xor` except that it accepts `comparator` which is     * invoked to compare elements of `arrays`. The order of result values is     * determined by the order they occur in the arrays. The comparator is invoked     * with two arguments: (arrVal, othVal).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Array     * @param {...Array} [arrays] The arrays to inspect.     * @param {Function} [comparator] The comparator invoked per element.     * @returns {Array} Returns the new array of filtered values.     * @example     *     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];     *     * _.xorWith(objects, others, _.isEqual);     * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]     */    var xorWith = baseRest(function(arrays) {      var comparator = last(arrays);      comparator = typeof comparator == 'function' ? comparator : undefined;      return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);    });    /**     * Creates an array of grouped elements, the first of which contains the     * first elements of the given arrays, the second of which contains the     * second elements of the given arrays, and so on.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Array     * @param {...Array} [arrays] The arrays to process.     * @returns {Array} Returns the new array of grouped elements.     * @example     *     * _.zip(['a', 'b'], [1, 2], [true, false]);     * // => [['a', 1, true], ['b', 2, false]]     */    var zip = baseRest(unzip);    /**     * This method is like `_.fromPairs` except that it accepts two arrays,     * one of property identifiers and one of corresponding values.     *     * @static     * @memberOf _     * @since 0.4.0     * @category Array     * @param {Array} [props=[]] The property identifiers.     * @param {Array} [values=[]] The property values.     * @returns {Object} Returns the new object.     * @example     *     * _.zipObject(['a', 'b'], [1, 2]);     * // => { 'a': 1, 'b': 2 }     */    function zipObject(props, values) {      return baseZipObject(props || [], values || [], assignValue);    }    /**     * This method is like `_.zipObject` except that it supports property paths.     *     * @static     * @memberOf _     * @since 4.1.0     * @category Array     * @param {Array} [props=[]] The property identifiers.     * @param {Array} [values=[]] The property values.     * @returns {Object} Returns the new object.     * @example     *     * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);     * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }     */    function zipObjectDeep(props, values) {      return baseZipObject(props || [], values || [], baseSet);    }    /**     * This method is like `_.zip` except that it accepts `iteratee` to specify     * how grouped values should be combined. The iteratee is invoked with the     * elements of each group: (...group).     *     * @static     * @memberOf _     * @since 3.8.0     * @category Array     * @param {...Array} [arrays] The arrays to process.     * @param {Function} [iteratee=_.identity] The function to combine     *  grouped values.     * @returns {Array} Returns the new array of grouped elements.     * @example     *     * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {     *   return a + b + c;     * });     * // => [111, 222]     */    var zipWith = baseRest(function(arrays) {      var length = arrays.length,          iteratee = length > 1 ? arrays[length - 1] : undefined;      iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;      return unzipWith(arrays, iteratee);    });    /*------------------------------------------------------------------------*/    /**     * Creates a `lodash` wrapper instance that wraps `value` with explicit method     * chain sequences enabled. The result of such sequences must be unwrapped     * with `_#value`.     *     * @static     * @memberOf _     * @since 1.3.0     * @category Seq     * @param {*} value The value to wrap.     * @returns {Object} Returns the new `lodash` wrapper instance.     * @example     *     * var users = [     *   { 'user': 'barney',  'age': 36 },     *   { 'user': 'fred',    'age': 40 },     *   { 'user': 'pebbles', 'age': 1 }     * ];     *     * var youngest = _     *   .chain(users)     *   .sortBy('age')     *   .map(function(o) {     *     return o.user + ' is ' + o.age;     *   })     *   .head()     *   .value();     * // => 'pebbles is 1'     */    function chain(value) {      var result = lodash(value);      result.__chain__ = true;      return result;    }    /**     * This method invokes `interceptor` and returns `value`. The interceptor     * is invoked with one argument; (value). The purpose of this method is to     * "tap into" a method chain sequence in order to modify intermediate results.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Seq     * @param {*} value The value to provide to `interceptor`.     * @param {Function} interceptor The function to invoke.     * @returns {*} Returns `value`.     * @example     *     * _([1, 2, 3])     *  .tap(function(array) {     *    // Mutate input array.     *    array.pop();     *  })     *  .reverse()     *  .value();     * // => [2, 1]     */    function tap(value, interceptor) {      interceptor(value);      return value;    }    /**     * This method is like `_.tap` except that it returns the result of `interceptor`.     * The purpose of this method is to "pass thru" values replacing intermediate     * results in a method chain sequence.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Seq     * @param {*} value The value to provide to `interceptor`.     * @param {Function} interceptor The function to invoke.     * @returns {*} Returns the result of `interceptor`.     * @example     *     * _('  abc  ')     *  .chain()     *  .trim()     *  .thru(function(value) {     *    return [value];     *  })     *  .value();     * // => ['abc']     */    function thru(value, interceptor) {      return interceptor(value);    }    /**     * This method is the wrapper version of `_.at`.     *     * @name at     * @memberOf _     * @since 1.0.0     * @category Seq     * @param {...(string|string[])} [paths] The property paths to pick.     * @returns {Object} Returns the new `lodash` wrapper instance.     * @example     *     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };     *     * _(object).at(['a[0].b.c', 'a[1]']).value();     * // => [3, 4]     */    var wrapperAt = flatRest(function(paths) {      var length = paths.length,          start = length ? paths[0] : 0,          value = this.__wrapped__,          interceptor = function(object) { return baseAt(object, paths); };      if (length > 1 || this.__actions__.length ||          !(value instanceof LazyWrapper) || !isIndex(start)) {        return this.thru(interceptor);      }      value = value.slice(start, +start + (length ? 1 : 0));      value.__actions__.push({        'func': thru,        'args': [interceptor],        'thisArg': undefined      });      return new LodashWrapper(value, this.__chain__).thru(function(array) {        if (length && !array.length) {          array.push(undefined);        }        return array;      });    });    /**     * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.     *     * @name chain     * @memberOf _     * @since 0.1.0     * @category Seq     * @returns {Object} Returns the new `lodash` wrapper instance.     * @example     *     * var users = [     *   { 'user': 'barney', 'age': 36 },     *   { 'user': 'fred',   'age': 40 }     * ];     *     * // A sequence without explicit chaining.     * _(users).head();     * // => { 'user': 'barney', 'age': 36 }     *     * // A sequence with explicit chaining.     * _(users)     *   .chain()     *   .head()     *   .pick('user')     *   .value();     * // => { 'user': 'barney' }     */    function wrapperChain() {      return chain(this);    }    /**     * Executes the chain sequence and returns the wrapped result.     *     * @name commit     * @memberOf _     * @since 3.2.0     * @category Seq     * @returns {Object} Returns the new `lodash` wrapper instance.     * @example     *     * var array = [1, 2];     * var wrapped = _(array).push(3);     *     * console.log(array);     * // => [1, 2]     *     * wrapped = wrapped.commit();     * console.log(array);     * // => [1, 2, 3]     *     * wrapped.last();     * // => 3     *     * console.log(array);     * // => [1, 2, 3]     */    function wrapperCommit() {      return new LodashWrapper(this.value(), this.__chain__);    }    /**     * Gets the next value on a wrapped object following the     * [iterator protocol](https://mdn.io/iteration_protocols#iterator).     *     * @name next     * @memberOf _     * @since 4.0.0     * @category Seq     * @returns {Object} Returns the next iterator value.     * @example     *     * var wrapped = _([1, 2]);     *     * wrapped.next();     * // => { 'done': false, 'value': 1 }     *     * wrapped.next();     * // => { 'done': false, 'value': 2 }     *     * wrapped.next();     * // => { 'done': true, 'value': undefined }     */    function wrapperNext() {      if (this.__values__ === undefined) {        this.__values__ = toArray(this.value());      }      var done = this.__index__ >= this.__values__.length,          value = done ? undefined : this.__values__[this.__index__++];      return { 'done': done, 'value': value };    }    /**     * Enables the wrapper to be iterable.     *     * @name Symbol.iterator     * @memberOf _     * @since 4.0.0     * @category Seq     * @returns {Object} Returns the wrapper object.     * @example     *     * var wrapped = _([1, 2]);     *     * wrapped[Symbol.iterator]() === wrapped;     * // => true     *     * Array.from(wrapped);     * // => [1, 2]     */    function wrapperToIterator() {      return this;    }    /**     * Creates a clone of the chain sequence planting `value` as the wrapped value.     *     * @name plant     * @memberOf _     * @since 3.2.0     * @category Seq     * @param {*} value The value to plant.     * @returns {Object} Returns the new `lodash` wrapper instance.     * @example     *     * function square(n) {     *   return n * n;     * }     *     * var wrapped = _([1, 2]).map(square);     * var other = wrapped.plant([3, 4]);     *     * other.value();     * // => [9, 16]     *     * wrapped.value();     * // => [1, 4]     */    function wrapperPlant(value) {      var result,          parent = this;      while (parent instanceof baseLodash) {        var clone = wrapperClone(parent);        clone.__index__ = 0;        clone.__values__ = undefined;        if (result) {          previous.__wrapped__ = clone;        } else {          result = clone;        }        var previous = clone;        parent = parent.__wrapped__;      }      previous.__wrapped__ = value;      return result;    }    /**     * This method is the wrapper version of `_.reverse`.     *     * **Note:** This method mutates the wrapped array.     *     * @name reverse     * @memberOf _     * @since 0.1.0     * @category Seq     * @returns {Object} Returns the new `lodash` wrapper instance.     * @example     *     * var array = [1, 2, 3];     *     * _(array).reverse().value()     * // => [3, 2, 1]     *     * console.log(array);     * // => [3, 2, 1]     */    function wrapperReverse() {      var value = this.__wrapped__;      if (value instanceof LazyWrapper) {        var wrapped = value;        if (this.__actions__.length) {          wrapped = new LazyWrapper(this);        }        wrapped = wrapped.reverse();        wrapped.__actions__.push({          'func': thru,          'args': [reverse],          'thisArg': undefined        });        return new LodashWrapper(wrapped, this.__chain__);      }      return this.thru(reverse);    }    /**     * Executes the chain sequence to resolve the unwrapped value.     *     * @name value     * @memberOf _     * @since 0.1.0     * @alias toJSON, valueOf     * @category Seq     * @returns {*} Returns the resolved unwrapped value.     * @example     *     * _([1, 2, 3]).value();     * // => [1, 2, 3]     */    function wrapperValue() {      return baseWrapperValue(this.__wrapped__, this.__actions__);    }    /*------------------------------------------------------------------------*/    /**     * Creates an object composed of keys generated from the results of running     * each element of `collection` thru `iteratee`. The corresponding value of     * each key is the number of times the key was returned by `iteratee`. The     * iteratee is invoked with one argument: (value).     *     * @static     * @memberOf _     * @since 0.5.0     * @category Collection     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.     * @returns {Object} Returns the composed aggregate object.     * @example     *     * _.countBy([6.1, 4.2, 6.3], Math.floor);     * // => { '4': 1, '6': 2 }     *     * // The `_.property` iteratee shorthand.     * _.countBy(['one', 'two', 'three'], 'length');     * // => { '3': 2, '5': 1 }     */    var countBy = createAggregator(function(result, value, key) {      if (hasOwnProperty.call(result, key)) {        ++result[key];      } else {        baseAssignValue(result, key, 1);      }    });    /**     * Checks if `predicate` returns truthy for **all** elements of `collection`.     * Iteration is stopped once `predicate` returns falsey. The predicate is     * invoked with three arguments: (value, index|key, collection).     *     * **Note:** This method returns `true` for     * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because     * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of     * elements of empty collections.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Collection     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} [predicate=_.identity] The function invoked per iteration.     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.     * @returns {boolean} Returns `true` if all elements pass the predicate check,     *  else `false`.     * @example     *     * _.every([true, 1, null, 'yes'], Boolean);     * // => false     *     * var users = [     *   { 'user': 'barney', 'age': 36, 'active': false },     *   { 'user': 'fred',   'age': 40, 'active': false }     * ];     *     * // The `_.matches` iteratee shorthand.     * _.every(users, { 'user': 'barney', 'active': false });     * // => false     *     * // The `_.matchesProperty` iteratee shorthand.     * _.every(users, ['active', false]);     * // => true     *     * // The `_.property` iteratee shorthand.     * _.every(users, 'active');     * // => false     */    function every(collection, predicate, guard) {      var func = isArray(collection) ? arrayEvery : baseEvery;      if (guard && isIterateeCall(collection, predicate, guard)) {        predicate = undefined;      }      return func(collection, getIteratee(predicate, 3));    }    /**     * Iterates over elements of `collection`, returning an array of all elements     * `predicate` returns truthy for. The predicate is invoked with three     * arguments: (value, index|key, collection).     *     * **Note:** Unlike `_.remove`, this method returns a new array.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Collection     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} [predicate=_.identity] The function invoked per iteration.     * @returns {Array} Returns the new filtered array.     * @see _.reject     * @example     *     * var users = [     *   { 'user': 'barney', 'age': 36, 'active': true },     *   { 'user': 'fred',   'age': 40, 'active': false }     * ];     *     * _.filter(users, function(o) { return !o.active; });     * // => objects for ['fred']     *     * // The `_.matches` iteratee shorthand.     * _.filter(users, { 'age': 36, 'active': true });     * // => objects for ['barney']     *     * // The `_.matchesProperty` iteratee shorthand.     * _.filter(users, ['active', false]);     * // => objects for ['fred']     *     * // The `_.property` iteratee shorthand.     * _.filter(users, 'active');     * // => objects for ['barney']     */    function filter(collection, predicate) {      var func = isArray(collection) ? arrayFilter : baseFilter;      return func(collection, getIteratee(predicate, 3));    }    /**     * Iterates over elements of `collection`, returning the first element     * `predicate` returns truthy for. The predicate is invoked with three     * arguments: (value, index|key, collection).     *     * @static     * @memberOf _     * @since 0.1.0     * @category Collection     * @param {Array|Object} collection The collection to inspect.     * @param {Function} [predicate=_.identity] The function invoked per iteration.     * @param {number} [fromIndex=0] The index to search from.     * @returns {*} Returns the matched element, else `undefined`.     * @example     *     * var users = [     *   { 'user': 'barney',  'age': 36, 'active': true },     *   { 'user': 'fred',    'age': 40, 'active': false },     *   { 'user': 'pebbles', 'age': 1,  'active': true }     * ];     *     * _.find(users, function(o) { return o.age < 40; });     * // => object for 'barney'     *     * // The `_.matches` iteratee shorthand.     * _.find(users, { 'age': 1, 'active': true });     * // => object for 'pebbles'     *     * // The `_.matchesProperty` iteratee shorthand.     * _.find(users, ['active', false]);     * // => object for 'fred'     *     * // The `_.property` iteratee shorthand.     * _.find(users, 'active');     * // => object for 'barney'     */    var find = createFind(findIndex);    /**     * This method is like `_.find` except that it iterates over elements of     * `collection` from right to left.     *     * @static     * @memberOf _     * @since 2.0.0     * @category Collection     * @param {Array|Object} collection The collection to inspect.     * @param {Function} [predicate=_.identity] The function invoked per iteration.     * @param {number} [fromIndex=collection.length-1] The index to search from.     * @returns {*} Returns the matched element, else `undefined`.     * @example     *     * _.findLast([1, 2, 3, 4], function(n) {     *   return n % 2 == 1;     * });     * // => 3     */    var findLast = createFind(findLastIndex);    /**     * Creates a flattened array of values by running each element in `collection`     * thru `iteratee` and flattening the mapped results. The iteratee is invoked     * with three arguments: (value, index|key, collection).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Collection     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @returns {Array} Returns the new flattened array.     * @example     *     * function duplicate(n) {     *   return [n, n];     * }     *     * _.flatMap([1, 2], duplicate);     * // => [1, 1, 2, 2]     */    function flatMap(collection, iteratee) {      return baseFlatten(map(collection, iteratee), 1);    }    /**     * This method is like `_.flatMap` except that it recursively flattens the     * mapped results.     *     * @static     * @memberOf _     * @since 4.7.0     * @category Collection     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @returns {Array} Returns the new flattened array.     * @example     *     * function duplicate(n) {     *   return [[[n, n]]];     * }     *     * _.flatMapDeep([1, 2], duplicate);     * // => [1, 1, 2, 2]     */    function flatMapDeep(collection, iteratee) {      return baseFlatten(map(collection, iteratee), INFINITY);    }    /**     * This method is like `_.flatMap` except that it recursively flattens the     * mapped results up to `depth` times.     *     * @static     * @memberOf _     * @since 4.7.0     * @category Collection     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @param {number} [depth=1] The maximum recursion depth.     * @returns {Array} Returns the new flattened array.     * @example     *     * function duplicate(n) {     *   return [[[n, n]]];     * }     *     * _.flatMapDepth([1, 2], duplicate, 2);     * // => [[1, 1], [2, 2]]     */    function flatMapDepth(collection, iteratee, depth) {      depth = depth === undefined ? 1 : toInteger(depth);      return baseFlatten(map(collection, iteratee), depth);    }    /**     * Iterates over elements of `collection` and invokes `iteratee` for each element.     * The iteratee is invoked with three arguments: (value, index|key, collection).     * Iteratee functions may exit iteration early by explicitly returning `false`.     *     * **Note:** As with other "Collections" methods, objects with a "length"     * property are iterated like arrays. To avoid this behavior use `_.forIn`     * or `_.forOwn` for object iteration.     *     * @static     * @memberOf _     * @since 0.1.0     * @alias each     * @category Collection     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @returns {Array|Object} Returns `collection`.     * @see _.forEachRight     * @example     *     * _.forEach([1, 2], function(value) {     *   console.log(value);     * });     * // => Logs `1` then `2`.     *     * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {     *   console.log(key);     * });     * // => Logs 'a' then 'b' (iteration order is not guaranteed).     */    function forEach(collection, iteratee) {      var func = isArray(collection) ? arrayEach : baseEach;      return func(collection, getIteratee(iteratee, 3));    }    /**     * This method is like `_.forEach` except that it iterates over elements of     * `collection` from right to left.     *     * @static     * @memberOf _     * @since 2.0.0     * @alias eachRight     * @category Collection     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @returns {Array|Object} Returns `collection`.     * @see _.forEach     * @example     *     * _.forEachRight([1, 2], function(value) {     *   console.log(value);     * });     * // => Logs `2` then `1`.     */    function forEachRight(collection, iteratee) {      var func = isArray(collection) ? arrayEachRight : baseEachRight;      return func(collection, getIteratee(iteratee, 3));    }    /**     * Creates an object composed of keys generated from the results of running     * each element of `collection` thru `iteratee`. The order of grouped values     * is determined by the order they occur in `collection`. The corresponding     * value of each key is an array of elements responsible for generating the     * key. The iteratee is invoked with one argument: (value).     *     * @static     * @memberOf _     * @since 0.1.0     * @category Collection     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.     * @returns {Object} Returns the composed aggregate object.     * @example     *     * _.groupBy([6.1, 4.2, 6.3], Math.floor);     * // => { '4': [4.2], '6': [6.1, 6.3] }     *     * // The `_.property` iteratee shorthand.     * _.groupBy(['one', 'two', 'three'], 'length');     * // => { '3': ['one', 'two'], '5': ['three'] }     */    var groupBy = createAggregator(function(result, value, key) {      if (hasOwnProperty.call(result, key)) {        result[key].push(value);      } else {        baseAssignValue(result, key, [value]);      }    });    /**     * Checks if `value` is in `collection`. If `collection` is a string, it's     * checked for a substring of `value`, otherwise     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)     * is used for equality comparisons. If `fromIndex` is negative, it's used as     * the offset from the end of `collection`.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Collection     * @param {Array|Object|string} collection The collection to inspect.     * @param {*} value The value to search for.     * @param {number} [fromIndex=0] The index to search from.     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.     * @returns {boolean} Returns `true` if `value` is found, else `false`.     * @example     *     * _.includes([1, 2, 3], 1);     * // => true     *     * _.includes([1, 2, 3], 1, 2);     * // => false     *     * _.includes({ 'a': 1, 'b': 2 }, 1);     * // => true     *     * _.includes('abcd', 'bc');     * // => true     */    function includes(collection, value, fromIndex, guard) {      collection = isArrayLike(collection) ? collection : values(collection);      fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;      var length = collection.length;      if (fromIndex < 0) {        fromIndex = nativeMax(length + fromIndex, 0);      }      return isString(collection)        ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)        : (!!length && baseIndexOf(collection, value, fromIndex) > -1);    }    /**     * Invokes the method at `path` of each element in `collection`, returning     * an array of the results of each invoked method. Any additional arguments     * are provided to each invoked method. If `path` is a function, it's invoked     * for, and `this` bound to, each element in `collection`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Collection     * @param {Array|Object} collection The collection to iterate over.     * @param {Array|Function|string} path The path of the method to invoke or     *  the function invoked per iteration.     * @param {...*} [args] The arguments to invoke each method with.     * @returns {Array} Returns the array of results.     * @example     *     * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');     * // => [[1, 5, 7], [1, 2, 3]]     *     * _.invokeMap([123, 456], String.prototype.split, '');     * // => [['1', '2', '3'], ['4', '5', '6']]     */    var invokeMap = baseRest(function(collection, path, args) {      var index = -1,          isFunc = typeof path == 'function',          result = isArrayLike(collection) ? Array(collection.length) : [];      baseEach(collection, function(value) {        result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);      });      return result;    });    /**     * Creates an object composed of keys generated from the results of running     * each element of `collection` thru `iteratee`. The corresponding value of     * each key is the last element responsible for generating the key. The     * iteratee is invoked with one argument: (value).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Collection     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.     * @returns {Object} Returns the composed aggregate object.     * @example     *     * var array = [     *   { 'dir': 'left', 'code': 97 },     *   { 'dir': 'right', 'code': 100 }     * ];     *     * _.keyBy(array, function(o) {     *   return String.fromCharCode(o.code);     * });     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }     *     * _.keyBy(array, 'dir');     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }     */    var keyBy = createAggregator(function(result, value, key) {      baseAssignValue(result, key, value);    });    /**     * Creates an array of values by running each element in `collection` thru     * `iteratee`. The iteratee is invoked with three arguments:     * (value, index|key, collection).     *     * Many lodash methods are guarded to work as iteratees for methods like     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.     *     * The guarded methods are:     * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,     * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,     * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,     * `template`, `trim`, `trimEnd`, `trimStart`, and `words`     *     * @static     * @memberOf _     * @since 0.1.0     * @category Collection     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @returns {Array} Returns the new mapped array.     * @example     *     * function square(n) {     *   return n * n;     * }     *     * _.map([4, 8], square);     * // => [16, 64]     *     * _.map({ 'a': 4, 'b': 8 }, square);     * // => [16, 64] (iteration order is not guaranteed)     *     * var users = [     *   { 'user': 'barney' },     *   { 'user': 'fred' }     * ];     *     * // The `_.property` iteratee shorthand.     * _.map(users, 'user');     * // => ['barney', 'fred']     */    function map(collection, iteratee) {      var func = isArray(collection) ? arrayMap : baseMap;      return func(collection, getIteratee(iteratee, 3));    }    /**     * This method is like `_.sortBy` except that it allows specifying the sort     * orders of the iteratees to sort by. If `orders` is unspecified, all values     * are sorted in ascending order. Otherwise, specify an order of "desc" for     * descending or "asc" for ascending sort order of corresponding values.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Collection     * @param {Array|Object} collection The collection to iterate over.     * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]     *  The iteratees to sort by.     * @param {string[]} [orders] The sort orders of `iteratees`.     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.     * @returns {Array} Returns the new sorted array.     * @example     *     * var users = [     *   { 'user': 'fred',   'age': 48 },     *   { 'user': 'barney', 'age': 34 },     *   { 'user': 'fred',   'age': 40 },     *   { 'user': 'barney', 'age': 36 }     * ];     *     * // Sort by `user` in ascending order and by `age` in descending order.     * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]     */    function orderBy(collection, iteratees, orders, guard) {      if (collection == null) {        return [];      }      if (!isArray(iteratees)) {        iteratees = iteratees == null ? [] : [iteratees];      }      orders = guard ? undefined : orders;      if (!isArray(orders)) {        orders = orders == null ? [] : [orders];      }      return baseOrderBy(collection, iteratees, orders);    }    /**     * Creates an array of elements split into two groups, the first of which     * contains elements `predicate` returns truthy for, the second of which     * contains elements `predicate` returns falsey for. The predicate is     * invoked with one argument: (value).     *     * @static     * @memberOf _     * @since 3.0.0     * @category Collection     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} [predicate=_.identity] The function invoked per iteration.     * @returns {Array} Returns the array of grouped elements.     * @example     *     * var users = [     *   { 'user': 'barney',  'age': 36, 'active': false },     *   { 'user': 'fred',    'age': 40, 'active': true },     *   { 'user': 'pebbles', 'age': 1,  'active': false }     * ];     *     * _.partition(users, function(o) { return o.active; });     * // => objects for [['fred'], ['barney', 'pebbles']]     *     * // The `_.matches` iteratee shorthand.     * _.partition(users, { 'age': 1, 'active': false });     * // => objects for [['pebbles'], ['barney', 'fred']]     *     * // The `_.matchesProperty` iteratee shorthand.     * _.partition(users, ['active', false]);     * // => objects for [['barney', 'pebbles'], ['fred']]     *     * // The `_.property` iteratee shorthand.     * _.partition(users, 'active');     * // => objects for [['fred'], ['barney', 'pebbles']]     */    var partition = createAggregator(function(result, value, key) {      result[key ? 0 : 1].push(value);    }, function() { return [[], []]; });    /**     * Reduces `collection` to a value which is the accumulated result of running     * each element in `collection` thru `iteratee`, where each successive     * invocation is supplied the return value of the previous. If `accumulator`     * is not given, the first element of `collection` is used as the initial     * value. The iteratee is invoked with four arguments:     * (accumulator, value, index|key, collection).     *     * Many lodash methods are guarded to work as iteratees for methods like     * `_.reduce`, `_.reduceRight`, and `_.transform`.     *     * The guarded methods are:     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,     * and `sortBy`     *     * @static     * @memberOf _     * @since 0.1.0     * @category Collection     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @param {*} [accumulator] The initial value.     * @returns {*} Returns the accumulated value.     * @see _.reduceRight     * @example     *     * _.reduce([1, 2], function(sum, n) {     *   return sum + n;     * }, 0);     * // => 3     *     * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {     *   (result[value] || (result[value] = [])).push(key);     *   return result;     * }, {});     * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)     */    function reduce(collection, iteratee, accumulator) {      var func = isArray(collection) ? arrayReduce : baseReduce,          initAccum = arguments.length < 3;      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);    }    /**     * This method is like `_.reduce` except that it iterates over elements of     * `collection` from right to left.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Collection     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @param {*} [accumulator] The initial value.     * @returns {*} Returns the accumulated value.     * @see _.reduce     * @example     *     * var array = [[0, 1], [2, 3], [4, 5]];     *     * _.reduceRight(array, function(flattened, other) {     *   return flattened.concat(other);     * }, []);     * // => [4, 5, 2, 3, 0, 1]     */    function reduceRight(collection, iteratee, accumulator) {      var func = isArray(collection) ? arrayReduceRight : baseReduce,          initAccum = arguments.length < 3;      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);    }    /**     * The opposite of `_.filter`; this method returns the elements of `collection`     * that `predicate` does **not** return truthy for.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Collection     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} [predicate=_.identity] The function invoked per iteration.     * @returns {Array} Returns the new filtered array.     * @see _.filter     * @example     *     * var users = [     *   { 'user': 'barney', 'age': 36, 'active': false },     *   { 'user': 'fred',   'age': 40, 'active': true }     * ];     *     * _.reject(users, function(o) { return !o.active; });     * // => objects for ['fred']     *     * // The `_.matches` iteratee shorthand.     * _.reject(users, { 'age': 40, 'active': true });     * // => objects for ['barney']     *     * // The `_.matchesProperty` iteratee shorthand.     * _.reject(users, ['active', false]);     * // => objects for ['fred']     *     * // The `_.property` iteratee shorthand.     * _.reject(users, 'active');     * // => objects for ['barney']     */    function reject(collection, predicate) {      var func = isArray(collection) ? arrayFilter : baseFilter;      return func(collection, negate(getIteratee(predicate, 3)));    }    /**     * Gets a random element from `collection`.     *     * @static     * @memberOf _     * @since 2.0.0     * @category Collection     * @param {Array|Object} collection The collection to sample.     * @returns {*} Returns the random element.     * @example     *     * _.sample([1, 2, 3, 4]);     * // => 2     */    function sample(collection) {      var func = isArray(collection) ? arraySample : baseSample;      return func(collection);    }    /**     * Gets `n` random elements at unique keys from `collection` up to the     * size of `collection`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Collection     * @param {Array|Object} collection The collection to sample.     * @param {number} [n=1] The number of elements to sample.     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.     * @returns {Array} Returns the random elements.     * @example     *     * _.sampleSize([1, 2, 3], 2);     * // => [3, 1]     *     * _.sampleSize([1, 2, 3], 4);     * // => [2, 3, 1]     */    function sampleSize(collection, n, guard) {      if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {        n = 1;      } else {        n = toInteger(n);      }      var func = isArray(collection) ? arraySampleSize : baseSampleSize;      return func(collection, n);    }    /**     * Creates an array of shuffled values, using a version of the     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).     *     * @static     * @memberOf _     * @since 0.1.0     * @category Collection     * @param {Array|Object} collection The collection to shuffle.     * @returns {Array} Returns the new shuffled array.     * @example     *     * _.shuffle([1, 2, 3, 4]);     * // => [4, 1, 3, 2]     */    function shuffle(collection) {      var func = isArray(collection) ? arrayShuffle : baseShuffle;      return func(collection);    }    /**     * Gets the size of `collection` by returning its length for array-like     * values or the number of own enumerable string keyed properties for objects.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Collection     * @param {Array|Object|string} collection The collection to inspect.     * @returns {number} Returns the collection size.     * @example     *     * _.size([1, 2, 3]);     * // => 3     *     * _.size({ 'a': 1, 'b': 2 });     * // => 2     *     * _.size('pebbles');     * // => 7     */    function size(collection) {      if (collection == null) {        return 0;      }      if (isArrayLike(collection)) {        return isString(collection) ? stringSize(collection) : collection.length;      }      var tag = getTag(collection);      if (tag == mapTag || tag == setTag) {        return collection.size;      }      return baseKeys(collection).length;    }    /**     * Checks if `predicate` returns truthy for **any** element of `collection`.     * Iteration is stopped once `predicate` returns truthy. The predicate is     * invoked with three arguments: (value, index|key, collection).     *     * @static     * @memberOf _     * @since 0.1.0     * @category Collection     * @param {Array|Object} collection The collection to iterate over.     * @param {Function} [predicate=_.identity] The function invoked per iteration.     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.     * @returns {boolean} Returns `true` if any element passes the predicate check,     *  else `false`.     * @example     *     * _.some([null, 0, 'yes', false], Boolean);     * // => true     *     * var users = [     *   { 'user': 'barney', 'active': true },     *   { 'user': 'fred',   'active': false }     * ];     *     * // The `_.matches` iteratee shorthand.     * _.some(users, { 'user': 'barney', 'active': false });     * // => false     *     * // The `_.matchesProperty` iteratee shorthand.     * _.some(users, ['active', false]);     * // => true     *     * // The `_.property` iteratee shorthand.     * _.some(users, 'active');     * // => true     */    function some(collection, predicate, guard) {      var func = isArray(collection) ? arraySome : baseSome;      if (guard && isIterateeCall(collection, predicate, guard)) {        predicate = undefined;      }      return func(collection, getIteratee(predicate, 3));    }    /**     * Creates an array of elements, sorted in ascending order by the results of     * running each element in a collection thru each iteratee. This method     * performs a stable sort, that is, it preserves the original sort order of     * equal elements. The iteratees are invoked with one argument: (value).     *     * @static     * @memberOf _     * @since 0.1.0     * @category Collection     * @param {Array|Object} collection The collection to iterate over.     * @param {...(Function|Function[])} [iteratees=[_.identity]]     *  The iteratees to sort by.     * @returns {Array} Returns the new sorted array.     * @example     *     * var users = [     *   { 'user': 'fred',   'age': 48 },     *   { 'user': 'barney', 'age': 36 },     *   { 'user': 'fred',   'age': 40 },     *   { 'user': 'barney', 'age': 34 }     * ];     *     * _.sortBy(users, [function(o) { return o.user; }]);     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]     *     * _.sortBy(users, ['user', 'age']);     * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]     */    var sortBy = baseRest(function(collection, iteratees) {      if (collection == null) {        return [];      }      var length = iteratees.length;      if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {        iteratees = [];      } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {        iteratees = [iteratees[0]];      }      return baseOrderBy(collection, baseFlatten(iteratees, 1), []);    });    /*------------------------------------------------------------------------*/    /**     * Gets the timestamp of the number of milliseconds that have elapsed since     * the Unix epoch (1 January 1970 00:00:00 UTC).     *     * @static     * @memberOf _     * @since 2.4.0     * @category Date     * @returns {number} Returns the timestamp.     * @example     *     * _.defer(function(stamp) {     *   console.log(_.now() - stamp);     * }, _.now());     * // => Logs the number of milliseconds it took for the deferred invocation.     */    var now = ctxNow || function() {      return root.Date.now();    };    /*------------------------------------------------------------------------*/    /**     * The opposite of `_.before`; this method creates a function that invokes     * `func` once it's called `n` or more times.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Function     * @param {number} n The number of calls before `func` is invoked.     * @param {Function} func The function to restrict.     * @returns {Function} Returns the new restricted function.     * @example     *     * var saves = ['profile', 'settings'];     *     * var done = _.after(saves.length, function() {     *   console.log('done saving!');     * });     *     * _.forEach(saves, function(type) {     *   asyncSave({ 'type': type, 'complete': done });     * });     * // => Logs 'done saving!' after the two async saves have completed.     */    function after(n, func) {      if (typeof func != 'function') {        throw new TypeError(FUNC_ERROR_TEXT);      }      n = toInteger(n);      return function() {        if (--n < 1) {          return func.apply(this, arguments);        }      };    }    /**     * Creates a function that invokes `func`, with up to `n` arguments,     * ignoring any additional arguments.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Function     * @param {Function} func The function to cap arguments for.     * @param {number} [n=func.length] The arity cap.     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.     * @returns {Function} Returns the new capped function.     * @example     *     * _.map(['6', '8', '10'], _.ary(parseInt, 1));     * // => [6, 8, 10]     */    function ary(func, n, guard) {      n = guard ? undefined : n;      n = (func && n == null) ? func.length : n;      return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);    }    /**     * Creates a function that invokes `func`, with the `this` binding and arguments     * of the created function, while it's called less than `n` times. Subsequent     * calls to the created function return the result of the last `func` invocation.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Function     * @param {number} n The number of calls at which `func` is no longer invoked.     * @param {Function} func The function to restrict.     * @returns {Function} Returns the new restricted function.     * @example     *     * jQuery(element).on('click', _.before(5, addContactToList));     * // => Allows adding up to 4 contacts to the list.     */    function before(n, func) {      var result;      if (typeof func != 'function') {        throw new TypeError(FUNC_ERROR_TEXT);      }      n = toInteger(n);      return function() {        if (--n > 0) {          result = func.apply(this, arguments);        }        if (n <= 1) {          func = undefined;        }        return result;      };    }    /**     * Creates a function that invokes `func` with the `this` binding of `thisArg`     * and `partials` prepended to the arguments it receives.     *     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,     * may be used as a placeholder for partially applied arguments.     *     * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"     * property of bound functions.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Function     * @param {Function} func The function to bind.     * @param {*} thisArg The `this` binding of `func`.     * @param {...*} [partials] The arguments to be partially applied.     * @returns {Function} Returns the new bound function.     * @example     *     * function greet(greeting, punctuation) {     *   return greeting + ' ' + this.user + punctuation;     * }     *     * var object = { 'user': 'fred' };     *     * var bound = _.bind(greet, object, 'hi');     * bound('!');     * // => 'hi fred!'     *     * // Bound with placeholders.     * var bound = _.bind(greet, object, _, '!');     * bound('hi');     * // => 'hi fred!'     */    var bind = baseRest(function(func, thisArg, partials) {      var bitmask = WRAP_BIND_FLAG;      if (partials.length) {        var holders = replaceHolders(partials, getHolder(bind));        bitmask |= WRAP_PARTIAL_FLAG;      }      return createWrap(func, bitmask, thisArg, partials, holders);    });    /**     * Creates a function that invokes the method at `object[key]` with `partials`     * prepended to the arguments it receives.     *     * This method differs from `_.bind` by allowing bound functions to reference     * methods that may be redefined or don't yet exist. See     * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)     * for more details.     *     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic     * builds, may be used as a placeholder for partially applied arguments.     *     * @static     * @memberOf _     * @since 0.10.0     * @category Function     * @param {Object} object The object to invoke the method on.     * @param {string} key The key of the method.     * @param {...*} [partials] The arguments to be partially applied.     * @returns {Function} Returns the new bound function.     * @example     *     * var object = {     *   'user': 'fred',     *   'greet': function(greeting, punctuation) {     *     return greeting + ' ' + this.user + punctuation;     *   }     * };     *     * var bound = _.bindKey(object, 'greet', 'hi');     * bound('!');     * // => 'hi fred!'     *     * object.greet = function(greeting, punctuation) {     *   return greeting + 'ya ' + this.user + punctuation;     * };     *     * bound('!');     * // => 'hiya fred!'     *     * // Bound with placeholders.     * var bound = _.bindKey(object, 'greet', _, '!');     * bound('hi');     * // => 'hiya fred!'     */    var bindKey = baseRest(function(object, key, partials) {      var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;      if (partials.length) {        var holders = replaceHolders(partials, getHolder(bindKey));        bitmask |= WRAP_PARTIAL_FLAG;      }      return createWrap(key, bitmask, object, partials, holders);    });    /**     * Creates a function that accepts arguments of `func` and either invokes     * `func` returning its result, if at least `arity` number of arguments have     * been provided, or returns a function that accepts the remaining `func`     * arguments, and so on. The arity of `func` may be specified if `func.length`     * is not sufficient.     *     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,     * may be used as a placeholder for provided arguments.     *     * **Note:** This method doesn't set the "length" property of curried functions.     *     * @static     * @memberOf _     * @since 2.0.0     * @category Function     * @param {Function} func The function to curry.     * @param {number} [arity=func.length] The arity of `func`.     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.     * @returns {Function} Returns the new curried function.     * @example     *     * var abc = function(a, b, c) {     *   return [a, b, c];     * };     *     * var curried = _.curry(abc);     *     * curried(1)(2)(3);     * // => [1, 2, 3]     *     * curried(1, 2)(3);     * // => [1, 2, 3]     *     * curried(1, 2, 3);     * // => [1, 2, 3]     *     * // Curried with placeholders.     * curried(1)(_, 3)(2);     * // => [1, 2, 3]     */    function curry(func, arity, guard) {      arity = guard ? undefined : arity;      var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);      result.placeholder = curry.placeholder;      return result;    }    /**     * This method is like `_.curry` except that arguments are applied to `func`     * in the manner of `_.partialRight` instead of `_.partial`.     *     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic     * builds, may be used as a placeholder for provided arguments.     *     * **Note:** This method doesn't set the "length" property of curried functions.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Function     * @param {Function} func The function to curry.     * @param {number} [arity=func.length] The arity of `func`.     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.     * @returns {Function} Returns the new curried function.     * @example     *     * var abc = function(a, b, c) {     *   return [a, b, c];     * };     *     * var curried = _.curryRight(abc);     *     * curried(3)(2)(1);     * // => [1, 2, 3]     *     * curried(2, 3)(1);     * // => [1, 2, 3]     *     * curried(1, 2, 3);     * // => [1, 2, 3]     *     * // Curried with placeholders.     * curried(3)(1, _)(2);     * // => [1, 2, 3]     */    function curryRight(func, arity, guard) {      arity = guard ? undefined : arity;      var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);      result.placeholder = curryRight.placeholder;      return result;    }    /**     * Creates a debounced function that delays invoking `func` until after `wait`     * milliseconds have elapsed since the last time the debounced function was     * invoked. The debounced function comes with a `cancel` method to cancel     * delayed `func` invocations and a `flush` method to immediately invoke them.     * Provide `options` to indicate whether `func` should be invoked on the     * leading and/or trailing edge of the `wait` timeout. The `func` is invoked     * with the last arguments provided to the debounced function. Subsequent     * calls to the debounced function return the result of the last `func`     * invocation.     *     * **Note:** If `leading` and `trailing` options are `true`, `func` is     * invoked on the trailing edge of the timeout only if the debounced function     * is invoked more than once during the `wait` timeout.     *     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred     * until to the next tick, similar to `setTimeout` with a timeout of `0`.     *     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)     * for details over the differences between `_.debounce` and `_.throttle`.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Function     * @param {Function} func The function to debounce.     * @param {number} [wait=0] The number of milliseconds to delay.     * @param {Object} [options={}] The options object.     * @param {boolean} [options.leading=false]     *  Specify invoking on the leading edge of the timeout.     * @param {number} [options.maxWait]     *  The maximum time `func` is allowed to be delayed before it's invoked.     * @param {boolean} [options.trailing=true]     *  Specify invoking on the trailing edge of the timeout.     * @returns {Function} Returns the new debounced function.     * @example     *     * // Avoid costly calculations while the window size is in flux.     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));     *     * // Invoke `sendMail` when clicked, debouncing subsequent calls.     * jQuery(element).on('click', _.debounce(sendMail, 300, {     *   'leading': true,     *   'trailing': false     * }));     *     * // Ensure `batchLog` is invoked once after 1 second of debounced calls.     * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });     * var source = new EventSource('/stream');     * jQuery(source).on('message', debounced);     *     * // Cancel the trailing debounced invocation.     * jQuery(window).on('popstate', debounced.cancel);     */    function debounce(func, wait, options) {      var lastArgs,          lastThis,          maxWait,          result,          timerId,          lastCallTime,          lastInvokeTime = 0,          leading = false,          maxing = false,          trailing = true;      if (typeof func != 'function') {        throw new TypeError(FUNC_ERROR_TEXT);      }      wait = toNumber(wait) || 0;      if (isObject(options)) {        leading = !!options.leading;        maxing = 'maxWait' in options;        maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;        trailing = 'trailing' in options ? !!options.trailing : trailing;      }      function invokeFunc(time) {        var args = lastArgs,            thisArg = lastThis;        lastArgs = lastThis = undefined;        lastInvokeTime = time;        result = func.apply(thisArg, args);        return result;      }      function leadingEdge(time) {        // Reset any `maxWait` timer.        lastInvokeTime = time;        // Start the timer for the trailing edge.        timerId = setTimeout(timerExpired, wait);        // Invoke the leading edge.        return leading ? invokeFunc(time) : result;      }      function remainingWait(time) {        var timeSinceLastCall = time - lastCallTime,            timeSinceLastInvoke = time - lastInvokeTime,            timeWaiting = wait - timeSinceLastCall;        return maxing          ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)          : timeWaiting;      }      function shouldInvoke(time) {        var timeSinceLastCall = time - lastCallTime,            timeSinceLastInvoke = time - lastInvokeTime;        // Either this is the first call, activity has stopped and we're at the        // trailing edge, the system time has gone backwards and we're treating        // it as the trailing edge, or we've hit the `maxWait` limit.        return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||          (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));      }      function timerExpired() {        var time = now();        if (shouldInvoke(time)) {          return trailingEdge(time);        }        // Restart the timer.        timerId = setTimeout(timerExpired, remainingWait(time));      }      function trailingEdge(time) {        timerId = undefined;        // Only invoke if we have `lastArgs` which means `func` has been        // debounced at least once.        if (trailing && lastArgs) {          return invokeFunc(time);        }        lastArgs = lastThis = undefined;        return result;      }      function cancel() {        if (timerId !== undefined) {          clearTimeout(timerId);        }        lastInvokeTime = 0;        lastArgs = lastCallTime = lastThis = timerId = undefined;      }      function flush() {        return timerId === undefined ? result : trailingEdge(now());      }      function debounced() {        var time = now(),            isInvoking = shouldInvoke(time);        lastArgs = arguments;        lastThis = this;        lastCallTime = time;        if (isInvoking) {          if (timerId === undefined) {            return leadingEdge(lastCallTime);          }          if (maxing) {            // Handle invocations in a tight loop.            timerId = setTimeout(timerExpired, wait);            return invokeFunc(lastCallTime);          }        }        if (timerId === undefined) {          timerId = setTimeout(timerExpired, wait);        }        return result;      }      debounced.cancel = cancel;      debounced.flush = flush;      return debounced;    }    /**     * Defers invoking the `func` until the current call stack has cleared. Any     * additional arguments are provided to `func` when it's invoked.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Function     * @param {Function} func The function to defer.     * @param {...*} [args] The arguments to invoke `func` with.     * @returns {number} Returns the timer id.     * @example     *     * _.defer(function(text) {     *   console.log(text);     * }, 'deferred');     * // => Logs 'deferred' after one millisecond.     */    var defer = baseRest(function(func, args) {      return baseDelay(func, 1, args);    });    /**     * Invokes `func` after `wait` milliseconds. Any additional arguments are     * provided to `func` when it's invoked.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Function     * @param {Function} func The function to delay.     * @param {number} wait The number of milliseconds to delay invocation.     * @param {...*} [args] The arguments to invoke `func` with.     * @returns {number} Returns the timer id.     * @example     *     * _.delay(function(text) {     *   console.log(text);     * }, 1000, 'later');     * // => Logs 'later' after one second.     */    var delay = baseRest(function(func, wait, args) {      return baseDelay(func, toNumber(wait) || 0, args);    });    /**     * Creates a function that invokes `func` with arguments reversed.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Function     * @param {Function} func The function to flip arguments for.     * @returns {Function} Returns the new flipped function.     * @example     *     * var flipped = _.flip(function() {     *   return _.toArray(arguments);     * });     *     * flipped('a', 'b', 'c', 'd');     * // => ['d', 'c', 'b', 'a']     */    function flip(func) {      return createWrap(func, WRAP_FLIP_FLAG);    }    /**     * Creates a function that memoizes the result of `func`. If `resolver` is     * provided, it determines the cache key for storing the result based on the     * arguments provided to the memoized function. By default, the first argument     * provided to the memoized function is used as the map cache key. The `func`     * is invoked with the `this` binding of the memoized function.     *     * **Note:** The cache is exposed as the `cache` property on the memoized     * function. Its creation may be customized by replacing the `_.memoize.Cache`     * constructor with one whose instances implement the     * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)     * method interface of `clear`, `delete`, `get`, `has`, and `set`.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Function     * @param {Function} func The function to have its output memoized.     * @param {Function} [resolver] The function to resolve the cache key.     * @returns {Function} Returns the new memoized function.     * @example     *     * var object = { 'a': 1, 'b': 2 };     * var other = { 'c': 3, 'd': 4 };     *     * var values = _.memoize(_.values);     * values(object);     * // => [1, 2]     *     * values(other);     * // => [3, 4]     *     * object.a = 2;     * values(object);     * // => [1, 2]     *     * // Modify the result cache.     * values.cache.set(object, ['a', 'b']);     * values(object);     * // => ['a', 'b']     *     * // Replace `_.memoize.Cache`.     * _.memoize.Cache = WeakMap;     */    function memoize(func, resolver) {      if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {        throw new TypeError(FUNC_ERROR_TEXT);      }      var memoized = function() {        var args = arguments,            key = resolver ? resolver.apply(this, args) : args[0],            cache = memoized.cache;        if (cache.has(key)) {          return cache.get(key);        }        var result = func.apply(this, args);        memoized.cache = cache.set(key, result) || cache;        return result;      };      memoized.cache = new (memoize.Cache || MapCache);      return memoized;    }    // Expose `MapCache`.    memoize.Cache = MapCache;    /**     * Creates a function that negates the result of the predicate `func`. The     * `func` predicate is invoked with the `this` binding and arguments of the     * created function.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Function     * @param {Function} predicate The predicate to negate.     * @returns {Function} Returns the new negated function.     * @example     *     * function isEven(n) {     *   return n % 2 == 0;     * }     *     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));     * // => [1, 3, 5]     */    function negate(predicate) {      if (typeof predicate != 'function') {        throw new TypeError(FUNC_ERROR_TEXT);      }      return function() {        var args = arguments;        switch (args.length) {          case 0: return !predicate.call(this);          case 1: return !predicate.call(this, args[0]);          case 2: return !predicate.call(this, args[0], args[1]);          case 3: return !predicate.call(this, args[0], args[1], args[2]);        }        return !predicate.apply(this, args);      };    }    /**     * Creates a function that is restricted to invoking `func` once. Repeat calls     * to the function return the value of the first invocation. The `func` is     * invoked with the `this` binding and arguments of the created function.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Function     * @param {Function} func The function to restrict.     * @returns {Function} Returns the new restricted function.     * @example     *     * var initialize = _.once(createApplication);     * initialize();     * initialize();     * // => `createApplication` is invoked once     */    function once(func) {      return before(2, func);    }    /**     * Creates a function that invokes `func` with its arguments transformed.     *     * @static     * @since 4.0.0     * @memberOf _     * @category Function     * @param {Function} func The function to wrap.     * @param {...(Function|Function[])} [transforms=[_.identity]]     *  The argument transforms.     * @returns {Function} Returns the new function.     * @example     *     * function doubled(n) {     *   return n * 2;     * }     *     * function square(n) {     *   return n * n;     * }     *     * var func = _.overArgs(function(x, y) {     *   return [x, y];     * }, [square, doubled]);     *     * func(9, 3);     * // => [81, 6]     *     * func(10, 5);     * // => [100, 10]     */    var overArgs = castRest(function(func, transforms) {      transforms = (transforms.length == 1 && isArray(transforms[0]))        ? arrayMap(transforms[0], baseUnary(getIteratee()))        : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));      var funcsLength = transforms.length;      return baseRest(function(args) {        var index = -1,            length = nativeMin(args.length, funcsLength);        while (++index < length) {          args[index] = transforms[index].call(this, args[index]);        }        return apply(func, this, args);      });    });    /**     * Creates a function that invokes `func` with `partials` prepended to the     * arguments it receives. This method is like `_.bind` except it does **not**     * alter the `this` binding.     *     * The `_.partial.placeholder` value, which defaults to `_` in monolithic     * builds, may be used as a placeholder for partially applied arguments.     *     * **Note:** This method doesn't set the "length" property of partially     * applied functions.     *     * @static     * @memberOf _     * @since 0.2.0     * @category Function     * @param {Function} func The function to partially apply arguments to.     * @param {...*} [partials] The arguments to be partially applied.     * @returns {Function} Returns the new partially applied function.     * @example     *     * function greet(greeting, name) {     *   return greeting + ' ' + name;     * }     *     * var sayHelloTo = _.partial(greet, 'hello');     * sayHelloTo('fred');     * // => 'hello fred'     *     * // Partially applied with placeholders.     * var greetFred = _.partial(greet, _, 'fred');     * greetFred('hi');     * // => 'hi fred'     */    var partial = baseRest(function(func, partials) {      var holders = replaceHolders(partials, getHolder(partial));      return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);    });    /**     * This method is like `_.partial` except that partially applied arguments     * are appended to the arguments it receives.     *     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic     * builds, may be used as a placeholder for partially applied arguments.     *     * **Note:** This method doesn't set the "length" property of partially     * applied functions.     *     * @static     * @memberOf _     * @since 1.0.0     * @category Function     * @param {Function} func The function to partially apply arguments to.     * @param {...*} [partials] The arguments to be partially applied.     * @returns {Function} Returns the new partially applied function.     * @example     *     * function greet(greeting, name) {     *   return greeting + ' ' + name;     * }     *     * var greetFred = _.partialRight(greet, 'fred');     * greetFred('hi');     * // => 'hi fred'     *     * // Partially applied with placeholders.     * var sayHelloTo = _.partialRight(greet, 'hello', _);     * sayHelloTo('fred');     * // => 'hello fred'     */    var partialRight = baseRest(function(func, partials) {      var holders = replaceHolders(partials, getHolder(partialRight));      return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);    });    /**     * Creates a function that invokes `func` with arguments arranged according     * to the specified `indexes` where the argument value at the first index is     * provided as the first argument, the argument value at the second index is     * provided as the second argument, and so on.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Function     * @param {Function} func The function to rearrange arguments for.     * @param {...(number|number[])} indexes The arranged argument indexes.     * @returns {Function} Returns the new function.     * @example     *     * var rearged = _.rearg(function(a, b, c) {     *   return [a, b, c];     * }, [2, 0, 1]);     *     * rearged('b', 'c', 'a')     * // => ['a', 'b', 'c']     */    var rearg = flatRest(function(func, indexes) {      return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);    });    /**     * Creates a function that invokes `func` with the `this` binding of the     * created function and arguments from `start` and beyond provided as     * an array.     *     * **Note:** This method is based on the     * [rest parameter](https://mdn.io/rest_parameters).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Function     * @param {Function} func The function to apply a rest parameter to.     * @param {number} [start=func.length-1] The start position of the rest parameter.     * @returns {Function} Returns the new function.     * @example     *     * var say = _.rest(function(what, names) {     *   return what + ' ' + _.initial(names).join(', ') +     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);     * });     *     * say('hello', 'fred', 'barney', 'pebbles');     * // => 'hello fred, barney, & pebbles'     */    function rest(func, start) {      if (typeof func != 'function') {        throw new TypeError(FUNC_ERROR_TEXT);      }      start = start === undefined ? start : toInteger(start);      return baseRest(func, start);    }    /**     * Creates a function that invokes `func` with the `this` binding of the     * create function and an array of arguments much like     * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).     *     * **Note:** This method is based on the     * [spread operator](https://mdn.io/spread_operator).     *     * @static     * @memberOf _     * @since 3.2.0     * @category Function     * @param {Function} func The function to spread arguments over.     * @param {number} [start=0] The start position of the spread.     * @returns {Function} Returns the new function.     * @example     *     * var say = _.spread(function(who, what) {     *   return who + ' says ' + what;     * });     *     * say(['fred', 'hello']);     * // => 'fred says hello'     *     * var numbers = Promise.all([     *   Promise.resolve(40),     *   Promise.resolve(36)     * ]);     *     * numbers.then(_.spread(function(x, y) {     *   return x + y;     * }));     * // => a Promise of 76     */    function spread(func, start) {      if (typeof func != 'function') {        throw new TypeError(FUNC_ERROR_TEXT);      }      start = start == null ? 0 : nativeMax(toInteger(start), 0);      return baseRest(function(args) {        var array = args[start],            otherArgs = castSlice(args, 0, start);        if (array) {          arrayPush(otherArgs, array);        }        return apply(func, this, otherArgs);      });    }    /**     * Creates a throttled function that only invokes `func` at most once per     * every `wait` milliseconds. The throttled function comes with a `cancel`     * method to cancel delayed `func` invocations and a `flush` method to     * immediately invoke them. Provide `options` to indicate whether `func`     * should be invoked on the leading and/or trailing edge of the `wait`     * timeout. The `func` is invoked with the last arguments provided to the     * throttled function. Subsequent calls to the throttled function return the     * result of the last `func` invocation.     *     * **Note:** If `leading` and `trailing` options are `true`, `func` is     * invoked on the trailing edge of the timeout only if the throttled function     * is invoked more than once during the `wait` timeout.     *     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred     * until to the next tick, similar to `setTimeout` with a timeout of `0`.     *     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)     * for details over the differences between `_.throttle` and `_.debounce`.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Function     * @param {Function} func The function to throttle.     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.     * @param {Object} [options={}] The options object.     * @param {boolean} [options.leading=true]     *  Specify invoking on the leading edge of the timeout.     * @param {boolean} [options.trailing=true]     *  Specify invoking on the trailing edge of the timeout.     * @returns {Function} Returns the new throttled function.     * @example     *     * // Avoid excessively updating the position while scrolling.     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));     *     * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.     * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });     * jQuery(element).on('click', throttled);     *     * // Cancel the trailing throttled invocation.     * jQuery(window).on('popstate', throttled.cancel);     */    function throttle(func, wait, options) {      var leading = true,          trailing = true;      if (typeof func != 'function') {        throw new TypeError(FUNC_ERROR_TEXT);      }      if (isObject(options)) {        leading = 'leading' in options ? !!options.leading : leading;        trailing = 'trailing' in options ? !!options.trailing : trailing;      }      return debounce(func, wait, {        'leading': leading,        'maxWait': wait,        'trailing': trailing      });    }    /**     * Creates a function that accepts up to one argument, ignoring any     * additional arguments.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Function     * @param {Function} func The function to cap arguments for.     * @returns {Function} Returns the new capped function.     * @example     *     * _.map(['6', '8', '10'], _.unary(parseInt));     * // => [6, 8, 10]     */    function unary(func) {      return ary(func, 1);    }    /**     * Creates a function that provides `value` to `wrapper` as its first     * argument. Any additional arguments provided to the function are appended     * to those provided to the `wrapper`. The wrapper is invoked with the `this`     * binding of the created function.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Function     * @param {*} value The value to wrap.     * @param {Function} [wrapper=identity] The wrapper function.     * @returns {Function} Returns the new function.     * @example     *     * var p = _.wrap(_.escape, function(func, text) {     *   return '<p>' + func(text) + '</p>';     * });     *     * p('fred, barney, & pebbles');     * // => '<p>fred, barney, & pebbles</p>'     */    function wrap(value, wrapper) {      return partial(castFunction(wrapper), value);    }    /*------------------------------------------------------------------------*/    /**     * Casts `value` as an array if it's not one.     *     * @static     * @memberOf _     * @since 4.4.0     * @category Lang     * @param {*} value The value to inspect.     * @returns {Array} Returns the cast array.     * @example     *     * _.castArray(1);     * // => [1]     *     * _.castArray({ 'a': 1 });     * // => [{ 'a': 1 }]     *     * _.castArray('abc');     * // => ['abc']     *     * _.castArray(null);     * // => [null]     *     * _.castArray(undefined);     * // => [undefined]     *     * _.castArray();     * // => []     *     * var array = [1, 2, 3];     * console.log(_.castArray(array) === array);     * // => true     */    function castArray() {      if (!arguments.length) {        return [];      }      var value = arguments[0];      return isArray(value) ? value : [value];    }    /**     * Creates a shallow clone of `value`.     *     * **Note:** This method is loosely based on the     * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)     * and supports cloning arrays, array buffers, booleans, date objects, maps,     * numbers, `Object` objects, regexes, sets, strings, symbols, and typed     * arrays. The own enumerable properties of `arguments` objects are cloned     * as plain objects. An empty object is returned for uncloneable values such     * as error objects, functions, DOM nodes, and WeakMaps.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Lang     * @param {*} value The value to clone.     * @returns {*} Returns the cloned value.     * @see _.cloneDeep     * @example     *     * var objects = [{ 'a': 1 }, { 'b': 2 }];     *     * var shallow = _.clone(objects);     * console.log(shallow[0] === objects[0]);     * // => true     */    function clone(value) {      return baseClone(value, CLONE_SYMBOLS_FLAG);    }    /**     * This method is like `_.clone` except that it accepts `customizer` which     * is invoked to produce the cloned value. If `customizer` returns `undefined`,     * cloning is handled by the method instead. The `customizer` is invoked with     * up to four arguments; (value [, index|key, object, stack]).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Lang     * @param {*} value The value to clone.     * @param {Function} [customizer] The function to customize cloning.     * @returns {*} Returns the cloned value.     * @see _.cloneDeepWith     * @example     *     * function customizer(value) {     *   if (_.isElement(value)) {     *     return value.cloneNode(false);     *   }     * }     *     * var el = _.cloneWith(document.body, customizer);     *     * console.log(el === document.body);     * // => false     * console.log(el.nodeName);     * // => 'BODY'     * console.log(el.childNodes.length);     * // => 0     */    function cloneWith(value, customizer) {      customizer = typeof customizer == 'function' ? customizer : undefined;      return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);    }    /**     * This method is like `_.clone` except that it recursively clones `value`.     *     * @static     * @memberOf _     * @since 1.0.0     * @category Lang     * @param {*} value The value to recursively clone.     * @returns {*} Returns the deep cloned value.     * @see _.clone     * @example     *     * var objects = [{ 'a': 1 }, { 'b': 2 }];     *     * var deep = _.cloneDeep(objects);     * console.log(deep[0] === objects[0]);     * // => false     */    function cloneDeep(value) {      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);    }    /**     * This method is like `_.cloneWith` except that it recursively clones `value`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Lang     * @param {*} value The value to recursively clone.     * @param {Function} [customizer] The function to customize cloning.     * @returns {*} Returns the deep cloned value.     * @see _.cloneWith     * @example     *     * function customizer(value) {     *   if (_.isElement(value)) {     *     return value.cloneNode(true);     *   }     * }     *     * var el = _.cloneDeepWith(document.body, customizer);     *     * console.log(el === document.body);     * // => false     * console.log(el.nodeName);     * // => 'BODY'     * console.log(el.childNodes.length);     * // => 20     */    function cloneDeepWith(value, customizer) {      customizer = typeof customizer == 'function' ? customizer : undefined;      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);    }    /**     * Checks if `object` conforms to `source` by invoking the predicate     * properties of `source` with the corresponding property values of `object`.     *     * **Note:** This method is equivalent to `_.conforms` when `source` is     * partially applied.     *     * @static     * @memberOf _     * @since 4.14.0     * @category Lang     * @param {Object} object The object to inspect.     * @param {Object} source The object of property predicates to conform to.     * @returns {boolean} Returns `true` if `object` conforms, else `false`.     * @example     *     * var object = { 'a': 1, 'b': 2 };     *     * _.conformsTo(object, { 'b': function(n) { return n > 1; } });     * // => true     *     * _.conformsTo(object, { 'b': function(n) { return n > 2; } });     * // => false     */    function conformsTo(object, source) {      return source == null || baseConformsTo(object, source, keys(source));    }    /**     * Performs a     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)     * comparison between two values to determine if they are equivalent.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Lang     * @param {*} value The value to compare.     * @param {*} other The other value to compare.     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.     * @example     *     * var object = { 'a': 1 };     * var other = { 'a': 1 };     *     * _.eq(object, object);     * // => true     *     * _.eq(object, other);     * // => false     *     * _.eq('a', 'a');     * // => true     *     * _.eq('a', Object('a'));     * // => false     *     * _.eq(NaN, NaN);     * // => true     */    function eq(value, other) {      return value === other || (value !== value && other !== other);    }    /**     * Checks if `value` is greater than `other`.     *     * @static     * @memberOf _     * @since 3.9.0     * @category Lang     * @param {*} value The value to compare.     * @param {*} other The other value to compare.     * @returns {boolean} Returns `true` if `value` is greater than `other`,     *  else `false`.     * @see _.lt     * @example     *     * _.gt(3, 1);     * // => true     *     * _.gt(3, 3);     * // => false     *     * _.gt(1, 3);     * // => false     */    var gt = createRelationalOperation(baseGt);    /**     * Checks if `value` is greater than or equal to `other`.     *     * @static     * @memberOf _     * @since 3.9.0     * @category Lang     * @param {*} value The value to compare.     * @param {*} other The other value to compare.     * @returns {boolean} Returns `true` if `value` is greater than or equal to     *  `other`, else `false`.     * @see _.lte     * @example     *     * _.gte(3, 1);     * // => true     *     * _.gte(3, 3);     * // => true     *     * _.gte(1, 3);     * // => false     */    var gte = createRelationalOperation(function(value, other) {      return value >= other;    });    /**     * Checks if `value` is likely an `arguments` object.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is an `arguments` object,     *  else `false`.     * @example     *     * _.isArguments(function() { return arguments; }());     * // => true     *     * _.isArguments([1, 2, 3]);     * // => false     */    var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {      return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&        !propertyIsEnumerable.call(value, 'callee');    };    /**     * Checks if `value` is classified as an `Array` object.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is an array, else `false`.     * @example     *     * _.isArray([1, 2, 3]);     * // => true     *     * _.isArray(document.body.children);     * // => false     *     * _.isArray('abc');     * // => false     *     * _.isArray(_.noop);     * // => false     */    var isArray = Array.isArray;    /**     * Checks if `value` is classified as an `ArrayBuffer` object.     *     * @static     * @memberOf _     * @since 4.3.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.     * @example     *     * _.isArrayBuffer(new ArrayBuffer(2));     * // => true     *     * _.isArrayBuffer(new Array(2));     * // => false     */    var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;    /**     * Checks if `value` is array-like. A value is considered array-like if it's     * not a function and has a `value.length` that's an integer greater than or     * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.     * @example     *     * _.isArrayLike([1, 2, 3]);     * // => true     *     * _.isArrayLike(document.body.children);     * // => true     *     * _.isArrayLike('abc');     * // => true     *     * _.isArrayLike(_.noop);     * // => false     */    function isArrayLike(value) {      return value != null && isLength(value.length) && !isFunction(value);    }    /**     * This method is like `_.isArrayLike` except that it also checks if `value`     * is an object.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is an array-like object,     *  else `false`.     * @example     *     * _.isArrayLikeObject([1, 2, 3]);     * // => true     *     * _.isArrayLikeObject(document.body.children);     * // => true     *     * _.isArrayLikeObject('abc');     * // => false     *     * _.isArrayLikeObject(_.noop);     * // => false     */    function isArrayLikeObject(value) {      return isObjectLike(value) && isArrayLike(value);    }    /**     * Checks if `value` is classified as a boolean primitive or object.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.     * @example     *     * _.isBoolean(false);     * // => true     *     * _.isBoolean(null);     * // => false     */    function isBoolean(value) {      return value === true || value === false ||        (isObjectLike(value) && baseGetTag(value) == boolTag);    }    /**     * Checks if `value` is a buffer.     *     * @static     * @memberOf _     * @since 4.3.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.     * @example     *     * _.isBuffer(new Buffer(2));     * // => true     *     * _.isBuffer(new Uint8Array(2));     * // => false     */    var isBuffer = nativeIsBuffer || stubFalse;    /**     * Checks if `value` is classified as a `Date` object.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.     * @example     *     * _.isDate(new Date);     * // => true     *     * _.isDate('Mon April 23 2012');     * // => false     */    var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;    /**     * Checks if `value` is likely a DOM element.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.     * @example     *     * _.isElement(document.body);     * // => true     *     * _.isElement('<body>');     * // => false     */    function isElement(value) {      return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);    }    /**     * Checks if `value` is an empty object, collection, map, or set.     *     * Objects are considered empty if they have no own enumerable string keyed     * properties.     *     * Array-like values such as `arguments` objects, arrays, buffers, strings, or     * jQuery-like collections are considered empty if they have a `length` of `0`.     * Similarly, maps and sets are considered empty if they have a `size` of `0`.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is empty, else `false`.     * @example     *     * _.isEmpty(null);     * // => true     *     * _.isEmpty(true);     * // => true     *     * _.isEmpty(1);     * // => true     *     * _.isEmpty([1, 2, 3]);     * // => false     *     * _.isEmpty({ 'a': 1 });     * // => false     */    function isEmpty(value) {      if (value == null) {        return true;      }      if (isArrayLike(value) &&          (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||            isBuffer(value) || isTypedArray(value) || isArguments(value))) {        return !value.length;      }      var tag = getTag(value);      if (tag == mapTag || tag == setTag) {        return !value.size;      }      if (isPrototype(value)) {        return !baseKeys(value).length;      }      for (var key in value) {        if (hasOwnProperty.call(value, key)) {          return false;        }      }      return true;    }    /**     * Performs a deep comparison between two values to determine if they are     * equivalent.     *     * **Note:** This method supports comparing arrays, array buffers, booleans,     * date objects, error objects, maps, numbers, `Object` objects, regexes,     * sets, strings, symbols, and typed arrays. `Object` objects are compared     * by their own, not inherited, enumerable properties. Functions and DOM     * nodes are compared by strict equality, i.e. `===`.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Lang     * @param {*} value The value to compare.     * @param {*} other The other value to compare.     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.     * @example     *     * var object = { 'a': 1 };     * var other = { 'a': 1 };     *     * _.isEqual(object, other);     * // => true     *     * object === other;     * // => false     */    function isEqual(value, other) {      return baseIsEqual(value, other);    }    /**     * This method is like `_.isEqual` except that it accepts `customizer` which     * is invoked to compare values. If `customizer` returns `undefined`, comparisons     * are handled by the method instead. The `customizer` is invoked with up to     * six arguments: (objValue, othValue [, index|key, object, other, stack]).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Lang     * @param {*} value The value to compare.     * @param {*} other The other value to compare.     * @param {Function} [customizer] The function to customize comparisons.     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.     * @example     *     * function isGreeting(value) {     *   return /^h(?:i|ello)$/.test(value);     * }     *     * function customizer(objValue, othValue) {     *   if (isGreeting(objValue) && isGreeting(othValue)) {     *     return true;     *   }     * }     *     * var array = ['hello', 'goodbye'];     * var other = ['hi', 'goodbye'];     *     * _.isEqualWith(array, other, customizer);     * // => true     */    function isEqualWith(value, other, customizer) {      customizer = typeof customizer == 'function' ? customizer : undefined;      var result = customizer ? customizer(value, other) : undefined;      return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;    }    /**     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,     * `SyntaxError`, `TypeError`, or `URIError` object.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is an error object, else `false`.     * @example     *     * _.isError(new Error);     * // => true     *     * _.isError(Error);     * // => false     */    function isError(value) {      if (!isObjectLike(value)) {        return false;      }      var tag = baseGetTag(value);      return tag == errorTag || tag == domExcTag ||        (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));    }    /**     * Checks if `value` is a finite primitive number.     *     * **Note:** This method is based on     * [`Number.isFinite`](https://mdn.io/Number/isFinite).     *     * @static     * @memberOf _     * @since 0.1.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.     * @example     *     * _.isFinite(3);     * // => true     *     * _.isFinite(Number.MIN_VALUE);     * // => true     *     * _.isFinite(Infinity);     * // => false     *     * _.isFinite('3');     * // => false     */    function isFinite(value) {      return typeof value == 'number' && nativeIsFinite(value);    }    /**     * Checks if `value` is classified as a `Function` object.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a function, else `false`.     * @example     *     * _.isFunction(_);     * // => true     *     * _.isFunction(/abc/);     * // => false     */    function isFunction(value) {      if (!isObject(value)) {        return false;      }      // The use of `Object#toString` avoids issues with the `typeof` operator      // in Safari 9 which returns 'object' for typed arrays and other constructors.      var tag = baseGetTag(value);      return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;    }    /**     * Checks if `value` is an integer.     *     * **Note:** This method is based on     * [`Number.isInteger`](https://mdn.io/Number/isInteger).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is an integer, else `false`.     * @example     *     * _.isInteger(3);     * // => true     *     * _.isInteger(Number.MIN_VALUE);     * // => false     *     * _.isInteger(Infinity);     * // => false     *     * _.isInteger('3');     * // => false     */    function isInteger(value) {      return typeof value == 'number' && value == toInteger(value);    }    /**     * Checks if `value` is a valid array-like length.     *     * **Note:** This method is loosely based on     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.     * @example     *     * _.isLength(3);     * // => true     *     * _.isLength(Number.MIN_VALUE);     * // => false     *     * _.isLength(Infinity);     * // => false     *     * _.isLength('3');     * // => false     */    function isLength(value) {      return typeof value == 'number' &&        value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;    }    /**     * Checks if `value` is the     * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)     * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)     *     * @static     * @memberOf _     * @since 0.1.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is an object, else `false`.     * @example     *     * _.isObject({});     * // => true     *     * _.isObject([1, 2, 3]);     * // => true     *     * _.isObject(_.noop);     * // => true     *     * _.isObject(null);     * // => false     */    function isObject(value) {      var type = typeof value;      return value != null && (type == 'object' || type == 'function');    }    /**     * Checks if `value` is object-like. A value is object-like if it's not `null`     * and has a `typeof` result of "object".     *     * @static     * @memberOf _     * @since 4.0.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.     * @example     *     * _.isObjectLike({});     * // => true     *     * _.isObjectLike([1, 2, 3]);     * // => true     *     * _.isObjectLike(_.noop);     * // => false     *     * _.isObjectLike(null);     * // => false     */    function isObjectLike(value) {      return value != null && typeof value == 'object';    }    /**     * Checks if `value` is classified as a `Map` object.     *     * @static     * @memberOf _     * @since 4.3.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a map, else `false`.     * @example     *     * _.isMap(new Map);     * // => true     *     * _.isMap(new WeakMap);     * // => false     */    var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;    /**     * Performs a partial deep comparison between `object` and `source` to     * determine if `object` contains equivalent property values.     *     * **Note:** This method is equivalent to `_.matches` when `source` is     * partially applied.     *     * Partial comparisons will match empty array and empty object `source`     * values against any array or object value, respectively. See `_.isEqual`     * for a list of supported value comparisons.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Lang     * @param {Object} object The object to inspect.     * @param {Object} source The object of property values to match.     * @returns {boolean} Returns `true` if `object` is a match, else `false`.     * @example     *     * var object = { 'a': 1, 'b': 2 };     *     * _.isMatch(object, { 'b': 2 });     * // => true     *     * _.isMatch(object, { 'b': 1 });     * // => false     */    function isMatch(object, source) {      return object === source || baseIsMatch(object, source, getMatchData(source));    }    /**     * This method is like `_.isMatch` except that it accepts `customizer` which     * is invoked to compare values. If `customizer` returns `undefined`, comparisons     * are handled by the method instead. The `customizer` is invoked with five     * arguments: (objValue, srcValue, index|key, object, source).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Lang     * @param {Object} object The object to inspect.     * @param {Object} source The object of property values to match.     * @param {Function} [customizer] The function to customize comparisons.     * @returns {boolean} Returns `true` if `object` is a match, else `false`.     * @example     *     * function isGreeting(value) {     *   return /^h(?:i|ello)$/.test(value);     * }     *     * function customizer(objValue, srcValue) {     *   if (isGreeting(objValue) && isGreeting(srcValue)) {     *     return true;     *   }     * }     *     * var object = { 'greeting': 'hello' };     * var source = { 'greeting': 'hi' };     *     * _.isMatchWith(object, source, customizer);     * // => true     */    function isMatchWith(object, source, customizer) {      customizer = typeof customizer == 'function' ? customizer : undefined;      return baseIsMatch(object, source, getMatchData(source), customizer);    }    /**     * Checks if `value` is `NaN`.     *     * **Note:** This method is based on     * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as     * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for     * `undefined` and other non-number values.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.     * @example     *     * _.isNaN(NaN);     * // => true     *     * _.isNaN(new Number(NaN));     * // => true     *     * isNaN(undefined);     * // => true     *     * _.isNaN(undefined);     * // => false     */    function isNaN(value) {      // An `NaN` primitive is the only value that is not equal to itself.      // Perform the `toStringTag` check first to avoid errors with some      // ActiveX objects in IE.      return isNumber(value) && value != +value;    }    /**     * Checks if `value` is a pristine native function.     *     * **Note:** This method can't reliably detect native functions in the presence     * of the core-js package because core-js circumvents this kind of detection.     * Despite multiple requests, the core-js maintainer has made it clear: any     * attempt to fix the detection will be obstructed. As a result, we're left     * with little choice but to throw an error. Unfortunately, this also affects     * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),     * which rely on core-js.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a native function,     *  else `false`.     * @example     *     * _.isNative(Array.prototype.push);     * // => true     *     * _.isNative(_);     * // => false     */    function isNative(value) {      if (isMaskable(value)) {        throw new Error(CORE_ERROR_TEXT);      }      return baseIsNative(value);    }    /**     * Checks if `value` is `null`.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.     * @example     *     * _.isNull(null);     * // => true     *     * _.isNull(void 0);     * // => false     */    function isNull(value) {      return value === null;    }    /**     * Checks if `value` is `null` or `undefined`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is nullish, else `false`.     * @example     *     * _.isNil(null);     * // => true     *     * _.isNil(void 0);     * // => true     *     * _.isNil(NaN);     * // => false     */    function isNil(value) {      return value == null;    }    /**     * Checks if `value` is classified as a `Number` primitive or object.     *     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are     * classified as numbers, use the `_.isFinite` method.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a number, else `false`.     * @example     *     * _.isNumber(3);     * // => true     *     * _.isNumber(Number.MIN_VALUE);     * // => true     *     * _.isNumber(Infinity);     * // => true     *     * _.isNumber('3');     * // => false     */    function isNumber(value) {      return typeof value == 'number' ||        (isObjectLike(value) && baseGetTag(value) == numberTag);    }    /**     * Checks if `value` is a plain object, that is, an object created by the     * `Object` constructor or one with a `[[Prototype]]` of `null`.     *     * @static     * @memberOf _     * @since 0.8.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.     * @example     *     * function Foo() {     *   this.a = 1;     * }     *     * _.isPlainObject(new Foo);     * // => false     *     * _.isPlainObject([1, 2, 3]);     * // => false     *     * _.isPlainObject({ 'x': 0, 'y': 0 });     * // => true     *     * _.isPlainObject(Object.create(null));     * // => true     */    function isPlainObject(value) {      if (!isObjectLike(value) || baseGetTag(value) != objectTag) {        return false;      }      var proto = getPrototype(value);      if (proto === null) {        return true;      }      var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;      return typeof Ctor == 'function' && Ctor instanceof Ctor &&        funcToString.call(Ctor) == objectCtorString;    }    /**     * Checks if `value` is classified as a `RegExp` object.     *     * @static     * @memberOf _     * @since 0.1.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.     * @example     *     * _.isRegExp(/abc/);     * // => true     *     * _.isRegExp('/abc/');     * // => false     */    var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;    /**     * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754     * double precision number which isn't the result of a rounded unsafe integer.     *     * **Note:** This method is based on     * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.     * @example     *     * _.isSafeInteger(3);     * // => true     *     * _.isSafeInteger(Number.MIN_VALUE);     * // => false     *     * _.isSafeInteger(Infinity);     * // => false     *     * _.isSafeInteger('3');     * // => false     */    function isSafeInteger(value) {      return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;    }    /**     * Checks if `value` is classified as a `Set` object.     *     * @static     * @memberOf _     * @since 4.3.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a set, else `false`.     * @example     *     * _.isSet(new Set);     * // => true     *     * _.isSet(new WeakSet);     * // => false     */    var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;    /**     * Checks if `value` is classified as a `String` primitive or object.     *     * @static     * @since 0.1.0     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a string, else `false`.     * @example     *     * _.isString('abc');     * // => true     *     * _.isString(1);     * // => false     */    function isString(value) {      return typeof value == 'string' ||        (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);    }    /**     * Checks if `value` is classified as a `Symbol` primitive or object.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.     * @example     *     * _.isSymbol(Symbol.iterator);     * // => true     *     * _.isSymbol('abc');     * // => false     */    function isSymbol(value) {      return typeof value == 'symbol' ||        (isObjectLike(value) && baseGetTag(value) == symbolTag);    }    /**     * Checks if `value` is classified as a typed array.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.     * @example     *     * _.isTypedArray(new Uint8Array);     * // => true     *     * _.isTypedArray([]);     * // => false     */    var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;    /**     * Checks if `value` is `undefined`.     *     * @static     * @since 0.1.0     * @memberOf _     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.     * @example     *     * _.isUndefined(void 0);     * // => true     *     * _.isUndefined(null);     * // => false     */    function isUndefined(value) {      return value === undefined;    }    /**     * Checks if `value` is classified as a `WeakMap` object.     *     * @static     * @memberOf _     * @since 4.3.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.     * @example     *     * _.isWeakMap(new WeakMap);     * // => true     *     * _.isWeakMap(new Map);     * // => false     */    function isWeakMap(value) {      return isObjectLike(value) && getTag(value) == weakMapTag;    }    /**     * Checks if `value` is classified as a `WeakSet` object.     *     * @static     * @memberOf _     * @since 4.3.0     * @category Lang     * @param {*} value The value to check.     * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.     * @example     *     * _.isWeakSet(new WeakSet);     * // => true     *     * _.isWeakSet(new Set);     * // => false     */    function isWeakSet(value) {      return isObjectLike(value) && baseGetTag(value) == weakSetTag;    }    /**     * Checks if `value` is less than `other`.     *     * @static     * @memberOf _     * @since 3.9.0     * @category Lang     * @param {*} value The value to compare.     * @param {*} other The other value to compare.     * @returns {boolean} Returns `true` if `value` is less than `other`,     *  else `false`.     * @see _.gt     * @example     *     * _.lt(1, 3);     * // => true     *     * _.lt(3, 3);     * // => false     *     * _.lt(3, 1);     * // => false     */    var lt = createRelationalOperation(baseLt);    /**     * Checks if `value` is less than or equal to `other`.     *     * @static     * @memberOf _     * @since 3.9.0     * @category Lang     * @param {*} value The value to compare.     * @param {*} other The other value to compare.     * @returns {boolean} Returns `true` if `value` is less than or equal to     *  `other`, else `false`.     * @see _.gte     * @example     *     * _.lte(1, 3);     * // => true     *     * _.lte(3, 3);     * // => true     *     * _.lte(3, 1);     * // => false     */    var lte = createRelationalOperation(function(value, other) {      return value <= other;    });    /**     * Converts `value` to an array.     *     * @static     * @since 0.1.0     * @memberOf _     * @category Lang     * @param {*} value The value to convert.     * @returns {Array} Returns the converted array.     * @example     *     * _.toArray({ 'a': 1, 'b': 2 });     * // => [1, 2]     *     * _.toArray('abc');     * // => ['a', 'b', 'c']     *     * _.toArray(1);     * // => []     *     * _.toArray(null);     * // => []     */    function toArray(value) {      if (!value) {        return [];      }      if (isArrayLike(value)) {        return isString(value) ? stringToArray(value) : copyArray(value);      }      if (symIterator && value[symIterator]) {        return iteratorToArray(value[symIterator]());      }      var tag = getTag(value),          func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);      return func(value);    }    /**     * Converts `value` to a finite number.     *     * @static     * @memberOf _     * @since 4.12.0     * @category Lang     * @param {*} value The value to convert.     * @returns {number} Returns the converted number.     * @example     *     * _.toFinite(3.2);     * // => 3.2     *     * _.toFinite(Number.MIN_VALUE);     * // => 5e-324     *     * _.toFinite(Infinity);     * // => 1.7976931348623157e+308     *     * _.toFinite('3.2');     * // => 3.2     */    function toFinite(value) {      if (!value) {        return value === 0 ? value : 0;      }      value = toNumber(value);      if (value === INFINITY || value === -INFINITY) {        var sign = (value < 0 ? -1 : 1);        return sign * MAX_INTEGER;      }      return value === value ? value : 0;    }    /**     * Converts `value` to an integer.     *     * **Note:** This method is loosely based on     * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Lang     * @param {*} value The value to convert.     * @returns {number} Returns the converted integer.     * @example     *     * _.toInteger(3.2);     * // => 3     *     * _.toInteger(Number.MIN_VALUE);     * // => 0     *     * _.toInteger(Infinity);     * // => 1.7976931348623157e+308     *     * _.toInteger('3.2');     * // => 3     */    function toInteger(value) {      var result = toFinite(value),          remainder = result % 1;      return result === result ? (remainder ? result - remainder : result) : 0;    }    /**     * Converts `value` to an integer suitable for use as the length of an     * array-like object.     *     * **Note:** This method is based on     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Lang     * @param {*} value The value to convert.     * @returns {number} Returns the converted integer.     * @example     *     * _.toLength(3.2);     * // => 3     *     * _.toLength(Number.MIN_VALUE);     * // => 0     *     * _.toLength(Infinity);     * // => 4294967295     *     * _.toLength('3.2');     * // => 3     */    function toLength(value) {      return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;    }    /**     * Converts `value` to a number.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Lang     * @param {*} value The value to process.     * @returns {number} Returns the number.     * @example     *     * _.toNumber(3.2);     * // => 3.2     *     * _.toNumber(Number.MIN_VALUE);     * // => 5e-324     *     * _.toNumber(Infinity);     * // => Infinity     *     * _.toNumber('3.2');     * // => 3.2     */    function toNumber(value) {      if (typeof value == 'number') {        return value;      }      if (isSymbol(value)) {        return NAN;      }      if (isObject(value)) {        var other = typeof value.valueOf == 'function' ? value.valueOf() : value;        value = isObject(other) ? (other + '') : other;      }      if (typeof value != 'string') {        return value === 0 ? value : +value;      }      value = value.replace(reTrim, '');      var isBinary = reIsBinary.test(value);      return (isBinary || reIsOctal.test(value))        ? freeParseInt(value.slice(2), isBinary ? 2 : 8)        : (reIsBadHex.test(value) ? NAN : +value);    }    /**     * Converts `value` to a plain object flattening inherited enumerable string     * keyed properties of `value` to own properties of the plain object.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Lang     * @param {*} value The value to convert.     * @returns {Object} Returns the converted plain object.     * @example     *     * function Foo() {     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.assign({ 'a': 1 }, new Foo);     * // => { 'a': 1, 'b': 2 }     *     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));     * // => { 'a': 1, 'b': 2, 'c': 3 }     */    function toPlainObject(value) {      return copyObject(value, keysIn(value));    }    /**     * Converts `value` to a safe integer. A safe integer can be compared and     * represented correctly.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Lang     * @param {*} value The value to convert.     * @returns {number} Returns the converted integer.     * @example     *     * _.toSafeInteger(3.2);     * // => 3     *     * _.toSafeInteger(Number.MIN_VALUE);     * // => 0     *     * _.toSafeInteger(Infinity);     * // => 9007199254740991     *     * _.toSafeInteger('3.2');     * // => 3     */    function toSafeInteger(value) {      return value        ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)        : (value === 0 ? value : 0);    }    /**     * Converts `value` to a string. An empty string is returned for `null`     * and `undefined` values. The sign of `-0` is preserved.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Lang     * @param {*} value The value to convert.     * @returns {string} Returns the converted string.     * @example     *     * _.toString(null);     * // => ''     *     * _.toString(-0);     * // => '-0'     *     * _.toString([1, 2, 3]);     * // => '1,2,3'     */    function toString(value) {      return value == null ? '' : baseToString(value);    }    /*------------------------------------------------------------------------*/    /**     * Assigns own enumerable string keyed properties of source objects to the     * destination object. Source objects are applied from left to right.     * Subsequent sources overwrite property assignments of previous sources.     *     * **Note:** This method mutates `object` and is loosely based on     * [`Object.assign`](https://mdn.io/Object/assign).     *     * @static     * @memberOf _     * @since 0.10.0     * @category Object     * @param {Object} object The destination object.     * @param {...Object} [sources] The source objects.     * @returns {Object} Returns `object`.     * @see _.assignIn     * @example     *     * function Foo() {     *   this.a = 1;     * }     *     * function Bar() {     *   this.c = 3;     * }     *     * Foo.prototype.b = 2;     * Bar.prototype.d = 4;     *     * _.assign({ 'a': 0 }, new Foo, new Bar);     * // => { 'a': 1, 'c': 3 }     */    var assign = createAssigner(function(object, source) {      if (isPrototype(source) || isArrayLike(source)) {        copyObject(source, keys(source), object);        return;      }      for (var key in source) {        if (hasOwnProperty.call(source, key)) {          assignValue(object, key, source[key]);        }      }    });    /**     * This method is like `_.assign` except that it iterates over own and     * inherited source properties.     *     * **Note:** This method mutates `object`.     *     * @static     * @memberOf _     * @since 4.0.0     * @alias extend     * @category Object     * @param {Object} object The destination object.     * @param {...Object} [sources] The source objects.     * @returns {Object} Returns `object`.     * @see _.assign     * @example     *     * function Foo() {     *   this.a = 1;     * }     *     * function Bar() {     *   this.c = 3;     * }     *     * Foo.prototype.b = 2;     * Bar.prototype.d = 4;     *     * _.assignIn({ 'a': 0 }, new Foo, new Bar);     * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }     */    var assignIn = createAssigner(function(object, source) {      copyObject(source, keysIn(source), object);    });    /**     * This method is like `_.assignIn` except that it accepts `customizer`     * which is invoked to produce the assigned values. If `customizer` returns     * `undefined`, assignment is handled by the method instead. The `customizer`     * is invoked with five arguments: (objValue, srcValue, key, object, source).     *     * **Note:** This method mutates `object`.     *     * @static     * @memberOf _     * @since 4.0.0     * @alias extendWith     * @category Object     * @param {Object} object The destination object.     * @param {...Object} sources The source objects.     * @param {Function} [customizer] The function to customize assigned values.     * @returns {Object} Returns `object`.     * @see _.assignWith     * @example     *     * function customizer(objValue, srcValue) {     *   return _.isUndefined(objValue) ? srcValue : objValue;     * }     *     * var defaults = _.partialRight(_.assignInWith, customizer);     *     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });     * // => { 'a': 1, 'b': 2 }     */    var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {      copyObject(source, keysIn(source), object, customizer);    });    /**     * This method is like `_.assign` except that it accepts `customizer`     * which is invoked to produce the assigned values. If `customizer` returns     * `undefined`, assignment is handled by the method instead. The `customizer`     * is invoked with five arguments: (objValue, srcValue, key, object, source).     *     * **Note:** This method mutates `object`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Object     * @param {Object} object The destination object.     * @param {...Object} sources The source objects.     * @param {Function} [customizer] The function to customize assigned values.     * @returns {Object} Returns `object`.     * @see _.assignInWith     * @example     *     * function customizer(objValue, srcValue) {     *   return _.isUndefined(objValue) ? srcValue : objValue;     * }     *     * var defaults = _.partialRight(_.assignWith, customizer);     *     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });     * // => { 'a': 1, 'b': 2 }     */    var assignWith = createAssigner(function(object, source, srcIndex, customizer) {      copyObject(source, keys(source), object, customizer);    });    /**     * Creates an array of values corresponding to `paths` of `object`.     *     * @static     * @memberOf _     * @since 1.0.0     * @category Object     * @param {Object} object The object to iterate over.     * @param {...(string|string[])} [paths] The property paths to pick.     * @returns {Array} Returns the picked values.     * @example     *     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };     *     * _.at(object, ['a[0].b.c', 'a[1]']);     * // => [3, 4]     */    var at = flatRest(baseAt);    /**     * Creates an object that inherits from the `prototype` object. If a     * `properties` object is given, its own enumerable string keyed properties     * are assigned to the created object.     *     * @static     * @memberOf _     * @since 2.3.0     * @category Object     * @param {Object} prototype The object to inherit from.     * @param {Object} [properties] The properties to assign to the object.     * @returns {Object} Returns the new object.     * @example     *     * function Shape() {     *   this.x = 0;     *   this.y = 0;     * }     *     * function Circle() {     *   Shape.call(this);     * }     *     * Circle.prototype = _.create(Shape.prototype, {     *   'constructor': Circle     * });     *     * var circle = new Circle;     * circle instanceof Circle;     * // => true     *     * circle instanceof Shape;     * // => true     */    function create(prototype, properties) {      var result = baseCreate(prototype);      return properties == null ? result : baseAssign(result, properties);    }    /**     * Assigns own and inherited enumerable string keyed properties of source     * objects to the destination object for all destination properties that     * resolve to `undefined`. Source objects are applied from left to right.     * Once a property is set, additional values of the same property are ignored.     *     * **Note:** This method mutates `object`.     *     * @static     * @since 0.1.0     * @memberOf _     * @category Object     * @param {Object} object The destination object.     * @param {...Object} [sources] The source objects.     * @returns {Object} Returns `object`.     * @see _.defaultsDeep     * @example     *     * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });     * // => { 'a': 1, 'b': 2 }     */    var defaults = baseRest(function(object, sources) {      object = Object(object);      var index = -1;      var length = sources.length;      var guard = length > 2 ? sources[2] : undefined;      if (guard && isIterateeCall(sources[0], sources[1], guard)) {        length = 1;      }      while (++index < length) {        var source = sources[index];        var props = keysIn(source);        var propsIndex = -1;        var propsLength = props.length;        while (++propsIndex < propsLength) {          var key = props[propsIndex];          var value = object[key];          if (value === undefined ||              (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) {            object[key] = source[key];          }        }      }      return object;    });    /**     * This method is like `_.defaults` except that it recursively assigns     * default properties.     *     * **Note:** This method mutates `object`.     *     * @static     * @memberOf _     * @since 3.10.0     * @category Object     * @param {Object} object The destination object.     * @param {...Object} [sources] The source objects.     * @returns {Object} Returns `object`.     * @see _.defaults     * @example     *     * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });     * // => { 'a': { 'b': 2, 'c': 3 } }     */    var defaultsDeep = baseRest(function(args) {      args.push(undefined, customDefaultsMerge);      return apply(mergeWith, undefined, args);    });    /**     * This method is like `_.find` except that it returns the key of the first     * element `predicate` returns truthy for instead of the element itself.     *     * @static     * @memberOf _     * @since 1.1.0     * @category Object     * @param {Object} object The object to inspect.     * @param {Function} [predicate=_.identity] The function invoked per iteration.     * @returns {string|undefined} Returns the key of the matched element,     *  else `undefined`.     * @example     *     * var users = {     *   'barney':  { 'age': 36, 'active': true },     *   'fred':    { 'age': 40, 'active': false },     *   'pebbles': { 'age': 1,  'active': true }     * };     *     * _.findKey(users, function(o) { return o.age < 40; });     * // => 'barney' (iteration order is not guaranteed)     *     * // The `_.matches` iteratee shorthand.     * _.findKey(users, { 'age': 1, 'active': true });     * // => 'pebbles'     *     * // The `_.matchesProperty` iteratee shorthand.     * _.findKey(users, ['active', false]);     * // => 'fred'     *     * // The `_.property` iteratee shorthand.     * _.findKey(users, 'active');     * // => 'barney'     */    function findKey(object, predicate) {      return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);    }    /**     * This method is like `_.findKey` except that it iterates over elements of     * a collection in the opposite order.     *     * @static     * @memberOf _     * @since 2.0.0     * @category Object     * @param {Object} object The object to inspect.     * @param {Function} [predicate=_.identity] The function invoked per iteration.     * @returns {string|undefined} Returns the key of the matched element,     *  else `undefined`.     * @example     *     * var users = {     *   'barney':  { 'age': 36, 'active': true },     *   'fred':    { 'age': 40, 'active': false },     *   'pebbles': { 'age': 1,  'active': true }     * };     *     * _.findLastKey(users, function(o) { return o.age < 40; });     * // => returns 'pebbles' assuming `_.findKey` returns 'barney'     *     * // The `_.matches` iteratee shorthand.     * _.findLastKey(users, { 'age': 36, 'active': true });     * // => 'barney'     *     * // The `_.matchesProperty` iteratee shorthand.     * _.findLastKey(users, ['active', false]);     * // => 'fred'     *     * // The `_.property` iteratee shorthand.     * _.findLastKey(users, 'active');     * // => 'pebbles'     */    function findLastKey(object, predicate) {      return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);    }    /**     * Iterates over own and inherited enumerable string keyed properties of an     * object and invokes `iteratee` for each property. The iteratee is invoked     * with three arguments: (value, key, object). Iteratee functions may exit     * iteration early by explicitly returning `false`.     *     * @static     * @memberOf _     * @since 0.3.0     * @category Object     * @param {Object} object The object to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @returns {Object} Returns `object`.     * @see _.forInRight     * @example     *     * function Foo() {     *   this.a = 1;     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.forIn(new Foo, function(value, key) {     *   console.log(key);     * });     * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).     */    function forIn(object, iteratee) {      return object == null        ? object        : baseFor(object, getIteratee(iteratee, 3), keysIn);    }    /**     * This method is like `_.forIn` except that it iterates over properties of     * `object` in the opposite order.     *     * @static     * @memberOf _     * @since 2.0.0     * @category Object     * @param {Object} object The object to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @returns {Object} Returns `object`.     * @see _.forIn     * @example     *     * function Foo() {     *   this.a = 1;     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.forInRight(new Foo, function(value, key) {     *   console.log(key);     * });     * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.     */    function forInRight(object, iteratee) {      return object == null        ? object        : baseForRight(object, getIteratee(iteratee, 3), keysIn);    }    /**     * Iterates over own enumerable string keyed properties of an object and     * invokes `iteratee` for each property. The iteratee is invoked with three     * arguments: (value, key, object). Iteratee functions may exit iteration     * early by explicitly returning `false`.     *     * @static     * @memberOf _     * @since 0.3.0     * @category Object     * @param {Object} object The object to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @returns {Object} Returns `object`.     * @see _.forOwnRight     * @example     *     * function Foo() {     *   this.a = 1;     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.forOwn(new Foo, function(value, key) {     *   console.log(key);     * });     * // => Logs 'a' then 'b' (iteration order is not guaranteed).     */    function forOwn(object, iteratee) {      return object && baseForOwn(object, getIteratee(iteratee, 3));    }    /**     * This method is like `_.forOwn` except that it iterates over properties of     * `object` in the opposite order.     *     * @static     * @memberOf _     * @since 2.0.0     * @category Object     * @param {Object} object The object to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @returns {Object} Returns `object`.     * @see _.forOwn     * @example     *     * function Foo() {     *   this.a = 1;     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.forOwnRight(new Foo, function(value, key) {     *   console.log(key);     * });     * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.     */    function forOwnRight(object, iteratee) {      return object && baseForOwnRight(object, getIteratee(iteratee, 3));    }    /**     * Creates an array of function property names from own enumerable properties     * of `object`.     *     * @static     * @since 0.1.0     * @memberOf _     * @category Object     * @param {Object} object The object to inspect.     * @returns {Array} Returns the function names.     * @see _.functionsIn     * @example     *     * function Foo() {     *   this.a = _.constant('a');     *   this.b = _.constant('b');     * }     *     * Foo.prototype.c = _.constant('c');     *     * _.functions(new Foo);     * // => ['a', 'b']     */    function functions(object) {      return object == null ? [] : baseFunctions(object, keys(object));    }    /**     * Creates an array of function property names from own and inherited     * enumerable properties of `object`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Object     * @param {Object} object The object to inspect.     * @returns {Array} Returns the function names.     * @see _.functions     * @example     *     * function Foo() {     *   this.a = _.constant('a');     *   this.b = _.constant('b');     * }     *     * Foo.prototype.c = _.constant('c');     *     * _.functionsIn(new Foo);     * // => ['a', 'b', 'c']     */    function functionsIn(object) {      return object == null ? [] : baseFunctions(object, keysIn(object));    }    /**     * Gets the value at `path` of `object`. If the resolved value is     * `undefined`, the `defaultValue` is returned in its place.     *     * @static     * @memberOf _     * @since 3.7.0     * @category Object     * @param {Object} object The object to query.     * @param {Array|string} path The path of the property to get.     * @param {*} [defaultValue] The value returned for `undefined` resolved values.     * @returns {*} Returns the resolved value.     * @example     *     * var object = { 'a': [{ 'b': { 'c': 3 } }] };     *     * _.get(object, 'a[0].b.c');     * // => 3     *     * _.get(object, ['a', '0', 'b', 'c']);     * // => 3     *     * _.get(object, 'a.b.c', 'default');     * // => 'default'     */    function get(object, path, defaultValue) {      var result = object == null ? undefined : baseGet(object, path);      return result === undefined ? defaultValue : result;    }    /**     * Checks if `path` is a direct property of `object`.     *     * @static     * @since 0.1.0     * @memberOf _     * @category Object     * @param {Object} object The object to query.     * @param {Array|string} path The path to check.     * @returns {boolean} Returns `true` if `path` exists, else `false`.     * @example     *     * var object = { 'a': { 'b': 2 } };     * var other = _.create({ 'a': _.create({ 'b': 2 }) });     *     * _.has(object, 'a');     * // => true     *     * _.has(object, 'a.b');     * // => true     *     * _.has(object, ['a', 'b']);     * // => true     *     * _.has(other, 'a');     * // => false     */    function has(object, path) {      return object != null && hasPath(object, path, baseHas);    }    /**     * Checks if `path` is a direct or inherited property of `object`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Object     * @param {Object} object The object to query.     * @param {Array|string} path The path to check.     * @returns {boolean} Returns `true` if `path` exists, else `false`.     * @example     *     * var object = _.create({ 'a': _.create({ 'b': 2 }) });     *     * _.hasIn(object, 'a');     * // => true     *     * _.hasIn(object, 'a.b');     * // => true     *     * _.hasIn(object, ['a', 'b']);     * // => true     *     * _.hasIn(object, 'b');     * // => false     */    function hasIn(object, path) {      return object != null && hasPath(object, path, baseHasIn);    }    /**     * Creates an object composed of the inverted keys and values of `object`.     * If `object` contains duplicate values, subsequent values overwrite     * property assignments of previous values.     *     * @static     * @memberOf _     * @since 0.7.0     * @category Object     * @param {Object} object The object to invert.     * @returns {Object} Returns the new inverted object.     * @example     *     * var object = { 'a': 1, 'b': 2, 'c': 1 };     *     * _.invert(object);     * // => { '1': 'c', '2': 'b' }     */    var invert = createInverter(function(result, value, key) {      if (value != null &&          typeof value.toString != 'function') {        value = nativeObjectToString.call(value);      }      result[value] = key;    }, constant(identity));    /**     * This method is like `_.invert` except that the inverted object is generated     * from the results of running each element of `object` thru `iteratee`. The     * corresponding inverted value of each inverted key is an array of keys     * responsible for generating the inverted value. The iteratee is invoked     * with one argument: (value).     *     * @static     * @memberOf _     * @since 4.1.0     * @category Object     * @param {Object} object The object to invert.     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.     * @returns {Object} Returns the new inverted object.     * @example     *     * var object = { 'a': 1, 'b': 2, 'c': 1 };     *     * _.invertBy(object);     * // => { '1': ['a', 'c'], '2': ['b'] }     *     * _.invertBy(object, function(value) {     *   return 'group' + value;     * });     * // => { 'group1': ['a', 'c'], 'group2': ['b'] }     */    var invertBy = createInverter(function(result, value, key) {      if (value != null &&          typeof value.toString != 'function') {        value = nativeObjectToString.call(value);      }      if (hasOwnProperty.call(result, value)) {        result[value].push(key);      } else {        result[value] = [key];      }    }, getIteratee);    /**     * Invokes the method at `path` of `object`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Object     * @param {Object} object The object to query.     * @param {Array|string} path The path of the method to invoke.     * @param {...*} [args] The arguments to invoke the method with.     * @returns {*} Returns the result of the invoked method.     * @example     *     * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };     *     * _.invoke(object, 'a[0].b.c.slice', 1, 3);     * // => [2, 3]     */    var invoke = baseRest(baseInvoke);    /**     * Creates an array of the own enumerable property names of `object`.     *     * **Note:** Non-object values are coerced to objects. See the     * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)     * for more details.     *     * @static     * @since 0.1.0     * @memberOf _     * @category Object     * @param {Object} object The object to query.     * @returns {Array} Returns the array of property names.     * @example     *     * function Foo() {     *   this.a = 1;     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.keys(new Foo);     * // => ['a', 'b'] (iteration order is not guaranteed)     *     * _.keys('hi');     * // => ['0', '1']     */    function keys(object) {      return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);    }    /**     * Creates an array of the own and inherited enumerable property names of `object`.     *     * **Note:** Non-object values are coerced to objects.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Object     * @param {Object} object The object to query.     * @returns {Array} Returns the array of property names.     * @example     *     * function Foo() {     *   this.a = 1;     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.keysIn(new Foo);     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)     */    function keysIn(object) {      return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);    }    /**     * The opposite of `_.mapValues`; this method creates an object with the     * same values as `object` and keys generated by running each own enumerable     * string keyed property of `object` thru `iteratee`. The iteratee is invoked     * with three arguments: (value, key, object).     *     * @static     * @memberOf _     * @since 3.8.0     * @category Object     * @param {Object} object The object to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @returns {Object} Returns the new mapped object.     * @see _.mapValues     * @example     *     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {     *   return key + value;     * });     * // => { 'a1': 1, 'b2': 2 }     */    function mapKeys(object, iteratee) {      var result = {};      iteratee = getIteratee(iteratee, 3);      baseForOwn(object, function(value, key, object) {        baseAssignValue(result, iteratee(value, key, object), value);      });      return result;    }    /**     * Creates an object with the same keys as `object` and values generated     * by running each own enumerable string keyed property of `object` thru     * `iteratee`. The iteratee is invoked with three arguments:     * (value, key, object).     *     * @static     * @memberOf _     * @since 2.4.0     * @category Object     * @param {Object} object The object to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @returns {Object} Returns the new mapped object.     * @see _.mapKeys     * @example     *     * var users = {     *   'fred':    { 'user': 'fred',    'age': 40 },     *   'pebbles': { 'user': 'pebbles', 'age': 1 }     * };     *     * _.mapValues(users, function(o) { return o.age; });     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)     *     * // The `_.property` iteratee shorthand.     * _.mapValues(users, 'age');     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)     */    function mapValues(object, iteratee) {      var result = {};      iteratee = getIteratee(iteratee, 3);      baseForOwn(object, function(value, key, object) {        baseAssignValue(result, key, iteratee(value, key, object));      });      return result;    }    /**     * This method is like `_.assign` except that it recursively merges own and     * inherited enumerable string keyed properties of source objects into the     * destination object. Source properties that resolve to `undefined` are     * skipped if a destination value exists. Array and plain object properties     * are merged recursively. Other objects and value types are overridden by     * assignment. Source objects are applied from left to right. Subsequent     * sources overwrite property assignments of previous sources.     *     * **Note:** This method mutates `object`.     *     * @static     * @memberOf _     * @since 0.5.0     * @category Object     * @param {Object} object The destination object.     * @param {...Object} [sources] The source objects.     * @returns {Object} Returns `object`.     * @example     *     * var object = {     *   'a': [{ 'b': 2 }, { 'd': 4 }]     * };     *     * var other = {     *   'a': [{ 'c': 3 }, { 'e': 5 }]     * };     *     * _.merge(object, other);     * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }     */    var merge = createAssigner(function(object, source, srcIndex) {      baseMerge(object, source, srcIndex);    });    /**     * This method is like `_.merge` except that it accepts `customizer` which     * is invoked to produce the merged values of the destination and source     * properties. If `customizer` returns `undefined`, merging is handled by the     * method instead. The `customizer` is invoked with six arguments:     * (objValue, srcValue, key, object, source, stack).     *     * **Note:** This method mutates `object`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Object     * @param {Object} object The destination object.     * @param {...Object} sources The source objects.     * @param {Function} customizer The function to customize assigned values.     * @returns {Object} Returns `object`.     * @example     *     * function customizer(objValue, srcValue) {     *   if (_.isArray(objValue)) {     *     return objValue.concat(srcValue);     *   }     * }     *     * var object = { 'a': [1], 'b': [2] };     * var other = { 'a': [3], 'b': [4] };     *     * _.mergeWith(object, other, customizer);     * // => { 'a': [1, 3], 'b': [2, 4] }     */    var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {      baseMerge(object, source, srcIndex, customizer);    });    /**     * The opposite of `_.pick`; this method creates an object composed of the     * own and inherited enumerable property paths of `object` that are not omitted.     *     * **Note:** This method is considerably slower than `_.pick`.     *     * @static     * @since 0.1.0     * @memberOf _     * @category Object     * @param {Object} object The source object.     * @param {...(string|string[])} [paths] The property paths to omit.     * @returns {Object} Returns the new object.     * @example     *     * var object = { 'a': 1, 'b': '2', 'c': 3 };     *     * _.omit(object, ['a', 'c']);     * // => { 'b': '2' }     */    var omit = flatRest(function(object, paths) {      var result = {};      if (object == null) {        return result;      }      var isDeep = false;      paths = arrayMap(paths, function(path) {        path = castPath(path, object);        isDeep || (isDeep = path.length > 1);        return path;      });      copyObject(object, getAllKeysIn(object), result);      if (isDeep) {        result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);      }      var length = paths.length;      while (length--) {        baseUnset(result, paths[length]);      }      return result;    });    /**     * The opposite of `_.pickBy`; this method creates an object composed of     * the own and inherited enumerable string keyed properties of `object` that     * `predicate` doesn't return truthy for. The predicate is invoked with two     * arguments: (value, key).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Object     * @param {Object} object The source object.     * @param {Function} [predicate=_.identity] The function invoked per property.     * @returns {Object} Returns the new object.     * @example     *     * var object = { 'a': 1, 'b': '2', 'c': 3 };     *     * _.omitBy(object, _.isNumber);     * // => { 'b': '2' }     */    function omitBy(object, predicate) {      return pickBy(object, negate(getIteratee(predicate)));    }    /**     * Creates an object composed of the picked `object` properties.     *     * @static     * @since 0.1.0     * @memberOf _     * @category Object     * @param {Object} object The source object.     * @param {...(string|string[])} [paths] The property paths to pick.     * @returns {Object} Returns the new object.     * @example     *     * var object = { 'a': 1, 'b': '2', 'c': 3 };     *     * _.pick(object, ['a', 'c']);     * // => { 'a': 1, 'c': 3 }     */    var pick = flatRest(function(object, paths) {      return object == null ? {} : basePick(object, paths);    });    /**     * Creates an object composed of the `object` properties `predicate` returns     * truthy for. The predicate is invoked with two arguments: (value, key).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Object     * @param {Object} object The source object.     * @param {Function} [predicate=_.identity] The function invoked per property.     * @returns {Object} Returns the new object.     * @example     *     * var object = { 'a': 1, 'b': '2', 'c': 3 };     *     * _.pickBy(object, _.isNumber);     * // => { 'a': 1, 'c': 3 }     */    function pickBy(object, predicate) {      if (object == null) {        return {};      }      var props = arrayMap(getAllKeysIn(object), function(prop) {        return [prop];      });      predicate = getIteratee(predicate);      return basePickBy(object, props, function(value, path) {        return predicate(value, path[0]);      });    }    /**     * This method is like `_.get` except that if the resolved value is a     * function it's invoked with the `this` binding of its parent object and     * its result is returned.     *     * @static     * @since 0.1.0     * @memberOf _     * @category Object     * @param {Object} object The object to query.     * @param {Array|string} path The path of the property to resolve.     * @param {*} [defaultValue] The value returned for `undefined` resolved values.     * @returns {*} Returns the resolved value.     * @example     *     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };     *     * _.result(object, 'a[0].b.c1');     * // => 3     *     * _.result(object, 'a[0].b.c2');     * // => 4     *     * _.result(object, 'a[0].b.c3', 'default');     * // => 'default'     *     * _.result(object, 'a[0].b.c3', _.constant('default'));     * // => 'default'     */    function result(object, path, defaultValue) {      path = castPath(path, object);      var index = -1,          length = path.length;      // Ensure the loop is entered when path is empty.      if (!length) {        length = 1;        object = undefined;      }      while (++index < length) {        var value = object == null ? undefined : object[toKey(path[index])];        if (value === undefined) {          index = length;          value = defaultValue;        }        object = isFunction(value) ? value.call(object) : value;      }      return object;    }    /**     * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,     * it's created. Arrays are created for missing index properties while objects     * are created for all other missing properties. Use `_.setWith` to customize     * `path` creation.     *     * **Note:** This method mutates `object`.     *     * @static     * @memberOf _     * @since 3.7.0     * @category Object     * @param {Object} object The object to modify.     * @param {Array|string} path The path of the property to set.     * @param {*} value The value to set.     * @returns {Object} Returns `object`.     * @example     *     * var object = { 'a': [{ 'b': { 'c': 3 } }] };     *     * _.set(object, 'a[0].b.c', 4);     * console.log(object.a[0].b.c);     * // => 4     *     * _.set(object, ['x', '0', 'y', 'z'], 5);     * console.log(object.x[0].y.z);     * // => 5     */    function set(object, path, value) {      return object == null ? object : baseSet(object, path, value);    }    /**     * This method is like `_.set` except that it accepts `customizer` which is     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`     * path creation is handled by the method instead. The `customizer` is invoked     * with three arguments: (nsValue, key, nsObject).     *     * **Note:** This method mutates `object`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Object     * @param {Object} object The object to modify.     * @param {Array|string} path The path of the property to set.     * @param {*} value The value to set.     * @param {Function} [customizer] The function to customize assigned values.     * @returns {Object} Returns `object`.     * @example     *     * var object = {};     *     * _.setWith(object, '[0][1]', 'a', Object);     * // => { '0': { '1': 'a' } }     */    function setWith(object, path, value, customizer) {      customizer = typeof customizer == 'function' ? customizer : undefined;      return object == null ? object : baseSet(object, path, value, customizer);    }    /**     * Creates an array of own enumerable string keyed-value pairs for `object`     * which can be consumed by `_.fromPairs`. If `object` is a map or set, its     * entries are returned.     *     * @static     * @memberOf _     * @since 4.0.0     * @alias entries     * @category Object     * @param {Object} object The object to query.     * @returns {Array} Returns the key-value pairs.     * @example     *     * function Foo() {     *   this.a = 1;     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.toPairs(new Foo);     * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)     */    var toPairs = createToPairs(keys);    /**     * Creates an array of own and inherited enumerable string keyed-value pairs     * for `object` which can be consumed by `_.fromPairs`. If `object` is a map     * or set, its entries are returned.     *     * @static     * @memberOf _     * @since 4.0.0     * @alias entriesIn     * @category Object     * @param {Object} object The object to query.     * @returns {Array} Returns the key-value pairs.     * @example     *     * function Foo() {     *   this.a = 1;     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.toPairsIn(new Foo);     * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)     */    var toPairsIn = createToPairs(keysIn);    /**     * An alternative to `_.reduce`; this method transforms `object` to a new     * `accumulator` object which is the result of running each of its own     * enumerable string keyed properties thru `iteratee`, with each invocation     * potentially mutating the `accumulator` object. If `accumulator` is not     * provided, a new object with the same `[[Prototype]]` will be used. The     * iteratee is invoked with four arguments: (accumulator, value, key, object).     * Iteratee functions may exit iteration early by explicitly returning `false`.     *     * @static     * @memberOf _     * @since 1.3.0     * @category Object     * @param {Object} object The object to iterate over.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @param {*} [accumulator] The custom accumulator value.     * @returns {*} Returns the accumulated value.     * @example     *     * _.transform([2, 3, 4], function(result, n) {     *   result.push(n *= n);     *   return n % 2 == 0;     * }, []);     * // => [4, 9]     *     * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {     *   (result[value] || (result[value] = [])).push(key);     * }, {});     * // => { '1': ['a', 'c'], '2': ['b'] }     */    function transform(object, iteratee, accumulator) {      var isArr = isArray(object),          isArrLike = isArr || isBuffer(object) || isTypedArray(object);      iteratee = getIteratee(iteratee, 4);      if (accumulator == null) {        var Ctor = object && object.constructor;        if (isArrLike) {          accumulator = isArr ? new Ctor : [];        }        else if (isObject(object)) {          accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};        }        else {          accumulator = {};        }      }      (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {        return iteratee(accumulator, value, index, object);      });      return accumulator;    }    /**     * Removes the property at `path` of `object`.     *     * **Note:** This method mutates `object`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Object     * @param {Object} object The object to modify.     * @param {Array|string} path The path of the property to unset.     * @returns {boolean} Returns `true` if the property is deleted, else `false`.     * @example     *     * var object = { 'a': [{ 'b': { 'c': 7 } }] };     * _.unset(object, 'a[0].b.c');     * // => true     *     * console.log(object);     * // => { 'a': [{ 'b': {} }] };     *     * _.unset(object, ['a', '0', 'b', 'c']);     * // => true     *     * console.log(object);     * // => { 'a': [{ 'b': {} }] };     */    function unset(object, path) {      return object == null ? true : baseUnset(object, path);    }    /**     * This method is like `_.set` except that accepts `updater` to produce the     * value to set. Use `_.updateWith` to customize `path` creation. The `updater`     * is invoked with one argument: (value).     *     * **Note:** This method mutates `object`.     *     * @static     * @memberOf _     * @since 4.6.0     * @category Object     * @param {Object} object The object to modify.     * @param {Array|string} path The path of the property to set.     * @param {Function} updater The function to produce the updated value.     * @returns {Object} Returns `object`.     * @example     *     * var object = { 'a': [{ 'b': { 'c': 3 } }] };     *     * _.update(object, 'a[0].b.c', function(n) { return n * n; });     * console.log(object.a[0].b.c);     * // => 9     *     * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });     * console.log(object.x[0].y.z);     * // => 0     */    function update(object, path, updater) {      return object == null ? object : baseUpdate(object, path, castFunction(updater));    }    /**     * This method is like `_.update` except that it accepts `customizer` which is     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`     * path creation is handled by the method instead. The `customizer` is invoked     * with three arguments: (nsValue, key, nsObject).     *     * **Note:** This method mutates `object`.     *     * @static     * @memberOf _     * @since 4.6.0     * @category Object     * @param {Object} object The object to modify.     * @param {Array|string} path The path of the property to set.     * @param {Function} updater The function to produce the updated value.     * @param {Function} [customizer] The function to customize assigned values.     * @returns {Object} Returns `object`.     * @example     *     * var object = {};     *     * _.updateWith(object, '[0][1]', _.constant('a'), Object);     * // => { '0': { '1': 'a' } }     */    function updateWith(object, path, updater, customizer) {      customizer = typeof customizer == 'function' ? customizer : undefined;      return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);    }    /**     * Creates an array of the own enumerable string keyed property values of `object`.     *     * **Note:** Non-object values are coerced to objects.     *     * @static     * @since 0.1.0     * @memberOf _     * @category Object     * @param {Object} object The object to query.     * @returns {Array} Returns the array of property values.     * @example     *     * function Foo() {     *   this.a = 1;     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.values(new Foo);     * // => [1, 2] (iteration order is not guaranteed)     *     * _.values('hi');     * // => ['h', 'i']     */    function values(object) {      return object == null ? [] : baseValues(object, keys(object));    }    /**     * Creates an array of the own and inherited enumerable string keyed property     * values of `object`.     *     * **Note:** Non-object values are coerced to objects.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Object     * @param {Object} object The object to query.     * @returns {Array} Returns the array of property values.     * @example     *     * function Foo() {     *   this.a = 1;     *   this.b = 2;     * }     *     * Foo.prototype.c = 3;     *     * _.valuesIn(new Foo);     * // => [1, 2, 3] (iteration order is not guaranteed)     */    function valuesIn(object) {      return object == null ? [] : baseValues(object, keysIn(object));    }    /*------------------------------------------------------------------------*/    /**     * Clamps `number` within the inclusive `lower` and `upper` bounds.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Number     * @param {number} number The number to clamp.     * @param {number} [lower] The lower bound.     * @param {number} upper The upper bound.     * @returns {number} Returns the clamped number.     * @example     *     * _.clamp(-10, -5, 5);     * // => -5     *     * _.clamp(10, -5, 5);     * // => 5     */    function clamp(number, lower, upper) {      if (upper === undefined) {        upper = lower;        lower = undefined;      }      if (upper !== undefined) {        upper = toNumber(upper);        upper = upper === upper ? upper : 0;      }      if (lower !== undefined) {        lower = toNumber(lower);        lower = lower === lower ? lower : 0;      }      return baseClamp(toNumber(number), lower, upper);    }    /**     * Checks if `n` is between `start` and up to, but not including, `end`. If     * `end` is not specified, it's set to `start` with `start` then set to `0`.     * If `start` is greater than `end` the params are swapped to support     * negative ranges.     *     * @static     * @memberOf _     * @since 3.3.0     * @category Number     * @param {number} number The number to check.     * @param {number} [start=0] The start of the range.     * @param {number} end The end of the range.     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.     * @see _.range, _.rangeRight     * @example     *     * _.inRange(3, 2, 4);     * // => true     *     * _.inRange(4, 8);     * // => true     *     * _.inRange(4, 2);     * // => false     *     * _.inRange(2, 2);     * // => false     *     * _.inRange(1.2, 2);     * // => true     *     * _.inRange(5.2, 4);     * // => false     *     * _.inRange(-3, -2, -6);     * // => true     */    function inRange(number, start, end) {      start = toFinite(start);      if (end === undefined) {        end = start;        start = 0;      } else {        end = toFinite(end);      }      number = toNumber(number);      return baseInRange(number, start, end);    }    /**     * Produces a random number between the inclusive `lower` and `upper` bounds.     * If only one argument is provided a number between `0` and the given number     * is returned. If `floating` is `true`, or either `lower` or `upper` are     * floats, a floating-point number is returned instead of an integer.     *     * **Note:** JavaScript follows the IEEE-754 standard for resolving     * floating-point values which can produce unexpected results.     *     * @static     * @memberOf _     * @since 0.7.0     * @category Number     * @param {number} [lower=0] The lower bound.     * @param {number} [upper=1] The upper bound.     * @param {boolean} [floating] Specify returning a floating-point number.     * @returns {number} Returns the random number.     * @example     *     * _.random(0, 5);     * // => an integer between 0 and 5     *     * _.random(5);     * // => also an integer between 0 and 5     *     * _.random(5, true);     * // => a floating-point number between 0 and 5     *     * _.random(1.2, 5.2);     * // => a floating-point number between 1.2 and 5.2     */    function random(lower, upper, floating) {      if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {        upper = floating = undefined;      }      if (floating === undefined) {        if (typeof upper == 'boolean') {          floating = upper;          upper = undefined;        }        else if (typeof lower == 'boolean') {          floating = lower;          lower = undefined;        }      }      if (lower === undefined && upper === undefined) {        lower = 0;        upper = 1;      }      else {        lower = toFinite(lower);        if (upper === undefined) {          upper = lower;          lower = 0;        } else {          upper = toFinite(upper);        }      }      if (lower > upper) {        var temp = lower;        lower = upper;        upper = temp;      }      if (floating || lower % 1 || upper % 1) {        var rand = nativeRandom();        return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);      }      return baseRandom(lower, upper);    }    /*------------------------------------------------------------------------*/    /**     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).     *     * @static     * @memberOf _     * @since 3.0.0     * @category String     * @param {string} [string=''] The string to convert.     * @returns {string} Returns the camel cased string.     * @example     *     * _.camelCase('Foo Bar');     * // => 'fooBar'     *     * _.camelCase('--foo-bar--');     * // => 'fooBar'     *     * _.camelCase('__FOO_BAR__');     * // => 'fooBar'     */    var camelCase = createCompounder(function(result, word, index) {      word = word.toLowerCase();      return result + (index ? capitalize(word) : word);    });    /**     * Converts the first character of `string` to upper case and the remaining     * to lower case.     *     * @static     * @memberOf _     * @since 3.0.0     * @category String     * @param {string} [string=''] The string to capitalize.     * @returns {string} Returns the capitalized string.     * @example     *     * _.capitalize('FRED');     * // => 'Fred'     */    function capitalize(string) {      return upperFirst(toString(string).toLowerCase());    }    /**     * Deburrs `string` by converting     * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)     * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)     * letters to basic Latin letters and removing     * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).     *     * @static     * @memberOf _     * @since 3.0.0     * @category String     * @param {string} [string=''] The string to deburr.     * @returns {string} Returns the deburred string.     * @example     *     * _.deburr('déjà vu');     * // => 'deja vu'     */    function deburr(string) {      string = toString(string);      return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');    }    /**     * Checks if `string` ends with the given target string.     *     * @static     * @memberOf _     * @since 3.0.0     * @category String     * @param {string} [string=''] The string to inspect.     * @param {string} [target] The string to search for.     * @param {number} [position=string.length] The position to search up to.     * @returns {boolean} Returns `true` if `string` ends with `target`,     *  else `false`.     * @example     *     * _.endsWith('abc', 'c');     * // => true     *     * _.endsWith('abc', 'b');     * // => false     *     * _.endsWith('abc', 'b', 2);     * // => true     */    function endsWith(string, target, position) {      string = toString(string);      target = baseToString(target);      var length = string.length;      position = position === undefined        ? length        : baseClamp(toInteger(position), 0, length);      var end = position;      position -= target.length;      return position >= 0 && string.slice(position, end) == target;    }    /**     * Converts the characters "&", "<", ">", '"', and "'" in `string` to their     * corresponding HTML entities.     *     * **Note:** No other characters are escaped. To escape additional     * characters use a third-party library like [_he_](https://mths.be/he).     *     * Though the ">" character is escaped for symmetry, characters like     * ">" and "/" don't need escaping in HTML and have no special meaning     * unless they're part of a tag or unquoted attribute value. See     * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)     * (under "semi-related fun fact") for more details.     *     * When working with HTML you should always     * [quote attribute values](http://wonko.com/post/html-escaping) to reduce     * XSS vectors.     *     * @static     * @since 0.1.0     * @memberOf _     * @category String     * @param {string} [string=''] The string to escape.     * @returns {string} Returns the escaped string.     * @example     *     * _.escape('fred, barney, & pebbles');     * // => 'fred, barney, & pebbles'     */    function escape(string) {      string = toString(string);      return (string && reHasUnescapedHtml.test(string))        ? string.replace(reUnescapedHtml, escapeHtmlChar)        : string;    }    /**     * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",     * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.     *     * @static     * @memberOf _     * @since 3.0.0     * @category String     * @param {string} [string=''] The string to escape.     * @returns {string} Returns the escaped string.     * @example     *     * _.escapeRegExp('[lodash](https://lodash.com/)');     * // => '\[lodash\]\(https://lodash\.com/\)'     */    function escapeRegExp(string) {      string = toString(string);      return (string && reHasRegExpChar.test(string))        ? string.replace(reRegExpChar, '\\$&')        : string;    }    /**     * Converts `string` to     * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).     *     * @static     * @memberOf _     * @since 3.0.0     * @category String     * @param {string} [string=''] The string to convert.     * @returns {string} Returns the kebab cased string.     * @example     *     * _.kebabCase('Foo Bar');     * // => 'foo-bar'     *     * _.kebabCase('fooBar');     * // => 'foo-bar'     *     * _.kebabCase('__FOO_BAR__');     * // => 'foo-bar'     */    var kebabCase = createCompounder(function(result, word, index) {      return result + (index ? '-' : '') + word.toLowerCase();    });    /**     * Converts `string`, as space separated words, to lower case.     *     * @static     * @memberOf _     * @since 4.0.0     * @category String     * @param {string} [string=''] The string to convert.     * @returns {string} Returns the lower cased string.     * @example     *     * _.lowerCase('--Foo-Bar--');     * // => 'foo bar'     *     * _.lowerCase('fooBar');     * // => 'foo bar'     *     * _.lowerCase('__FOO_BAR__');     * // => 'foo bar'     */    var lowerCase = createCompounder(function(result, word, index) {      return result + (index ? ' ' : '') + word.toLowerCase();    });    /**     * Converts the first character of `string` to lower case.     *     * @static     * @memberOf _     * @since 4.0.0     * @category String     * @param {string} [string=''] The string to convert.     * @returns {string} Returns the converted string.     * @example     *     * _.lowerFirst('Fred');     * // => 'fred'     *     * _.lowerFirst('FRED');     * // => 'fRED'     */    var lowerFirst = createCaseFirst('toLowerCase');    /**     * Pads `string` on the left and right sides if it's shorter than `length`.     * Padding characters are truncated if they can't be evenly divided by `length`.     *     * @static     * @memberOf _     * @since 3.0.0     * @category String     * @param {string} [string=''] The string to pad.     * @param {number} [length=0] The padding length.     * @param {string} [chars=' '] The string used as padding.     * @returns {string} Returns the padded string.     * @example     *     * _.pad('abc', 8);     * // => '  abc   '     *     * _.pad('abc', 8, '_-');     * // => '_-abc_-_'     *     * _.pad('abc', 3);     * // => 'abc'     */    function pad(string, length, chars) {      string = toString(string);      length = toInteger(length);      var strLength = length ? stringSize(string) : 0;      if (!length || strLength >= length) {        return string;      }      var mid = (length - strLength) / 2;      return (        createPadding(nativeFloor(mid), chars) +        string +        createPadding(nativeCeil(mid), chars)      );    }    /**     * Pads `string` on the right side if it's shorter than `length`. Padding     * characters are truncated if they exceed `length`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category String     * @param {string} [string=''] The string to pad.     * @param {number} [length=0] The padding length.     * @param {string} [chars=' '] The string used as padding.     * @returns {string} Returns the padded string.     * @example     *     * _.padEnd('abc', 6);     * // => 'abc   '     *     * _.padEnd('abc', 6, '_-');     * // => 'abc_-_'     *     * _.padEnd('abc', 3);     * // => 'abc'     */    function padEnd(string, length, chars) {      string = toString(string);      length = toInteger(length);      var strLength = length ? stringSize(string) : 0;      return (length && strLength < length)        ? (string + createPadding(length - strLength, chars))        : string;    }    /**     * Pads `string` on the left side if it's shorter than `length`. Padding     * characters are truncated if they exceed `length`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category String     * @param {string} [string=''] The string to pad.     * @param {number} [length=0] The padding length.     * @param {string} [chars=' '] The string used as padding.     * @returns {string} Returns the padded string.     * @example     *     * _.padStart('abc', 6);     * // => '   abc'     *     * _.padStart('abc', 6, '_-');     * // => '_-_abc'     *     * _.padStart('abc', 3);     * // => 'abc'     */    function padStart(string, length, chars) {      string = toString(string);      length = toInteger(length);      var strLength = length ? stringSize(string) : 0;      return (length && strLength < length)        ? (createPadding(length - strLength, chars) + string)        : string;    }    /**     * Converts `string` to an integer of the specified radix. If `radix` is     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a     * hexadecimal, in which case a `radix` of `16` is used.     *     * **Note:** This method aligns with the     * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.     *     * @static     * @memberOf _     * @since 1.1.0     * @category String     * @param {string} string The string to convert.     * @param {number} [radix=10] The radix to interpret `value` by.     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.     * @returns {number} Returns the converted integer.     * @example     *     * _.parseInt('08');     * // => 8     *     * _.map(['6', '08', '10'], _.parseInt);     * // => [6, 8, 10]     */    function parseInt(string, radix, guard) {      if (guard || radix == null) {        radix = 0;      } else if (radix) {        radix = +radix;      }      return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);    }    /**     * Repeats the given string `n` times.     *     * @static     * @memberOf _     * @since 3.0.0     * @category String     * @param {string} [string=''] The string to repeat.     * @param {number} [n=1] The number of times to repeat the string.     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.     * @returns {string} Returns the repeated string.     * @example     *     * _.repeat('*', 3);     * // => '***'     *     * _.repeat('abc', 2);     * // => 'abcabc'     *     * _.repeat('abc', 0);     * // => ''     */    function repeat(string, n, guard) {      if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {        n = 1;      } else {        n = toInteger(n);      }      return baseRepeat(toString(string), n);    }    /**     * Replaces matches for `pattern` in `string` with `replacement`.     *     * **Note:** This method is based on     * [`String#replace`](https://mdn.io/String/replace).     *     * @static     * @memberOf _     * @since 4.0.0     * @category String     * @param {string} [string=''] The string to modify.     * @param {RegExp|string} pattern The pattern to replace.     * @param {Function|string} replacement The match replacement.     * @returns {string} Returns the modified string.     * @example     *     * _.replace('Hi Fred', 'Fred', 'Barney');     * // => 'Hi Barney'     */    function replace() {      var args = arguments,          string = toString(args[0]);      return args.length < 3 ? string : string.replace(args[1], args[2]);    }    /**     * Converts `string` to     * [snake case](https://en.wikipedia.org/wiki/Snake_case).     *     * @static     * @memberOf _     * @since 3.0.0     * @category String     * @param {string} [string=''] The string to convert.     * @returns {string} Returns the snake cased string.     * @example     *     * _.snakeCase('Foo Bar');     * // => 'foo_bar'     *     * _.snakeCase('fooBar');     * // => 'foo_bar'     *     * _.snakeCase('--FOO-BAR--');     * // => 'foo_bar'     */    var snakeCase = createCompounder(function(result, word, index) {      return result + (index ? '_' : '') + word.toLowerCase();    });    /**     * Splits `string` by `separator`.     *     * **Note:** This method is based on     * [`String#split`](https://mdn.io/String/split).     *     * @static     * @memberOf _     * @since 4.0.0     * @category String     * @param {string} [string=''] The string to split.     * @param {RegExp|string} separator The separator pattern to split by.     * @param {number} [limit] The length to truncate results to.     * @returns {Array} Returns the string segments.     * @example     *     * _.split('a-b-c', '-', 2);     * // => ['a', 'b']     */    function split(string, separator, limit) {      if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {        separator = limit = undefined;      }      limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;      if (!limit) {        return [];      }      string = toString(string);      if (string && (            typeof separator == 'string' ||            (separator != null && !isRegExp(separator))          )) {        separator = baseToString(separator);        if (!separator && hasUnicode(string)) {          return castSlice(stringToArray(string), 0, limit);        }      }      return string.split(separator, limit);    }    /**     * Converts `string` to     * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).     *     * @static     * @memberOf _     * @since 3.1.0     * @category String     * @param {string} [string=''] The string to convert.     * @returns {string} Returns the start cased string.     * @example     *     * _.startCase('--foo-bar--');     * // => 'Foo Bar'     *     * _.startCase('fooBar');     * // => 'Foo Bar'     *     * _.startCase('__FOO_BAR__');     * // => 'FOO BAR'     */    var startCase = createCompounder(function(result, word, index) {      return result + (index ? ' ' : '') + upperFirst(word);    });    /**     * Checks if `string` starts with the given target string.     *     * @static     * @memberOf _     * @since 3.0.0     * @category String     * @param {string} [string=''] The string to inspect.     * @param {string} [target] The string to search for.     * @param {number} [position=0] The position to search from.     * @returns {boolean} Returns `true` if `string` starts with `target`,     *  else `false`.     * @example     *     * _.startsWith('abc', 'a');     * // => true     *     * _.startsWith('abc', 'b');     * // => false     *     * _.startsWith('abc', 'b', 1);     * // => true     */    function startsWith(string, target, position) {      string = toString(string);      position = position == null        ? 0        : baseClamp(toInteger(position), 0, string.length);      target = baseToString(target);      return string.slice(position, position + target.length) == target;    }    /**     * Creates a compiled template function that can interpolate data properties     * in "interpolate" delimiters, HTML-escape interpolated data properties in     * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data     * properties may be accessed as free variables in the template. If a setting     * object is given, it takes precedence over `_.templateSettings` values.     *     * **Note:** In the development build `_.template` utilizes     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)     * for easier debugging.     *     * For more information on precompiling templates see     * [lodash's custom builds documentation](https://lodash.com/custom-builds).     *     * For more information on Chrome extension sandboxes see     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).     *     * @static     * @since 0.1.0     * @memberOf _     * @category String     * @param {string} [string=''] The template string.     * @param {Object} [options={}] The options object.     * @param {RegExp} [options.escape=_.templateSettings.escape]     *  The HTML "escape" delimiter.     * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]     *  The "evaluate" delimiter.     * @param {Object} [options.imports=_.templateSettings.imports]     *  An object to import into the template as free variables.     * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]     *  The "interpolate" delimiter.     * @param {string} [options.sourceURL='lodash.templateSources[n]']     *  The sourceURL of the compiled template.     * @param {string} [options.variable='obj']     *  The data object variable name.     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.     * @returns {Function} Returns the compiled template function.     * @example     *     * // Use the "interpolate" delimiter to create a compiled template.     * var compiled = _.template('hello <%= user %>!');     * compiled({ 'user': 'fred' });     * // => 'hello fred!'     *     * // Use the HTML "escape" delimiter to escape data property values.     * var compiled = _.template('<b><%- value %></b>');     * compiled({ 'value': '<script>' });     * // => '<b><script></b>'     *     * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');     * compiled({ 'users': ['fred', 'barney'] });     * // => '<li>fred</li><li>barney</li>'     *     * // Use the internal `print` function in "evaluate" delimiters.     * var compiled = _.template('<% print("hello " + user); %>!');     * compiled({ 'user': 'barney' });     * // => 'hello barney!'     *     * // Use the ES template literal delimiter as an "interpolate" delimiter.     * // Disable support by replacing the "interpolate" delimiter.     * var compiled = _.template('hello ${ user }!');     * compiled({ 'user': 'pebbles' });     * // => 'hello pebbles!'     *     * // Use backslashes to treat delimiters as plain text.     * var compiled = _.template('<%= "\\<%- value %\\>" %>');     * compiled({ 'value': 'ignored' });     * // => '<%- value %>'     *     * // Use the `imports` option to import `jQuery` as `jq`.     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });     * compiled({ 'users': ['fred', 'barney'] });     * // => '<li>fred</li><li>barney</li>'     *     * // Use the `sourceURL` option to specify a custom sourceURL for the template.     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });     * compiled(data);     * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.     *     * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });     * compiled.source;     * // => function(data) {     * //   var __t, __p = '';     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';     * //   return __p;     * // }     *     * // Use custom template delimiters.     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;     * var compiled = _.template('hello {{ user }}!');     * compiled({ 'user': 'mustache' });     * // => 'hello mustache!'     *     * // Use the `source` property to inline compiled templates for meaningful     * // line numbers in error messages and stack traces.     * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\     *   var JST = {\     *     "main": ' + _.template(mainText).source + '\     *   };\     * ');     */    function template(string, options, guard) {      // Based on John Resig's `tmpl` implementation      // (http://ejohn.org/blog/javascript-micro-templating/)      // and Laura Doktorova's doT.js (https://github.com/olado/doT).      var settings = lodash.templateSettings;      if (guard && isIterateeCall(string, options, guard)) {        options = undefined;      }      string = toString(string);      options = assignInWith({}, options, settings, customDefaultsAssignIn);      var imports = assignInWith({}, options.imports, settings.imports, customDefaultsAssignIn),          importsKeys = keys(imports),          importsValues = baseValues(imports, importsKeys);      var isEscaping,          isEvaluating,          index = 0,          interpolate = options.interpolate || reNoMatch,          source = "__p += '";      // Compile the regexp to match each delimiter.      var reDelimiters = RegExp(        (options.escape || reNoMatch).source + '|' +        interpolate.source + '|' +        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +        (options.evaluate || reNoMatch).source + '|$'      , 'g');      // Use a sourceURL for easier debugging.      var sourceURL = '//# sourceURL=' +        ('sourceURL' in options          ? options.sourceURL          : ('lodash.templateSources[' + (++templateCounter) + ']')        ) + '\n';      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {        interpolateValue || (interpolateValue = esTemplateValue);        // Escape characters that can't be included in string literals.        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);        // Replace delimiters with snippets.        if (escapeValue) {          isEscaping = true;          source += "' +\n__e(" + escapeValue + ") +\n'";        }        if (evaluateValue) {          isEvaluating = true;          source += "';\n" + evaluateValue + ";\n__p += '";        }        if (interpolateValue) {          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";        }        index = offset + match.length;        // The JS engine embedded in Adobe products needs `match` returned in        // order to produce the correct `offset` value.        return match;      });      source += "';\n";      // If `variable` is not specified wrap a with-statement around the generated      // code to add the data object to the top of the scope chain.      var variable = options.variable;      if (!variable) {        source = 'with (obj) {\n' + source + '\n}\n';      }      // Cleanup code by stripping empty strings.      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)        .replace(reEmptyStringMiddle, '$1')        .replace(reEmptyStringTrailing, '$1;');      // Frame code as the function body.      source = 'function(' + (variable || 'obj') + ') {\n' +        (variable          ? ''          : 'obj || (obj = {});\n'        ) +        "var __t, __p = ''" +        (isEscaping           ? ', __e = _.escape'           : ''        ) +        (isEvaluating          ? ', __j = Array.prototype.join;\n' +            "function print() { __p += __j.call(arguments, '') }\n"          : ';\n'        ) +        source +        'return __p\n}';      var result = attempt(function() {        return Function(importsKeys, sourceURL + 'return ' + source)          .apply(undefined, importsValues);      });      // Provide the compiled function's source by its `toString` method or      // the `source` property as a convenience for inlining compiled templates.      result.source = source;      if (isError(result)) {        throw result;      }      return result;    }    /**     * Converts `string`, as a whole, to lower case just like     * [String#toLowerCase](https://mdn.io/toLowerCase).     *     * @static     * @memberOf _     * @since 4.0.0     * @category String     * @param {string} [string=''] The string to convert.     * @returns {string} Returns the lower cased string.     * @example     *     * _.toLower('--Foo-Bar--');     * // => '--foo-bar--'     *     * _.toLower('fooBar');     * // => 'foobar'     *     * _.toLower('__FOO_BAR__');     * // => '__foo_bar__'     */    function toLower(value) {      return toString(value).toLowerCase();    }    /**     * Converts `string`, as a whole, to upper case just like     * [String#toUpperCase](https://mdn.io/toUpperCase).     *     * @static     * @memberOf _     * @since 4.0.0     * @category String     * @param {string} [string=''] The string to convert.     * @returns {string} Returns the upper cased string.     * @example     *     * _.toUpper('--foo-bar--');     * // => '--FOO-BAR--'     *     * _.toUpper('fooBar');     * // => 'FOOBAR'     *     * _.toUpper('__foo_bar__');     * // => '__FOO_BAR__'     */    function toUpper(value) {      return toString(value).toUpperCase();    }    /**     * Removes leading and trailing whitespace or specified characters from `string`.     *     * @static     * @memberOf _     * @since 3.0.0     * @category String     * @param {string} [string=''] The string to trim.     * @param {string} [chars=whitespace] The characters to trim.     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.     * @returns {string} Returns the trimmed string.     * @example     *     * _.trim('  abc  ');     * // => 'abc'     *     * _.trim('-_-abc-_-', '_-');     * // => 'abc'     *     * _.map(['  foo  ', '  bar  '], _.trim);     * // => ['foo', 'bar']     */    function trim(string, chars, guard) {      string = toString(string);      if (string && (guard || chars === undefined)) {        return string.replace(reTrim, '');      }      if (!string || !(chars = baseToString(chars))) {        return string;      }      var strSymbols = stringToArray(string),          chrSymbols = stringToArray(chars),          start = charsStartIndex(strSymbols, chrSymbols),          end = charsEndIndex(strSymbols, chrSymbols) + 1;      return castSlice(strSymbols, start, end).join('');    }    /**     * Removes trailing whitespace or specified characters from `string`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category String     * @param {string} [string=''] The string to trim.     * @param {string} [chars=whitespace] The characters to trim.     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.     * @returns {string} Returns the trimmed string.     * @example     *     * _.trimEnd('  abc  ');     * // => '  abc'     *     * _.trimEnd('-_-abc-_-', '_-');     * // => '-_-abc'     */    function trimEnd(string, chars, guard) {      string = toString(string);      if (string && (guard || chars === undefined)) {        return string.replace(reTrimEnd, '');      }      if (!string || !(chars = baseToString(chars))) {        return string;      }      var strSymbols = stringToArray(string),          end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;      return castSlice(strSymbols, 0, end).join('');    }    /**     * Removes leading whitespace or specified characters from `string`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category String     * @param {string} [string=''] The string to trim.     * @param {string} [chars=whitespace] The characters to trim.     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.     * @returns {string} Returns the trimmed string.     * @example     *     * _.trimStart('  abc  ');     * // => 'abc  '     *     * _.trimStart('-_-abc-_-', '_-');     * // => 'abc-_-'     */    function trimStart(string, chars, guard) {      string = toString(string);      if (string && (guard || chars === undefined)) {        return string.replace(reTrimStart, '');      }      if (!string || !(chars = baseToString(chars))) {        return string;      }      var strSymbols = stringToArray(string),          start = charsStartIndex(strSymbols, stringToArray(chars));      return castSlice(strSymbols, start).join('');    }    /**     * Truncates `string` if it's longer than the given maximum string length.     * The last characters of the truncated string are replaced with the omission     * string which defaults to "...".     *     * @static     * @memberOf _     * @since 4.0.0     * @category String     * @param {string} [string=''] The string to truncate.     * @param {Object} [options={}] The options object.     * @param {number} [options.length=30] The maximum string length.     * @param {string} [options.omission='...'] The string to indicate text is omitted.     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.     * @returns {string} Returns the truncated string.     * @example     *     * _.truncate('hi-diddly-ho there, neighborino');     * // => 'hi-diddly-ho there, neighbo...'     *     * _.truncate('hi-diddly-ho there, neighborino', {     *   'length': 24,     *   'separator': ' '     * });     * // => 'hi-diddly-ho there,...'     *     * _.truncate('hi-diddly-ho there, neighborino', {     *   'length': 24,     *   'separator': /,? +/     * });     * // => 'hi-diddly-ho there...'     *     * _.truncate('hi-diddly-ho there, neighborino', {     *   'omission': ' [...]'     * });     * // => 'hi-diddly-ho there, neig [...]'     */    function truncate(string, options) {      var length = DEFAULT_TRUNC_LENGTH,          omission = DEFAULT_TRUNC_OMISSION;      if (isObject(options)) {        var separator = 'separator' in options ? options.separator : separator;        length = 'length' in options ? toInteger(options.length) : length;        omission = 'omission' in options ? baseToString(options.omission) : omission;      }      string = toString(string);      var strLength = string.length;      if (hasUnicode(string)) {        var strSymbols = stringToArray(string);        strLength = strSymbols.length;      }      if (length >= strLength) {        return string;      }      var end = length - stringSize(omission);      if (end < 1) {        return omission;      }      var result = strSymbols        ? castSlice(strSymbols, 0, end).join('')        : string.slice(0, end);      if (separator === undefined) {        return result + omission;      }      if (strSymbols) {        end += (result.length - end);      }      if (isRegExp(separator)) {        if (string.slice(end).search(separator)) {          var match,              substring = result;          if (!separator.global) {            separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');          }          separator.lastIndex = 0;          while ((match = separator.exec(substring))) {            var newEnd = match.index;          }          result = result.slice(0, newEnd === undefined ? end : newEnd);        }      } else if (string.indexOf(baseToString(separator), end) != end) {        var index = result.lastIndexOf(separator);        if (index > -1) {          result = result.slice(0, index);        }      }      return result + omission;    }    /**     * The inverse of `_.escape`; this method converts the HTML entities     * `&`, `<`, `>`, `"`, and `'` in `string` to     * their corresponding characters.     *     * **Note:** No other HTML entities are unescaped. To unescape additional     * HTML entities use a third-party library like [_he_](https://mths.be/he).     *     * @static     * @memberOf _     * @since 0.6.0     * @category String     * @param {string} [string=''] The string to unescape.     * @returns {string} Returns the unescaped string.     * @example     *     * _.unescape('fred, barney, & pebbles');     * // => 'fred, barney, & pebbles'     */    function unescape(string) {      string = toString(string);      return (string && reHasEscapedHtml.test(string))        ? string.replace(reEscapedHtml, unescapeHtmlChar)        : string;    }    /**     * Converts `string`, as space separated words, to upper case.     *     * @static     * @memberOf _     * @since 4.0.0     * @category String     * @param {string} [string=''] The string to convert.     * @returns {string} Returns the upper cased string.     * @example     *     * _.upperCase('--foo-bar');     * // => 'FOO BAR'     *     * _.upperCase('fooBar');     * // => 'FOO BAR'     *     * _.upperCase('__foo_bar__');     * // => 'FOO BAR'     */    var upperCase = createCompounder(function(result, word, index) {      return result + (index ? ' ' : '') + word.toUpperCase();    });    /**     * Converts the first character of `string` to upper case.     *     * @static     * @memberOf _     * @since 4.0.0     * @category String     * @param {string} [string=''] The string to convert.     * @returns {string} Returns the converted string.     * @example     *     * _.upperFirst('fred');     * // => 'Fred'     *     * _.upperFirst('FRED');     * // => 'FRED'     */    var upperFirst = createCaseFirst('toUpperCase');    /**     * Splits `string` into an array of its words.     *     * @static     * @memberOf _     * @since 3.0.0     * @category String     * @param {string} [string=''] The string to inspect.     * @param {RegExp|string} [pattern] The pattern to match words.     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.     * @returns {Array} Returns the words of `string`.     * @example     *     * _.words('fred, barney, & pebbles');     * // => ['fred', 'barney', 'pebbles']     *     * _.words('fred, barney, & pebbles', /[^, ]+/g);     * // => ['fred', 'barney', '&', 'pebbles']     */    function words(string, pattern, guard) {      string = toString(string);      pattern = guard ? undefined : pattern;      if (pattern === undefined) {        return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);      }      return string.match(pattern) || [];    }    /*------------------------------------------------------------------------*/    /**     * Attempts to invoke `func`, returning either the result or the caught error     * object. Any additional arguments are provided to `func` when it's invoked.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Util     * @param {Function} func The function to attempt.     * @param {...*} [args] The arguments to invoke `func` with.     * @returns {*} Returns the `func` result or error object.     * @example     *     * // Avoid throwing errors for invalid selectors.     * var elements = _.attempt(function(selector) {     *   return document.querySelectorAll(selector);     * }, '>_>');     *     * if (_.isError(elements)) {     *   elements = [];     * }     */    var attempt = baseRest(function(func, args) {      try {        return apply(func, undefined, args);      } catch (e) {        return isError(e) ? e : new Error(e);      }    });    /**     * Binds methods of an object to the object itself, overwriting the existing     * method.     *     * **Note:** This method doesn't set the "length" property of bound functions.     *     * @static     * @since 0.1.0     * @memberOf _     * @category Util     * @param {Object} object The object to bind and assign the bound methods to.     * @param {...(string|string[])} methodNames The object method names to bind.     * @returns {Object} Returns `object`.     * @example     *     * var view = {     *   'label': 'docs',     *   'click': function() {     *     console.log('clicked ' + this.label);     *   }     * };     *     * _.bindAll(view, ['click']);     * jQuery(element).on('click', view.click);     * // => Logs 'clicked docs' when clicked.     */    var bindAll = flatRest(function(object, methodNames) {      arrayEach(methodNames, function(key) {        key = toKey(key);        baseAssignValue(object, key, bind(object[key], object));      });      return object;    });    /**     * Creates a function that iterates over `pairs` and invokes the corresponding     * function of the first predicate to return truthy. The predicate-function     * pairs are invoked with the `this` binding and arguments of the created     * function.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Util     * @param {Array} pairs The predicate-function pairs.     * @returns {Function} Returns the new composite function.     * @example     *     * var func = _.cond([     *   [_.matches({ 'a': 1 }),           _.constant('matches A')],     *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],     *   [_.stubTrue,                      _.constant('no match')]     * ]);     *     * func({ 'a': 1, 'b': 2 });     * // => 'matches A'     *     * func({ 'a': 0, 'b': 1 });     * // => 'matches B'     *     * func({ 'a': '1', 'b': '2' });     * // => 'no match'     */    function cond(pairs) {      var length = pairs == null ? 0 : pairs.length,          toIteratee = getIteratee();      pairs = !length ? [] : arrayMap(pairs, function(pair) {        if (typeof pair[1] != 'function') {          throw new TypeError(FUNC_ERROR_TEXT);        }        return [toIteratee(pair[0]), pair[1]];      });      return baseRest(function(args) {        var index = -1;        while (++index < length) {          var pair = pairs[index];          if (apply(pair[0], this, args)) {            return apply(pair[1], this, args);          }        }      });    }    /**     * Creates a function that invokes the predicate properties of `source` with     * the corresponding property values of a given object, returning `true` if     * all predicates return truthy, else `false`.     *     * **Note:** The created function is equivalent to `_.conformsTo` with     * `source` partially applied.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Util     * @param {Object} source The object of property predicates to conform to.     * @returns {Function} Returns the new spec function.     * @example     *     * var objects = [     *   { 'a': 2, 'b': 1 },     *   { 'a': 1, 'b': 2 }     * ];     *     * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));     * // => [{ 'a': 1, 'b': 2 }]     */    function conforms(source) {      return baseConforms(baseClone(source, CLONE_DEEP_FLAG));    }    /**     * Creates a function that returns `value`.     *     * @static     * @memberOf _     * @since 2.4.0     * @category Util     * @param {*} value The value to return from the new function.     * @returns {Function} Returns the new constant function.     * @example     *     * var objects = _.times(2, _.constant({ 'a': 1 }));     *     * console.log(objects);     * // => [{ 'a': 1 }, { 'a': 1 }]     *     * console.log(objects[0] === objects[1]);     * // => true     */    function constant(value) {      return function() {        return value;      };    }    /**     * Checks `value` to determine whether a default value should be returned in     * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,     * or `undefined`.     *     * @static     * @memberOf _     * @since 4.14.0     * @category Util     * @param {*} value The value to check.     * @param {*} defaultValue The default value.     * @returns {*} Returns the resolved value.     * @example     *     * _.defaultTo(1, 10);     * // => 1     *     * _.defaultTo(undefined, 10);     * // => 10     */    function defaultTo(value, defaultValue) {      return (value == null || value !== value) ? defaultValue : value;    }    /**     * Creates a function that returns the result of invoking the given functions     * with the `this` binding of the created function, where each successive     * invocation is supplied the return value of the previous.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Util     * @param {...(Function|Function[])} [funcs] The functions to invoke.     * @returns {Function} Returns the new composite function.     * @see _.flowRight     * @example     *     * function square(n) {     *   return n * n;     * }     *     * var addSquare = _.flow([_.add, square]);     * addSquare(1, 2);     * // => 9     */    var flow = createFlow();    /**     * This method is like `_.flow` except that it creates a function that     * invokes the given functions from right to left.     *     * @static     * @since 3.0.0     * @memberOf _     * @category Util     * @param {...(Function|Function[])} [funcs] The functions to invoke.     * @returns {Function} Returns the new composite function.     * @see _.flow     * @example     *     * function square(n) {     *   return n * n;     * }     *     * var addSquare = _.flowRight([square, _.add]);     * addSquare(1, 2);     * // => 9     */    var flowRight = createFlow(true);    /**     * This method returns the first argument it receives.     *     * @static     * @since 0.1.0     * @memberOf _     * @category Util     * @param {*} value Any value.     * @returns {*} Returns `value`.     * @example     *     * var object = { 'a': 1 };     *     * console.log(_.identity(object) === object);     * // => true     */    function identity(value) {      return value;    }    /**     * Creates a function that invokes `func` with the arguments of the created     * function. If `func` is a property name, the created function returns the     * property value for a given element. If `func` is an array or object, the     * created function returns `true` for elements that contain the equivalent     * source properties, otherwise it returns `false`.     *     * @static     * @since 4.0.0     * @memberOf _     * @category Util     * @param {*} [func=_.identity] The value to convert to a callback.     * @returns {Function} Returns the callback.     * @example     *     * var users = [     *   { 'user': 'barney', 'age': 36, 'active': true },     *   { 'user': 'fred',   'age': 40, 'active': false }     * ];     *     * // The `_.matches` iteratee shorthand.     * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));     * // => [{ 'user': 'barney', 'age': 36, 'active': true }]     *     * // The `_.matchesProperty` iteratee shorthand.     * _.filter(users, _.iteratee(['user', 'fred']));     * // => [{ 'user': 'fred', 'age': 40 }]     *     * // The `_.property` iteratee shorthand.     * _.map(users, _.iteratee('user'));     * // => ['barney', 'fred']     *     * // Create custom iteratee shorthands.     * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {     *   return !_.isRegExp(func) ? iteratee(func) : function(string) {     *     return func.test(string);     *   };     * });     *     * _.filter(['abc', 'def'], /ef/);     * // => ['def']     */    function iteratee(func) {      return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));    }    /**     * Creates a function that performs a partial deep comparison between a given     * object and `source`, returning `true` if the given object has equivalent     * property values, else `false`.     *     * **Note:** The created function is equivalent to `_.isMatch` with `source`     * partially applied.     *     * Partial comparisons will match empty array and empty object `source`     * values against any array or object value, respectively. See `_.isEqual`     * for a list of supported value comparisons.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Util     * @param {Object} source The object of property values to match.     * @returns {Function} Returns the new spec function.     * @example     *     * var objects = [     *   { 'a': 1, 'b': 2, 'c': 3 },     *   { 'a': 4, 'b': 5, 'c': 6 }     * ];     *     * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));     * // => [{ 'a': 4, 'b': 5, 'c': 6 }]     */    function matches(source) {      return baseMatches(baseClone(source, CLONE_DEEP_FLAG));    }    /**     * Creates a function that performs a partial deep comparison between the     * value at `path` of a given object to `srcValue`, returning `true` if the     * object value is equivalent, else `false`.     *     * **Note:** Partial comparisons will match empty array and empty object     * `srcValue` values against any array or object value, respectively. See     * `_.isEqual` for a list of supported value comparisons.     *     * @static     * @memberOf _     * @since 3.2.0     * @category Util     * @param {Array|string} path The path of the property to get.     * @param {*} srcValue The value to match.     * @returns {Function} Returns the new spec function.     * @example     *     * var objects = [     *   { 'a': 1, 'b': 2, 'c': 3 },     *   { 'a': 4, 'b': 5, 'c': 6 }     * ];     *     * _.find(objects, _.matchesProperty('a', 4));     * // => { 'a': 4, 'b': 5, 'c': 6 }     */    function matchesProperty(path, srcValue) {      return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));    }    /**     * Creates a function that invokes the method at `path` of a given object.     * Any additional arguments are provided to the invoked method.     *     * @static     * @memberOf _     * @since 3.7.0     * @category Util     * @param {Array|string} path The path of the method to invoke.     * @param {...*} [args] The arguments to invoke the method with.     * @returns {Function} Returns the new invoker function.     * @example     *     * var objects = [     *   { 'a': { 'b': _.constant(2) } },     *   { 'a': { 'b': _.constant(1) } }     * ];     *     * _.map(objects, _.method('a.b'));     * // => [2, 1]     *     * _.map(objects, _.method(['a', 'b']));     * // => [2, 1]     */    var method = baseRest(function(path, args) {      return function(object) {        return baseInvoke(object, path, args);      };    });    /**     * The opposite of `_.method`; this method creates a function that invokes     * the method at a given path of `object`. Any additional arguments are     * provided to the invoked method.     *     * @static     * @memberOf _     * @since 3.7.0     * @category Util     * @param {Object} object The object to query.     * @param {...*} [args] The arguments to invoke the method with.     * @returns {Function} Returns the new invoker function.     * @example     *     * var array = _.times(3, _.constant),     *     object = { 'a': array, 'b': array, 'c': array };     *     * _.map(['a[2]', 'c[0]'], _.methodOf(object));     * // => [2, 0]     *     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));     * // => [2, 0]     */    var methodOf = baseRest(function(object, args) {      return function(path) {        return baseInvoke(object, path, args);      };    });    /**     * Adds all own enumerable string keyed function properties of a source     * object to the destination object. If `object` is a function, then methods     * are added to its prototype as well.     *     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to     * avoid conflicts caused by modifying the original.     *     * @static     * @since 0.1.0     * @memberOf _     * @category Util     * @param {Function|Object} [object=lodash] The destination object.     * @param {Object} source The object of functions to add.     * @param {Object} [options={}] The options object.     * @param {boolean} [options.chain=true] Specify whether mixins are chainable.     * @returns {Function|Object} Returns `object`.     * @example     *     * function vowels(string) {     *   return _.filter(string, function(v) {     *     return /[aeiou]/i.test(v);     *   });     * }     *     * _.mixin({ 'vowels': vowels });     * _.vowels('fred');     * // => ['e']     *     * _('fred').vowels().value();     * // => ['e']     *     * _.mixin({ 'vowels': vowels }, { 'chain': false });     * _('fred').vowels();     * // => ['e']     */    function mixin(object, source, options) {      var props = keys(source),          methodNames = baseFunctions(source, props);      if (options == null &&          !(isObject(source) && (methodNames.length || !props.length))) {        options = source;        source = object;        object = this;        methodNames = baseFunctions(source, keys(source));      }      var chain = !(isObject(options) && 'chain' in options) || !!options.chain,          isFunc = isFunction(object);      arrayEach(methodNames, function(methodName) {        var func = source[methodName];        object[methodName] = func;        if (isFunc) {          object.prototype[methodName] = function() {            var chainAll = this.__chain__;            if (chain || chainAll) {              var result = object(this.__wrapped__),                  actions = result.__actions__ = copyArray(this.__actions__);              actions.push({ 'func': func, 'args': arguments, 'thisArg': object });              result.__chain__ = chainAll;              return result;            }            return func.apply(object, arrayPush([this.value()], arguments));          };        }      });      return object;    }    /**     * Reverts the `_` variable to its previous value and returns a reference to     * the `lodash` function.     *     * @static     * @since 0.1.0     * @memberOf _     * @category Util     * @returns {Function} Returns the `lodash` function.     * @example     *     * var lodash = _.noConflict();     */    function noConflict() {      if (root._ === this) {        root._ = oldDash;      }      return this;    }    /**     * This method returns `undefined`.     *     * @static     * @memberOf _     * @since 2.3.0     * @category Util     * @example     *     * _.times(2, _.noop);     * // => [undefined, undefined]     */    function noop() {      // No operation performed.    }    /**     * Creates a function that gets the argument at index `n`. If `n` is negative,     * the nth argument from the end is returned.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Util     * @param {number} [n=0] The index of the argument to return.     * @returns {Function} Returns the new pass-thru function.     * @example     *     * var func = _.nthArg(1);     * func('a', 'b', 'c', 'd');     * // => 'b'     *     * var func = _.nthArg(-2);     * func('a', 'b', 'c', 'd');     * // => 'c'     */    function nthArg(n) {      n = toInteger(n);      return baseRest(function(args) {        return baseNth(args, n);      });    }    /**     * Creates a function that invokes `iteratees` with the arguments it receives     * and returns their results.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Util     * @param {...(Function|Function[])} [iteratees=[_.identity]]     *  The iteratees to invoke.     * @returns {Function} Returns the new function.     * @example     *     * var func = _.over([Math.max, Math.min]);     *     * func(1, 2, 3, 4);     * // => [4, 1]     */    var over = createOver(arrayMap);    /**     * Creates a function that checks if **all** of the `predicates` return     * truthy when invoked with the arguments it receives.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Util     * @param {...(Function|Function[])} [predicates=[_.identity]]     *  The predicates to check.     * @returns {Function} Returns the new function.     * @example     *     * var func = _.overEvery([Boolean, isFinite]);     *     * func('1');     * // => true     *     * func(null);     * // => false     *     * func(NaN);     * // => false     */    var overEvery = createOver(arrayEvery);    /**     * Creates a function that checks if **any** of the `predicates` return     * truthy when invoked with the arguments it receives.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Util     * @param {...(Function|Function[])} [predicates=[_.identity]]     *  The predicates to check.     * @returns {Function} Returns the new function.     * @example     *     * var func = _.overSome([Boolean, isFinite]);     *     * func('1');     * // => true     *     * func(null);     * // => true     *     * func(NaN);     * // => false     */    var overSome = createOver(arraySome);    /**     * Creates a function that returns the value at `path` of a given object.     *     * @static     * @memberOf _     * @since 2.4.0     * @category Util     * @param {Array|string} path The path of the property to get.     * @returns {Function} Returns the new accessor function.     * @example     *     * var objects = [     *   { 'a': { 'b': 2 } },     *   { 'a': { 'b': 1 } }     * ];     *     * _.map(objects, _.property('a.b'));     * // => [2, 1]     *     * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');     * // => [1, 2]     */    function property(path) {      return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);    }    /**     * The opposite of `_.property`; this method creates a function that returns     * the value at a given path of `object`.     *     * @static     * @memberOf _     * @since 3.0.0     * @category Util     * @param {Object} object The object to query.     * @returns {Function} Returns the new accessor function.     * @example     *     * var array = [0, 1, 2],     *     object = { 'a': array, 'b': array, 'c': array };     *     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));     * // => [2, 0]     *     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));     * // => [2, 0]     */    function propertyOf(object) {      return function(path) {        return object == null ? undefined : baseGet(object, path);      };    }    /**     * Creates an array of numbers (positive and/or negative) progressing from     * `start` up to, but not including, `end`. A step of `-1` is used if a negative     * `start` is specified without an `end` or `step`. If `end` is not specified,     * it's set to `start` with `start` then set to `0`.     *     * **Note:** JavaScript follows the IEEE-754 standard for resolving     * floating-point values which can produce unexpected results.     *     * @static     * @since 0.1.0     * @memberOf _     * @category Util     * @param {number} [start=0] The start of the range.     * @param {number} end The end of the range.     * @param {number} [step=1] The value to increment or decrement by.     * @returns {Array} Returns the range of numbers.     * @see _.inRange, _.rangeRight     * @example     *     * _.range(4);     * // => [0, 1, 2, 3]     *     * _.range(-4);     * // => [0, -1, -2, -3]     *     * _.range(1, 5);     * // => [1, 2, 3, 4]     *     * _.range(0, 20, 5);     * // => [0, 5, 10, 15]     *     * _.range(0, -4, -1);     * // => [0, -1, -2, -3]     *     * _.range(1, 4, 0);     * // => [1, 1, 1]     *     * _.range(0);     * // => []     */    var range = createRange();    /**     * This method is like `_.range` except that it populates values in     * descending order.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Util     * @param {number} [start=0] The start of the range.     * @param {number} end The end of the range.     * @param {number} [step=1] The value to increment or decrement by.     * @returns {Array} Returns the range of numbers.     * @see _.inRange, _.range     * @example     *     * _.rangeRight(4);     * // => [3, 2, 1, 0]     *     * _.rangeRight(-4);     * // => [-3, -2, -1, 0]     *     * _.rangeRight(1, 5);     * // => [4, 3, 2, 1]     *     * _.rangeRight(0, 20, 5);     * // => [15, 10, 5, 0]     *     * _.rangeRight(0, -4, -1);     * // => [-3, -2, -1, 0]     *     * _.rangeRight(1, 4, 0);     * // => [1, 1, 1]     *     * _.rangeRight(0);     * // => []     */    var rangeRight = createRange(true);    /**     * This method returns a new empty array.     *     * @static     * @memberOf _     * @since 4.13.0     * @category Util     * @returns {Array} Returns the new empty array.     * @example     *     * var arrays = _.times(2, _.stubArray);     *     * console.log(arrays);     * // => [[], []]     *     * console.log(arrays[0] === arrays[1]);     * // => false     */    function stubArray() {      return [];    }    /**     * This method returns `false`.     *     * @static     * @memberOf _     * @since 4.13.0     * @category Util     * @returns {boolean} Returns `false`.     * @example     *     * _.times(2, _.stubFalse);     * // => [false, false]     */    function stubFalse() {      return false;    }    /**     * This method returns a new empty object.     *     * @static     * @memberOf _     * @since 4.13.0     * @category Util     * @returns {Object} Returns the new empty object.     * @example     *     * var objects = _.times(2, _.stubObject);     *     * console.log(objects);     * // => [{}, {}]     *     * console.log(objects[0] === objects[1]);     * // => false     */    function stubObject() {      return {};    }    /**     * This method returns an empty string.     *     * @static     * @memberOf _     * @since 4.13.0     * @category Util     * @returns {string} Returns the empty string.     * @example     *     * _.times(2, _.stubString);     * // => ['', '']     */    function stubString() {      return '';    }    /**     * This method returns `true`.     *     * @static     * @memberOf _     * @since 4.13.0     * @category Util     * @returns {boolean} Returns `true`.     * @example     *     * _.times(2, _.stubTrue);     * // => [true, true]     */    function stubTrue() {      return true;    }    /**     * Invokes the iteratee `n` times, returning an array of the results of     * each invocation. The iteratee is invoked with one argument; (index).     *     * @static     * @since 0.1.0     * @memberOf _     * @category Util     * @param {number} n The number of times to invoke `iteratee`.     * @param {Function} [iteratee=_.identity] The function invoked per iteration.     * @returns {Array} Returns the array of results.     * @example     *     * _.times(3, String);     * // => ['0', '1', '2']     *     *  _.times(4, _.constant(0));     * // => [0, 0, 0, 0]     */    function times(n, iteratee) {      n = toInteger(n);      if (n < 1 || n > MAX_SAFE_INTEGER) {        return [];      }      var index = MAX_ARRAY_LENGTH,          length = nativeMin(n, MAX_ARRAY_LENGTH);      iteratee = getIteratee(iteratee);      n -= MAX_ARRAY_LENGTH;      var result = baseTimes(length, iteratee);      while (++index < n) {        iteratee(index);      }      return result;    }    /**     * Converts `value` to a property path array.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Util     * @param {*} value The value to convert.     * @returns {Array} Returns the new property path array.     * @example     *     * _.toPath('a.b.c');     * // => ['a', 'b', 'c']     *     * _.toPath('a[0].b.c');     * // => ['a', '0', 'b', 'c']     */    function toPath(value) {      if (isArray(value)) {        return arrayMap(value, toKey);      }      return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));    }    /**     * Generates a unique ID. If `prefix` is given, the ID is appended to it.     *     * @static     * @since 0.1.0     * @memberOf _     * @category Util     * @param {string} [prefix=''] The value to prefix the ID with.     * @returns {string} Returns the unique ID.     * @example     *     * _.uniqueId('contact_');     * // => 'contact_104'     *     * _.uniqueId();     * // => '105'     */    function uniqueId(prefix) {      var id = ++idCounter;      return toString(prefix) + id;    }    /*------------------------------------------------------------------------*/    /**     * Adds two numbers.     *     * @static     * @memberOf _     * @since 3.4.0     * @category Math     * @param {number} augend The first number in an addition.     * @param {number} addend The second number in an addition.     * @returns {number} Returns the total.     * @example     *     * _.add(6, 4);     * // => 10     */    var add = createMathOperation(function(augend, addend) {      return augend + addend;    }, 0);    /**     * Computes `number` rounded up to `precision`.     *     * @static     * @memberOf _     * @since 3.10.0     * @category Math     * @param {number} number The number to round up.     * @param {number} [precision=0] The precision to round up to.     * @returns {number} Returns the rounded up number.     * @example     *     * _.ceil(4.006);     * // => 5     *     * _.ceil(6.004, 2);     * // => 6.01     *     * _.ceil(6040, -2);     * // => 6100     */    var ceil = createRound('ceil');    /**     * Divide two numbers.     *     * @static     * @memberOf _     * @since 4.7.0     * @category Math     * @param {number} dividend The first number in a division.     * @param {number} divisor The second number in a division.     * @returns {number} Returns the quotient.     * @example     *     * _.divide(6, 4);     * // => 1.5     */    var divide = createMathOperation(function(dividend, divisor) {      return dividend / divisor;    }, 1);    /**     * Computes `number` rounded down to `precision`.     *     * @static     * @memberOf _     * @since 3.10.0     * @category Math     * @param {number} number The number to round down.     * @param {number} [precision=0] The precision to round down to.     * @returns {number} Returns the rounded down number.     * @example     *     * _.floor(4.006);     * // => 4     *     * _.floor(0.046, 2);     * // => 0.04     *     * _.floor(4060, -2);     * // => 4000     */    var floor = createRound('floor');    /**     * Computes the maximum value of `array`. If `array` is empty or falsey,     * `undefined` is returned.     *     * @static     * @since 0.1.0     * @memberOf _     * @category Math     * @param {Array} array The array to iterate over.     * @returns {*} Returns the maximum value.     * @example     *     * _.max([4, 2, 8, 6]);     * // => 8     *     * _.max([]);     * // => undefined     */    function max(array) {      return (array && array.length)        ? baseExtremum(array, identity, baseGt)        : undefined;    }    /**     * This method is like `_.max` except that it accepts `iteratee` which is     * invoked for each element in `array` to generate the criterion by which     * the value is ranked. The iteratee is invoked with one argument: (value).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Math     * @param {Array} array The array to iterate over.     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.     * @returns {*} Returns the maximum value.     * @example     *     * var objects = [{ 'n': 1 }, { 'n': 2 }];     *     * _.maxBy(objects, function(o) { return o.n; });     * // => { 'n': 2 }     *     * // The `_.property` iteratee shorthand.     * _.maxBy(objects, 'n');     * // => { 'n': 2 }     */    function maxBy(array, iteratee) {      return (array && array.length)        ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)        : undefined;    }    /**     * Computes the mean of the values in `array`.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Math     * @param {Array} array The array to iterate over.     * @returns {number} Returns the mean.     * @example     *     * _.mean([4, 2, 8, 6]);     * // => 5     */    function mean(array) {      return baseMean(array, identity);    }    /**     * This method is like `_.mean` except that it accepts `iteratee` which is     * invoked for each element in `array` to generate the value to be averaged.     * The iteratee is invoked with one argument: (value).     *     * @static     * @memberOf _     * @since 4.7.0     * @category Math     * @param {Array} array The array to iterate over.     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.     * @returns {number} Returns the mean.     * @example     *     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];     *     * _.meanBy(objects, function(o) { return o.n; });     * // => 5     *     * // The `_.property` iteratee shorthand.     * _.meanBy(objects, 'n');     * // => 5     */    function meanBy(array, iteratee) {      return baseMean(array, getIteratee(iteratee, 2));    }    /**     * Computes the minimum value of `array`. If `array` is empty or falsey,     * `undefined` is returned.     *     * @static     * @since 0.1.0     * @memberOf _     * @category Math     * @param {Array} array The array to iterate over.     * @returns {*} Returns the minimum value.     * @example     *     * _.min([4, 2, 8, 6]);     * // => 2     *     * _.min([]);     * // => undefined     */    function min(array) {      return (array && array.length)        ? baseExtremum(array, identity, baseLt)        : undefined;    }    /**     * This method is like `_.min` except that it accepts `iteratee` which is     * invoked for each element in `array` to generate the criterion by which     * the value is ranked. The iteratee is invoked with one argument: (value).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Math     * @param {Array} array The array to iterate over.     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.     * @returns {*} Returns the minimum value.     * @example     *     * var objects = [{ 'n': 1 }, { 'n': 2 }];     *     * _.minBy(objects, function(o) { return o.n; });     * // => { 'n': 1 }     *     * // The `_.property` iteratee shorthand.     * _.minBy(objects, 'n');     * // => { 'n': 1 }     */    function minBy(array, iteratee) {      return (array && array.length)        ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)        : undefined;    }    /**     * Multiply two numbers.     *     * @static     * @memberOf _     * @since 4.7.0     * @category Math     * @param {number} multiplier The first number in a multiplication.     * @param {number} multiplicand The second number in a multiplication.     * @returns {number} Returns the product.     * @example     *     * _.multiply(6, 4);     * // => 24     */    var multiply = createMathOperation(function(multiplier, multiplicand) {      return multiplier * multiplicand;    }, 1);    /**     * Computes `number` rounded to `precision`.     *     * @static     * @memberOf _     * @since 3.10.0     * @category Math     * @param {number} number The number to round.     * @param {number} [precision=0] The precision to round to.     * @returns {number} Returns the rounded number.     * @example     *     * _.round(4.006);     * // => 4     *     * _.round(4.006, 2);     * // => 4.01     *     * _.round(4060, -2);     * // => 4100     */    var round = createRound('round');    /**     * Subtract two numbers.     *     * @static     * @memberOf _     * @since 4.0.0     * @category Math     * @param {number} minuend The first number in a subtraction.     * @param {number} subtrahend The second number in a subtraction.     * @returns {number} Returns the difference.     * @example     *     * _.subtract(6, 4);     * // => 2     */    var subtract = createMathOperation(function(minuend, subtrahend) {      return minuend - subtrahend;    }, 0);    /**     * Computes the sum of the values in `array`.     *     * @static     * @memberOf _     * @since 3.4.0     * @category Math     * @param {Array} array The array to iterate over.     * @returns {number} Returns the sum.     * @example     *     * _.sum([4, 2, 8, 6]);     * // => 20     */    function sum(array) {      return (array && array.length)        ? baseSum(array, identity)        : 0;    }    /**     * This method is like `_.sum` except that it accepts `iteratee` which is     * invoked for each element in `array` to generate the value to be summed.     * The iteratee is invoked with one argument: (value).     *     * @static     * @memberOf _     * @since 4.0.0     * @category Math     * @param {Array} array The array to iterate over.     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.     * @returns {number} Returns the sum.     * @example     *     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];     *     * _.sumBy(objects, function(o) { return o.n; });     * // => 20     *     * // The `_.property` iteratee shorthand.     * _.sumBy(objects, 'n');     * // => 20     */    function sumBy(array, iteratee) {      return (array && array.length)        ? baseSum(array, getIteratee(iteratee, 2))        : 0;    }    /*------------------------------------------------------------------------*/    // Add methods that return wrapped values in chain sequences.    lodash.after = after;    lodash.ary = ary;    lodash.assign = assign;    lodash.assignIn = assignIn;    lodash.assignInWith = assignInWith;    lodash.assignWith = assignWith;    lodash.at = at;    lodash.before = before;    lodash.bind = bind;    lodash.bindAll = bindAll;    lodash.bindKey = bindKey;    lodash.castArray = castArray;    lodash.chain = chain;    lodash.chunk = chunk;    lodash.compact = compact;    lodash.concat = concat;    lodash.cond = cond;    lodash.conforms = conforms;    lodash.constant = constant;    lodash.countBy = countBy;    lodash.create = create;    lodash.curry = curry;    lodash.curryRight = curryRight;    lodash.debounce = debounce;    lodash.defaults = defaults;    lodash.defaultsDeep = defaultsDeep;    lodash.defer = defer;    lodash.delay = delay;    lodash.difference = difference;    lodash.differenceBy = differenceBy;    lodash.differenceWith = differenceWith;    lodash.drop = drop;    lodash.dropRight = dropRight;    lodash.dropRightWhile = dropRightWhile;    lodash.dropWhile = dropWhile;    lodash.fill = fill;    lodash.filter = filter;    lodash.flatMap = flatMap;    lodash.flatMapDeep = flatMapDeep;    lodash.flatMapDepth = flatMapDepth;    lodash.flatten = flatten;    lodash.flattenDeep = flattenDeep;    lodash.flattenDepth = flattenDepth;    lodash.flip = flip;    lodash.flow = flow;    lodash.flowRight = flowRight;    lodash.fromPairs = fromPairs;    lodash.functions = functions;    lodash.functionsIn = functionsIn;    lodash.groupBy = groupBy;    lodash.initial = initial;    lodash.intersection = intersection;    lodash.intersectionBy = intersectionBy;    lodash.intersectionWith = intersectionWith;    lodash.invert = invert;    lodash.invertBy = invertBy;    lodash.invokeMap = invokeMap;    lodash.iteratee = iteratee;    lodash.keyBy = keyBy;    lodash.keys = keys;    lodash.keysIn = keysIn;    lodash.map = map;    lodash.mapKeys = mapKeys;    lodash.mapValues = mapValues;    lodash.matches = matches;    lodash.matchesProperty = matchesProperty;    lodash.memoize = memoize;    lodash.merge = merge;    lodash.mergeWith = mergeWith;    lodash.method = method;    lodash.methodOf = methodOf;    lodash.mixin = mixin;    lodash.negate = negate;    lodash.nthArg = nthArg;    lodash.omit = omit;    lodash.omitBy = omitBy;    lodash.once = once;    lodash.orderBy = orderBy;    lodash.over = over;    lodash.overArgs = overArgs;    lodash.overEvery = overEvery;    lodash.overSome = overSome;    lodash.partial = partial;    lodash.partialRight = partialRight;    lodash.partition = partition;    lodash.pick = pick;    lodash.pickBy = pickBy;    lodash.property = property;    lodash.propertyOf = propertyOf;    lodash.pull = pull;    lodash.pullAll = pullAll;    lodash.pullAllBy = pullAllBy;    lodash.pullAllWith = pullAllWith;    lodash.pullAt = pullAt;    lodash.range = range;    lodash.rangeRight = rangeRight;    lodash.rearg = rearg;    lodash.reject = reject;    lodash.remove = remove;    lodash.rest = rest;    lodash.reverse = reverse;    lodash.sampleSize = sampleSize;    lodash.set = set;    lodash.setWith = setWith;    lodash.shuffle = shuffle;    lodash.slice = slice;    lodash.sortBy = sortBy;    lodash.sortedUniq = sortedUniq;    lodash.sortedUniqBy = sortedUniqBy;    lodash.split = split;    lodash.spread = spread;    lodash.tail = tail;    lodash.take = take;    lodash.takeRight = takeRight;    lodash.takeRightWhile = takeRightWhile;    lodash.takeWhile = takeWhile;    lodash.tap = tap;    lodash.throttle = throttle;    lodash.thru = thru;    lodash.toArray = toArray;    lodash.toPairs = toPairs;    lodash.toPairsIn = toPairsIn;    lodash.toPath = toPath;    lodash.toPlainObject = toPlainObject;    lodash.transform = transform;    lodash.unary = unary;    lodash.union = union;    lodash.unionBy = unionBy;    lodash.unionWith = unionWith;    lodash.uniq = uniq;    lodash.uniqBy = uniqBy;    lodash.uniqWith = uniqWith;    lodash.unset = unset;    lodash.unzip = unzip;    lodash.unzipWith = unzipWith;    lodash.update = update;    lodash.updateWith = updateWith;    lodash.values = values;    lodash.valuesIn = valuesIn;    lodash.without = without;    lodash.words = words;    lodash.wrap = wrap;    lodash.xor = xor;    lodash.xorBy = xorBy;    lodash.xorWith = xorWith;    lodash.zip = zip;    lodash.zipObject = zipObject;    lodash.zipObjectDeep = zipObjectDeep;    lodash.zipWith = zipWith;    // Add aliases.    lodash.entries = toPairs;    lodash.entriesIn = toPairsIn;    lodash.extend = assignIn;    lodash.extendWith = assignInWith;    // Add methods to `lodash.prototype`.    mixin(lodash, lodash);    /*------------------------------------------------------------------------*/    // Add methods that return unwrapped values in chain sequences.    lodash.add = add;    lodash.attempt = attempt;    lodash.camelCase = camelCase;    lodash.capitalize = capitalize;    lodash.ceil = ceil;    lodash.clamp = clamp;    lodash.clone = clone;    lodash.cloneDeep = cloneDeep;    lodash.cloneDeepWith = cloneDeepWith;    lodash.cloneWith = cloneWith;    lodash.conformsTo = conformsTo;    lodash.deburr = deburr;    lodash.defaultTo = defaultTo;    lodash.divide = divide;    lodash.endsWith = endsWith;    lodash.eq = eq;    lodash.escape = escape;    lodash.escapeRegExp = escapeRegExp;    lodash.every = every;    lodash.find = find;    lodash.findIndex = findIndex;    lodash.findKey = findKey;    lodash.findLast = findLast;    lodash.findLastIndex = findLastIndex;    lodash.findLastKey = findLastKey;    lodash.floor = floor;    lodash.forEach = forEach;    lodash.forEachRight = forEachRight;    lodash.forIn = forIn;    lodash.forInRight = forInRight;    lodash.forOwn = forOwn;    lodash.forOwnRight = forOwnRight;    lodash.get = get;    lodash.gt = gt;    lodash.gte = gte;    lodash.has = has;    lodash.hasIn = hasIn;    lodash.head = head;    lodash.identity = identity;    lodash.includes = includes;    lodash.indexOf = indexOf;    lodash.inRange = inRange;    lodash.invoke = invoke;    lodash.isArguments = isArguments;    lodash.isArray = isArray;    lodash.isArrayBuffer = isArrayBuffer;    lodash.isArrayLike = isArrayLike;    lodash.isArrayLikeObject = isArrayLikeObject;    lodash.isBoolean = isBoolean;    lodash.isBuffer = isBuffer;    lodash.isDate = isDate;    lodash.isElement = isElement;    lodash.isEmpty = isEmpty;    lodash.isEqual = isEqual;    lodash.isEqualWith = isEqualWith;    lodash.isError = isError;    lodash.isFinite = isFinite;    lodash.isFunction = isFunction;    lodash.isInteger = isInteger;    lodash.isLength = isLength;    lodash.isMap = isMap;    lodash.isMatch = isMatch;    lodash.isMatchWith = isMatchWith;    lodash.isNaN = isNaN;    lodash.isNative = isNative;    lodash.isNil = isNil;    lodash.isNull = isNull;    lodash.isNumber = isNumber;    lodash.isObject = isObject;    lodash.isObjectLike = isObjectLike;    lodash.isPlainObject = isPlainObject;    lodash.isRegExp = isRegExp;    lodash.isSafeInteger = isSafeInteger;    lodash.isSet = isSet;    lodash.isString = isString;    lodash.isSymbol = isSymbol;    lodash.isTypedArray = isTypedArray;    lodash.isUndefined = isUndefined;    lodash.isWeakMap = isWeakMap;    lodash.isWeakSet = isWeakSet;    lodash.join = join;    lodash.kebabCase = kebabCase;    lodash.last = last;    lodash.lastIndexOf = lastIndexOf;    lodash.lowerCase = lowerCase;    lodash.lowerFirst = lowerFirst;    lodash.lt = lt;    lodash.lte = lte;    lodash.max = max;    lodash.maxBy = maxBy;    lodash.mean = mean;    lodash.meanBy = meanBy;    lodash.min = min;    lodash.minBy = minBy;    lodash.stubArray = stubArray;    lodash.stubFalse = stubFalse;    lodash.stubObject = stubObject;    lodash.stubString = stubString;    lodash.stubTrue = stubTrue;    lodash.multiply = multiply;    lodash.nth = nth;    lodash.noConflict = noConflict;    lodash.noop = noop;    lodash.now = now;    lodash.pad = pad;    lodash.padEnd = padEnd;    lodash.padStart = padStart;    lodash.parseInt = parseInt;    lodash.random = random;    lodash.reduce = reduce;    lodash.reduceRight = reduceRight;    lodash.repeat = repeat;    lodash.replace = replace;    lodash.result = result;    lodash.round = round;    lodash.runInContext = runInContext;    lodash.sample = sample;    lodash.size = size;    lodash.snakeCase = snakeCase;    lodash.some = some;    lodash.sortedIndex = sortedIndex;    lodash.sortedIndexBy = sortedIndexBy;    lodash.sortedIndexOf = sortedIndexOf;    lodash.sortedLastIndex = sortedLastIndex;    lodash.sortedLastIndexBy = sortedLastIndexBy;    lodash.sortedLastIndexOf = sortedLastIndexOf;    lodash.startCase = startCase;    lodash.startsWith = startsWith;    lodash.subtract = subtract;    lodash.sum = sum;    lodash.sumBy = sumBy;    lodash.template = template;    lodash.times = times;    lodash.toFinite = toFinite;    lodash.toInteger = toInteger;    lodash.toLength = toLength;    lodash.toLower = toLower;    lodash.toNumber = toNumber;    lodash.toSafeInteger = toSafeInteger;    lodash.toString = toString;    lodash.toUpper = toUpper;    lodash.trim = trim;    lodash.trimEnd = trimEnd;    lodash.trimStart = trimStart;    lodash.truncate = truncate;    lodash.unescape = unescape;    lodash.uniqueId = uniqueId;    lodash.upperCase = upperCase;    lodash.upperFirst = upperFirst;    // Add aliases.    lodash.each = forEach;    lodash.eachRight = forEachRight;    lodash.first = head;    mixin(lodash, (function() {      var source = {};      baseForOwn(lodash, function(func, methodName) {        if (!hasOwnProperty.call(lodash.prototype, methodName)) {          source[methodName] = func;        }      });      return source;    }()), { 'chain': false });    /*------------------------------------------------------------------------*/    /**     * The semantic version number.     *     * @static     * @memberOf _     * @type {string}     */    lodash.VERSION = VERSION;    // Assign default placeholders.    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {      lodash[methodName].placeholder = lodash;    });    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.    arrayEach(['drop', 'take'], function(methodName, index) {      LazyWrapper.prototype[methodName] = function(n) {        n = n === undefined ? 1 : nativeMax(toInteger(n), 0);        var result = (this.__filtered__ && !index)          ? new LazyWrapper(this)          : this.clone();        if (result.__filtered__) {          result.__takeCount__ = nativeMin(n, result.__takeCount__);        } else {          result.__views__.push({            'size': nativeMin(n, MAX_ARRAY_LENGTH),            'type': methodName + (result.__dir__ < 0 ? 'Right' : '')          });        }        return result;      };      LazyWrapper.prototype[methodName + 'Right'] = function(n) {        return this.reverse()[methodName](n).reverse();      };    });    // Add `LazyWrapper` methods that accept an `iteratee` value.    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {      var type = index + 1,          isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;      LazyWrapper.prototype[methodName] = function(iteratee) {        var result = this.clone();        result.__iteratees__.push({          'iteratee': getIteratee(iteratee, 3),          'type': type        });        result.__filtered__ = result.__filtered__ || isFilter;        return result;      };    });    // Add `LazyWrapper` methods for `_.head` and `_.last`.    arrayEach(['head', 'last'], function(methodName, index) {      var takeName = 'take' + (index ? 'Right' : '');      LazyWrapper.prototype[methodName] = function() {        return this[takeName](1).value()[0];      };    });    // Add `LazyWrapper` methods for `_.initial` and `_.tail`.    arrayEach(['initial', 'tail'], function(methodName, index) {      var dropName = 'drop' + (index ? '' : 'Right');      LazyWrapper.prototype[methodName] = function() {        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);      };    });    LazyWrapper.prototype.compact = function() {      return this.filter(identity);    };    LazyWrapper.prototype.find = function(predicate) {      return this.filter(predicate).head();    };    LazyWrapper.prototype.findLast = function(predicate) {      return this.reverse().find(predicate);    };    LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {      if (typeof path == 'function') {        return new LazyWrapper(this);      }      return this.map(function(value) {        return baseInvoke(value, path, args);      });    });    LazyWrapper.prototype.reject = function(predicate) {      return this.filter(negate(getIteratee(predicate)));    };    LazyWrapper.prototype.slice = function(start, end) {      start = toInteger(start);      var result = this;      if (result.__filtered__ && (start > 0 || end < 0)) {        return new LazyWrapper(result);      }      if (start < 0) {        result = result.takeRight(-start);      } else if (start) {        result = result.drop(start);      }      if (end !== undefined) {        end = toInteger(end);        result = end < 0 ? result.dropRight(-end) : result.take(end - start);      }      return result;    };    LazyWrapper.prototype.takeRightWhile = function(predicate) {      return this.reverse().takeWhile(predicate).reverse();    };    LazyWrapper.prototype.toArray = function() {      return this.take(MAX_ARRAY_LENGTH);    };    // Add `LazyWrapper` methods to `lodash.prototype`.    baseForOwn(LazyWrapper.prototype, function(func, methodName) {      var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),          isTaker = /^(?:head|last)$/.test(methodName),          lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],          retUnwrapped = isTaker || /^find/.test(methodName);      if (!lodashFunc) {        return;      }      lodash.prototype[methodName] = function() {        var value = this.__wrapped__,            args = isTaker ? [1] : arguments,            isLazy = value instanceof LazyWrapper,            iteratee = args[0],            useLazy = isLazy || isArray(value);        var interceptor = function(value) {          var result = lodashFunc.apply(lodash, arrayPush([value], args));          return (isTaker && chainAll) ? result[0] : result;        };        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {          // Avoid lazy use if the iteratee has a "length" value other than `1`.          isLazy = useLazy = false;        }        var chainAll = this.__chain__,            isHybrid = !!this.__actions__.length,            isUnwrapped = retUnwrapped && !chainAll,            onlyLazy = isLazy && !isHybrid;        if (!retUnwrapped && useLazy) {          value = onlyLazy ? value : new LazyWrapper(this);          var result = func.apply(value, args);          result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });          return new LodashWrapper(result, chainAll);        }        if (isUnwrapped && onlyLazy) {          return func.apply(this, args);        }        result = this.thru(interceptor);        return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;      };    });    // Add `Array` methods to `lodash.prototype`.    arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {      var func = arrayProto[methodName],          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',          retUnwrapped = /^(?:pop|shift)$/.test(methodName);      lodash.prototype[methodName] = function() {        var args = arguments;        if (retUnwrapped && !this.__chain__) {          var value = this.value();          return func.apply(isArray(value) ? value : [], args);        }        return this[chainName](function(value) {          return func.apply(isArray(value) ? value : [], args);        });      };    });    // Map minified method names to their real names.    baseForOwn(LazyWrapper.prototype, function(func, methodName) {      var lodashFunc = lodash[methodName];      if (lodashFunc) {        var key = (lodashFunc.name + ''),            names = realNames[key] || (realNames[key] = []);        names.push({ 'name': methodName, 'func': lodashFunc });      }    });    realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{      'name': 'wrapper',      'func': undefined    }];    // Add methods to `LazyWrapper`.    LazyWrapper.prototype.clone = lazyClone;    LazyWrapper.prototype.reverse = lazyReverse;    LazyWrapper.prototype.value = lazyValue;    // Add chain sequence methods to the `lodash` wrapper.    lodash.prototype.at = wrapperAt;    lodash.prototype.chain = wrapperChain;    lodash.prototype.commit = wrapperCommit;    lodash.prototype.next = wrapperNext;    lodash.prototype.plant = wrapperPlant;    lodash.prototype.reverse = wrapperReverse;    lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;    // Add lazy aliases.    lodash.prototype.first = lodash.prototype.head;    if (symIterator) {      lodash.prototype[symIterator] = wrapperToIterator;    }    return lodash;  });  /*--------------------------------------------------------------------------*/  // Export lodash.  var _ = runInContext();  // Some AMD build optimizers, like r.js, check for condition patterns like:  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {    // Expose Lodash on the global object to prevent errors when Lodash is    // loaded by a script tag in the presence of an AMD loader.    // See http://requirejs.org/docs/errors.html#mismatch for more details.    // Use `_.noConflict` to remove Lodash from the global object.    root._ = _;    // Define as an anonymous module so, through path mapping, it can be    // referenced as the "underscore" module.    define(function() {      return _;    });  }  // Check for `exports` after `define` in case a build optimizer adds it.  else if (freeModule) {    // Export for Node.js.    (freeModule.exports = _)._ = _;    // Export for CommonJS support.    freeExports._ = _;  }  else {    // Export to the global object.    root._ = _;  }}.call(this));}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})},{}],194:[function(require,module,exports){'use strict'var inherits = require('inherits')var HashBase = require('hash-base')var Buffer = require('safe-buffer').Buffervar ARRAY16 = new Array(16)function MD5 () {  HashBase.call(this, 64)  // state  this._a = 0x67452301  this._b = 0xefcdab89  this._c = 0x98badcfe  this._d = 0x10325476}inherits(MD5, HashBase)MD5.prototype._update = function () {  var M = ARRAY16  for (var i = 0; i < 16; ++i) M[i] = this._block.readInt32LE(i * 4)  var a = this._a  var b = this._b  var c = this._c  var d = this._d  a = fnF(a, b, c, d, M[0], 0xd76aa478, 7)  d = fnF(d, a, b, c, M[1], 0xe8c7b756, 12)  c = fnF(c, d, a, b, M[2], 0x242070db, 17)  b = fnF(b, c, d, a, M[3], 0xc1bdceee, 22)  a = fnF(a, b, c, d, M[4], 0xf57c0faf, 7)  d = fnF(d, a, b, c, M[5], 0x4787c62a, 12)  c = fnF(c, d, a, b, M[6], 0xa8304613, 17)  b = fnF(b, c, d, a, M[7], 0xfd469501, 22)  a = fnF(a, b, c, d, M[8], 0x698098d8, 7)  d = fnF(d, a, b, c, M[9], 0x8b44f7af, 12)  c = fnF(c, d, a, b, M[10], 0xffff5bb1, 17)  b = fnF(b, c, d, a, M[11], 0x895cd7be, 22)  a = fnF(a, b, c, d, M[12], 0x6b901122, 7)  d = fnF(d, a, b, c, M[13], 0xfd987193, 12)  c = fnF(c, d, a, b, M[14], 0xa679438e, 17)  b = fnF(b, c, d, a, M[15], 0x49b40821, 22)  a = fnG(a, b, c, d, M[1], 0xf61e2562, 5)  d = fnG(d, a, b, c, M[6], 0xc040b340, 9)  c = fnG(c, d, a, b, M[11], 0x265e5a51, 14)  b = fnG(b, c, d, a, M[0], 0xe9b6c7aa, 20)  a = fnG(a, b, c, d, M[5], 0xd62f105d, 5)  d = fnG(d, a, b, c, M[10], 0x02441453, 9)  c = fnG(c, d, a, b, M[15], 0xd8a1e681, 14)  b = fnG(b, c, d, a, M[4], 0xe7d3fbc8, 20)  a = fnG(a, b, c, d, M[9], 0x21e1cde6, 5)  d = fnG(d, a, b, c, M[14], 0xc33707d6, 9)  c = fnG(c, d, a, b, M[3], 0xf4d50d87, 14)  b = fnG(b, c, d, a, M[8], 0x455a14ed, 20)  a = fnG(a, b, c, d, M[13], 0xa9e3e905, 5)  d = fnG(d, a, b, c, M[2], 0xfcefa3f8, 9)  c = fnG(c, d, a, b, M[7], 0x676f02d9, 14)  b = fnG(b, c, d, a, M[12], 0x8d2a4c8a, 20)  a = fnH(a, b, c, d, M[5], 0xfffa3942, 4)  d = fnH(d, a, b, c, M[8], 0x8771f681, 11)  c = fnH(c, d, a, b, M[11], 0x6d9d6122, 16)  b = fnH(b, c, d, a, M[14], 0xfde5380c, 23)  a = fnH(a, b, c, d, M[1], 0xa4beea44, 4)  d = fnH(d, a, b, c, M[4], 0x4bdecfa9, 11)  c = fnH(c, d, a, b, M[7], 0xf6bb4b60, 16)  b = fnH(b, c, d, a, M[10], 0xbebfbc70, 23)  a = fnH(a, b, c, d, M[13], 0x289b7ec6, 4)  d = fnH(d, a, b, c, M[0], 0xeaa127fa, 11)  c = fnH(c, d, a, b, M[3], 0xd4ef3085, 16)  b = fnH(b, c, d, a, M[6], 0x04881d05, 23)  a = fnH(a, b, c, d, M[9], 0xd9d4d039, 4)  d = fnH(d, a, b, c, M[12], 0xe6db99e5, 11)  c = fnH(c, d, a, b, M[15], 0x1fa27cf8, 16)  b = fnH(b, c, d, a, M[2], 0xc4ac5665, 23)  a = fnI(a, b, c, d, M[0], 0xf4292244, 6)  d = fnI(d, a, b, c, M[7], 0x432aff97, 10)  c = fnI(c, d, a, b, M[14], 0xab9423a7, 15)  b = fnI(b, c, d, a, M[5], 0xfc93a039, 21)  a = fnI(a, b, c, d, M[12], 0x655b59c3, 6)  d = fnI(d, a, b, c, M[3], 0x8f0ccc92, 10)  c = fnI(c, d, a, b, M[10], 0xffeff47d, 15)  b = fnI(b, c, d, a, M[1], 0x85845dd1, 21)  a = fnI(a, b, c, d, M[8], 0x6fa87e4f, 6)  d = fnI(d, a, b, c, M[15], 0xfe2ce6e0, 10)  c = fnI(c, d, a, b, M[6], 0xa3014314, 15)  b = fnI(b, c, d, a, M[13], 0x4e0811a1, 21)  a = fnI(a, b, c, d, M[4], 0xf7537e82, 6)  d = fnI(d, a, b, c, M[11], 0xbd3af235, 10)  c = fnI(c, d, a, b, M[2], 0x2ad7d2bb, 15)  b = fnI(b, c, d, a, M[9], 0xeb86d391, 21)  this._a = (this._a + a) | 0  this._b = (this._b + b) | 0  this._c = (this._c + c) | 0  this._d = (this._d + d) | 0}MD5.prototype._digest = function () {  // create padding and handle blocks  this._block[this._blockOffset++] = 0x80  if (this._blockOffset > 56) {    this._block.fill(0, this._blockOffset, 64)    this._update()    this._blockOffset = 0  }  this._block.fill(0, this._blockOffset, 56)  this._block.writeUInt32LE(this._length[0], 56)  this._block.writeUInt32LE(this._length[1], 60)  this._update()  // produce result  var buffer = Buffer.allocUnsafe(16)  buffer.writeInt32LE(this._a, 0)  buffer.writeInt32LE(this._b, 4)  buffer.writeInt32LE(this._c, 8)  buffer.writeInt32LE(this._d, 12)  return buffer}function rotl (x, n) {  return (x << n) | (x >>> (32 - n))}function fnF (a, b, c, d, m, k, s) {  return (rotl((a + ((b & c) | ((~b) & d)) + m + k) | 0, s) + b) | 0}function fnG (a, b, c, d, m, k, s) {  return (rotl((a + ((b & d) | (c & (~d))) + m + k) | 0, s) + b) | 0}function fnH (a, b, c, d, m, k, s) {  return (rotl((a + (b ^ c ^ d) + m + k) | 0, s) + b) | 0}function fnI (a, b, c, d, m, k, s) {  return (rotl((a + ((c ^ (b | (~d)))) + m + k) | 0, s) + b) | 0}module.exports = MD5},{"hash-base":138,"inherits":154,"safe-buffer":195}],195:[function(require,module,exports){arguments[4][68][0].apply(exports,arguments)},{"buffer":79,"dup":68}],196:[function(require,module,exports){var bn = require('bn.js');var brorand = require('brorand');function MillerRabin(rand) {  this.rand = rand || new brorand.Rand();}module.exports = MillerRabin;MillerRabin.create = function create(rand) {  return new MillerRabin(rand);};MillerRabin.prototype._randbelow = function _randbelow(n) {  var len = n.bitLength();  var min_bytes = Math.ceil(len / 8);  // Generage random bytes until a number less than n is found.  // This ensures that 0..n-1 have an equal probability of being selected.  do    var a = new bn(this.rand.generate(min_bytes));  while (a.cmp(n) >= 0);  return a;};MillerRabin.prototype._randrange = function _randrange(start, stop) {  // Generate a random number greater than or equal to start and less than stop.  var size = stop.sub(start);  return start.add(this._randbelow(size));};MillerRabin.prototype.test = function test(n, k, cb) {  var len = n.bitLength();  var red = bn.mont(n);  var rone = new bn(1).toRed(red);  if (!k)    k = Math.max(1, (len / 48) | 0);  // Find d and s, (n - 1) = (2 ^ s) * d;  var n1 = n.subn(1);  for (var s = 0; !n1.testn(s); s++) {}  var d = n.shrn(s);  var rn1 = n1.toRed(red);  var prime = true;  for (; k > 0; k--) {    var a = this._randrange(new bn(2), n1);    if (cb)      cb(a);    var x = a.toRed(red).redPow(d);    if (x.cmp(rone) === 0 || x.cmp(rn1) === 0)      continue;    for (var i = 1; i < s; i++) {      x = x.redSqr();      if (x.cmp(rone) === 0)        return false;      if (x.cmp(rn1) === 0)        break;    }    if (i === s)      return false;  }  return prime;};MillerRabin.prototype.getDivisor = function getDivisor(n, k) {  var len = n.bitLength();  var red = bn.mont(n);  var rone = new bn(1).toRed(red);  if (!k)    k = Math.max(1, (len / 48) | 0);  // Find d and s, (n - 1) = (2 ^ s) * d;  var n1 = n.subn(1);  for (var s = 0; !n1.testn(s); s++) {}  var d = n.shrn(s);  var rn1 = n1.toRed(red);  for (; k > 0; k--) {    var a = this._randrange(new bn(2), n1);    var g = n.gcd(a);    if (g.cmpn(1) !== 0)      return g;    var x = a.toRed(red).redPow(d);    if (x.cmp(rone) === 0 || x.cmp(rn1) === 0)      continue;    for (var i = 1; i < s; i++) {      x = x.redSqr();      if (x.cmp(rone) === 0)        return x.fromRed().subn(1).gcd(n);      if (x.cmp(rn1) === 0)        break;    }    if (i === s) {      x = x.redSqr();      return x.fromRed().subn(1).gcd(n);    }  }  return false;};},{"bn.js":45,"brorand":46}],197:[function(require,module,exports){module.exports = assert;function assert(val, msg) {  if (!val)    throw new Error(msg || 'Assertion failed');}assert.equal = function assertEqual(l, r, msg) {  if (l != r)    throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r));};},{}],198:[function(require,module,exports){'use strict';var utils = exports;function toArray(msg, enc) {  if (Array.isArray(msg))    return msg.slice();  if (!msg)    return [];  var res = [];  if (typeof msg !== 'string') {    for (var i = 0; i < msg.length; i++)      res[i] = msg[i] | 0;    return res;  }  if (enc === 'hex') {    msg = msg.replace(/[^a-z0-9]+/ig, '');    if (msg.length % 2 !== 0)      msg = '0' + msg;    for (var i = 0; i < msg.length; i += 2)      res.push(parseInt(msg[i] + msg[i + 1], 16));  } else {    for (var i = 0; i < msg.length; i++) {      var c = msg.charCodeAt(i);      var hi = c >> 8;      var lo = c & 0xff;      if (hi)        res.push(hi, lo);      else        res.push(lo);    }  }  return res;}utils.toArray = toArray;function zero2(word) {  if (word.length === 1)    return '0' + word;  else    return word;}utils.zero2 = zero2;function toHex(msg) {  var res = '';  for (var i = 0; i < msg.length; i++)    res += zero2(msg[i].toString(16));  return res;}utils.toHex = toHex;utils.encode = function encode(arr, enc) {  if (enc === 'hex')    return toHex(arr);  else    return arr;};},{}],199:[function(require,module,exports){// Top level file is just a mixin of submodules & constants'use strict';var assign    = require('./lib/utils/common').assign;var deflate   = require('./lib/deflate');var inflate   = require('./lib/inflate');var constants = require('./lib/zlib/constants');var pako = {};assign(pako, deflate, inflate, constants);module.exports = pako;},{"./lib/deflate":200,"./lib/inflate":201,"./lib/utils/common":202,"./lib/zlib/constants":205}],200:[function(require,module,exports){'use strict';var zlib_deflate = require('./zlib/deflate');var utils        = require('./utils/common');var strings      = require('./utils/strings');var msg          = require('./zlib/messages');var ZStream      = require('./zlib/zstream');var toString = Object.prototype.toString;/* Public constants ==========================================================*//* ===========================================================================*/var Z_NO_FLUSH      = 0;var Z_FINISH        = 4;var Z_OK            = 0;var Z_STREAM_END    = 1;var Z_SYNC_FLUSH    = 2;var Z_DEFAULT_COMPRESSION = -1;var Z_DEFAULT_STRATEGY    = 0;var Z_DEFLATED  = 8;/* ===========================================================================*//** * class Deflate * * Generic JS-style wrapper for zlib calls. If you don't need * streaming behaviour - use more simple functions: [[deflate]], * [[deflateRaw]] and [[gzip]]. **//* internal * Deflate.chunks -> Array * * Chunks of output data, if [[Deflate#onData]] not overridden. **//** * Deflate.result -> Uint8Array|Array * * Compressed result, generated by default [[Deflate#onData]] * and [[Deflate#onEnd]] handlers. Filled after you push last chunk * (call [[Deflate#push]] with `Z_FINISH` / `true` param)  or if you * push a chunk with explicit flush (call [[Deflate#push]] with * `Z_SYNC_FLUSH` param). **//** * Deflate.err -> Number * * Error code after deflate finished. 0 (Z_OK) on success. * You will not need it in real life, because deflate errors * are possible only on wrong options or bad `onData` / `onEnd` * custom handlers. **//** * Deflate.msg -> String * * Error message, if [[Deflate.err]] != 0 **//** * new Deflate(options) * - options (Object): zlib deflate options. * * Creates new deflator instance with specified params. Throws exception * on bad params. Supported options: * * - `level` * - `windowBits` * - `memLevel` * - `strategy` * - `dictionary` * * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) * for more information on these. * * Additional options, for internal needs: * * - `chunkSize` - size of generated data chunks (16K by default) * - `raw` (Boolean) - do raw deflate * - `gzip` (Boolean) - create gzip wrapper * - `to` (String) - if equal to 'string', then result will be "binary string" *    (each char code [0..255]) * - `header` (Object) - custom header for gzip *   - `text` (Boolean) - true if compressed data believed to be text *   - `time` (Number) - modification time, unix timestamp *   - `os` (Number) - operation system code *   - `extra` (Array) - array of bytes with extra data (max 65536) *   - `name` (String) - file name (binary string) *   - `comment` (String) - comment (binary string) *   - `hcrc` (Boolean) - true if header crc should be added * * ##### Example: * * ```javascript * var pako = require('pako') *   , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9]) *   , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]); * * var deflate = new pako.Deflate({ level: 3}); * * deflate.push(chunk1, false); * deflate.push(chunk2, true);  // true -> last chunk * * if (deflate.err) { throw new Error(deflate.err); } * * console.log(deflate.result); * ``` **/function Deflate(options) {  if (!(this instanceof Deflate)) return new Deflate(options);  this.options = utils.assign({    level: Z_DEFAULT_COMPRESSION,    method: Z_DEFLATED,    chunkSize: 16384,    windowBits: 15,    memLevel: 8,    strategy: Z_DEFAULT_STRATEGY,    to: ''  }, options || {});  var opt = this.options;  if (opt.raw && (opt.windowBits > 0)) {    opt.windowBits = -opt.windowBits;  }  else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) {    opt.windowBits += 16;  }  this.err    = 0;      // error code, if happens (0 = Z_OK)  this.msg    = '';     // error message  this.ended  = false;  // used to avoid multiple onEnd() calls  this.chunks = [];     // chunks of compressed data  this.strm = new ZStream();  this.strm.avail_out = 0;  var status = zlib_deflate.deflateInit2(    this.strm,    opt.level,    opt.method,    opt.windowBits,    opt.memLevel,    opt.strategy  );  if (status !== Z_OK) {    throw new Error(msg[status]);  }  if (opt.header) {    zlib_deflate.deflateSetHeader(this.strm, opt.header);  }  if (opt.dictionary) {    var dict;    // Convert data if needed    if (typeof opt.dictionary === 'string') {      // If we need to compress text, change encoding to utf8.      dict = strings.string2buf(opt.dictionary);    } else if (toString.call(opt.dictionary) === '[object ArrayBuffer]') {      dict = new Uint8Array(opt.dictionary);    } else {      dict = opt.dictionary;    }    status = zlib_deflate.deflateSetDictionary(this.strm, dict);    if (status !== Z_OK) {      throw new Error(msg[status]);    }    this._dict_set = true;  }}/** * Deflate#push(data[, mode]) -> Boolean * - data (Uint8Array|Array|ArrayBuffer|String): input data. Strings will be *   converted to utf8 byte sequence. * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. *   See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH. * * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with * new compressed chunks. Returns `true` on success. The last data block must have * mode Z_FINISH (or `true`). That will flush internal pending buffers and call * [[Deflate#onEnd]]. For interim explicit flushes (without ending the stream) you * can use mode Z_SYNC_FLUSH, keeping the compression context. * * On fail call [[Deflate#onEnd]] with error code and return false. * * We strongly recommend to use `Uint8Array` on input for best speed (output * array format is detected automatically). Also, don't skip last param and always * use the same type in your code (boolean or number). That will improve JS speed. * * For regular `Array`-s make sure all elements are [0..255]. * * ##### Example * * ```javascript * push(chunk, false); // push one of data chunks * ... * push(chunk, true);  // push last chunk * ``` **/Deflate.prototype.push = function (data, mode) {  var strm = this.strm;  var chunkSize = this.options.chunkSize;  var status, _mode;  if (this.ended) { return false; }  _mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH : Z_NO_FLUSH);  // Convert data if needed  if (typeof data === 'string') {    // If we need to compress text, change encoding to utf8.    strm.input = strings.string2buf(data);  } else if (toString.call(data) === '[object ArrayBuffer]') {    strm.input = new Uint8Array(data);  } else {    strm.input = data;  }  strm.next_in = 0;  strm.avail_in = strm.input.length;  do {    if (strm.avail_out === 0) {      strm.output = new utils.Buf8(chunkSize);      strm.next_out = 0;      strm.avail_out = chunkSize;    }    status = zlib_deflate.deflate(strm, _mode);    /* no bad return value */    if (status !== Z_STREAM_END && status !== Z_OK) {      this.onEnd(status);      this.ended = true;      return false;    }    if (strm.avail_out === 0 || (strm.avail_in === 0 && (_mode === Z_FINISH || _mode === Z_SYNC_FLUSH))) {      if (this.options.to === 'string') {        this.onData(strings.buf2binstring(utils.shrinkBuf(strm.output, strm.next_out)));      } else {        this.onData(utils.shrinkBuf(strm.output, strm.next_out));      }    }  } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END);  // Finalize on the last chunk.  if (_mode === Z_FINISH) {    status = zlib_deflate.deflateEnd(this.strm);    this.onEnd(status);    this.ended = true;    return status === Z_OK;  }  // callback interim results if Z_SYNC_FLUSH.  if (_mode === Z_SYNC_FLUSH) {    this.onEnd(Z_OK);    strm.avail_out = 0;    return true;  }  return true;};/** * Deflate#onData(chunk) -> Void * - chunk (Uint8Array|Array|String): output data. Type of array depends *   on js engine support. When string output requested, each chunk *   will be string. * * By default, stores data blocks in `chunks[]` property and glue * those in `onEnd`. Override this handler, if you need another behaviour. **/Deflate.prototype.onData = function (chunk) {  this.chunks.push(chunk);};/** * Deflate#onEnd(status) -> Void * - status (Number): deflate status. 0 (Z_OK) on success, *   other if not. * * Called once after you tell deflate that the input stream is * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH) * or if an error happened. By default - join collected chunks, * free memory and fill `results` / `err` properties. **/Deflate.prototype.onEnd = function (status) {  // On success - join  if (status === Z_OK) {    if (this.options.to === 'string') {      this.result = this.chunks.join('');    } else {      this.result = utils.flattenChunks(this.chunks);    }  }  this.chunks = [];  this.err = status;  this.msg = this.strm.msg;};/** * deflate(data[, options]) -> Uint8Array|Array|String * - data (Uint8Array|Array|String): input data to compress. * - options (Object): zlib deflate options. * * Compress `data` with deflate algorithm and `options`. * * Supported options are: * * - level * - windowBits * - memLevel * - strategy * - dictionary * * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) * for more information on these. * * Sugar (options): * * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify *   negative windowBits implicitly. * - `to` (String) - if equal to 'string', then result will be "binary string" *    (each char code [0..255]) * * ##### Example: * * ```javascript * var pako = require('pako') *   , data = Uint8Array([1,2,3,4,5,6,7,8,9]); * * console.log(pako.deflate(data)); * ``` **/function deflate(input, options) {  var deflator = new Deflate(options);  deflator.push(input, true);  // That will never happens, if you don't cheat with options :)  if (deflator.err) { throw deflator.msg || msg[deflator.err]; }  return deflator.result;}/** * deflateRaw(data[, options]) -> Uint8Array|Array|String * - data (Uint8Array|Array|String): input data to compress. * - options (Object): zlib deflate options. * * The same as [[deflate]], but creates raw data, without wrapper * (header and adler32 crc). **/function deflateRaw(input, options) {  options = options || {};  options.raw = true;  return deflate(input, options);}/** * gzip(data[, options]) -> Uint8Array|Array|String * - data (Uint8Array|Array|String): input data to compress. * - options (Object): zlib deflate options. * * The same as [[deflate]], but create gzip wrapper instead of * deflate one. **/function gzip(input, options) {  options = options || {};  options.gzip = true;  return deflate(input, options);}exports.Deflate = Deflate;exports.deflate = deflate;exports.deflateRaw = deflateRaw;exports.gzip = gzip;},{"./utils/common":202,"./utils/strings":203,"./zlib/deflate":207,"./zlib/messages":212,"./zlib/zstream":214}],201:[function(require,module,exports){'use strict';var zlib_inflate = require('./zlib/inflate');var utils        = require('./utils/common');var strings      = require('./utils/strings');var c            = require('./zlib/constants');var msg          = require('./zlib/messages');var ZStream      = require('./zlib/zstream');var GZheader     = require('./zlib/gzheader');var toString = Object.prototype.toString;/** * class Inflate * * Generic JS-style wrapper for zlib calls. If you don't need * streaming behaviour - use more simple functions: [[inflate]] * and [[inflateRaw]]. **//* internal * inflate.chunks -> Array * * Chunks of output data, if [[Inflate#onData]] not overridden. **//** * Inflate.result -> Uint8Array|Array|String * * Uncompressed result, generated by default [[Inflate#onData]] * and [[Inflate#onEnd]] handlers. Filled after you push last chunk * (call [[Inflate#push]] with `Z_FINISH` / `true` param) or if you * push a chunk with explicit flush (call [[Inflate#push]] with * `Z_SYNC_FLUSH` param). **//** * Inflate.err -> Number * * Error code after inflate finished. 0 (Z_OK) on success. * Should be checked if broken data possible. **//** * Inflate.msg -> String * * Error message, if [[Inflate.err]] != 0 **//** * new Inflate(options) * - options (Object): zlib inflate options. * * Creates new inflator instance with specified params. Throws exception * on bad params. Supported options: * * - `windowBits` * - `dictionary` * * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) * for more information on these. * * Additional options, for internal needs: * * - `chunkSize` - size of generated data chunks (16K by default) * - `raw` (Boolean) - do raw inflate * - `to` (String) - if equal to 'string', then result will be converted *   from utf8 to utf16 (javascript) string. When string output requested, *   chunk length can differ from `chunkSize`, depending on content. * * By default, when no options set, autodetect deflate/gzip data format via * wrapper header. * * ##### Example: * * ```javascript * var pako = require('pako') *   , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9]) *   , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]); * * var inflate = new pako.Inflate({ level: 3}); * * inflate.push(chunk1, false); * inflate.push(chunk2, true);  // true -> last chunk * * if (inflate.err) { throw new Error(inflate.err); } * * console.log(inflate.result); * ``` **/function Inflate(options) {  if (!(this instanceof Inflate)) return new Inflate(options);  this.options = utils.assign({    chunkSize: 16384,    windowBits: 0,    to: ''  }, options || {});  var opt = this.options;  // Force window size for `raw` data, if not set directly,  // because we have no header for autodetect.  if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) {    opt.windowBits = -opt.windowBits;    if (opt.windowBits === 0) { opt.windowBits = -15; }  }  // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate  if ((opt.windowBits >= 0) && (opt.windowBits < 16) &&      !(options && options.windowBits)) {    opt.windowBits += 32;  }  // Gzip header has no info about windows size, we can do autodetect only  // for deflate. So, if window size not set, force it to max when gzip possible  if ((opt.windowBits > 15) && (opt.windowBits < 48)) {    // bit 3 (16) -> gzipped data    // bit 4 (32) -> autodetect gzip/deflate    if ((opt.windowBits & 15) === 0) {      opt.windowBits |= 15;    }  }  this.err    = 0;      // error code, if happens (0 = Z_OK)  this.msg    = '';     // error message  this.ended  = false;  // used to avoid multiple onEnd() calls  this.chunks = [];     // chunks of compressed data  this.strm   = new ZStream();  this.strm.avail_out = 0;  var status  = zlib_inflate.inflateInit2(    this.strm,    opt.windowBits  );  if (status !== c.Z_OK) {    throw new Error(msg[status]);  }  this.header = new GZheader();  zlib_inflate.inflateGetHeader(this.strm, this.header);}/** * Inflate#push(data[, mode]) -> Boolean * - data (Uint8Array|Array|ArrayBuffer|String): input data * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. *   See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH. * * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with * new output chunks. Returns `true` on success. The last data block must have * mode Z_FINISH (or `true`). That will flush internal pending buffers and call * [[Inflate#onEnd]]. For interim explicit flushes (without ending the stream) you * can use mode Z_SYNC_FLUSH, keeping the decompression context. * * On fail call [[Inflate#onEnd]] with error code and return false. * * We strongly recommend to use `Uint8Array` on input for best speed (output * format is detected automatically). Also, don't skip last param and always * use the same type in your code (boolean or number). That will improve JS speed. * * For regular `Array`-s make sure all elements are [0..255]. * * ##### Example * * ```javascript * push(chunk, false); // push one of data chunks * ... * push(chunk, true);  // push last chunk * ``` **/Inflate.prototype.push = function (data, mode) {  var strm = this.strm;  var chunkSize = this.options.chunkSize;  var dictionary = this.options.dictionary;  var status, _mode;  var next_out_utf8, tail, utf8str;  var dict;  // Flag to properly process Z_BUF_ERROR on testing inflate call  // when we check that all output data was flushed.  var allowBufError = false;  if (this.ended) { return false; }  _mode = (mode === ~~mode) ? mode : ((mode === true) ? c.Z_FINISH : c.Z_NO_FLUSH);  // Convert data if needed  if (typeof data === 'string') {    // Only binary strings can be decompressed on practice    strm.input = strings.binstring2buf(data);  } else if (toString.call(data) === '[object ArrayBuffer]') {    strm.input = new Uint8Array(data);  } else {    strm.input = data;  }  strm.next_in = 0;  strm.avail_in = strm.input.length;  do {    if (strm.avail_out === 0) {      strm.output = new utils.Buf8(chunkSize);      strm.next_out = 0;      strm.avail_out = chunkSize;    }    status = zlib_inflate.inflate(strm, c.Z_NO_FLUSH);    /* no bad return value */    if (status === c.Z_NEED_DICT && dictionary) {      // Convert data if needed      if (typeof dictionary === 'string') {        dict = strings.string2buf(dictionary);      } else if (toString.call(dictionary) === '[object ArrayBuffer]') {        dict = new Uint8Array(dictionary);      } else {        dict = dictionary;      }      status = zlib_inflate.inflateSetDictionary(this.strm, dict);    }    if (status === c.Z_BUF_ERROR && allowBufError === true) {      status = c.Z_OK;      allowBufError = false;    }    if (status !== c.Z_STREAM_END && status !== c.Z_OK) {      this.onEnd(status);      this.ended = true;      return false;    }    if (strm.next_out) {      if (strm.avail_out === 0 || status === c.Z_STREAM_END || (strm.avail_in === 0 && (_mode === c.Z_FINISH || _mode === c.Z_SYNC_FLUSH))) {        if (this.options.to === 'string') {          next_out_utf8 = strings.utf8border(strm.output, strm.next_out);          tail = strm.next_out - next_out_utf8;          utf8str = strings.buf2string(strm.output, next_out_utf8);          // move tail          strm.next_out = tail;          strm.avail_out = chunkSize - tail;          if (tail) { utils.arraySet(strm.output, strm.output, next_out_utf8, tail, 0); }          this.onData(utf8str);        } else {          this.onData(utils.shrinkBuf(strm.output, strm.next_out));        }      }    }    // When no more input data, we should check that internal inflate buffers    // are flushed. The only way to do it when avail_out = 0 - run one more    // inflate pass. But if output data not exists, inflate return Z_BUF_ERROR.    // Here we set flag to process this error properly.    //    // NOTE. Deflate does not return error in this case and does not needs such    // logic.    if (strm.avail_in === 0 && strm.avail_out === 0) {      allowBufError = true;    }  } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== c.Z_STREAM_END);  if (status === c.Z_STREAM_END) {    _mode = c.Z_FINISH;  }  // Finalize on the last chunk.  if (_mode === c.Z_FINISH) {    status = zlib_inflate.inflateEnd(this.strm);    this.onEnd(status);    this.ended = true;    return status === c.Z_OK;  }  // callback interim results if Z_SYNC_FLUSH.  if (_mode === c.Z_SYNC_FLUSH) {    this.onEnd(c.Z_OK);    strm.avail_out = 0;    return true;  }  return true;};/** * Inflate#onData(chunk) -> Void * - chunk (Uint8Array|Array|String): output data. Type of array depends *   on js engine support. When string output requested, each chunk *   will be string. * * By default, stores data blocks in `chunks[]` property and glue * those in `onEnd`. Override this handler, if you need another behaviour. **/Inflate.prototype.onData = function (chunk) {  this.chunks.push(chunk);};/** * Inflate#onEnd(status) -> Void * - status (Number): inflate status. 0 (Z_OK) on success, *   other if not. * * Called either after you tell inflate that the input stream is * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH) * or if an error happened. By default - join collected chunks, * free memory and fill `results` / `err` properties. **/Inflate.prototype.onEnd = function (status) {  // On success - join  if (status === c.Z_OK) {    if (this.options.to === 'string') {      // Glue & convert here, until we teach pako to send      // utf8 aligned strings to onData      this.result = this.chunks.join('');    } else {      this.result = utils.flattenChunks(this.chunks);    }  }  this.chunks = [];  this.err = status;  this.msg = this.strm.msg;};/** * inflate(data[, options]) -> Uint8Array|Array|String * - data (Uint8Array|Array|String): input data to decompress. * - options (Object): zlib inflate options. * * Decompress `data` with inflate/ungzip and `options`. Autodetect * format via wrapper header by default. That's why we don't provide * separate `ungzip` method. * * Supported options are: * * - windowBits * * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) * for more information. * * Sugar (options): * * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify *   negative windowBits implicitly. * - `to` (String) - if equal to 'string', then result will be converted *   from utf8 to utf16 (javascript) string. When string output requested, *   chunk length can differ from `chunkSize`, depending on content. * * * ##### Example: * * ```javascript * var pako = require('pako') *   , input = pako.deflate([1,2,3,4,5,6,7,8,9]) *   , output; * * try { *   output = pako.inflate(input); * } catch (err) *   console.log(err); * } * ``` **/function inflate(input, options) {  var inflator = new Inflate(options);  inflator.push(input, true);  // That will never happens, if you don't cheat with options :)  if (inflator.err) { throw inflator.msg || msg[inflator.err]; }  return inflator.result;}/** * inflateRaw(data[, options]) -> Uint8Array|Array|String * - data (Uint8Array|Array|String): input data to decompress. * - options (Object): zlib inflate options. * * The same as [[inflate]], but creates raw data, without wrapper * (header and adler32 crc). **/function inflateRaw(input, options) {  options = options || {};  options.raw = true;  return inflate(input, options);}/** * ungzip(data[, options]) -> Uint8Array|Array|String * - data (Uint8Array|Array|String): input data to decompress. * - options (Object): zlib inflate options. * * Just shortcut to [[inflate]], because it autodetects format * by header.content. Done for convenience. **/exports.Inflate = Inflate;exports.inflate = inflate;exports.inflateRaw = inflateRaw;exports.ungzip  = inflate;},{"./utils/common":202,"./utils/strings":203,"./zlib/constants":205,"./zlib/gzheader":208,"./zlib/inflate":210,"./zlib/messages":212,"./zlib/zstream":214}],202:[function(require,module,exports){'use strict';var TYPED_OK =  (typeof Uint8Array !== 'undefined') &&                (typeof Uint16Array !== 'undefined') &&                (typeof Int32Array !== 'undefined');function _has(obj, key) {  return Object.prototype.hasOwnProperty.call(obj, key);}exports.assign = function (obj /*from1, from2, from3, ...*/) {  var sources = Array.prototype.slice.call(arguments, 1);  while (sources.length) {    var source = sources.shift();    if (!source) { continue; }    if (typeof source !== 'object') {      throw new TypeError(source + 'must be non-object');    }    for (var p in source) {      if (_has(source, p)) {        obj[p] = source[p];      }    }  }  return obj;};// reduce buffer size, avoiding mem copyexports.shrinkBuf = function (buf, size) {  if (buf.length === size) { return buf; }  if (buf.subarray) { return buf.subarray(0, size); }  buf.length = size;  return buf;};var fnTyped = {  arraySet: function (dest, src, src_offs, len, dest_offs) {    if (src.subarray && dest.subarray) {      dest.set(src.subarray(src_offs, src_offs + len), dest_offs);      return;    }    // Fallback to ordinary array    for (var i = 0; i < len; i++) {      dest[dest_offs + i] = src[src_offs + i];    }  },  // Join array of chunks to single array.  flattenChunks: function (chunks) {    var i, l, len, pos, chunk, result;    // calculate data length    len = 0;    for (i = 0, l = chunks.length; i < l; i++) {      len += chunks[i].length;    }    // join chunks    result = new Uint8Array(len);    pos = 0;    for (i = 0, l = chunks.length; i < l; i++) {      chunk = chunks[i];      result.set(chunk, pos);      pos += chunk.length;    }    return result;  }};var fnUntyped = {  arraySet: function (dest, src, src_offs, len, dest_offs) {    for (var i = 0; i < len; i++) {      dest[dest_offs + i] = src[src_offs + i];    }  },  // Join array of chunks to single array.  flattenChunks: function (chunks) {    return [].concat.apply([], chunks);  }};// Enable/Disable typed arrays use, for testing//exports.setTyped = function (on) {  if (on) {    exports.Buf8  = Uint8Array;    exports.Buf16 = Uint16Array;    exports.Buf32 = Int32Array;    exports.assign(exports, fnTyped);  } else {    exports.Buf8  = Array;    exports.Buf16 = Array;    exports.Buf32 = Array;    exports.assign(exports, fnUntyped);  }};exports.setTyped(TYPED_OK);},{}],203:[function(require,module,exports){// String encode/decode helpers'use strict';var utils = require('./common');// Quick check if we can use fast array to bin string conversion//// - apply(Array) can fail on Android 2.2// - apply(Uint8Array) can fail on iOS 5.1 Safari//var STR_APPLY_OK = true;var STR_APPLY_UIA_OK = true;try { String.fromCharCode.apply(null, [ 0 ]); } catch (__) { STR_APPLY_OK = false; }try { String.fromCharCode.apply(null, new Uint8Array(1)); } catch (__) { STR_APPLY_UIA_OK = false; }// Table with utf8 lengths (calculated by first byte of sequence)// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS,// because max possible codepoint is 0x10ffffvar _utf8len = new utils.Buf8(256);for (var q = 0; q < 256; q++) {  _utf8len[q] = (q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1);}_utf8len[254] = _utf8len[254] = 1; // Invalid sequence start// convert string to array (typed, when possible)exports.string2buf = function (str) {  var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0;  // count binary size  for (m_pos = 0; m_pos < str_len; m_pos++) {    c = str.charCodeAt(m_pos);    if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) {      c2 = str.charCodeAt(m_pos + 1);      if ((c2 & 0xfc00) === 0xdc00) {        c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);        m_pos++;      }    }    buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4;  }  // allocate buffer  buf = new utils.Buf8(buf_len);  // convert  for (i = 0, m_pos = 0; i < buf_len; m_pos++) {    c = str.charCodeAt(m_pos);    if ((c & 0xfc00) === 0xd800 && (m_pos + 1 < str_len)) {      c2 = str.charCodeAt(m_pos + 1);      if ((c2 & 0xfc00) === 0xdc00) {        c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);        m_pos++;      }    }    if (c < 0x80) {      /* one byte */      buf[i++] = c;    } else if (c < 0x800) {      /* two bytes */      buf[i++] = 0xC0 | (c >>> 6);      buf[i++] = 0x80 | (c & 0x3f);    } else if (c < 0x10000) {      /* three bytes */      buf[i++] = 0xE0 | (c >>> 12);      buf[i++] = 0x80 | (c >>> 6 & 0x3f);      buf[i++] = 0x80 | (c & 0x3f);    } else {      /* four bytes */      buf[i++] = 0xf0 | (c >>> 18);      buf[i++] = 0x80 | (c >>> 12 & 0x3f);      buf[i++] = 0x80 | (c >>> 6 & 0x3f);      buf[i++] = 0x80 | (c & 0x3f);    }  }  return buf;};// Helper (used in 2 places)function buf2binstring(buf, len) {  // use fallback for big arrays to avoid stack overflow  if (len < 65537) {    if ((buf.subarray && STR_APPLY_UIA_OK) || (!buf.subarray && STR_APPLY_OK)) {      return String.fromCharCode.apply(null, utils.shrinkBuf(buf, len));    }  }  var result = '';  for (var i = 0; i < len; i++) {    result += String.fromCharCode(buf[i]);  }  return result;}// Convert byte array to binary stringexports.buf2binstring = function (buf) {  return buf2binstring(buf, buf.length);};// Convert binary string (typed, when possible)exports.binstring2buf = function (str) {  var buf = new utils.Buf8(str.length);  for (var i = 0, len = buf.length; i < len; i++) {    buf[i] = str.charCodeAt(i);  }  return buf;};// convert array to stringexports.buf2string = function (buf, max) {  var i, out, c, c_len;  var len = max || buf.length;  // Reserve max possible length (2 words per char)  // NB: by unknown reasons, Array is significantly faster for  //     String.fromCharCode.apply than Uint16Array.  var utf16buf = new Array(len * 2);  for (out = 0, i = 0; i < len;) {    c = buf[i++];    // quick process ascii    if (c < 0x80) { utf16buf[out++] = c; continue; }    c_len = _utf8len[c];    // skip 5 & 6 byte codes    if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len - 1; continue; }    // apply mask on first byte    c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07;    // join the rest    while (c_len > 1 && i < len) {      c = (c << 6) | (buf[i++] & 0x3f);      c_len--;    }    // terminated by end of string?    if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; }    if (c < 0x10000) {      utf16buf[out++] = c;    } else {      c -= 0x10000;      utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff);      utf16buf[out++] = 0xdc00 | (c & 0x3ff);    }  }  return buf2binstring(utf16buf, out);};// Calculate max possible position in utf8 buffer,// that will not break sequence. If that's not possible// - (very small limits) return max size as is.//// buf[] - utf8 bytes array// max   - length limit (mandatory);exports.utf8border = function (buf, max) {  var pos;  max = max || buf.length;  if (max > buf.length) { max = buf.length; }  // go back from last position, until start of sequence found  pos = max - 1;  while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; }  // Very small and broken sequence,  // return max, because we should return something anyway.  if (pos < 0) { return max; }  // If we came to start of buffer - that means buffer is too small,  // return max too.  if (pos === 0) { return max; }  return (pos + _utf8len[buf[pos]] > max) ? pos : max;};},{"./common":202}],204:[function(require,module,exports){'use strict';// Note: adler32 takes 12% for level 0 and 2% for level 6.// It isn't worth it to make additional optimizations as in original.// Small size is preferable.// (C) 1995-2013 Jean-loup Gailly and Mark Adler// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin//// This software is provided 'as-is', without any express or implied// warranty. In no event will the authors be held liable for any damages// arising from the use of this software.//// Permission is granted to anyone to use this software for any purpose,// including commercial applications, and to alter it and redistribute it// freely, subject to the following restrictions://// 1. The origin of this software must not be misrepresented; you must not//   claim that you wrote the original software. If you use this software//   in a product, an acknowledgment in the product documentation would be//   appreciated but is not required.// 2. Altered source versions must be plainly marked as such, and must not be//   misrepresented as being the original software.// 3. This notice may not be removed or altered from any source distribution.function adler32(adler, buf, len, pos) {  var s1 = (adler & 0xffff) |0,      s2 = ((adler >>> 16) & 0xffff) |0,      n = 0;  while (len !== 0) {    // Set limit ~ twice less than 5552, to keep    // s2 in 31-bits, because we force signed ints.    // in other case %= will fail.    n = len > 2000 ? 2000 : len;    len -= n;    do {      s1 = (s1 + buf[pos++]) |0;      s2 = (s2 + s1) |0;    } while (--n);    s1 %= 65521;    s2 %= 65521;  }  return (s1 | (s2 << 16)) |0;}module.exports = adler32;},{}],205:[function(require,module,exports){'use strict';// (C) 1995-2013 Jean-loup Gailly and Mark Adler// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin//// This software is provided 'as-is', without any express or implied// warranty. In no event will the authors be held liable for any damages// arising from the use of this software.//// Permission is granted to anyone to use this software for any purpose,// including commercial applications, and to alter it and redistribute it// freely, subject to the following restrictions://// 1. The origin of this software must not be misrepresented; you must not//   claim that you wrote the original software. If you use this software//   in a product, an acknowledgment in the product documentation would be//   appreciated but is not required.// 2. Altered source versions must be plainly marked as such, and must not be//   misrepresented as being the original software.// 3. This notice may not be removed or altered from any source distribution.module.exports = {  /* Allowed flush values; see deflate() and inflate() below for details */  Z_NO_FLUSH:         0,  Z_PARTIAL_FLUSH:    1,  Z_SYNC_FLUSH:       2,  Z_FULL_FLUSH:       3,  Z_FINISH:           4,  Z_BLOCK:            5,  Z_TREES:            6,  /* Return codes for the compression/decompression functions. Negative values  * are errors, positive values are used for special but normal events.  */  Z_OK:               0,  Z_STREAM_END:       1,  Z_NEED_DICT:        2,  Z_ERRNO:           -1,  Z_STREAM_ERROR:    -2,  Z_DATA_ERROR:      -3,  //Z_MEM_ERROR:     -4,  Z_BUF_ERROR:       -5,  //Z_VERSION_ERROR: -6,  /* compression levels */  Z_NO_COMPRESSION:         0,  Z_BEST_SPEED:             1,  Z_BEST_COMPRESSION:       9,  Z_DEFAULT_COMPRESSION:   -1,  Z_FILTERED:               1,  Z_HUFFMAN_ONLY:           2,  Z_RLE:                    3,  Z_FIXED:                  4,  Z_DEFAULT_STRATEGY:       0,  /* Possible values of the data_type field (though see inflate()) */  Z_BINARY:                 0,  Z_TEXT:                   1,  //Z_ASCII:                1, // = Z_TEXT (deprecated)  Z_UNKNOWN:                2,  /* The deflate compression method */  Z_DEFLATED:               8  //Z_NULL:                 null // Use -1 or null inline, depending on var type};},{}],206:[function(require,module,exports){'use strict';// Note: we can't get significant speed boost here.// So write code to minimize size - no pregenerated tables// and array tools dependencies.// (C) 1995-2013 Jean-loup Gailly and Mark Adler// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin//// This software is provided 'as-is', without any express or implied// warranty. In no event will the authors be held liable for any damages// arising from the use of this software.//// Permission is granted to anyone to use this software for any purpose,// including commercial applications, and to alter it and redistribute it// freely, subject to the following restrictions://// 1. The origin of this software must not be misrepresented; you must not//   claim that you wrote the original software. If you use this software//   in a product, an acknowledgment in the product documentation would be//   appreciated but is not required.// 2. Altered source versions must be plainly marked as such, and must not be//   misrepresented as being the original software.// 3. This notice may not be removed or altered from any source distribution.// Use ordinary array, since untyped makes no boost herefunction makeTable() {  var c, table = [];  for (var n = 0; n < 256; n++) {    c = n;    for (var k = 0; k < 8; k++) {      c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));    }    table[n] = c;  }  return table;}// Create table on load. Just 255 signed longs. Not a problem.var crcTable = makeTable();function crc32(crc, buf, len, pos) {  var t = crcTable,      end = pos + len;  crc ^= -1;  for (var i = pos; i < end; i++) {    crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF];  }  return (crc ^ (-1)); // >>> 0;}module.exports = crc32;},{}],207:[function(require,module,exports){'use strict';// (C) 1995-2013 Jean-loup Gailly and Mark Adler// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin//// This software is provided 'as-is', without any express or implied// warranty. In no event will the authors be held liable for any damages// arising from the use of this software.//// Permission is granted to anyone to use this software for any purpose,// including commercial applications, and to alter it and redistribute it// freely, subject to the following restrictions://// 1. The origin of this software must not be misrepresented; you must not//   claim that you wrote the original software. If you use this software//   in a product, an acknowledgment in the product documentation would be//   appreciated but is not required.// 2. Altered source versions must be plainly marked as such, and must not be//   misrepresented as being the original software.// 3. This notice may not be removed or altered from any source distribution.var utils   = require('../utils/common');var trees   = require('./trees');var adler32 = require('./adler32');var crc32   = require('./crc32');var msg     = require('./messages');/* Public constants ==========================================================*//* ===========================================================================*//* Allowed flush values; see deflate() and inflate() below for details */var Z_NO_FLUSH      = 0;var Z_PARTIAL_FLUSH = 1;//var Z_SYNC_FLUSH    = 2;var Z_FULL_FLUSH    = 3;var Z_FINISH        = 4;var Z_BLOCK         = 5;//var Z_TREES         = 6;/* Return codes for the compression/decompression functions. Negative values * are errors, positive values are used for special but normal events. */var Z_OK            = 0;var Z_STREAM_END    = 1;//var Z_NEED_DICT     = 2;//var Z_ERRNO         = -1;var Z_STREAM_ERROR  = -2;var Z_DATA_ERROR    = -3;//var Z_MEM_ERROR     = -4;var Z_BUF_ERROR     = -5;//var Z_VERSION_ERROR = -6;/* compression levels *///var Z_NO_COMPRESSION      = 0;//var Z_BEST_SPEED          = 1;//var Z_BEST_COMPRESSION    = 9;var Z_DEFAULT_COMPRESSION = -1;var Z_FILTERED            = 1;var Z_HUFFMAN_ONLY        = 2;var Z_RLE                 = 3;var Z_FIXED               = 4;var Z_DEFAULT_STRATEGY    = 0;/* Possible values of the data_type field (though see inflate()) *///var Z_BINARY              = 0;//var Z_TEXT                = 1;//var Z_ASCII               = 1; // = Z_TEXTvar Z_UNKNOWN             = 2;/* The deflate compression method */var Z_DEFLATED  = 8;/*============================================================================*/var MAX_MEM_LEVEL = 9;/* Maximum value for memLevel in deflateInit2 */var MAX_WBITS = 15;/* 32K LZ77 window */var DEF_MEM_LEVEL = 8;var LENGTH_CODES  = 29;/* number of length codes, not counting the special END_BLOCK code */var LITERALS      = 256;/* number of literal bytes 0..255 */var L_CODES       = LITERALS + 1 + LENGTH_CODES;/* number of Literal or Length codes, including the END_BLOCK code */var D_CODES       = 30;/* number of distance codes */var BL_CODES      = 19;/* number of codes used to transfer the bit lengths */var HEAP_SIZE     = 2 * L_CODES + 1;/* maximum heap size */var MAX_BITS  = 15;/* All codes must not exceed MAX_BITS bits */var MIN_MATCH = 3;var MAX_MATCH = 258;var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);var PRESET_DICT = 0x20;var INIT_STATE = 42;var EXTRA_STATE = 69;var NAME_STATE = 73;var COMMENT_STATE = 91;var HCRC_STATE = 103;var BUSY_STATE = 113;var FINISH_STATE = 666;var BS_NEED_MORE      = 1; /* block not completed, need more input or more output */var BS_BLOCK_DONE     = 2; /* block flush performed */var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */var BS_FINISH_DONE    = 4; /* finish done, accept no more input or output */var OS_CODE = 0x03; // Unix :) . Don't detect, use this default.function err(strm, errorCode) {  strm.msg = msg[errorCode];  return errorCode;}function rank(f) {  return ((f) << 1) - ((f) > 4 ? 9 : 0);}function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } }/* ========================================================================= * Flush as much pending output as possible. All deflate() output goes * through this function so some applications may wish to modify it * to avoid allocating a large strm->output buffer and copying into it. * (See also read_buf()). */function flush_pending(strm) {  var s = strm.state;  //_tr_flush_bits(s);  var len = s.pending;  if (len > strm.avail_out) {    len = strm.avail_out;  }  if (len === 0) { return; }  utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out);  strm.next_out += len;  s.pending_out += len;  strm.total_out += len;  strm.avail_out -= len;  s.pending -= len;  if (s.pending === 0) {    s.pending_out = 0;  }}function flush_block_only(s, last) {  trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last);  s.block_start = s.strstart;  flush_pending(s.strm);}function put_byte(s, b) {  s.pending_buf[s.pending++] = b;}/* ========================================================================= * Put a short in the pending buffer. The 16-bit value is put in MSB order. * IN assertion: the stream state is correct and there is enough room in * pending_buf. */function putShortMSB(s, b) {//  put_byte(s, (Byte)(b >> 8));//  put_byte(s, (Byte)(b & 0xff));  s.pending_buf[s.pending++] = (b >>> 8) & 0xff;  s.pending_buf[s.pending++] = b & 0xff;}/* =========================================================================== * Read a new buffer from the current input stream, update the adler32 * and total number of bytes read.  All deflate() input goes through * this function so some applications may wish to modify it to avoid * allocating a large strm->input buffer and copying from it. * (See also flush_pending()). */function read_buf(strm, buf, start, size) {  var len = strm.avail_in;  if (len > size) { len = size; }  if (len === 0) { return 0; }  strm.avail_in -= len;  // zmemcpy(buf, strm->next_in, len);  utils.arraySet(buf, strm.input, strm.next_in, len, start);  if (strm.state.wrap === 1) {    strm.adler = adler32(strm.adler, buf, len, start);  }  else if (strm.state.wrap === 2) {    strm.adler = crc32(strm.adler, buf, len, start);  }  strm.next_in += len;  strm.total_in += len;  return len;}/* =========================================================================== * Set match_start to the longest match starting at the given string and * return its length. Matches shorter or equal to prev_length are discarded, * in which case the result is equal to prev_length and match_start is * garbage. * IN assertions: cur_match is the head of the hash chain for the current *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 * OUT assertion: the match length is not greater than s->lookahead. */function longest_match(s, cur_match) {  var chain_length = s.max_chain_length;      /* max hash chain length */  var scan = s.strstart; /* current string */  var match;                       /* matched string */  var len;                           /* length of current match */  var best_len = s.prev_length;              /* best match length so far */  var nice_match = s.nice_match;             /* stop if match long enough */  var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ?      s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/;  var _win = s.window; // shortcut  var wmask = s.w_mask;  var prev  = s.prev;  /* Stop when cur_match becomes <= limit. To simplify the code,   * we prevent matches with the string of window index 0.   */  var strend = s.strstart + MAX_MATCH;  var scan_end1  = _win[scan + best_len - 1];  var scan_end   = _win[scan + best_len];  /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.   * It is easy to get rid of this optimization if necessary.   */  // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");  /* Do not waste too much time if we already have a good match: */  if (s.prev_length >= s.good_match) {    chain_length >>= 2;  }  /* Do not look for matches beyond the end of the input. This is necessary   * to make deflate deterministic.   */  if (nice_match > s.lookahead) { nice_match = s.lookahead; }  // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");  do {    // Assert(cur_match < s->strstart, "no future");    match = cur_match;    /* Skip to next match if the match length cannot increase     * or if the match length is less than 2.  Note that the checks below     * for insufficient lookahead only occur occasionally for performance     * reasons.  Therefore uninitialized memory will be accessed, and     * conditional jumps will be made that depend on those values.     * However the length of the match is limited to the lookahead, so     * the output of deflate is not affected by the uninitialized values.     */    if (_win[match + best_len]     !== scan_end  ||        _win[match + best_len - 1] !== scan_end1 ||        _win[match]                !== _win[scan] ||        _win[++match]              !== _win[scan + 1]) {      continue;    }    /* The check at best_len-1 can be removed because it will be made     * again later. (This heuristic is not always a win.)     * It is not necessary to compare scan[2] and match[2] since they     * are always equal when the other bytes match, given that     * the hash keys are equal and that HASH_BITS >= 8.     */    scan += 2;    match++;    // Assert(*scan == *match, "match[2]?");    /* We check for insufficient lookahead only every 8th comparison;     * the 256th check will be made at strstart+258.     */    do {      /*jshint noempty:false*/    } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&             _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&             _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&             _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&             scan < strend);    // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");    len = MAX_MATCH - (strend - scan);    scan = strend - MAX_MATCH;    if (len > best_len) {      s.match_start = cur_match;      best_len = len;      if (len >= nice_match) {        break;      }      scan_end1  = _win[scan + best_len - 1];      scan_end   = _win[scan + best_len];    }  } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0);  if (best_len <= s.lookahead) {    return best_len;  }  return s.lookahead;}/* =========================================================================== * Fill the window when the lookahead becomes insufficient. * Updates strstart and lookahead. * * IN assertion: lookahead < MIN_LOOKAHEAD * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD *    At least one byte has been read, or avail_in == 0; reads are *    performed for at least two bytes (required for the zip translate_eol *    option -- not supported here). */function fill_window(s) {  var _w_size = s.w_size;  var p, n, m, more, str;  //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");  do {    more = s.window_size - s.lookahead - s.strstart;    // JS ints have 32 bit, block below not needed    /* Deal with !@#$% 64K limit: */    //if (sizeof(int) <= 2) {    //    if (more == 0 && s->strstart == 0 && s->lookahead == 0) {    //        more = wsize;    //    //  } else if (more == (unsigned)(-1)) {    //        /* Very unlikely, but possible on 16 bit machine if    //         * strstart == 0 && lookahead == 1 (input done a byte at time)    //         */    //        more--;    //    }    //}    /* If the window is almost full and there is insufficient lookahead,     * move the upper half to the lower one to make room in the upper half.     */    if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) {      utils.arraySet(s.window, s.window, _w_size, _w_size, 0);      s.match_start -= _w_size;      s.strstart -= _w_size;      /* we now have strstart >= MAX_DIST */      s.block_start -= _w_size;      /* Slide the hash table (could be avoided with 32 bit values       at the expense of memory usage). We slide even when level == 0       to keep the hash table consistent if we switch back to level > 0       later. (Using level 0 permanently is not an optimal usage of       zlib, so we don't care about this pathological case.)       */      n = s.hash_size;      p = n;      do {        m = s.head[--p];        s.head[p] = (m >= _w_size ? m - _w_size : 0);      } while (--n);      n = _w_size;      p = n;      do {        m = s.prev[--p];        s.prev[p] = (m >= _w_size ? m - _w_size : 0);        /* If n is not on any hash chain, prev[n] is garbage but         * its value will never be used.         */      } while (--n);      more += _w_size;    }    if (s.strm.avail_in === 0) {      break;    }    /* If there was no sliding:     *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&     *    more == window_size - lookahead - strstart     * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)     * => more >= window_size - 2*WSIZE + 2     * In the BIG_MEM or MMAP case (not yet supported),     *   window_size == input_size + MIN_LOOKAHEAD  &&     *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.     * Otherwise, window_size == 2*WSIZE so more >= 2.     * If there was sliding, more >= WSIZE. So in all cases, more >= 2.     */    //Assert(more >= 2, "more < 2");    n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more);    s.lookahead += n;    /* Initialize the hash value now that we have some input: */    if (s.lookahead + s.insert >= MIN_MATCH) {      str = s.strstart - s.insert;      s.ins_h = s.window[str];      /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */      s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask;//#if MIN_MATCH != 3//        Call update_hash() MIN_MATCH-3 more times//#endif      while (s.insert) {        /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */        s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;        s.prev[str & s.w_mask] = s.head[s.ins_h];        s.head[s.ins_h] = str;        str++;        s.insert--;        if (s.lookahead + s.insert < MIN_MATCH) {          break;        }      }    }    /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,     * but this is not important since only literal bytes will be emitted.     */  } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0);  /* If the WIN_INIT bytes after the end of the current data have never been   * written, then zero those bytes in order to avoid memory check reports of   * the use of uninitialized (or uninitialised as Julian writes) bytes by   * the longest match routines.  Update the high water mark for the next   * time through here.  WIN_INIT is set to MAX_MATCH since the longest match   * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.   *///  if (s.high_water < s.window_size) {//    var curr = s.strstart + s.lookahead;//    var init = 0;////    if (s.high_water < curr) {//      /* Previous high water mark below current data -- zero WIN_INIT//       * bytes or up to end of window, whichever is less.//       *///      init = s.window_size - curr;//      if (init > WIN_INIT)//        init = WIN_INIT;//      zmemzero(s->window + curr, (unsigned)init);//      s->high_water = curr + init;//    }//    else if (s->high_water < (ulg)curr + WIN_INIT) {//      /* High water mark at or above current data, but below current data//       * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up//       * to end of window, whichever is less.//       *///      init = (ulg)curr + WIN_INIT - s->high_water;//      if (init > s->window_size - s->high_water)//        init = s->window_size - s->high_water;//      zmemzero(s->window + s->high_water, (unsigned)init);//      s->high_water += init;//    }//  }////  Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,//    "not enough room for search");}/* =========================================================================== * Copy without compression as much as possible from the input stream, return * the current block state. * This function does not insert new strings in the dictionary since * uncompressible data is probably not useful. This function is used * only for the level=0 compression option. * NOTE: this function should be optimized to avoid extra copying from * window to pending_buf. */function deflate_stored(s, flush) {  /* Stored blocks are limited to 0xffff bytes, pending_buf is limited   * to pending_buf_size, and each stored block has a 5 byte header:   */  var max_block_size = 0xffff;  if (max_block_size > s.pending_buf_size - 5) {    max_block_size = s.pending_buf_size - 5;  }  /* Copy as much as possible from input to output: */  for (;;) {    /* Fill the window as much as possible: */    if (s.lookahead <= 1) {      //Assert(s->strstart < s->w_size+MAX_DIST(s) ||      //  s->block_start >= (long)s->w_size, "slide too late");//      if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) ||//        s.block_start >= s.w_size)) {//        throw  new Error("slide too late");//      }      fill_window(s);      if (s.lookahead === 0 && flush === Z_NO_FLUSH) {        return BS_NEED_MORE;      }      if (s.lookahead === 0) {        break;      }      /* flush the current block */    }    //Assert(s->block_start >= 0L, "block gone");//    if (s.block_start < 0) throw new Error("block gone");    s.strstart += s.lookahead;    s.lookahead = 0;    /* Emit a stored block if pending_buf will be full: */    var max_start = s.block_start + max_block_size;    if (s.strstart === 0 || s.strstart >= max_start) {      /* strstart == 0 is possible when wraparound on 16-bit machine */      s.lookahead = s.strstart - max_start;      s.strstart = max_start;      /*** FLUSH_BLOCK(s, 0); ***/      flush_block_only(s, false);      if (s.strm.avail_out === 0) {        return BS_NEED_MORE;      }      /***/    }    /* Flush if we may have to slide, otherwise block_start may become     * negative and the data will be gone:     */    if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) {      /*** FLUSH_BLOCK(s, 0); ***/      flush_block_only(s, false);      if (s.strm.avail_out === 0) {        return BS_NEED_MORE;      }      /***/    }  }  s.insert = 0;  if (flush === Z_FINISH) {    /*** FLUSH_BLOCK(s, 1); ***/    flush_block_only(s, true);    if (s.strm.avail_out === 0) {      return BS_FINISH_STARTED;    }    /***/    return BS_FINISH_DONE;  }  if (s.strstart > s.block_start) {    /*** FLUSH_BLOCK(s, 0); ***/    flush_block_only(s, false);    if (s.strm.avail_out === 0) {      return BS_NEED_MORE;    }    /***/  }  return BS_NEED_MORE;}/* =========================================================================== * Compress as much as possible from the input stream, return the current * block state. * This function does not perform lazy evaluation of matches and inserts * new strings in the dictionary only for unmatched strings or for short * matches. It is used only for the fast compression options. */function deflate_fast(s, flush) {  var hash_head;        /* head of the hash chain */  var bflush;           /* set if current block must be flushed */  for (;;) {    /* Make sure that we always have enough lookahead, except     * at the end of the input file. We need MAX_MATCH bytes     * for the next match, plus MIN_MATCH bytes to insert the     * string following the next match.     */    if (s.lookahead < MIN_LOOKAHEAD) {      fill_window(s);      if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {        return BS_NEED_MORE;      }      if (s.lookahead === 0) {        break; /* flush the current block */      }    }    /* Insert the string window[strstart .. strstart+2] in the     * dictionary, and set hash_head to the head of the hash chain:     */    hash_head = 0/*NIL*/;    if (s.lookahead >= MIN_MATCH) {      /*** INSERT_STRING(s, s.strstart, hash_head); ***/      s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;      hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];      s.head[s.ins_h] = s.strstart;      /***/    }    /* Find the longest match, discarding those <= prev_length.     * At this point we have always match_length < MIN_MATCH     */    if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) {      /* To simplify the code, we prevent matches with the string       * of window index 0 (in particular we have to avoid a match       * of the string with itself at the start of the input file).       */      s.match_length = longest_match(s, hash_head);      /* longest_match() sets match_start */    }    if (s.match_length >= MIN_MATCH) {      // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only      /*** _tr_tally_dist(s, s.strstart - s.match_start,                     s.match_length - MIN_MATCH, bflush); ***/      bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH);      s.lookahead -= s.match_length;      /* Insert new strings in the hash table only if the match length       * is not too large. This saves time but degrades compression.       */      if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) {        s.match_length--; /* string at strstart already in table */        do {          s.strstart++;          /*** INSERT_STRING(s, s.strstart, hash_head); ***/          s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;          hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];          s.head[s.ins_h] = s.strstart;          /***/          /* strstart never exceeds WSIZE-MAX_MATCH, so there are           * always MIN_MATCH bytes ahead.           */        } while (--s.match_length !== 0);        s.strstart++;      } else      {        s.strstart += s.match_length;        s.match_length = 0;        s.ins_h = s.window[s.strstart];        /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */        s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask;//#if MIN_MATCH != 3//                Call UPDATE_HASH() MIN_MATCH-3 more times//#endif        /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not         * matter since it will be recomputed at next deflate call.         */      }    } else {      /* No match, output a literal byte */      //Tracevv((stderr,"%c", s.window[s.strstart]));      /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/      bflush = trees._tr_tally(s, 0, s.window[s.strstart]);      s.lookahead--;      s.strstart++;    }    if (bflush) {      /*** FLUSH_BLOCK(s, 0); ***/      flush_block_only(s, false);      if (s.strm.avail_out === 0) {        return BS_NEED_MORE;      }      /***/    }  }  s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1);  if (flush === Z_FINISH) {    /*** FLUSH_BLOCK(s, 1); ***/    flush_block_only(s, true);    if (s.strm.avail_out === 0) {      return BS_FINISH_STARTED;    }    /***/    return BS_FINISH_DONE;  }  if (s.last_lit) {    /*** FLUSH_BLOCK(s, 0); ***/    flush_block_only(s, false);    if (s.strm.avail_out === 0) {      return BS_NEED_MORE;    }    /***/  }  return BS_BLOCK_DONE;}/* =========================================================================== * Same as above, but achieves better compression. We use a lazy * evaluation for matches: a match is finally adopted only if there is * no better match at the next window position. */function deflate_slow(s, flush) {  var hash_head;          /* head of hash chain */  var bflush;              /* set if current block must be flushed */  var max_insert;  /* Process the input block. */  for (;;) {    /* Make sure that we always have enough lookahead, except     * at the end of the input file. We need MAX_MATCH bytes     * for the next match, plus MIN_MATCH bytes to insert the     * string following the next match.     */    if (s.lookahead < MIN_LOOKAHEAD) {      fill_window(s);      if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {        return BS_NEED_MORE;      }      if (s.lookahead === 0) { break; } /* flush the current block */    }    /* Insert the string window[strstart .. strstart+2] in the     * dictionary, and set hash_head to the head of the hash chain:     */    hash_head = 0/*NIL*/;    if (s.lookahead >= MIN_MATCH) {      /*** INSERT_STRING(s, s.strstart, hash_head); ***/      s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;      hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];      s.head[s.ins_h] = s.strstart;      /***/    }    /* Find the longest match, discarding those <= prev_length.     */    s.prev_length = s.match_length;    s.prev_match = s.match_start;    s.match_length = MIN_MATCH - 1;    if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match &&        s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) {      /* To simplify the code, we prevent matches with the string       * of window index 0 (in particular we have to avoid a match       * of the string with itself at the start of the input file).       */      s.match_length = longest_match(s, hash_head);      /* longest_match() sets match_start */      if (s.match_length <= 5 &&         (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) {        /* If prev_match is also MIN_MATCH, match_start is garbage         * but we will ignore the current match anyway.         */        s.match_length = MIN_MATCH - 1;      }    }    /* If there was a match at the previous step and the current     * match is not better, output the previous match:     */    if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) {      max_insert = s.strstart + s.lookahead - MIN_MATCH;      /* Do not insert strings in hash table beyond this. */      //check_match(s, s.strstart-1, s.prev_match, s.prev_length);      /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match,                     s.prev_length - MIN_MATCH, bflush);***/      bflush = trees._tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH);      /* Insert in hash table all strings up to the end of the match.       * strstart-1 and strstart are already inserted. If there is not       * enough lookahead, the last two strings are not inserted in       * the hash table.       */      s.lookahead -= s.prev_length - 1;      s.prev_length -= 2;      do {        if (++s.strstart <= max_insert) {          /*** INSERT_STRING(s, s.strstart, hash_head); ***/          s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;          hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];          s.head[s.ins_h] = s.strstart;          /***/        }      } while (--s.prev_length !== 0);      s.match_available = 0;      s.match_length = MIN_MATCH - 1;      s.strstart++;      if (bflush) {        /*** FLUSH_BLOCK(s, 0); ***/        flush_block_only(s, false);        if (s.strm.avail_out === 0) {          return BS_NEED_MORE;        }        /***/      }    } else if (s.match_available) {      /* If there was no match at the previous position, output a       * single literal. If there was a match but the current match       * is longer, truncate the previous match to a single literal.       */      //Tracevv((stderr,"%c", s->window[s->strstart-1]));      /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/      bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]);      if (bflush) {        /*** FLUSH_BLOCK_ONLY(s, 0) ***/        flush_block_only(s, false);        /***/      }      s.strstart++;      s.lookahead--;      if (s.strm.avail_out === 0) {        return BS_NEED_MORE;      }    } else {      /* There is no previous match to compare with, wait for       * the next step to decide.       */      s.match_available = 1;      s.strstart++;      s.lookahead--;    }  }  //Assert (flush != Z_NO_FLUSH, "no flush?");  if (s.match_available) {    //Tracevv((stderr,"%c", s->window[s->strstart-1]));    /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/    bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]);    s.match_available = 0;  }  s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1;  if (flush === Z_FINISH) {    /*** FLUSH_BLOCK(s, 1); ***/    flush_block_only(s, true);    if (s.strm.avail_out === 0) {      return BS_FINISH_STARTED;    }    /***/    return BS_FINISH_DONE;  }  if (s.last_lit) {    /*** FLUSH_BLOCK(s, 0); ***/    flush_block_only(s, false);    if (s.strm.avail_out === 0) {      return BS_NEED_MORE;    }    /***/  }  return BS_BLOCK_DONE;}/* =========================================================================== * For Z_RLE, simply look for runs of bytes, generate matches only of distance * one.  Do not maintain a hash table.  (It will be regenerated if this run of * deflate switches away from Z_RLE.) */function deflate_rle(s, flush) {  var bflush;            /* set if current block must be flushed */  var prev;              /* byte at distance one to match */  var scan, strend;      /* scan goes up to strend for length of run */  var _win = s.window;  for (;;) {    /* Make sure that we always have enough lookahead, except     * at the end of the input file. We need MAX_MATCH bytes     * for the longest run, plus one for the unrolled loop.     */    if (s.lookahead <= MAX_MATCH) {      fill_window(s);      if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH) {        return BS_NEED_MORE;      }      if (s.lookahead === 0) { break; } /* flush the current block */    }    /* See how many times the previous byte repeats */    s.match_length = 0;    if (s.lookahead >= MIN_MATCH && s.strstart > 0) {      scan = s.strstart - 1;      prev = _win[scan];      if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) {        strend = s.strstart + MAX_MATCH;        do {          /*jshint noempty:false*/        } while (prev === _win[++scan] && prev === _win[++scan] &&                 prev === _win[++scan] && prev === _win[++scan] &&                 prev === _win[++scan] && prev === _win[++scan] &&                 prev === _win[++scan] && prev === _win[++scan] &&                 scan < strend);        s.match_length = MAX_MATCH - (strend - scan);        if (s.match_length > s.lookahead) {          s.match_length = s.lookahead;        }      }      //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");    }    /* Emit match if have run of MIN_MATCH or longer, else emit literal */    if (s.match_length >= MIN_MATCH) {      //check_match(s, s.strstart, s.strstart - 1, s.match_length);      /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/      bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH);      s.lookahead -= s.match_length;      s.strstart += s.match_length;      s.match_length = 0;    } else {      /* No match, output a literal byte */      //Tracevv((stderr,"%c", s->window[s->strstart]));      /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/      bflush = trees._tr_tally(s, 0, s.window[s.strstart]);      s.lookahead--;      s.strstart++;    }    if (bflush) {      /*** FLUSH_BLOCK(s, 0); ***/      flush_block_only(s, false);      if (s.strm.avail_out === 0) {        return BS_NEED_MORE;      }      /***/    }  }  s.insert = 0;  if (flush === Z_FINISH) {    /*** FLUSH_BLOCK(s, 1); ***/    flush_block_only(s, true);    if (s.strm.avail_out === 0) {      return BS_FINISH_STARTED;    }    /***/    return BS_FINISH_DONE;  }  if (s.last_lit) {    /*** FLUSH_BLOCK(s, 0); ***/    flush_block_only(s, false);    if (s.strm.avail_out === 0) {      return BS_NEED_MORE;    }    /***/  }  return BS_BLOCK_DONE;}/* =========================================================================== * For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table. * (It will be regenerated if this run of deflate switches away from Huffman.) */function deflate_huff(s, flush) {  var bflush;             /* set if current block must be flushed */  for (;;) {    /* Make sure that we have a literal to write. */    if (s.lookahead === 0) {      fill_window(s);      if (s.lookahead === 0) {        if (flush === Z_NO_FLUSH) {          return BS_NEED_MORE;        }        break;      /* flush the current block */      }    }    /* Output a literal byte */    s.match_length = 0;    //Tracevv((stderr,"%c", s->window[s->strstart]));    /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/    bflush = trees._tr_tally(s, 0, s.window[s.strstart]);    s.lookahead--;    s.strstart++;    if (bflush) {      /*** FLUSH_BLOCK(s, 0); ***/      flush_block_only(s, false);      if (s.strm.avail_out === 0) {        return BS_NEED_MORE;      }      /***/    }  }  s.insert = 0;  if (flush === Z_FINISH) {    /*** FLUSH_BLOCK(s, 1); ***/    flush_block_only(s, true);    if (s.strm.avail_out === 0) {      return BS_FINISH_STARTED;    }    /***/    return BS_FINISH_DONE;  }  if (s.last_lit) {    /*** FLUSH_BLOCK(s, 0); ***/    flush_block_only(s, false);    if (s.strm.avail_out === 0) {      return BS_NEED_MORE;    }    /***/  }  return BS_BLOCK_DONE;}/* Values for max_lazy_match, good_match and max_chain_length, depending on * the desired pack level (0..9). The values given below have been tuned to * exclude worst case performance for pathological files. Better values may be * found for specific files. */function Config(good_length, max_lazy, nice_length, max_chain, func) {  this.good_length = good_length;  this.max_lazy = max_lazy;  this.nice_length = nice_length;  this.max_chain = max_chain;  this.func = func;}var configuration_table;configuration_table = [  /*      good lazy nice chain */  new Config(0, 0, 0, 0, deflate_stored),          /* 0 store only */  new Config(4, 4, 8, 4, deflate_fast),            /* 1 max speed, no lazy matches */  new Config(4, 5, 16, 8, deflate_fast),           /* 2 */  new Config(4, 6, 32, 32, deflate_fast),          /* 3 */  new Config(4, 4, 16, 16, deflate_slow),          /* 4 lazy matches */  new Config(8, 16, 32, 32, deflate_slow),         /* 5 */  new Config(8, 16, 128, 128, deflate_slow),       /* 6 */  new Config(8, 32, 128, 256, deflate_slow),       /* 7 */  new Config(32, 128, 258, 1024, deflate_slow),    /* 8 */  new Config(32, 258, 258, 4096, deflate_slow)     /* 9 max compression */];/* =========================================================================== * Initialize the "longest match" routines for a new zlib stream */function lm_init(s) {  s.window_size = 2 * s.w_size;  /*** CLEAR_HASH(s); ***/  zero(s.head); // Fill with NIL (= 0);  /* Set the default configuration parameters:   */  s.max_lazy_match = configuration_table[s.level].max_lazy;  s.good_match = configuration_table[s.level].good_length;  s.nice_match = configuration_table[s.level].nice_length;  s.max_chain_length = configuration_table[s.level].max_chain;  s.strstart = 0;  s.block_start = 0;  s.lookahead = 0;  s.insert = 0;  s.match_length = s.prev_length = MIN_MATCH - 1;  s.match_available = 0;  s.ins_h = 0;}function DeflateState() {  this.strm = null;            /* pointer back to this zlib stream */  this.status = 0;            /* as the name implies */  this.pending_buf = null;      /* output still pending */  this.pending_buf_size = 0;  /* size of pending_buf */  this.pending_out = 0;       /* next pending byte to output to the stream */  this.pending = 0;           /* nb of bytes in the pending buffer */  this.wrap = 0;              /* bit 0 true for zlib, bit 1 true for gzip */  this.gzhead = null;         /* gzip header information to write */  this.gzindex = 0;           /* where in extra, name, or comment */  this.method = Z_DEFLATED; /* can only be DEFLATED */  this.last_flush = -1;   /* value of flush param for previous deflate call */  this.w_size = 0;  /* LZ77 window size (32K by default) */  this.w_bits = 0;  /* log2(w_size)  (8..16) */  this.w_mask = 0;  /* w_size - 1 */  this.window = null;  /* Sliding window. Input bytes are read into the second half of the window,   * and move to the first half later to keep a dictionary of at least wSize   * bytes. With this organization, matches are limited to a distance of   * wSize-MAX_MATCH bytes, but this ensures that IO is always   * performed with a length multiple of the block size.   */  this.window_size = 0;  /* Actual size of window: 2*wSize, except when the user input buffer   * is directly used as sliding window.   */  this.prev = null;  /* Link to older string with same hash index. To limit the size of this   * array to 64K, this link is maintained only for the last 32K strings.   * An index in this array is thus a window index modulo 32K.   */  this.head = null;   /* Heads of the hash chains or NIL. */  this.ins_h = 0;       /* hash index of string to be inserted */  this.hash_size = 0;   /* number of elements in hash table */  this.hash_bits = 0;   /* log2(hash_size) */  this.hash_mask = 0;   /* hash_size-1 */  this.hash_shift = 0;  /* Number of bits by which ins_h must be shifted at each input   * step. It must be such that after MIN_MATCH steps, the oldest   * byte no longer takes part in the hash key, that is:   *   hash_shift * MIN_MATCH >= hash_bits   */  this.block_start = 0;  /* Window position at the beginning of the current output block. Gets   * negative when the window is moved backwards.   */  this.match_length = 0;      /* length of best match */  this.prev_match = 0;        /* previous match */  this.match_available = 0;   /* set if previous match exists */  this.strstart = 0;          /* start of string to insert */  this.match_start = 0;       /* start of matching string */  this.lookahead = 0;         /* number of valid bytes ahead in window */  this.prev_length = 0;  /* Length of the best match at previous step. Matches not greater than this   * are discarded. This is used in the lazy match evaluation.   */  this.max_chain_length = 0;  /* To speed up deflation, hash chains are never searched beyond this   * length.  A higher limit improves compression ratio but degrades the   * speed.   */  this.max_lazy_match = 0;  /* Attempt to find a better match only when the current match is strictly   * smaller than this value. This mechanism is used only for compression   * levels >= 4.   */  // That's alias to max_lazy_match, don't use directly  //this.max_insert_length = 0;  /* Insert new strings in the hash table only if the match length is not   * greater than this length. This saves time but degrades compression.   * max_insert_length is used only for compression levels <= 3.   */  this.level = 0;     /* compression level (1..9) */  this.strategy = 0;  /* favor or force Huffman coding*/  this.good_match = 0;  /* Use a faster search when the previous match is longer than this */  this.nice_match = 0; /* Stop searching when current match exceeds this */              /* used by trees.c: */  /* Didn't use ct_data typedef below to suppress compiler warning */  // struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */  // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */  // struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */  // Use flat array of DOUBLE size, with interleaved fata,  // because JS does not support effective  this.dyn_ltree  = new utils.Buf16(HEAP_SIZE * 2);  this.dyn_dtree  = new utils.Buf16((2 * D_CODES + 1) * 2);  this.bl_tree    = new utils.Buf16((2 * BL_CODES + 1) * 2);  zero(this.dyn_ltree);  zero(this.dyn_dtree);  zero(this.bl_tree);  this.l_desc   = null;         /* desc. for literal tree */  this.d_desc   = null;         /* desc. for distance tree */  this.bl_desc  = null;         /* desc. for bit length tree */  //ush bl_count[MAX_BITS+1];  this.bl_count = new utils.Buf16(MAX_BITS + 1);  /* number of codes at each bit length for an optimal tree */  //int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */  this.heap = new utils.Buf16(2 * L_CODES + 1);  /* heap used to build the Huffman trees */  zero(this.heap);  this.heap_len = 0;               /* number of elements in the heap */  this.heap_max = 0;               /* element of largest frequency */  /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.   * The same heap array is used to build all trees.   */  this.depth = new utils.Buf16(2 * L_CODES + 1); //uch depth[2*L_CODES+1];  zero(this.depth);  /* Depth of each subtree used as tie breaker for trees of equal frequency   */  this.l_buf = 0;          /* buffer index for literals or lengths */  this.lit_bufsize = 0;  /* Size of match buffer for literals/lengths.  There are 4 reasons for   * limiting lit_bufsize to 64K:   *   - frequencies can be kept in 16 bit counters   *   - if compression is not successful for the first block, all input   *     data is still in the window so we can still emit a stored block even   *     when input comes from standard input.  (This can also be done for   *     all blocks if lit_bufsize is not greater than 32K.)   *   - if compression is not successful for a file smaller than 64K, we can   *     even emit a stored file instead of a stored block (saving 5 bytes).   *     This is applicable only for zip (not gzip or zlib).   *   - creating new Huffman trees less frequently may not provide fast   *     adaptation to changes in the input data statistics. (Take for   *     example a binary file with poorly compressible code followed by   *     a highly compressible string table.) Smaller buffer sizes give   *     fast adaptation but have of course the overhead of transmitting   *     trees more frequently.   *   - I can't count above 4   */  this.last_lit = 0;      /* running index in l_buf */  this.d_buf = 0;  /* Buffer index for distances. To simplify the code, d_buf and l_buf have   * the same number of elements. To use different lengths, an extra flag   * array would be necessary.   */  this.opt_len = 0;       /* bit length of current block with optimal trees */  this.static_len = 0;    /* bit length of current block with static trees */  this.matches = 0;       /* number of string matches in current block */  this.insert = 0;        /* bytes at end of window left to insert */  this.bi_buf = 0;  /* Output buffer. bits are inserted starting at the bottom (least   * significant bits).   */  this.bi_valid = 0;  /* Number of valid bits in bi_buf.  All bits above the last valid bit   * are always zero.   */  // Used for window memory init. We safely ignore it for JS. That makes  // sense only for pointers and memory check tools.  //this.high_water = 0;  /* High water mark offset in window for initialized bytes -- bytes above   * this are set to zero in order to avoid memory check warnings when   * longest match routines access bytes past the input.  This is then   * updated to the new high water mark.   */}function deflateResetKeep(strm) {  var s;  if (!strm || !strm.state) {    return err(strm, Z_STREAM_ERROR);  }  strm.total_in = strm.total_out = 0;  strm.data_type = Z_UNKNOWN;  s = strm.state;  s.pending = 0;  s.pending_out = 0;  if (s.wrap < 0) {    s.wrap = -s.wrap;    /* was made negative by deflate(..., Z_FINISH); */  }  s.status = (s.wrap ? INIT_STATE : BUSY_STATE);  strm.adler = (s.wrap === 2) ?    0  // crc32(0, Z_NULL, 0)  :    1; // adler32(0, Z_NULL, 0)  s.last_flush = Z_NO_FLUSH;  trees._tr_init(s);  return Z_OK;}function deflateReset(strm) {  var ret = deflateResetKeep(strm);  if (ret === Z_OK) {    lm_init(strm.state);  }  return ret;}function deflateSetHeader(strm, head) {  if (!strm || !strm.state) { return Z_STREAM_ERROR; }  if (strm.state.wrap !== 2) { return Z_STREAM_ERROR; }  strm.state.gzhead = head;  return Z_OK;}function deflateInit2(strm, level, method, windowBits, memLevel, strategy) {  if (!strm) { // === Z_NULL    return Z_STREAM_ERROR;  }  var wrap = 1;  if (level === Z_DEFAULT_COMPRESSION) {    level = 6;  }  if (windowBits < 0) { /* suppress zlib wrapper */    wrap = 0;    windowBits = -windowBits;  }  else if (windowBits > 15) {    wrap = 2;           /* write gzip wrapper instead */    windowBits -= 16;  }  if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED ||    windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||    strategy < 0 || strategy > Z_FIXED) {    return err(strm, Z_STREAM_ERROR);  }  if (windowBits === 8) {    windowBits = 9;  }  /* until 256-byte window bug fixed */  var s = new DeflateState();  strm.state = s;  s.strm = strm;  s.wrap = wrap;  s.gzhead = null;  s.w_bits = windowBits;  s.w_size = 1 << s.w_bits;  s.w_mask = s.w_size - 1;  s.hash_bits = memLevel + 7;  s.hash_size = 1 << s.hash_bits;  s.hash_mask = s.hash_size - 1;  s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH);  s.window = new utils.Buf8(s.w_size * 2);  s.head = new utils.Buf16(s.hash_size);  s.prev = new utils.Buf16(s.w_size);  // Don't need mem init magic for JS.  //s.high_water = 0;  /* nothing written to s->window yet */  s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */  s.pending_buf_size = s.lit_bufsize * 4;  //overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);  //s->pending_buf = (uchf *) overlay;  s.pending_buf = new utils.Buf8(s.pending_buf_size);  // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`)  //s->d_buf = overlay + s->lit_bufsize/sizeof(ush);  s.d_buf = 1 * s.lit_bufsize;  //s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;  s.l_buf = (1 + 2) * s.lit_bufsize;  s.level = level;  s.strategy = strategy;  s.method = method;  return deflateReset(strm);}function deflateInit(strm, level) {  return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);}function deflate(strm, flush) {  var old_flush, s;  var beg, val; // for gzip header write only  if (!strm || !strm.state ||    flush > Z_BLOCK || flush < 0) {    return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR;  }  s = strm.state;  if (!strm.output ||      (!strm.input && strm.avail_in !== 0) ||      (s.status === FINISH_STATE && flush !== Z_FINISH)) {    return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR : Z_STREAM_ERROR);  }  s.strm = strm; /* just in case */  old_flush = s.last_flush;  s.last_flush = flush;  /* Write the header */  if (s.status === INIT_STATE) {    if (s.wrap === 2) { // GZIP header      strm.adler = 0;  //crc32(0L, Z_NULL, 0);      put_byte(s, 31);      put_byte(s, 139);      put_byte(s, 8);      if (!s.gzhead) { // s->gzhead == Z_NULL        put_byte(s, 0);        put_byte(s, 0);        put_byte(s, 0);        put_byte(s, 0);        put_byte(s, 0);        put_byte(s, s.level === 9 ? 2 :                    (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?                     4 : 0));        put_byte(s, OS_CODE);        s.status = BUSY_STATE;      }      else {        put_byte(s, (s.gzhead.text ? 1 : 0) +                    (s.gzhead.hcrc ? 2 : 0) +                    (!s.gzhead.extra ? 0 : 4) +                    (!s.gzhead.name ? 0 : 8) +                    (!s.gzhead.comment ? 0 : 16)                );        put_byte(s, s.gzhead.time & 0xff);        put_byte(s, (s.gzhead.time >> 8) & 0xff);        put_byte(s, (s.gzhead.time >> 16) & 0xff);        put_byte(s, (s.gzhead.time >> 24) & 0xff);        put_byte(s, s.level === 9 ? 2 :                    (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?                     4 : 0));        put_byte(s, s.gzhead.os & 0xff);        if (s.gzhead.extra && s.gzhead.extra.length) {          put_byte(s, s.gzhead.extra.length & 0xff);          put_byte(s, (s.gzhead.extra.length >> 8) & 0xff);        }        if (s.gzhead.hcrc) {          strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0);        }        s.gzindex = 0;        s.status = EXTRA_STATE;      }    }    else // DEFLATE header    {      var header = (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8;      var level_flags = -1;      if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) {        level_flags = 0;      } else if (s.level < 6) {        level_flags = 1;      } else if (s.level === 6) {        level_flags = 2;      } else {        level_flags = 3;      }      header |= (level_flags << 6);      if (s.strstart !== 0) { header |= PRESET_DICT; }      header += 31 - (header % 31);      s.status = BUSY_STATE;      putShortMSB(s, header);      /* Save the adler32 of the preset dictionary: */      if (s.strstart !== 0) {        putShortMSB(s, strm.adler >>> 16);        putShortMSB(s, strm.adler & 0xffff);      }      strm.adler = 1; // adler32(0L, Z_NULL, 0);    }  }//#ifdef GZIP  if (s.status === EXTRA_STATE) {    if (s.gzhead.extra/* != Z_NULL*/) {      beg = s.pending;  /* start of bytes to update crc */      while (s.gzindex < (s.gzhead.extra.length & 0xffff)) {        if (s.pending === s.pending_buf_size) {          if (s.gzhead.hcrc && s.pending > beg) {            strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);          }          flush_pending(strm);          beg = s.pending;          if (s.pending === s.pending_buf_size) {            break;          }        }        put_byte(s, s.gzhead.extra[s.gzindex] & 0xff);        s.gzindex++;      }      if (s.gzhead.hcrc && s.pending > beg) {        strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);      }      if (s.gzindex === s.gzhead.extra.length) {        s.gzindex = 0;        s.status = NAME_STATE;      }    }    else {      s.status = NAME_STATE;    }  }  if (s.status === NAME_STATE) {    if (s.gzhead.name/* != Z_NULL*/) {      beg = s.pending;  /* start of bytes to update crc */      //int val;      do {        if (s.pending === s.pending_buf_size) {          if (s.gzhead.hcrc && s.pending > beg) {            strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);          }          flush_pending(strm);          beg = s.pending;          if (s.pending === s.pending_buf_size) {            val = 1;            break;          }        }        // JS specific: little magic to add zero terminator to end of string        if (s.gzindex < s.gzhead.name.length) {          val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff;        } else {          val = 0;        }        put_byte(s, val);      } while (val !== 0);      if (s.gzhead.hcrc && s.pending > beg) {        strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);      }      if (val === 0) {        s.gzindex = 0;        s.status = COMMENT_STATE;      }    }    else {      s.status = COMMENT_STATE;    }  }  if (s.status === COMMENT_STATE) {    if (s.gzhead.comment/* != Z_NULL*/) {      beg = s.pending;  /* start of bytes to update crc */      //int val;      do {        if (s.pending === s.pending_buf_size) {          if (s.gzhead.hcrc && s.pending > beg) {            strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);          }          flush_pending(strm);          beg = s.pending;          if (s.pending === s.pending_buf_size) {            val = 1;            break;          }        }        // JS specific: little magic to add zero terminator to end of string        if (s.gzindex < s.gzhead.comment.length) {          val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff;        } else {          val = 0;        }        put_byte(s, val);      } while (val !== 0);      if (s.gzhead.hcrc && s.pending > beg) {        strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);      }      if (val === 0) {        s.status = HCRC_STATE;      }    }    else {      s.status = HCRC_STATE;    }  }  if (s.status === HCRC_STATE) {    if (s.gzhead.hcrc) {      if (s.pending + 2 > s.pending_buf_size) {        flush_pending(strm);      }      if (s.pending + 2 <= s.pending_buf_size) {        put_byte(s, strm.adler & 0xff);        put_byte(s, (strm.adler >> 8) & 0xff);        strm.adler = 0; //crc32(0L, Z_NULL, 0);        s.status = BUSY_STATE;      }    }    else {      s.status = BUSY_STATE;    }  }//#endif  /* Flush as much pending output as possible */  if (s.pending !== 0) {    flush_pending(strm);    if (strm.avail_out === 0) {      /* Since avail_out is 0, deflate will be called again with       * more output space, but possibly with both pending and       * avail_in equal to zero. There won't be anything to do,       * but this is not an error situation so make sure we       * return OK instead of BUF_ERROR at next call of deflate:       */      s.last_flush = -1;      return Z_OK;    }    /* Make sure there is something to do and avoid duplicate consecutive     * flushes. For repeated and useless calls with Z_FINISH, we keep     * returning Z_STREAM_END instead of Z_BUF_ERROR.     */  } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) &&    flush !== Z_FINISH) {    return err(strm, Z_BUF_ERROR);  }  /* User must not provide more input after the first FINISH: */  if (s.status === FINISH_STATE && strm.avail_in !== 0) {    return err(strm, Z_BUF_ERROR);  }  /* Start a new block or continue the current one.   */  if (strm.avail_in !== 0 || s.lookahead !== 0 ||    (flush !== Z_NO_FLUSH && s.status !== FINISH_STATE)) {    var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) :      (s.strategy === Z_RLE ? deflate_rle(s, flush) :        configuration_table[s.level].func(s, flush));    if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) {      s.status = FINISH_STATE;    }    if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) {      if (strm.avail_out === 0) {        s.last_flush = -1;        /* avoid BUF_ERROR next call, see above */      }      return Z_OK;      /* If flush != Z_NO_FLUSH && avail_out == 0, the next call       * of deflate should use the same flush parameter to make sure       * that the flush is complete. So we don't have to output an       * empty block here, this will be done at next call. This also       * ensures that for a very small output buffer, we emit at most       * one empty block.       */    }    if (bstate === BS_BLOCK_DONE) {      if (flush === Z_PARTIAL_FLUSH) {        trees._tr_align(s);      }      else if (flush !== Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */        trees._tr_stored_block(s, 0, 0, false);        /* For a full flush, this empty block will be recognized         * as a special marker by inflate_sync().         */        if (flush === Z_FULL_FLUSH) {          /*** CLEAR_HASH(s); ***/             /* forget history */          zero(s.head); // Fill with NIL (= 0);          if (s.lookahead === 0) {            s.strstart = 0;            s.block_start = 0;            s.insert = 0;          }        }      }      flush_pending(strm);      if (strm.avail_out === 0) {        s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */        return Z_OK;      }    }  }  //Assert(strm->avail_out > 0, "bug2");  //if (strm.avail_out <= 0) { throw new Error("bug2");}  if (flush !== Z_FINISH) { return Z_OK; }  if (s.wrap <= 0) { return Z_STREAM_END; }  /* Write the trailer */  if (s.wrap === 2) {    put_byte(s, strm.adler & 0xff);    put_byte(s, (strm.adler >> 8) & 0xff);    put_byte(s, (strm.adler >> 16) & 0xff);    put_byte(s, (strm.adler >> 24) & 0xff);    put_byte(s, strm.total_in & 0xff);    put_byte(s, (strm.total_in >> 8) & 0xff);    put_byte(s, (strm.total_in >> 16) & 0xff);    put_byte(s, (strm.total_in >> 24) & 0xff);  }  else  {    putShortMSB(s, strm.adler >>> 16);    putShortMSB(s, strm.adler & 0xffff);  }  flush_pending(strm);  /* If avail_out is zero, the application will call deflate again   * to flush the rest.   */  if (s.wrap > 0) { s.wrap = -s.wrap; }  /* write the trailer only once! */  return s.pending !== 0 ? Z_OK : Z_STREAM_END;}function deflateEnd(strm) {  var status;  if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) {    return Z_STREAM_ERROR;  }  status = strm.state.status;  if (status !== INIT_STATE &&    status !== EXTRA_STATE &&    status !== NAME_STATE &&    status !== COMMENT_STATE &&    status !== HCRC_STATE &&    status !== BUSY_STATE &&    status !== FINISH_STATE  ) {    return err(strm, Z_STREAM_ERROR);  }  strm.state = null;  return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK;}/* ========================================================================= * Initializes the compression dictionary from the given byte * sequence without producing any compressed output. */function deflateSetDictionary(strm, dictionary) {  var dictLength = dictionary.length;  var s;  var str, n;  var wrap;  var avail;  var next;  var input;  var tmpDict;  if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) {    return Z_STREAM_ERROR;  }  s = strm.state;  wrap = s.wrap;  if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) {    return Z_STREAM_ERROR;  }  /* when using zlib wrappers, compute Adler-32 for provided dictionary */  if (wrap === 1) {    /* adler32(strm->adler, dictionary, dictLength); */    strm.adler = adler32(strm.adler, dictionary, dictLength, 0);  }  s.wrap = 0;   /* avoid computing Adler-32 in read_buf */  /* if dictionary would fill window, just replace the history */  if (dictLength >= s.w_size) {    if (wrap === 0) {            /* already empty otherwise */      /*** CLEAR_HASH(s); ***/      zero(s.head); // Fill with NIL (= 0);      s.strstart = 0;      s.block_start = 0;      s.insert = 0;    }    /* use the tail */    // dictionary = dictionary.slice(dictLength - s.w_size);    tmpDict = new utils.Buf8(s.w_size);    utils.arraySet(tmpDict, dictionary, dictLength - s.w_size, s.w_size, 0);    dictionary = tmpDict;    dictLength = s.w_size;  }  /* insert dictionary into window and hash */  avail = strm.avail_in;  next = strm.next_in;  input = strm.input;  strm.avail_in = dictLength;  strm.next_in = 0;  strm.input = dictionary;  fill_window(s);  while (s.lookahead >= MIN_MATCH) {    str = s.strstart;    n = s.lookahead - (MIN_MATCH - 1);    do {      /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */      s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;      s.prev[str & s.w_mask] = s.head[s.ins_h];      s.head[s.ins_h] = str;      str++;    } while (--n);    s.strstart = str;    s.lookahead = MIN_MATCH - 1;    fill_window(s);  }  s.strstart += s.lookahead;  s.block_start = s.strstart;  s.insert = s.lookahead;  s.lookahead = 0;  s.match_length = s.prev_length = MIN_MATCH - 1;  s.match_available = 0;  strm.next_in = next;  strm.input = input;  strm.avail_in = avail;  s.wrap = wrap;  return Z_OK;}exports.deflateInit = deflateInit;exports.deflateInit2 = deflateInit2;exports.deflateReset = deflateReset;exports.deflateResetKeep = deflateResetKeep;exports.deflateSetHeader = deflateSetHeader;exports.deflate = deflate;exports.deflateEnd = deflateEnd;exports.deflateSetDictionary = deflateSetDictionary;exports.deflateInfo = 'pako deflate (from Nodeca project)';/* Not implementedexports.deflateBound = deflateBound;exports.deflateCopy = deflateCopy;exports.deflateParams = deflateParams;exports.deflatePending = deflatePending;exports.deflatePrime = deflatePrime;exports.deflateTune = deflateTune;*/},{"../utils/common":202,"./adler32":204,"./crc32":206,"./messages":212,"./trees":213}],208:[function(require,module,exports){'use strict';// (C) 1995-2013 Jean-loup Gailly and Mark Adler// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin//// This software is provided 'as-is', without any express or implied// warranty. In no event will the authors be held liable for any damages// arising from the use of this software.//// Permission is granted to anyone to use this software for any purpose,// including commercial applications, and to alter it and redistribute it// freely, subject to the following restrictions://// 1. The origin of this software must not be misrepresented; you must not//   claim that you wrote the original software. If you use this software//   in a product, an acknowledgment in the product documentation would be//   appreciated but is not required.// 2. Altered source versions must be plainly marked as such, and must not be//   misrepresented as being the original software.// 3. This notice may not be removed or altered from any source distribution.function GZheader() {  /* true if compressed data believed to be text */  this.text       = 0;  /* modification time */  this.time       = 0;  /* extra flags (not used when writing a gzip file) */  this.xflags     = 0;  /* operating system */  this.os         = 0;  /* pointer to extra field or Z_NULL if none */  this.extra      = null;  /* extra field length (valid if extra != Z_NULL) */  this.extra_len  = 0; // Actually, we don't need it in JS,                       // but leave for few code modifications  //  // Setup limits is not necessary because in js we should not preallocate memory  // for inflate use constant limit in 65536 bytes  //  /* space at extra (only when reading header) */  // this.extra_max  = 0;  /* pointer to zero-terminated file name or Z_NULL */  this.name       = '';  /* space at name (only when reading header) */  // this.name_max   = 0;  /* pointer to zero-terminated comment or Z_NULL */  this.comment    = '';  /* space at comment (only when reading header) */  // this.comm_max   = 0;  /* true if there was or will be a header crc */  this.hcrc       = 0;  /* true when done reading gzip header (not used when writing a gzip file) */  this.done       = false;}module.exports = GZheader;},{}],209:[function(require,module,exports){'use strict';// (C) 1995-2013 Jean-loup Gailly and Mark Adler// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin//// This software is provided 'as-is', without any express or implied// warranty. In no event will the authors be held liable for any damages// arising from the use of this software.//// Permission is granted to anyone to use this software for any purpose,// including commercial applications, and to alter it and redistribute it// freely, subject to the following restrictions://// 1. The origin of this software must not be misrepresented; you must not//   claim that you wrote the original software. If you use this software//   in a product, an acknowledgment in the product documentation would be//   appreciated but is not required.// 2. Altered source versions must be plainly marked as such, and must not be//   misrepresented as being the original software.// 3. This notice may not be removed or altered from any source distribution.// See state defs from inflate.jsvar BAD = 30;       /* got a data error -- remain here until reset */var TYPE = 12;      /* i: waiting for type bits, including last-flag bit *//*   Decode literal, length, and distance codes and write out the resulting   literal and match bytes until either not enough input or output is   available, an end-of-block is encountered, or a data error is encountered.   When large enough input and output buffers are supplied to inflate(), for   example, a 16K input buffer and a 64K output buffer, more than 95% of the   inflate execution time is spent in this routine.   Entry assumptions:        state.mode === LEN        strm.avail_in >= 6        strm.avail_out >= 258        start >= strm.avail_out        state.bits < 8   On return, state.mode is one of:        LEN -- ran out of enough output space or enough available input        TYPE -- reached end of block code, inflate() to interpret next block        BAD -- error in block data   Notes:    - The maximum input bits used by a length/distance pair is 15 bits for the      length code, 5 bits for the length extra, 15 bits for the distance code,      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.      Therefore if strm.avail_in >= 6, then there is enough input to avoid      checking for available input while decoding.    - The maximum bytes that a single length/distance pair can output is 258      bytes, which is the maximum length that can be coded.  inflate_fast()      requires strm.avail_out >= 258 for each loop to avoid checking for      output space. */module.exports = function inflate_fast(strm, start) {  var state;  var _in;                    /* local strm.input */  var last;                   /* have enough input while in < last */  var _out;                   /* local strm.output */  var beg;                    /* inflate()'s initial strm.output */  var end;                    /* while out < end, enough space available *///#ifdef INFLATE_STRICT  var dmax;                   /* maximum distance from zlib header *///#endif  var wsize;                  /* window size or zero if not using window */  var whave;                  /* valid bytes in the window */  var wnext;                  /* window write index */  // Use `s_window` instead `window`, avoid conflict with instrumentation tools  var s_window;               /* allocated sliding window, if wsize != 0 */  var hold;                   /* local strm.hold */  var bits;                   /* local strm.bits */  var lcode;                  /* local strm.lencode */  var dcode;                  /* local strm.distcode */  var lmask;                  /* mask for first level of length codes */  var dmask;                  /* mask for first level of distance codes */  var here;                   /* retrieved table entry */  var op;                     /* code bits, operation, extra bits, or */                              /*  window position, window bytes to copy */  var len;                    /* match length, unused bytes */  var dist;                   /* match distance */  var from;                   /* where to copy match from */  var from_source;  var input, output; // JS specific, because we have no pointers  /* copy state to local variables */  state = strm.state;  //here = state.here;  _in = strm.next_in;  input = strm.input;  last = _in + (strm.avail_in - 5);  _out = strm.next_out;  output = strm.output;  beg = _out - (start - strm.avail_out);  end = _out + (strm.avail_out - 257);//#ifdef INFLATE_STRICT  dmax = state.dmax;//#endif  wsize = state.wsize;  whave = state.whave;  wnext = state.wnext;  s_window = state.window;  hold = state.hold;  bits = state.bits;  lcode = state.lencode;  dcode = state.distcode;  lmask = (1 << state.lenbits) - 1;  dmask = (1 << state.distbits) - 1;  /* decode literals and length/distances until end-of-block or not enough     input data or output space */  top:  do {    if (bits < 15) {      hold += input[_in++] << bits;      bits += 8;      hold += input[_in++] << bits;      bits += 8;    }    here = lcode[hold & lmask];    dolen:    for (;;) { // Goto emulation      op = here >>> 24/*here.bits*/;      hold >>>= op;      bits -= op;      op = (here >>> 16) & 0xff/*here.op*/;      if (op === 0) {                          /* literal */        //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?        //        "inflate:         literal '%c'\n" :        //        "inflate:         literal 0x%02x\n", here.val));        output[_out++] = here & 0xffff/*here.val*/;      }      else if (op & 16) {                     /* length base */        len = here & 0xffff/*here.val*/;        op &= 15;                           /* number of extra bits */        if (op) {          if (bits < op) {            hold += input[_in++] << bits;            bits += 8;          }          len += hold & ((1 << op) - 1);          hold >>>= op;          bits -= op;        }        //Tracevv((stderr, "inflate:         length %u\n", len));        if (bits < 15) {          hold += input[_in++] << bits;          bits += 8;          hold += input[_in++] << bits;          bits += 8;        }        here = dcode[hold & dmask];        dodist:        for (;;) { // goto emulation          op = here >>> 24/*here.bits*/;          hold >>>= op;          bits -= op;          op = (here >>> 16) & 0xff/*here.op*/;          if (op & 16) {                      /* distance base */            dist = here & 0xffff/*here.val*/;            op &= 15;                       /* number of extra bits */            if (bits < op) {              hold += input[_in++] << bits;              bits += 8;              if (bits < op) {                hold += input[_in++] << bits;                bits += 8;              }            }            dist += hold & ((1 << op) - 1);//#ifdef INFLATE_STRICT            if (dist > dmax) {              strm.msg = 'invalid distance too far back';              state.mode = BAD;              break top;            }//#endif            hold >>>= op;            bits -= op;            //Tracevv((stderr, "inflate:         distance %u\n", dist));            op = _out - beg;                /* max distance in output */            if (dist > op) {                /* see if copy from window */              op = dist - op;               /* distance back in window */              if (op > whave) {                if (state.sane) {                  strm.msg = 'invalid distance too far back';                  state.mode = BAD;                  break top;                }// (!) This block is disabled in zlib defaults,// don't enable it for binary compatibility//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR//                if (len <= op - whave) {//                  do {//                    output[_out++] = 0;//                  } while (--len);//                  continue top;//                }//                len -= op - whave;//                do {//                  output[_out++] = 0;//                } while (--op > whave);//                if (op === 0) {//                  from = _out - dist;//                  do {//                    output[_out++] = output[from++];//                  } while (--len);//                  continue top;//                }//#endif              }              from = 0; // window index              from_source = s_window;              if (wnext === 0) {           /* very common case */                from += wsize - op;                if (op < len) {         /* some from window */                  len -= op;                  do {                    output[_out++] = s_window[from++];                  } while (--op);                  from = _out - dist;  /* rest from output */                  from_source = output;                }              }              else if (wnext < op) {      /* wrap around window */                from += wsize + wnext - op;                op -= wnext;                if (op < len) {         /* some from end of window */                  len -= op;                  do {                    output[_out++] = s_window[from++];                  } while (--op);                  from = 0;                  if (wnext < len) {  /* some from start of window */                    op = wnext;                    len -= op;                    do {                      output[_out++] = s_window[from++];                    } while (--op);                    from = _out - dist;      /* rest from output */                    from_source = output;                  }                }              }              else {                      /* contiguous in window */                from += wnext - op;                if (op < len) {         /* some from window */                  len -= op;                  do {                    output[_out++] = s_window[from++];                  } while (--op);                  from = _out - dist;  /* rest from output */                  from_source = output;                }              }              while (len > 2) {                output[_out++] = from_source[from++];                output[_out++] = from_source[from++];                output[_out++] = from_source[from++];                len -= 3;              }              if (len) {                output[_out++] = from_source[from++];                if (len > 1) {                  output[_out++] = from_source[from++];                }              }            }            else {              from = _out - dist;          /* copy direct from output */              do {                        /* minimum length is three */                output[_out++] = output[from++];                output[_out++] = output[from++];                output[_out++] = output[from++];                len -= 3;              } while (len > 2);              if (len) {                output[_out++] = output[from++];                if (len > 1) {                  output[_out++] = output[from++];                }              }            }          }          else if ((op & 64) === 0) {          /* 2nd level distance code */            here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];            continue dodist;          }          else {            strm.msg = 'invalid distance code';            state.mode = BAD;            break top;          }          break; // need to emulate goto via "continue"        }      }      else if ((op & 64) === 0) {              /* 2nd level length code */        here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))];        continue dolen;      }      else if (op & 32) {                     /* end-of-block */        //Tracevv((stderr, "inflate:         end of block\n"));        state.mode = TYPE;        break top;      }      else {        strm.msg = 'invalid literal/length code';        state.mode = BAD;        break top;      }      break; // need to emulate goto via "continue"    }  } while (_in < last && _out < end);  /* return unused bytes (on entry, bits < 8, so in won't go too far back) */  len = bits >> 3;  _in -= len;  bits -= len << 3;  hold &= (1 << bits) - 1;  /* update state and return */  strm.next_in = _in;  strm.next_out = _out;  strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last));  strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end));  state.hold = hold;  state.bits = bits;  return;};},{}],210:[function(require,module,exports){'use strict';// (C) 1995-2013 Jean-loup Gailly and Mark Adler// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin//// This software is provided 'as-is', without any express or implied// warranty. In no event will the authors be held liable for any damages// arising from the use of this software.//// Permission is granted to anyone to use this software for any purpose,// including commercial applications, and to alter it and redistribute it// freely, subject to the following restrictions://// 1. The origin of this software must not be misrepresented; you must not//   claim that you wrote the original software. If you use this software//   in a product, an acknowledgment in the product documentation would be//   appreciated but is not required.// 2. Altered source versions must be plainly marked as such, and must not be//   misrepresented as being the original software.// 3. This notice may not be removed or altered from any source distribution.var utils         = require('../utils/common');var adler32       = require('./adler32');var crc32         = require('./crc32');var inflate_fast  = require('./inffast');var inflate_table = require('./inftrees');var CODES = 0;var LENS = 1;var DISTS = 2;/* Public constants ==========================================================*//* ===========================================================================*//* Allowed flush values; see deflate() and inflate() below for details *///var Z_NO_FLUSH      = 0;//var Z_PARTIAL_FLUSH = 1;//var Z_SYNC_FLUSH    = 2;//var Z_FULL_FLUSH    = 3;var Z_FINISH        = 4;var Z_BLOCK         = 5;var Z_TREES         = 6;/* Return codes for the compression/decompression functions. Negative values * are errors, positive values are used for special but normal events. */var Z_OK            = 0;var Z_STREAM_END    = 1;var Z_NEED_DICT     = 2;//var Z_ERRNO         = -1;var Z_STREAM_ERROR  = -2;var Z_DATA_ERROR    = -3;var Z_MEM_ERROR     = -4;var Z_BUF_ERROR     = -5;//var Z_VERSION_ERROR = -6;/* The deflate compression method */var Z_DEFLATED  = 8;/* STATES ====================================================================*//* ===========================================================================*/var    HEAD = 1;       /* i: waiting for magic header */var    FLAGS = 2;      /* i: waiting for method and flags (gzip) */var    TIME = 3;       /* i: waiting for modification time (gzip) */var    OS = 4;         /* i: waiting for extra flags and operating system (gzip) */var    EXLEN = 5;      /* i: waiting for extra length (gzip) */var    EXTRA = 6;      /* i: waiting for extra bytes (gzip) */var    NAME = 7;       /* i: waiting for end of file name (gzip) */var    COMMENT = 8;    /* i: waiting for end of comment (gzip) */var    HCRC = 9;       /* i: waiting for header crc (gzip) */var    DICTID = 10;    /* i: waiting for dictionary check value */var    DICT = 11;      /* waiting for inflateSetDictionary() call */var        TYPE = 12;      /* i: waiting for type bits, including last-flag bit */var        TYPEDO = 13;    /* i: same, but skip check to exit inflate on new block */var        STORED = 14;    /* i: waiting for stored size (length and complement) */var        COPY_ = 15;     /* i/o: same as COPY below, but only first time in */var        COPY = 16;      /* i/o: waiting for input or output to copy stored block */var        TABLE = 17;     /* i: waiting for dynamic block table lengths */var        LENLENS = 18;   /* i: waiting for code length code lengths */var        CODELENS = 19;  /* i: waiting for length/lit and distance code lengths */var            LEN_ = 20;      /* i: same as LEN below, but only first time in */var            LEN = 21;       /* i: waiting for length/lit/eob code */var            LENEXT = 22;    /* i: waiting for length extra bits */var            DIST = 23;      /* i: waiting for distance code */var            DISTEXT = 24;   /* i: waiting for distance extra bits */var            MATCH = 25;     /* o: waiting for output space to copy string */var            LIT = 26;       /* o: waiting for output space to write literal */var    CHECK = 27;     /* i: waiting for 32-bit check value */var    LENGTH = 28;    /* i: waiting for 32-bit length (gzip) */var    DONE = 29;      /* finished check, done -- remain here until reset */var    BAD = 30;       /* got a data error -- remain here until reset */var    MEM = 31;       /* got an inflate() memory error -- remain here until reset */var    SYNC = 32;      /* looking for synchronization bytes to restart inflate() *//* ===========================================================================*/var ENOUGH_LENS = 852;var ENOUGH_DISTS = 592;//var ENOUGH =  (ENOUGH_LENS+ENOUGH_DISTS);var MAX_WBITS = 15;/* 32K LZ77 window */var DEF_WBITS = MAX_WBITS;function zswap32(q) {  return  (((q >>> 24) & 0xff) +          ((q >>> 8) & 0xff00) +          ((q & 0xff00) << 8) +          ((q & 0xff) << 24));}function InflateState() {  this.mode = 0;             /* current inflate mode */  this.last = false;          /* true if processing last block */  this.wrap = 0;              /* bit 0 true for zlib, bit 1 true for gzip */  this.havedict = false;      /* true if dictionary provided */  this.flags = 0;             /* gzip header method and flags (0 if zlib) */  this.dmax = 0;              /* zlib header max distance (INFLATE_STRICT) */  this.check = 0;             /* protected copy of check value */  this.total = 0;             /* protected copy of output count */  // TODO: may be {}  this.head = null;           /* where to save gzip header information */  /* sliding window */  this.wbits = 0;             /* log base 2 of requested window size */  this.wsize = 0;             /* window size or zero if not using window */  this.whave = 0;             /* valid bytes in the window */  this.wnext = 0;             /* window write index */  this.window = null;         /* allocated sliding window, if needed */  /* bit accumulator */  this.hold = 0;              /* input bit accumulator */  this.bits = 0;              /* number of bits in "in" */  /* for string and stored block copying */  this.length = 0;            /* literal or length of data to copy */  this.offset = 0;            /* distance back to copy string from */  /* for table and code decoding */  this.extra = 0;             /* extra bits needed */  /* fixed and dynamic code tables */  this.lencode = null;          /* starting table for length/literal codes */  this.distcode = null;         /* starting table for distance codes */  this.lenbits = 0;           /* index bits for lencode */  this.distbits = 0;          /* index bits for distcode */  /* dynamic table building */  this.ncode = 0;             /* number of code length code lengths */  this.nlen = 0;              /* number of length code lengths */  this.ndist = 0;             /* number of distance code lengths */  this.have = 0;              /* number of code lengths in lens[] */  this.next = null;              /* next available space in codes[] */  this.lens = new utils.Buf16(320); /* temporary storage for code lengths */  this.work = new utils.Buf16(288); /* work area for code table building */  /*   because we don't have pointers in js, we use lencode and distcode directly   as buffers so we don't need codes  */  //this.codes = new utils.Buf32(ENOUGH);       /* space for code tables */  this.lendyn = null;              /* dynamic table for length/literal codes (JS specific) */  this.distdyn = null;             /* dynamic table for distance codes (JS specific) */  this.sane = 0;                   /* if false, allow invalid distance too far */  this.back = 0;                   /* bits back of last unprocessed length/lit */  this.was = 0;                    /* initial length of match */}function inflateResetKeep(strm) {  var state;  if (!strm || !strm.state) { return Z_STREAM_ERROR; }  state = strm.state;  strm.total_in = strm.total_out = state.total = 0;  strm.msg = ''; /*Z_NULL*/  if (state.wrap) {       /* to support ill-conceived Java test suite */    strm.adler = state.wrap & 1;  }  state.mode = HEAD;  state.last = 0;  state.havedict = 0;  state.dmax = 32768;  state.head = null/*Z_NULL*/;  state.hold = 0;  state.bits = 0;  //state.lencode = state.distcode = state.next = state.codes;  state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS);  state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS);  state.sane = 1;  state.back = -1;  //Tracev((stderr, "inflate: reset\n"));  return Z_OK;}function inflateReset(strm) {  var state;  if (!strm || !strm.state) { return Z_STREAM_ERROR; }  state = strm.state;  state.wsize = 0;  state.whave = 0;  state.wnext = 0;  return inflateResetKeep(strm);}function inflateReset2(strm, windowBits) {  var wrap;  var state;  /* get the state */  if (!strm || !strm.state) { return Z_STREAM_ERROR; }  state = strm.state;  /* extract wrap request from windowBits parameter */  if (windowBits < 0) {    wrap = 0;    windowBits = -windowBits;  }  else {    wrap = (windowBits >> 4) + 1;    if (windowBits < 48) {      windowBits &= 15;    }  }  /* set number of window bits, free window if different */  if (windowBits && (windowBits < 8 || windowBits > 15)) {    return Z_STREAM_ERROR;  }  if (state.window !== null && state.wbits !== windowBits) {    state.window = null;  }  /* update state and reset the rest of it */  state.wrap = wrap;  state.wbits = windowBits;  return inflateReset(strm);}function inflateInit2(strm, windowBits) {  var ret;  var state;  if (!strm) { return Z_STREAM_ERROR; }  //strm.msg = Z_NULL;                 /* in case we return an error */  state = new InflateState();  //if (state === Z_NULL) return Z_MEM_ERROR;  //Tracev((stderr, "inflate: allocated\n"));  strm.state = state;  state.window = null/*Z_NULL*/;  ret = inflateReset2(strm, windowBits);  if (ret !== Z_OK) {    strm.state = null/*Z_NULL*/;  }  return ret;}function inflateInit(strm) {  return inflateInit2(strm, DEF_WBITS);}/* Return state with length and distance decoding tables and index sizes set to fixed code decoding.  Normally this returns fixed tables from inffixed.h. If BUILDFIXED is defined, then instead this routine builds the tables the first time it's called, and returns those tables the first time and thereafter.  This reduces the size of the code by about 2K bytes, in exchange for a little execution time.  However, BUILDFIXED should not be used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */var virgin = true;var lenfix, distfix; // We have no pointers in JS, so keep tables separatefunction fixedtables(state) {  /* build fixed huffman tables if first call (may not be thread safe) */  if (virgin) {    var sym;    lenfix = new utils.Buf32(512);    distfix = new utils.Buf32(32);    /* literal/length table */    sym = 0;    while (sym < 144) { state.lens[sym++] = 8; }    while (sym < 256) { state.lens[sym++] = 9; }    while (sym < 280) { state.lens[sym++] = 7; }    while (sym < 288) { state.lens[sym++] = 8; }    inflate_table(LENS,  state.lens, 0, 288, lenfix,   0, state.work, { bits: 9 });    /* distance table */    sym = 0;    while (sym < 32) { state.lens[sym++] = 5; }    inflate_table(DISTS, state.lens, 0, 32,   distfix, 0, state.work, { bits: 5 });    /* do this just once */    virgin = false;  }  state.lencode = lenfix;  state.lenbits = 9;  state.distcode = distfix;  state.distbits = 5;}/* Update the window with the last wsize (normally 32K) bytes written before returning.  If window does not exist yet, create it.  This is only called when a window is already in use, or when output has been written during this inflate call, but the end of the deflate stream has not been reached yet. It is also called to create a window for dictionary data when a dictionary is loaded. Providing output buffers larger than 32K to inflate() should provide a speed advantage, since only the last 32K of output is copied to the sliding window upon return from inflate(), and since all distances after the first 32K of output will fall in the output data, making match copies simpler and faster. The advantage may be dependent on the size of the processor's data caches. */function updatewindow(strm, src, end, copy) {  var dist;  var state = strm.state;  /* if it hasn't been done already, allocate space for the window */  if (state.window === null) {    state.wsize = 1 << state.wbits;    state.wnext = 0;    state.whave = 0;    state.window = new utils.Buf8(state.wsize);  }  /* copy state->wsize or less output bytes into the circular window */  if (copy >= state.wsize) {    utils.arraySet(state.window, src, end - state.wsize, state.wsize, 0);    state.wnext = 0;    state.whave = state.wsize;  }  else {    dist = state.wsize - state.wnext;    if (dist > copy) {      dist = copy;    }    //zmemcpy(state->window + state->wnext, end - copy, dist);    utils.arraySet(state.window, src, end - copy, dist, state.wnext);    copy -= dist;    if (copy) {      //zmemcpy(state->window, end - copy, copy);      utils.arraySet(state.window, src, end - copy, copy, 0);      state.wnext = copy;      state.whave = state.wsize;    }    else {      state.wnext += dist;      if (state.wnext === state.wsize) { state.wnext = 0; }      if (state.whave < state.wsize) { state.whave += dist; }    }  }  return 0;}function inflate(strm, flush) {  var state;  var input, output;          // input/output buffers  var next;                   /* next input INDEX */  var put;                    /* next output INDEX */  var have, left;             /* available input and output */  var hold;                   /* bit buffer */  var bits;                   /* bits in bit buffer */  var _in, _out;              /* save starting available input and output */  var copy;                   /* number of stored or match bytes to copy */  var from;                   /* where to copy match bytes from */  var from_source;  var here = 0;               /* current decoding table entry */  var here_bits, here_op, here_val; // paked "here" denormalized (JS specific)  //var last;                   /* parent table entry */  var last_bits, last_op, last_val; // paked "last" denormalized (JS specific)  var len;                    /* length to copy for repeats, bits to drop */  var ret;                    /* return code */  var hbuf = new utils.Buf8(4);    /* buffer for gzip header crc calculation */  var opts;  var n; // temporary var for NEED_BITS  var order = /* permutation of code lengths */    [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];  if (!strm || !strm.state || !strm.output ||      (!strm.input && strm.avail_in !== 0)) {    return Z_STREAM_ERROR;  }  state = strm.state;  if (state.mode === TYPE) { state.mode = TYPEDO; }    /* skip check */  //--- LOAD() ---  put = strm.next_out;  output = strm.output;  left = strm.avail_out;  next = strm.next_in;  input = strm.input;  have = strm.avail_in;  hold = state.hold;  bits = state.bits;  //---  _in = have;  _out = left;  ret = Z_OK;  inf_leave: // goto emulation  for (;;) {    switch (state.mode) {      case HEAD:        if (state.wrap === 0) {          state.mode = TYPEDO;          break;        }        //=== NEEDBITS(16);        while (bits < 16) {          if (have === 0) { break inf_leave; }          have--;          hold += input[next++] << bits;          bits += 8;        }        //===//        if ((state.wrap & 2) && hold === 0x8b1f) {  /* gzip header */          state.check = 0/*crc32(0L, Z_NULL, 0)*/;          //=== CRC2(state.check, hold);          hbuf[0] = hold & 0xff;          hbuf[1] = (hold >>> 8) & 0xff;          state.check = crc32(state.check, hbuf, 2, 0);          //===//          //=== INITBITS();          hold = 0;          bits = 0;          //===//          state.mode = FLAGS;          break;        }        state.flags = 0;           /* expect zlib header */        if (state.head) {          state.head.done = false;        }        if (!(state.wrap & 1) ||   /* check if zlib header allowed */          (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) {          strm.msg = 'incorrect header check';          state.mode = BAD;          break;        }        if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) {          strm.msg = 'unknown compression method';          state.mode = BAD;          break;        }        //--- DROPBITS(4) ---//        hold >>>= 4;        bits -= 4;        //---//        len = (hold & 0x0f)/*BITS(4)*/ + 8;        if (state.wbits === 0) {          state.wbits = len;        }        else if (len > state.wbits) {          strm.msg = 'invalid window size';          state.mode = BAD;          break;        }        state.dmax = 1 << len;        //Tracev((stderr, "inflate:   zlib header ok\n"));        strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;        state.mode = hold & 0x200 ? DICTID : TYPE;        //=== INITBITS();        hold = 0;        bits = 0;        //===//        break;      case FLAGS:        //=== NEEDBITS(16); */        while (bits < 16) {          if (have === 0) { break inf_leave; }          have--;          hold += input[next++] << bits;          bits += 8;        }        //===//        state.flags = hold;        if ((state.flags & 0xff) !== Z_DEFLATED) {          strm.msg = 'unknown compression method';          state.mode = BAD;          break;        }        if (state.flags & 0xe000) {          strm.msg = 'unknown header flags set';          state.mode = BAD;          break;        }        if (state.head) {          state.head.text = ((hold >> 8) & 1);        }        if (state.flags & 0x0200) {          //=== CRC2(state.check, hold);          hbuf[0] = hold & 0xff;          hbuf[1] = (hold >>> 8) & 0xff;          state.check = crc32(state.check, hbuf, 2, 0);          //===//        }        //=== INITBITS();        hold = 0;        bits = 0;        //===//        state.mode = TIME;        /* falls through */      case TIME:        //=== NEEDBITS(32); */        while (bits < 32) {          if (have === 0) { break inf_leave; }          have--;          hold += input[next++] << bits;          bits += 8;        }        //===//        if (state.head) {          state.head.time = hold;        }        if (state.flags & 0x0200) {          //=== CRC4(state.check, hold)          hbuf[0] = hold & 0xff;          hbuf[1] = (hold >>> 8) & 0xff;          hbuf[2] = (hold >>> 16) & 0xff;          hbuf[3] = (hold >>> 24) & 0xff;          state.check = crc32(state.check, hbuf, 4, 0);          //===        }        //=== INITBITS();        hold = 0;        bits = 0;        //===//        state.mode = OS;        /* falls through */      case OS:        //=== NEEDBITS(16); */        while (bits < 16) {          if (have === 0) { break inf_leave; }          have--;          hold += input[next++] << bits;          bits += 8;        }        //===//        if (state.head) {          state.head.xflags = (hold & 0xff);          state.head.os = (hold >> 8);        }        if (state.flags & 0x0200) {          //=== CRC2(state.check, hold);          hbuf[0] = hold & 0xff;          hbuf[1] = (hold >>> 8) & 0xff;          state.check = crc32(state.check, hbuf, 2, 0);          //===//        }        //=== INITBITS();        hold = 0;        bits = 0;        //===//        state.mode = EXLEN;        /* falls through */      case EXLEN:        if (state.flags & 0x0400) {          //=== NEEDBITS(16); */          while (bits < 16) {            if (have === 0) { break inf_leave; }            have--;            hold += input[next++] << bits;            bits += 8;          }          //===//          state.length = hold;          if (state.head) {            state.head.extra_len = hold;          }          if (state.flags & 0x0200) {            //=== CRC2(state.check, hold);            hbuf[0] = hold & 0xff;            hbuf[1] = (hold >>> 8) & 0xff;            state.check = crc32(state.check, hbuf, 2, 0);            //===//          }          //=== INITBITS();          hold = 0;          bits = 0;          //===//        }        else if (state.head) {          state.head.extra = null/*Z_NULL*/;        }        state.mode = EXTRA;        /* falls through */      case EXTRA:        if (state.flags & 0x0400) {          copy = state.length;          if (copy > have) { copy = have; }          if (copy) {            if (state.head) {              len = state.head.extra_len - state.length;              if (!state.head.extra) {                // Use untyped array for more convenient processing later                state.head.extra = new Array(state.head.extra_len);              }              utils.arraySet(                state.head.extra,                input,                next,                // extra field is limited to 65536 bytes                // - no need for additional size check                copy,                /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/                len              );              //zmemcpy(state.head.extra + len, next,              //        len + copy > state.head.extra_max ?              //        state.head.extra_max - len : copy);            }            if (state.flags & 0x0200) {              state.check = crc32(state.check, input, copy, next);            }            have -= copy;            next += copy;            state.length -= copy;          }          if (state.length) { break inf_leave; }        }        state.length = 0;        state.mode = NAME;        /* falls through */      case NAME:        if (state.flags & 0x0800) {          if (have === 0) { break inf_leave; }          copy = 0;          do {            // TODO: 2 or 1 bytes?            len = input[next + copy++];            /* use constant limit because in js we should not preallocate memory */            if (state.head && len &&                (state.length < 65536 /*state.head.name_max*/)) {              state.head.name += String.fromCharCode(len);            }          } while (len && copy < have);          if (state.flags & 0x0200) {            state.check = crc32(state.check, input, copy, next);          }          have -= copy;          next += copy;          if (len) { break inf_leave; }        }        else if (state.head) {          state.head.name = null;        }        state.length = 0;        state.mode = COMMENT;        /* falls through */      case COMMENT:        if (state.flags & 0x1000) {          if (have === 0) { break inf_leave; }          copy = 0;          do {            len = input[next + copy++];            /* use constant limit because in js we should not preallocate memory */            if (state.head && len &&                (state.length < 65536 /*state.head.comm_max*/)) {              state.head.comment += String.fromCharCode(len);            }          } while (len && copy < have);          if (state.flags & 0x0200) {            state.check = crc32(state.check, input, copy, next);          }          have -= copy;          next += copy;          if (len) { break inf_leave; }        }        else if (state.head) {          state.head.comment = null;        }        state.mode = HCRC;        /* falls through */      case HCRC:        if (state.flags & 0x0200) {          //=== NEEDBITS(16); */          while (bits < 16) {            if (have === 0) { break inf_leave; }            have--;            hold += input[next++] << bits;            bits += 8;          }          //===//          if (hold !== (state.check & 0xffff)) {            strm.msg = 'header crc mismatch';            state.mode = BAD;            break;          }          //=== INITBITS();          hold = 0;          bits = 0;          //===//        }        if (state.head) {          state.head.hcrc = ((state.flags >> 9) & 1);          state.head.done = true;        }        strm.adler = state.check = 0;        state.mode = TYPE;        break;      case DICTID:        //=== NEEDBITS(32); */        while (bits < 32) {          if (have === 0) { break inf_leave; }          have--;          hold += input[next++] << bits;          bits += 8;        }        //===//        strm.adler = state.check = zswap32(hold);        //=== INITBITS();        hold = 0;        bits = 0;        //===//        state.mode = DICT;        /* falls through */      case DICT:        if (state.havedict === 0) {          //--- RESTORE() ---          strm.next_out = put;          strm.avail_out = left;          strm.next_in = next;          strm.avail_in = have;          state.hold = hold;          state.bits = bits;          //---          return Z_NEED_DICT;        }        strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;        state.mode = TYPE;        /* falls through */      case TYPE:        if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; }        /* falls through */      case TYPEDO:        if (state.last) {          //--- BYTEBITS() ---//          hold >>>= bits & 7;          bits -= bits & 7;          //---//          state.mode = CHECK;          break;        }        //=== NEEDBITS(3); */        while (bits < 3) {          if (have === 0) { break inf_leave; }          have--;          hold += input[next++] << bits;          bits += 8;        }        //===//        state.last = (hold & 0x01)/*BITS(1)*/;        //--- DROPBITS(1) ---//        hold >>>= 1;        bits -= 1;        //---//        switch ((hold & 0x03)/*BITS(2)*/) {          case 0:                             /* stored block */            //Tracev((stderr, "inflate:     stored block%s\n",            //        state.last ? " (last)" : ""));            state.mode = STORED;            break;          case 1:                             /* fixed block */            fixedtables(state);            //Tracev((stderr, "inflate:     fixed codes block%s\n",            //        state.last ? " (last)" : ""));            state.mode = LEN_;             /* decode codes */            if (flush === Z_TREES) {              //--- DROPBITS(2) ---//              hold >>>= 2;              bits -= 2;              //---//              break inf_leave;            }            break;          case 2:                             /* dynamic block */            //Tracev((stderr, "inflate:     dynamic codes block%s\n",            //        state.last ? " (last)" : ""));            state.mode = TABLE;            break;          case 3:            strm.msg = 'invalid block type';            state.mode = BAD;        }        //--- DROPBITS(2) ---//        hold >>>= 2;        bits -= 2;        //---//        break;      case STORED:        //--- BYTEBITS() ---// /* go to byte boundary */        hold >>>= bits & 7;        bits -= bits & 7;        //---//        //=== NEEDBITS(32); */        while (bits < 32) {          if (have === 0) { break inf_leave; }          have--;          hold += input[next++] << bits;          bits += 8;        }        //===//        if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) {          strm.msg = 'invalid stored block lengths';          state.mode = BAD;          break;        }        state.length = hold & 0xffff;        //Tracev((stderr, "inflate:       stored length %u\n",        //        state.length));        //=== INITBITS();        hold = 0;        bits = 0;        //===//        state.mode = COPY_;        if (flush === Z_TREES) { break inf_leave; }        /* falls through */      case COPY_:        state.mode = COPY;        /* falls through */      case COPY:        copy = state.length;        if (copy) {          if (copy > have) { copy = have; }          if (copy > left) { copy = left; }          if (copy === 0) { break inf_leave; }          //--- zmemcpy(put, next, copy); ---          utils.arraySet(output, input, next, copy, put);          //---//          have -= copy;          next += copy;          left -= copy;          put += copy;          state.length -= copy;          break;        }        //Tracev((stderr, "inflate:       stored end\n"));        state.mode = TYPE;        break;      case TABLE:        //=== NEEDBITS(14); */        while (bits < 14) {          if (have === 0) { break inf_leave; }          have--;          hold += input[next++] << bits;          bits += 8;        }        //===//        state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257;        //--- DROPBITS(5) ---//        hold >>>= 5;        bits -= 5;        //---//        state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1;        //--- DROPBITS(5) ---//        hold >>>= 5;        bits -= 5;        //---//        state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4;        //--- DROPBITS(4) ---//        hold >>>= 4;        bits -= 4;        //---////#ifndef PKZIP_BUG_WORKAROUND        if (state.nlen > 286 || state.ndist > 30) {          strm.msg = 'too many length or distance symbols';          state.mode = BAD;          break;        }//#endif        //Tracev((stderr, "inflate:       table sizes ok\n"));        state.have = 0;        state.mode = LENLENS;        /* falls through */      case LENLENS:        while (state.have < state.ncode) {          //=== NEEDBITS(3);          while (bits < 3) {            if (have === 0) { break inf_leave; }            have--;            hold += input[next++] << bits;            bits += 8;          }          //===//          state.lens[order[state.have++]] = (hold & 0x07);//BITS(3);          //--- DROPBITS(3) ---//          hold >>>= 3;          bits -= 3;          //---//        }        while (state.have < 19) {          state.lens[order[state.have++]] = 0;        }        // We have separate tables & no pointers. 2 commented lines below not needed.        //state.next = state.codes;        //state.lencode = state.next;        // Switch to use dynamic table        state.lencode = state.lendyn;        state.lenbits = 7;        opts = { bits: state.lenbits };        ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts);        state.lenbits = opts.bits;        if (ret) {          strm.msg = 'invalid code lengths set';          state.mode = BAD;          break;        }        //Tracev((stderr, "inflate:       code lengths ok\n"));        state.have = 0;        state.mode = CODELENS;        /* falls through */      case CODELENS:        while (state.have < state.nlen + state.ndist) {          for (;;) {            here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/            here_bits = here >>> 24;            here_op = (here >>> 16) & 0xff;            here_val = here & 0xffff;            if ((here_bits) <= bits) { break; }            //--- PULLBYTE() ---//            if (have === 0) { break inf_leave; }            have--;            hold += input[next++] << bits;            bits += 8;            //---//          }          if (here_val < 16) {            //--- DROPBITS(here.bits) ---//            hold >>>= here_bits;            bits -= here_bits;            //---//            state.lens[state.have++] = here_val;          }          else {            if (here_val === 16) {              //=== NEEDBITS(here.bits + 2);              n = here_bits + 2;              while (bits < n) {                if (have === 0) { break inf_leave; }                have--;                hold += input[next++] << bits;                bits += 8;              }              //===//              //--- DROPBITS(here.bits) ---//              hold >>>= here_bits;              bits -= here_bits;              //---//              if (state.have === 0) {                strm.msg = 'invalid bit length repeat';                state.mode = BAD;                break;              }              len = state.lens[state.have - 1];              copy = 3 + (hold & 0x03);//BITS(2);              //--- DROPBITS(2) ---//              hold >>>= 2;              bits -= 2;              //---//            }            else if (here_val === 17) {              //=== NEEDBITS(here.bits + 3);              n = here_bits + 3;              while (bits < n) {                if (have === 0) { break inf_leave; }                have--;                hold += input[next++] << bits;                bits += 8;              }              //===//              //--- DROPBITS(here.bits) ---//              hold >>>= here_bits;              bits -= here_bits;              //---//              len = 0;              copy = 3 + (hold & 0x07);//BITS(3);              //--- DROPBITS(3) ---//              hold >>>= 3;              bits -= 3;              //---//            }            else {              //=== NEEDBITS(here.bits + 7);              n = here_bits + 7;              while (bits < n) {                if (have === 0) { break inf_leave; }                have--;                hold += input[next++] << bits;                bits += 8;              }              //===//              //--- DROPBITS(here.bits) ---//              hold >>>= here_bits;              bits -= here_bits;              //---//              len = 0;              copy = 11 + (hold & 0x7f);//BITS(7);              //--- DROPBITS(7) ---//              hold >>>= 7;              bits -= 7;              //---//            }            if (state.have + copy > state.nlen + state.ndist) {              strm.msg = 'invalid bit length repeat';              state.mode = BAD;              break;            }            while (copy--) {              state.lens[state.have++] = len;            }          }        }        /* handle error breaks in while */        if (state.mode === BAD) { break; }        /* check for end-of-block code (better have one) */        if (state.lens[256] === 0) {          strm.msg = 'invalid code -- missing end-of-block';          state.mode = BAD;          break;        }        /* build code tables -- note: do not change the lenbits or distbits           values here (9 and 6) without reading the comments in inftrees.h           concerning the ENOUGH constants, which depend on those values */        state.lenbits = 9;        opts = { bits: state.lenbits };        ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts);        // We have separate tables & no pointers. 2 commented lines below not needed.        // state.next_index = opts.table_index;        state.lenbits = opts.bits;        // state.lencode = state.next;        if (ret) {          strm.msg = 'invalid literal/lengths set';          state.mode = BAD;          break;        }        state.distbits = 6;        //state.distcode.copy(state.codes);        // Switch to use dynamic table        state.distcode = state.distdyn;        opts = { bits: state.distbits };        ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts);        // We have separate tables & no pointers. 2 commented lines below not needed.        // state.next_index = opts.table_index;        state.distbits = opts.bits;        // state.distcode = state.next;        if (ret) {          strm.msg = 'invalid distances set';          state.mode = BAD;          break;        }        //Tracev((stderr, 'inflate:       codes ok\n'));        state.mode = LEN_;        if (flush === Z_TREES) { break inf_leave; }        /* falls through */      case LEN_:        state.mode = LEN;        /* falls through */      case LEN:        if (have >= 6 && left >= 258) {          //--- RESTORE() ---          strm.next_out = put;          strm.avail_out = left;          strm.next_in = next;          strm.avail_in = have;          state.hold = hold;          state.bits = bits;          //---          inflate_fast(strm, _out);          //--- LOAD() ---          put = strm.next_out;          output = strm.output;          left = strm.avail_out;          next = strm.next_in;          input = strm.input;          have = strm.avail_in;          hold = state.hold;          bits = state.bits;          //---          if (state.mode === TYPE) {            state.back = -1;          }          break;        }        state.back = 0;        for (;;) {          here = state.lencode[hold & ((1 << state.lenbits) - 1)];  /*BITS(state.lenbits)*/          here_bits = here >>> 24;          here_op = (here >>> 16) & 0xff;          here_val = here & 0xffff;          if (here_bits <= bits) { break; }          //--- PULLBYTE() ---//          if (have === 0) { break inf_leave; }          have--;          hold += input[next++] << bits;          bits += 8;          //---//        }        if (here_op && (here_op & 0xf0) === 0) {          last_bits = here_bits;          last_op = here_op;          last_val = here_val;          for (;;) {            here = state.lencode[last_val +                    ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];            here_bits = here >>> 24;            here_op = (here >>> 16) & 0xff;            here_val = here & 0xffff;            if ((last_bits + here_bits) <= bits) { break; }            //--- PULLBYTE() ---//            if (have === 0) { break inf_leave; }            have--;            hold += input[next++] << bits;            bits += 8;            //---//          }          //--- DROPBITS(last.bits) ---//          hold >>>= last_bits;          bits -= last_bits;          //---//          state.back += last_bits;        }        //--- DROPBITS(here.bits) ---//        hold >>>= here_bits;        bits -= here_bits;        //---//        state.back += here_bits;        state.length = here_val;        if (here_op === 0) {          //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?          //        "inflate:         literal '%c'\n" :          //        "inflate:         literal 0x%02x\n", here.val));          state.mode = LIT;          break;        }        if (here_op & 32) {          //Tracevv((stderr, "inflate:         end of block\n"));          state.back = -1;          state.mode = TYPE;          break;        }        if (here_op & 64) {          strm.msg = 'invalid literal/length code';          state.mode = BAD;          break;        }        state.extra = here_op & 15;        state.mode = LENEXT;        /* falls through */      case LENEXT:        if (state.extra) {          //=== NEEDBITS(state.extra);          n = state.extra;          while (bits < n) {            if (have === 0) { break inf_leave; }            have--;            hold += input[next++] << bits;            bits += 8;          }          //===//          state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;          //--- DROPBITS(state.extra) ---//          hold >>>= state.extra;          bits -= state.extra;          //---//          state.back += state.extra;        }        //Tracevv((stderr, "inflate:         length %u\n", state.length));        state.was = state.length;        state.mode = DIST;        /* falls through */      case DIST:        for (;;) {          here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/          here_bits = here >>> 24;          here_op = (here >>> 16) & 0xff;          here_val = here & 0xffff;          if ((here_bits) <= bits) { break; }          //--- PULLBYTE() ---//          if (have === 0) { break inf_leave; }          have--;          hold += input[next++] << bits;          bits += 8;          //---//        }        if ((here_op & 0xf0) === 0) {          last_bits = here_bits;          last_op = here_op;          last_val = here_val;          for (;;) {            here = state.distcode[last_val +                    ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];            here_bits = here >>> 24;            here_op = (here >>> 16) & 0xff;            here_val = here & 0xffff;            if ((last_bits + here_bits) <= bits) { break; }            //--- PULLBYTE() ---//            if (have === 0) { break inf_leave; }            have--;            hold += input[next++] << bits;            bits += 8;            //---//          }          //--- DROPBITS(last.bits) ---//          hold >>>= last_bits;          bits -= last_bits;          //---//          state.back += last_bits;        }        //--- DROPBITS(here.bits) ---//        hold >>>= here_bits;        bits -= here_bits;        //---//        state.back += here_bits;        if (here_op & 64) {          strm.msg = 'invalid distance code';          state.mode = BAD;          break;        }        state.offset = here_val;        state.extra = (here_op) & 15;        state.mode = DISTEXT;        /* falls through */      case DISTEXT:        if (state.extra) {          //=== NEEDBITS(state.extra);          n = state.extra;          while (bits < n) {            if (have === 0) { break inf_leave; }            have--;            hold += input[next++] << bits;            bits += 8;          }          //===//          state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;          //--- DROPBITS(state.extra) ---//          hold >>>= state.extra;          bits -= state.extra;          //---//          state.back += state.extra;        }//#ifdef INFLATE_STRICT        if (state.offset > state.dmax) {          strm.msg = 'invalid distance too far back';          state.mode = BAD;          break;        }//#endif        //Tracevv((stderr, "inflate:         distance %u\n", state.offset));        state.mode = MATCH;        /* falls through */      case MATCH:        if (left === 0) { break inf_leave; }        copy = _out - left;        if (state.offset > copy) {         /* copy from window */          copy = state.offset - copy;          if (copy > state.whave) {            if (state.sane) {              strm.msg = 'invalid distance too far back';              state.mode = BAD;              break;            }// (!) This block is disabled in zlib defaults,// don't enable it for binary compatibility//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR//          Trace((stderr, "inflate.c too far\n"));//          copy -= state.whave;//          if (copy > state.length) { copy = state.length; }//          if (copy > left) { copy = left; }//          left -= copy;//          state.length -= copy;//          do {//            output[put++] = 0;//          } while (--copy);//          if (state.length === 0) { state.mode = LEN; }//          break;//#endif          }          if (copy > state.wnext) {            copy -= state.wnext;            from = state.wsize - copy;          }          else {            from = state.wnext - copy;          }          if (copy > state.length) { copy = state.length; }          from_source = state.window;        }        else {                              /* copy from output */          from_source = output;          from = put - state.offset;          copy = state.length;        }        if (copy > left) { copy = left; }        left -= copy;        state.length -= copy;        do {          output[put++] = from_source[from++];        } while (--copy);        if (state.length === 0) { state.mode = LEN; }        break;      case LIT:        if (left === 0) { break inf_leave; }        output[put++] = state.length;        left--;        state.mode = LEN;        break;      case CHECK:        if (state.wrap) {          //=== NEEDBITS(32);          while (bits < 32) {            if (have === 0) { break inf_leave; }            have--;            // Use '|' instead of '+' to make sure that result is signed            hold |= input[next++] << bits;            bits += 8;          }          //===//          _out -= left;          strm.total_out += _out;          state.total += _out;          if (_out) {            strm.adler = state.check =                /*UPDATE(state.check, put - _out, _out);*/                (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out));          }          _out = left;          // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too          if ((state.flags ? hold : zswap32(hold)) !== state.check) {            strm.msg = 'incorrect data check';            state.mode = BAD;            break;          }          //=== INITBITS();          hold = 0;          bits = 0;          //===//          //Tracev((stderr, "inflate:   check matches trailer\n"));        }        state.mode = LENGTH;        /* falls through */      case LENGTH:        if (state.wrap && state.flags) {          //=== NEEDBITS(32);          while (bits < 32) {            if (have === 0) { break inf_leave; }            have--;            hold += input[next++] << bits;            bits += 8;          }          //===//          if (hold !== (state.total & 0xffffffff)) {            strm.msg = 'incorrect length check';            state.mode = BAD;            break;          }          //=== INITBITS();          hold = 0;          bits = 0;          //===//          //Tracev((stderr, "inflate:   length matches trailer\n"));        }        state.mode = DONE;        /* falls through */      case DONE:        ret = Z_STREAM_END;        break inf_leave;      case BAD:        ret = Z_DATA_ERROR;        break inf_leave;      case MEM:        return Z_MEM_ERROR;      case SYNC:        /* falls through */      default:        return Z_STREAM_ERROR;    }  }  // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave"  /*     Return from inflate(), updating the total counts and the check value.     If there was no progress during the inflate() call, return a buffer     error.  Call updatewindow() to create and/or update the window state.     Note: a memory error from inflate() is non-recoverable.   */  //--- RESTORE() ---  strm.next_out = put;  strm.avail_out = left;  strm.next_in = next;  strm.avail_in = have;  state.hold = hold;  state.bits = bits;  //---  if (state.wsize || (_out !== strm.avail_out && state.mode < BAD &&                      (state.mode < CHECK || flush !== Z_FINISH))) {    if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) {      state.mode = MEM;      return Z_MEM_ERROR;    }  }  _in -= strm.avail_in;  _out -= strm.avail_out;  strm.total_in += _in;  strm.total_out += _out;  state.total += _out;  if (state.wrap && _out) {    strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/      (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out));  }  strm.data_type = state.bits + (state.last ? 64 : 0) +                    (state.mode === TYPE ? 128 : 0) +                    (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0);  if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) {    ret = Z_BUF_ERROR;  }  return ret;}function inflateEnd(strm) {  if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) {    return Z_STREAM_ERROR;  }  var state = strm.state;  if (state.window) {    state.window = null;  }  strm.state = null;  return Z_OK;}function inflateGetHeader(strm, head) {  var state;  /* check state */  if (!strm || !strm.state) { return Z_STREAM_ERROR; }  state = strm.state;  if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; }  /* save header structure */  state.head = head;  head.done = false;  return Z_OK;}function inflateSetDictionary(strm, dictionary) {  var dictLength = dictionary.length;  var state;  var dictid;  var ret;  /* check state */  if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) { return Z_STREAM_ERROR; }  state = strm.state;  if (state.wrap !== 0 && state.mode !== DICT) {    return Z_STREAM_ERROR;  }  /* check for correct dictionary identifier */  if (state.mode === DICT) {    dictid = 1; /* adler32(0, null, 0)*/    /* dictid = adler32(dictid, dictionary, dictLength); */    dictid = adler32(dictid, dictionary, dictLength, 0);    if (dictid !== state.check) {      return Z_DATA_ERROR;    }  }  /* copy dictionary to window using updatewindow(), which will amend the   existing dictionary if appropriate */  ret = updatewindow(strm, dictionary, dictLength, dictLength);  if (ret) {    state.mode = MEM;    return Z_MEM_ERROR;  }  state.havedict = 1;  // Tracev((stderr, "inflate:   dictionary set\n"));  return Z_OK;}exports.inflateReset = inflateReset;exports.inflateReset2 = inflateReset2;exports.inflateResetKeep = inflateResetKeep;exports.inflateInit = inflateInit;exports.inflateInit2 = inflateInit2;exports.inflate = inflate;exports.inflateEnd = inflateEnd;exports.inflateGetHeader = inflateGetHeader;exports.inflateSetDictionary = inflateSetDictionary;exports.inflateInfo = 'pako inflate (from Nodeca project)';/* Not implementedexports.inflateCopy = inflateCopy;exports.inflateGetDictionary = inflateGetDictionary;exports.inflateMark = inflateMark;exports.inflatePrime = inflatePrime;exports.inflateSync = inflateSync;exports.inflateSyncPoint = inflateSyncPoint;exports.inflateUndermine = inflateUndermine;*/},{"../utils/common":202,"./adler32":204,"./crc32":206,"./inffast":209,"./inftrees":211}],211:[function(require,module,exports){'use strict';// (C) 1995-2013 Jean-loup Gailly and Mark Adler// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin//// This software is provided 'as-is', without any express or implied// warranty. In no event will the authors be held liable for any damages// arising from the use of this software.//// Permission is granted to anyone to use this software for any purpose,// including commercial applications, and to alter it and redistribute it// freely, subject to the following restrictions://// 1. The origin of this software must not be misrepresented; you must not//   claim that you wrote the original software. If you use this software//   in a product, an acknowledgment in the product documentation would be//   appreciated but is not required.// 2. Altered source versions must be plainly marked as such, and must not be//   misrepresented as being the original software.// 3. This notice may not be removed or altered from any source distribution.var utils = require('../utils/common');var MAXBITS = 15;var ENOUGH_LENS = 852;var ENOUGH_DISTS = 592;//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);var CODES = 0;var LENS = 1;var DISTS = 2;var lbase = [ /* Length codes 257..285 base */  3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,  35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0];var lext = [ /* Length codes 257..285 extra */  16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,  19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78];var dbase = [ /* Distance codes 0..29 base */  1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,  257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,  8193, 12289, 16385, 24577, 0, 0];var dext = [ /* Distance codes 0..29 extra */  16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,  23, 23, 24, 24, 25, 25, 26, 26, 27, 27,  28, 28, 29, 29, 64, 64];module.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts){  var bits = opts.bits;      //here = opts.here; /* table entry for duplication */  var len = 0;               /* a code's length in bits */  var sym = 0;               /* index of code symbols */  var min = 0, max = 0;          /* minimum and maximum code lengths */  var root = 0;              /* number of index bits for root table */  var curr = 0;              /* number of index bits for current table */  var drop = 0;              /* code bits to drop for sub-table */  var left = 0;                   /* number of prefix codes available */  var used = 0;              /* code entries in table used */  var huff = 0;              /* Huffman code */  var incr;              /* for incrementing code, index */  var fill;              /* index for replicating entries */  var low;               /* low bits for current root entry */  var mask;              /* mask for low root bits */  var next;             /* next available space in table */  var base = null;     /* base value table to use */  var base_index = 0;//  var shoextra;    /* extra bits table to use */  var end;                    /* use base and extra for symbol > end */  var count = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1];    /* number of codes of each length */  var offs = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1];     /* offsets in table for each length */  var extra = null;  var extra_index = 0;  var here_bits, here_op, here_val;  /*   Process a set of code lengths to create a canonical Huffman code.  The   code lengths are lens[0..codes-1].  Each length corresponds to the   symbols 0..codes-1.  The Huffman code is generated by first sorting the   symbols by length from short to long, and retaining the symbol order   for codes with equal lengths.  Then the code starts with all zero bits   for the first code of the shortest length, and the codes are integer   increments for the same length, and zeros are appended as the length   increases.  For the deflate format, these bits are stored backwards   from their more natural integer increment ordering, and so when the   decoding tables are built in the large loop below, the integer codes   are incremented backwards.   This routine assumes, but does not check, that all of the entries in   lens[] are in the range 0..MAXBITS.  The caller must assure this.   1..MAXBITS is interpreted as that code length.  zero means that that   symbol does not occur in this code.   The codes are sorted by computing a count of codes for each length,   creating from that a table of starting indices for each length in the   sorted table, and then entering the symbols in order in the sorted   table.  The sorted table is work[], with that space being provided by   the caller.   The length counts are used for other purposes as well, i.e. finding   the minimum and maximum length codes, determining if there are any   codes at all, checking for a valid set of lengths, and looking ahead   at length counts to determine sub-table sizes when building the   decoding tables.   */  /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */  for (len = 0; len <= MAXBITS; len++) {    count[len] = 0;  }  for (sym = 0; sym < codes; sym++) {    count[lens[lens_index + sym]]++;  }  /* bound code lengths, force root to be within code lengths */  root = bits;  for (max = MAXBITS; max >= 1; max--) {    if (count[max] !== 0) { break; }  }  if (root > max) {    root = max;  }  if (max === 0) {                     /* no symbols to code at all */    //table.op[opts.table_index] = 64;  //here.op = (var char)64;    /* invalid code marker */    //table.bits[opts.table_index] = 1;   //here.bits = (var char)1;    //table.val[opts.table_index++] = 0;   //here.val = (var short)0;    table[table_index++] = (1 << 24) | (64 << 16) | 0;    //table.op[opts.table_index] = 64;    //table.bits[opts.table_index] = 1;    //table.val[opts.table_index++] = 0;    table[table_index++] = (1 << 24) | (64 << 16) | 0;    opts.bits = 1;    return 0;     /* no symbols, but wait for decoding to report error */  }  for (min = 1; min < max; min++) {    if (count[min] !== 0) { break; }  }  if (root < min) {    root = min;  }  /* check for an over-subscribed or incomplete set of lengths */  left = 1;  for (len = 1; len <= MAXBITS; len++) {    left <<= 1;    left -= count[len];    if (left < 0) {      return -1;    }        /* over-subscribed */  }  if (left > 0 && (type === CODES || max !== 1)) {    return -1;                      /* incomplete set */  }  /* generate offsets into symbol table for each length for sorting */  offs[1] = 0;  for (len = 1; len < MAXBITS; len++) {    offs[len + 1] = offs[len] + count[len];  }  /* sort symbols by length, by symbol order within each length */  for (sym = 0; sym < codes; sym++) {    if (lens[lens_index + sym] !== 0) {      work[offs[lens[lens_index + sym]]++] = sym;    }  }  /*   Create and fill in decoding tables.  In this loop, the table being   filled is at next and has curr index bits.  The code being used is huff   with length len.  That code is converted to an index by dropping drop   bits off of the bottom.  For codes where len is less than drop + curr,   those top drop + curr - len bits are incremented through all values to   fill the table with replicated entries.   root is the number of index bits for the root table.  When len exceeds   root, sub-tables are created pointed to by the root entry with an index   of the low root bits of huff.  This is saved in low to check for when a   new sub-table should be started.  drop is zero when the root table is   being filled, and drop is root when sub-tables are being filled.   When a new sub-table is needed, it is necessary to look ahead in the   code lengths to determine what size sub-table is needed.  The length   counts are used for this, and so count[] is decremented as codes are   entered in the tables.   used keeps track of how many table entries have been allocated from the   provided *table space.  It is checked for LENS and DIST tables against   the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in   the initial root table size constants.  See the comments in inftrees.h   for more information.   sym increments through all symbols, and the loop terminates when   all codes of length max, i.e. all codes, have been processed.  This   routine permits incomplete codes, so another loop after this one fills   in the rest of the decoding tables with invalid code markers.   */  /* set up for code type */  // poor man optimization - use if-else instead of switch,  // to avoid deopts in old v8  if (type === CODES) {    base = extra = work;    /* dummy value--not used */    end = 19;  } else if (type === LENS) {    base = lbase;    base_index -= 257;    extra = lext;    extra_index -= 257;    end = 256;  } else {                    /* DISTS */    base = dbase;    extra = dext;    end = -1;  }  /* initialize opts for loop */  huff = 0;                   /* starting code */  sym = 0;                    /* starting code symbol */  len = min;                  /* starting code length */  next = table_index;              /* current table to fill in */  curr = root;                /* current table index bits */  drop = 0;                   /* current bits to drop from code for index */  low = -1;                   /* trigger new sub-table when len > root */  used = 1 << root;          /* use root table entries */  mask = used - 1;            /* mask for comparing low */  /* check available table space */  if ((type === LENS && used > ENOUGH_LENS) ||    (type === DISTS && used > ENOUGH_DISTS)) {    return 1;  }  /* process all codes and make table entries */  for (;;) {    /* create table entry */    here_bits = len - drop;    if (work[sym] < end) {      here_op = 0;      here_val = work[sym];    }    else if (work[sym] > end) {      here_op = extra[extra_index + work[sym]];      here_val = base[base_index + work[sym]];    }    else {      here_op = 32 + 64;         /* end of block */      here_val = 0;    }    /* replicate for those indices with low len bits equal to huff */    incr = 1 << (len - drop);    fill = 1 << curr;    min = fill;                 /* save offset to next table */    do {      fill -= incr;      table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0;    } while (fill !== 0);    /* backwards increment the len-bit code huff */    incr = 1 << (len - 1);    while (huff & incr) {      incr >>= 1;    }    if (incr !== 0) {      huff &= incr - 1;      huff += incr;    } else {      huff = 0;    }    /* go to next symbol, update count, len */    sym++;    if (--count[len] === 0) {      if (len === max) { break; }      len = lens[lens_index + work[sym]];    }    /* create new sub-table if needed */    if (len > root && (huff & mask) !== low) {      /* if first time, transition to sub-tables */      if (drop === 0) {        drop = root;      }      /* increment past last table */      next += min;            /* here min is 1 << curr */      /* determine length of next table */      curr = len - drop;      left = 1 << curr;      while (curr + drop < max) {        left -= count[curr + drop];        if (left <= 0) { break; }        curr++;        left <<= 1;      }      /* check for enough space */      used += 1 << curr;      if ((type === LENS && used > ENOUGH_LENS) ||        (type === DISTS && used > ENOUGH_DISTS)) {        return 1;      }      /* point entry in root table to sub-table */      low = huff & mask;      /*table.op[low] = curr;      table.bits[low] = root;      table.val[low] = next - opts.table_index;*/      table[low] = (root << 24) | (curr << 16) | (next - table_index) |0;    }  }  /* fill in remaining table entry if code is incomplete (guaranteed to have   at most one remaining entry, since if the code is incomplete, the   maximum code length that was allowed to get this far is one bit) */  if (huff !== 0) {    //table.op[next + huff] = 64;            /* invalid code marker */    //table.bits[next + huff] = len - drop;    //table.val[next + huff] = 0;    table[next + huff] = ((len - drop) << 24) | (64 << 16) |0;  }  /* set return parameters */  //opts.table_index += used;  opts.bits = root;  return 0;};},{"../utils/common":202}],212:[function(require,module,exports){'use strict';// (C) 1995-2013 Jean-loup Gailly and Mark Adler// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin//// This software is provided 'as-is', without any express or implied// warranty. In no event will the authors be held liable for any damages// arising from the use of this software.//// Permission is granted to anyone to use this software for any purpose,// including commercial applications, and to alter it and redistribute it// freely, subject to the following restrictions://// 1. The origin of this software must not be misrepresented; you must not//   claim that you wrote the original software. If you use this software//   in a product, an acknowledgment in the product documentation would be//   appreciated but is not required.// 2. Altered source versions must be plainly marked as such, and must not be//   misrepresented as being the original software.// 3. This notice may not be removed or altered from any source distribution.module.exports = {  2:      'need dictionary',     /* Z_NEED_DICT       2  */  1:      'stream end',          /* Z_STREAM_END      1  */  0:      '',                    /* Z_OK              0  */  '-1':   'file error',          /* Z_ERRNO         (-1) */  '-2':   'stream error',        /* Z_STREAM_ERROR  (-2) */  '-3':   'data error',          /* Z_DATA_ERROR    (-3) */  '-4':   'insufficient memory', /* Z_MEM_ERROR     (-4) */  '-5':   'buffer error',        /* Z_BUF_ERROR     (-5) */  '-6':   'incompatible version' /* Z_VERSION_ERROR (-6) */};},{}],213:[function(require,module,exports){'use strict';// (C) 1995-2013 Jean-loup Gailly and Mark Adler// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin//// This software is provided 'as-is', without any express or implied// warranty. In no event will the authors be held liable for any damages// arising from the use of this software.//// Permission is granted to anyone to use this software for any purpose,// including commercial applications, and to alter it and redistribute it// freely, subject to the following restrictions://// 1. The origin of this software must not be misrepresented; you must not//   claim that you wrote the original software. If you use this software//   in a product, an acknowledgment in the product documentation would be//   appreciated but is not required.// 2. Altered source versions must be plainly marked as such, and must not be//   misrepresented as being the original software.// 3. This notice may not be removed or altered from any source distribution.var utils = require('../utils/common');/* Public constants ==========================================================*//* ===========================================================================*///var Z_FILTERED          = 1;//var Z_HUFFMAN_ONLY      = 2;//var Z_RLE               = 3;var Z_FIXED               = 4;//var Z_DEFAULT_STRATEGY  = 0;/* Possible values of the data_type field (though see inflate()) */var Z_BINARY              = 0;var Z_TEXT                = 1;//var Z_ASCII             = 1; // = Z_TEXTvar Z_UNKNOWN             = 2;/*============================================================================*/function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } }// From zutil.hvar STORED_BLOCK = 0;var STATIC_TREES = 1;var DYN_TREES    = 2;/* The three kinds of block type */var MIN_MATCH    = 3;var MAX_MATCH    = 258;/* The minimum and maximum match lengths */// From deflate.h/* =========================================================================== * Internal compression state. */var LENGTH_CODES  = 29;/* number of length codes, not counting the special END_BLOCK code */var LITERALS      = 256;/* number of literal bytes 0..255 */var L_CODES       = LITERALS + 1 + LENGTH_CODES;/* number of Literal or Length codes, including the END_BLOCK code */var D_CODES       = 30;/* number of distance codes */var BL_CODES      = 19;/* number of codes used to transfer the bit lengths */var HEAP_SIZE     = 2 * L_CODES + 1;/* maximum heap size */var MAX_BITS      = 15;/* All codes must not exceed MAX_BITS bits */var Buf_size      = 16;/* size of bit buffer in bi_buf *//* =========================================================================== * Constants */var MAX_BL_BITS = 7;/* Bit length codes must not exceed MAX_BL_BITS bits */var END_BLOCK   = 256;/* end of block literal code */var REP_3_6     = 16;/* repeat previous bit length 3-6 times (2 bits of repeat count) */var REPZ_3_10   = 17;/* repeat a zero length 3-10 times  (3 bits of repeat count) */var REPZ_11_138 = 18;/* repeat a zero length 11-138 times  (7 bits of repeat count) *//* eslint-disable comma-spacing,array-bracket-spacing */var extra_lbits =   /* extra bits for each length code */  [0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0];var extra_dbits =   /* extra bits for each distance code */  [0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13];var extra_blbits =  /* extra bits for each bit length code */  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7];var bl_order =  [16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];/* eslint-enable comma-spacing,array-bracket-spacing *//* The lengths of the bit length codes are sent in order of decreasing * probability, to avoid transmitting the lengths for unused bit length codes. *//* =========================================================================== * Local data. These are initialized only once. */// We pre-fill arrays with 0 to avoid uninitialized gapsvar DIST_CODE_LEN = 512; /* see definition of array dist_code below */// !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1var static_ltree  = new Array((L_CODES + 2) * 2);zero(static_ltree);/* The static literal tree. Since the bit lengths are imposed, there is no * need for the L_CODES extra codes used during heap construction. However * The codes 286 and 287 are needed to build a canonical tree (see _tr_init * below). */var static_dtree  = new Array(D_CODES * 2);zero(static_dtree);/* The static distance tree. (Actually a trivial tree since all codes use * 5 bits.) */var _dist_code    = new Array(DIST_CODE_LEN);zero(_dist_code);/* Distance codes. The first 256 values correspond to the distances * 3 .. 258, the last 256 values correspond to the top 8 bits of * the 15 bit distances. */var _length_code  = new Array(MAX_MATCH - MIN_MATCH + 1);zero(_length_code);/* length code for each normalized match length (0 == MIN_MATCH) */var base_length   = new Array(LENGTH_CODES);zero(base_length);/* First normalized length for each code (0 = MIN_MATCH) */var base_dist     = new Array(D_CODES);zero(base_dist);/* First normalized distance for each code (0 = distance of 1) */function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) {  this.static_tree  = static_tree;  /* static tree or NULL */  this.extra_bits   = extra_bits;   /* extra bits for each code or NULL */  this.extra_base   = extra_base;   /* base index for extra_bits */  this.elems        = elems;        /* max number of elements in the tree */  this.max_length   = max_length;   /* max bit length for the codes */  // show if `static_tree` has data or dummy - needed for monomorphic objects  this.has_stree    = static_tree && static_tree.length;}var static_l_desc;var static_d_desc;var static_bl_desc;function TreeDesc(dyn_tree, stat_desc) {  this.dyn_tree = dyn_tree;     /* the dynamic tree */  this.max_code = 0;            /* largest code with non zero frequency */  this.stat_desc = stat_desc;   /* the corresponding static tree */}function d_code(dist) {  return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)];}/* =========================================================================== * Output a short LSB first on the stream. * IN assertion: there is enough room in pendingBuf. */function put_short(s, w) {//    put_byte(s, (uch)((w) & 0xff));//    put_byte(s, (uch)((ush)(w) >> 8));  s.pending_buf[s.pending++] = (w) & 0xff;  s.pending_buf[s.pending++] = (w >>> 8) & 0xff;}/* =========================================================================== * Send a value on a given number of bits. * IN assertion: length <= 16 and value fits in length bits. */function send_bits(s, value, length) {  if (s.bi_valid > (Buf_size - length)) {    s.bi_buf |= (value << s.bi_valid) & 0xffff;    put_short(s, s.bi_buf);    s.bi_buf = value >> (Buf_size - s.bi_valid);    s.bi_valid += length - Buf_size;  } else {    s.bi_buf |= (value << s.bi_valid) & 0xffff;    s.bi_valid += length;  }}function send_code(s, c, tree) {  send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/);}/* =========================================================================== * Reverse the first len bits of a code, using straightforward code (a faster * method would use a table) * IN assertion: 1 <= len <= 15 */function bi_reverse(code, len) {  var res = 0;  do {    res |= code & 1;    code >>>= 1;    res <<= 1;  } while (--len > 0);  return res >>> 1;}/* =========================================================================== * Flush the bit buffer, keeping at most 7 bits in it. */function bi_flush(s) {  if (s.bi_valid === 16) {    put_short(s, s.bi_buf);    s.bi_buf = 0;    s.bi_valid = 0;  } else if (s.bi_valid >= 8) {    s.pending_buf[s.pending++] = s.bi_buf & 0xff;    s.bi_buf >>= 8;    s.bi_valid -= 8;  }}/* =========================================================================== * Compute the optimal bit lengths for a tree and update the total bit length * for the current block. * IN assertion: the fields freq and dad are set, heap[heap_max] and *    above are the tree nodes sorted by increasing frequency. * OUT assertions: the field len is set to the optimal bit length, the *     array bl_count contains the frequencies for each bit length. *     The length opt_len is updated; static_len is also updated if stree is *     not null. */function gen_bitlen(s, desc)//    deflate_state *s;//    tree_desc *desc;    /* the tree descriptor */{  var tree            = desc.dyn_tree;  var max_code        = desc.max_code;  var stree           = desc.stat_desc.static_tree;  var has_stree       = desc.stat_desc.has_stree;  var extra           = desc.stat_desc.extra_bits;  var base            = desc.stat_desc.extra_base;  var max_length      = desc.stat_desc.max_length;  var h;              /* heap index */  var n, m;           /* iterate over the tree elements */  var bits;           /* bit length */  var xbits;          /* extra bits */  var f;              /* frequency */  var overflow = 0;   /* number of elements with bit length too large */  for (bits = 0; bits <= MAX_BITS; bits++) {    s.bl_count[bits] = 0;  }  /* In a first pass, compute the optimal bit lengths (which may   * overflow in the case of the bit length tree).   */  tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */  for (h = s.heap_max + 1; h < HEAP_SIZE; h++) {    n = s.heap[h];    bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1;    if (bits > max_length) {      bits = max_length;      overflow++;    }    tree[n * 2 + 1]/*.Len*/ = bits;    /* We overwrite tree[n].Dad which is no longer needed */    if (n > max_code) { continue; } /* not a leaf node */    s.bl_count[bits]++;    xbits = 0;    if (n >= base) {      xbits = extra[n - base];    }    f = tree[n * 2]/*.Freq*/;    s.opt_len += f * (bits + xbits);    if (has_stree) {      s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits);    }  }  if (overflow === 0) { return; }  // Trace((stderr,"\nbit length overflow\n"));  /* This happens for example on obj2 and pic of the Calgary corpus */  /* Find the first bit length which could increase: */  do {    bits = max_length - 1;    while (s.bl_count[bits] === 0) { bits--; }    s.bl_count[bits]--;      /* move one leaf down the tree */    s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */    s.bl_count[max_length]--;    /* The brother of the overflow item also moves one step up,     * but this does not affect bl_count[max_length]     */    overflow -= 2;  } while (overflow > 0);  /* Now recompute all bit lengths, scanning in increasing frequency.   * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all   * lengths instead of fixing only the wrong ones. This idea is taken   * from 'ar' written by Haruhiko Okumura.)   */  for (bits = max_length; bits !== 0; bits--) {    n = s.bl_count[bits];    while (n !== 0) {      m = s.heap[--h];      if (m > max_code) { continue; }      if (tree[m * 2 + 1]/*.Len*/ !== bits) {        // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));        s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/;        tree[m * 2 + 1]/*.Len*/ = bits;      }      n--;    }  }}/* =========================================================================== * Generate the codes for a given tree and bit counts (which need not be * optimal). * IN assertion: the array bl_count contains the bit length statistics for * the given tree and the field len is set for all tree elements. * OUT assertion: the field code is set for all tree elements of non *     zero code length. */function gen_codes(tree, max_code, bl_count)//    ct_data *tree;             /* the tree to decorate *///    int max_code;              /* largest code with non zero frequency *///    ushf *bl_count;            /* number of codes at each bit length */{  var next_code = new Array(MAX_BITS + 1); /* next code value for each bit length */  var code = 0;              /* running code value */  var bits;                  /* bit index */  var n;                     /* code index */  /* The distribution counts are first used to generate the code values   * without bit reversal.   */  for (bits = 1; bits <= MAX_BITS; bits++) {    next_code[bits] = code = (code + bl_count[bits - 1]) << 1;  }  /* Check that the bit counts in bl_count are consistent. The last code   * must be all ones.   */  //Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,  //        "inconsistent bit counts");  //Tracev((stderr,"\ngen_codes: max_code %d ", max_code));  for (n = 0;  n <= max_code; n++) {    var len = tree[n * 2 + 1]/*.Len*/;    if (len === 0) { continue; }    /* Now reverse the bits */    tree[n * 2]/*.Code*/ = bi_reverse(next_code[len]++, len);    //Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",    //     n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));  }}/* =========================================================================== * Initialize the various 'constant' tables. */function tr_static_init() {  var n;        /* iterates over tree elements */  var bits;     /* bit counter */  var length;   /* length value */  var code;     /* code value */  var dist;     /* distance index */  var bl_count = new Array(MAX_BITS + 1);  /* number of codes at each bit length for an optimal tree */  // do check in _tr_init()  //if (static_init_done) return;  /* For some embedded targets, global variables are not initialized: *//*#ifdef NO_INIT_GLOBAL_POINTERS  static_l_desc.static_tree = static_ltree;  static_l_desc.extra_bits = extra_lbits;  static_d_desc.static_tree = static_dtree;  static_d_desc.extra_bits = extra_dbits;  static_bl_desc.extra_bits = extra_blbits;#endif*/  /* Initialize the mapping length (0..255) -> length code (0..28) */  length = 0;  for (code = 0; code < LENGTH_CODES - 1; code++) {    base_length[code] = length;    for (n = 0; n < (1 << extra_lbits[code]); n++) {      _length_code[length++] = code;    }  }  //Assert (length == 256, "tr_static_init: length != 256");  /* Note that the length 255 (match length 258) can be represented   * in two different ways: code 284 + 5 bits or code 285, so we   * overwrite length_code[255] to use the best encoding:   */  _length_code[length - 1] = code;  /* Initialize the mapping dist (0..32K) -> dist code (0..29) */  dist = 0;  for (code = 0; code < 16; code++) {    base_dist[code] = dist;    for (n = 0; n < (1 << extra_dbits[code]); n++) {      _dist_code[dist++] = code;    }  }  //Assert (dist == 256, "tr_static_init: dist != 256");  dist >>= 7; /* from now on, all distances are divided by 128 */  for (; code < D_CODES; code++) {    base_dist[code] = dist << 7;    for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) {      _dist_code[256 + dist++] = code;    }  }  //Assert (dist == 256, "tr_static_init: 256+dist != 512");  /* Construct the codes of the static literal tree */  for (bits = 0; bits <= MAX_BITS; bits++) {    bl_count[bits] = 0;  }  n = 0;  while (n <= 143) {    static_ltree[n * 2 + 1]/*.Len*/ = 8;    n++;    bl_count[8]++;  }  while (n <= 255) {    static_ltree[n * 2 + 1]/*.Len*/ = 9;    n++;    bl_count[9]++;  }  while (n <= 279) {    static_ltree[n * 2 + 1]/*.Len*/ = 7;    n++;    bl_count[7]++;  }  while (n <= 287) {    static_ltree[n * 2 + 1]/*.Len*/ = 8;    n++;    bl_count[8]++;  }  /* Codes 286 and 287 do not exist, but we must include them in the   * tree construction to get a canonical Huffman tree (longest code   * all ones)   */  gen_codes(static_ltree, L_CODES + 1, bl_count);  /* The static distance tree is trivial: */  for (n = 0; n < D_CODES; n++) {    static_dtree[n * 2 + 1]/*.Len*/ = 5;    static_dtree[n * 2]/*.Code*/ = bi_reverse(n, 5);  }  // Now data ready and we can init static trees  static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS + 1, L_CODES, MAX_BITS);  static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS);  static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0,         BL_CODES, MAX_BL_BITS);  //static_init_done = true;}/* =========================================================================== * Initialize a new block. */function init_block(s) {  var n; /* iterates over tree elements */  /* Initialize the trees. */  for (n = 0; n < L_CODES;  n++) { s.dyn_ltree[n * 2]/*.Freq*/ = 0; }  for (n = 0; n < D_CODES;  n++) { s.dyn_dtree[n * 2]/*.Freq*/ = 0; }  for (n = 0; n < BL_CODES; n++) { s.bl_tree[n * 2]/*.Freq*/ = 0; }  s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1;  s.opt_len = s.static_len = 0;  s.last_lit = s.matches = 0;}/* =========================================================================== * Flush the bit buffer and align the output on a byte boundary */function bi_windup(s){  if (s.bi_valid > 8) {    put_short(s, s.bi_buf);  } else if (s.bi_valid > 0) {    //put_byte(s, (Byte)s->bi_buf);    s.pending_buf[s.pending++] = s.bi_buf;  }  s.bi_buf = 0;  s.bi_valid = 0;}/* =========================================================================== * Copy a stored block, storing first the length and its * one's complement if requested. */function copy_block(s, buf, len, header)//DeflateState *s;//charf    *buf;    /* the input data *///unsigned len;     /* its length *///int      header;  /* true if block header must be written */{  bi_windup(s);        /* align on byte boundary */  if (header) {    put_short(s, len);    put_short(s, ~len);  }//  while (len--) {//    put_byte(s, *buf++);//  }  utils.arraySet(s.pending_buf, s.window, buf, len, s.pending);  s.pending += len;}/* =========================================================================== * Compares to subtrees, using the tree depth as tie breaker when * the subtrees have equal frequency. This minimizes the worst case length. */function smaller(tree, n, m, depth) {  var _n2 = n * 2;  var _m2 = m * 2;  return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ ||         (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m]));}/* =========================================================================== * Restore the heap property by moving down the tree starting at node k, * exchanging a node with the smallest of its two sons if necessary, stopping * when the heap property is re-established (each father smaller than its * two sons). */function pqdownheap(s, tree, k)//    deflate_state *s;//    ct_data *tree;  /* the tree to restore *///    int k;               /* node to move down */{  var v = s.heap[k];  var j = k << 1;  /* left son of k */  while (j <= s.heap_len) {    /* Set j to the smallest of the two sons: */    if (j < s.heap_len &&      smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) {      j++;    }    /* Exit if v is smaller than both sons */    if (smaller(tree, v, s.heap[j], s.depth)) { break; }    /* Exchange v with the smallest son */    s.heap[k] = s.heap[j];    k = j;    /* And continue down the tree, setting j to the left son of k */    j <<= 1;  }  s.heap[k] = v;}// inlined manually// var SMALLEST = 1;/* =========================================================================== * Send the block data compressed using the given Huffman trees */function compress_block(s, ltree, dtree)//    deflate_state *s;//    const ct_data *ltree; /* literal tree *///    const ct_data *dtree; /* distance tree */{  var dist;           /* distance of matched string */  var lc;             /* match length or unmatched char (if dist == 0) */  var lx = 0;         /* running index in l_buf */  var code;           /* the code to send */  var extra;          /* number of extra bits to send */  if (s.last_lit !== 0) {    do {      dist = (s.pending_buf[s.d_buf + lx * 2] << 8) | (s.pending_buf[s.d_buf + lx * 2 + 1]);      lc = s.pending_buf[s.l_buf + lx];      lx++;      if (dist === 0) {        send_code(s, lc, ltree); /* send a literal byte */        //Tracecv(isgraph(lc), (stderr," '%c' ", lc));      } else {        /* Here, lc is the match length - MIN_MATCH */        code = _length_code[lc];        send_code(s, code + LITERALS + 1, ltree); /* send the length code */        extra = extra_lbits[code];        if (extra !== 0) {          lc -= base_length[code];          send_bits(s, lc, extra);       /* send the extra length bits */        }        dist--; /* dist is now the match distance - 1 */        code = d_code(dist);        //Assert (code < D_CODES, "bad d_code");        send_code(s, code, dtree);       /* send the distance code */        extra = extra_dbits[code];        if (extra !== 0) {          dist -= base_dist[code];          send_bits(s, dist, extra);   /* send the extra distance bits */        }      } /* literal or match pair ? */      /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */      //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,      //       "pendingBuf overflow");    } while (lx < s.last_lit);  }  send_code(s, END_BLOCK, ltree);}/* =========================================================================== * Construct one Huffman tree and assigns the code bit strings and lengths. * Update the total bit length for the current block. * IN assertion: the field freq is set for all tree elements. * OUT assertions: the fields len and code are set to the optimal bit length *     and corresponding code. The length opt_len is updated; static_len is *     also updated if stree is not null. The field max_code is set. */function build_tree(s, desc)//    deflate_state *s;//    tree_desc *desc; /* the tree descriptor */{  var tree     = desc.dyn_tree;  var stree    = desc.stat_desc.static_tree;  var has_stree = desc.stat_desc.has_stree;  var elems    = desc.stat_desc.elems;  var n, m;          /* iterate over heap elements */  var max_code = -1; /* largest code with non zero frequency */  var node;          /* new node being created */  /* Construct the initial heap, with least frequent element in   * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].   * heap[0] is not used.   */  s.heap_len = 0;  s.heap_max = HEAP_SIZE;  for (n = 0; n < elems; n++) {    if (tree[n * 2]/*.Freq*/ !== 0) {      s.heap[++s.heap_len] = max_code = n;      s.depth[n] = 0;    } else {      tree[n * 2 + 1]/*.Len*/ = 0;    }  }  /* The pkzip format requires that at least one distance code exists,   * and that at least one bit should be sent even if there is only one   * possible code. So to avoid special checks later on we force at least   * two codes of non zero frequency.   */  while (s.heap_len < 2) {    node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0);    tree[node * 2]/*.Freq*/ = 1;    s.depth[node] = 0;    s.opt_len--;    if (has_stree) {      s.static_len -= stree[node * 2 + 1]/*.Len*/;    }    /* node is 0 or 1 so it does not have extra bits */  }  desc.max_code = max_code;  /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,   * establish sub-heaps of increasing lengths:   */  for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); }  /* Construct the Huffman tree by repeatedly combining the least two   * frequent nodes.   */  node = elems;              /* next internal node of the tree */  do {    //pqremove(s, tree, n);  /* n = node of least frequency */    /*** pqremove ***/    n = s.heap[1/*SMALLEST*/];    s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--];    pqdownheap(s, tree, 1/*SMALLEST*/);    /***/    m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */    s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */    s.heap[--s.heap_max] = m;    /* Create a new node father of n and m */    tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/;    s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1;    tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node;    /* and insert the new node in the heap */    s.heap[1/*SMALLEST*/] = node++;    pqdownheap(s, tree, 1/*SMALLEST*/);  } while (s.heap_len >= 2);  s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/];  /* At this point, the fields freq and dad are set. We can now   * generate the bit lengths.   */  gen_bitlen(s, desc);  /* The field len is now set, we can generate the bit codes */  gen_codes(tree, max_code, s.bl_count);}/* =========================================================================== * Scan a literal or distance tree to determine the frequencies of the codes * in the bit length tree. */function scan_tree(s, tree, max_code)//    deflate_state *s;//    ct_data *tree;   /* the tree to be scanned *///    int max_code;    /* and its largest code of non zero frequency */{  var n;                     /* iterates over all tree elements */  var prevlen = -1;          /* last emitted length */  var curlen;                /* length of current code */  var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */  var count = 0;             /* repeat count of the current code */  var max_count = 7;         /* max repeat count */  var min_count = 4;         /* min repeat count */  if (nextlen === 0) {    max_count = 138;    min_count = 3;  }  tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */  for (n = 0; n <= max_code; n++) {    curlen = nextlen;    nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;    if (++count < max_count && curlen === nextlen) {      continue;    } else if (count < min_count) {      s.bl_tree[curlen * 2]/*.Freq*/ += count;    } else if (curlen !== 0) {      if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; }      s.bl_tree[REP_3_6 * 2]/*.Freq*/++;    } else if (count <= 10) {      s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++;    } else {      s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++;    }    count = 0;    prevlen = curlen;    if (nextlen === 0) {      max_count = 138;      min_count = 3;    } else if (curlen === nextlen) {      max_count = 6;      min_count = 3;    } else {      max_count = 7;      min_count = 4;    }  }}/* =========================================================================== * Send a literal or distance tree in compressed form, using the codes in * bl_tree. */function send_tree(s, tree, max_code)//    deflate_state *s;//    ct_data *tree; /* the tree to be scanned *///    int max_code;       /* and its largest code of non zero frequency */{  var n;                     /* iterates over all tree elements */  var prevlen = -1;          /* last emitted length */  var curlen;                /* length of current code */  var nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */  var count = 0;             /* repeat count of the current code */  var max_count = 7;         /* max repeat count */  var min_count = 4;         /* min repeat count */  /* tree[max_code+1].Len = -1; */  /* guard already set */  if (nextlen === 0) {    max_count = 138;    min_count = 3;  }  for (n = 0; n <= max_code; n++) {    curlen = nextlen;    nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;    if (++count < max_count && curlen === nextlen) {      continue;    } else if (count < min_count) {      do { send_code(s, curlen, s.bl_tree); } while (--count !== 0);    } else if (curlen !== 0) {      if (curlen !== prevlen) {        send_code(s, curlen, s.bl_tree);        count--;      }      //Assert(count >= 3 && count <= 6, " 3_6?");      send_code(s, REP_3_6, s.bl_tree);      send_bits(s, count - 3, 2);    } else if (count <= 10) {      send_code(s, REPZ_3_10, s.bl_tree);      send_bits(s, count - 3, 3);    } else {      send_code(s, REPZ_11_138, s.bl_tree);      send_bits(s, count - 11, 7);    }    count = 0;    prevlen = curlen;    if (nextlen === 0) {      max_count = 138;      min_count = 3;    } else if (curlen === nextlen) {      max_count = 6;      min_count = 3;    } else {      max_count = 7;      min_count = 4;    }  }}/* =========================================================================== * Construct the Huffman tree for the bit lengths and return the index in * bl_order of the last bit length code to send. */function build_bl_tree(s) {  var max_blindex;  /* index of last bit length code of non zero freq */  /* Determine the bit length frequencies for literal and distance trees */  scan_tree(s, s.dyn_ltree, s.l_desc.max_code);  scan_tree(s, s.dyn_dtree, s.d_desc.max_code);  /* Build the bit length tree: */  build_tree(s, s.bl_desc);  /* opt_len now includes the length of the tree representations, except   * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.   */  /* Determine the number of bit length codes to send. The pkzip format   * requires that at least 4 bit length codes be sent. (appnote.txt says   * 3 but the actual value used is 4.)   */  for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {    if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) {      break;    }  }  /* Update opt_len to include the bit length tree and counts */  s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;  //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",  //        s->opt_len, s->static_len));  return max_blindex;}/* =========================================================================== * Send the header for a block using dynamic Huffman trees: the counts, the * lengths of the bit length codes, the literal tree and the distance tree. * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. */function send_all_trees(s, lcodes, dcodes, blcodes)//    deflate_state *s;//    int lcodes, dcodes, blcodes; /* number of codes for each tree */{  var rank;                    /* index in bl_order */  //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");  //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,  //        "too many codes");  //Tracev((stderr, "\nbl counts: "));  send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */  send_bits(s, dcodes - 1,   5);  send_bits(s, blcodes - 4,  4); /* not -3 as stated in appnote.txt */  for (rank = 0; rank < blcodes; rank++) {    //Tracev((stderr, "\nbl code %2d ", bl_order[rank]));    send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3);  }  //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));  send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */  //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));  send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */  //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));}/* =========================================================================== * Check if the data type is TEXT or BINARY, using the following algorithm: * - TEXT if the two conditions below are satisfied: *    a) There are no non-portable control characters belonging to the *       "black list" (0..6, 14..25, 28..31). *    b) There is at least one printable character belonging to the *       "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). * - BINARY otherwise. * - The following partially-portable control characters form a *   "gray list" that is ignored in this detection algorithm: *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). * IN assertion: the fields Freq of dyn_ltree are set. */function detect_data_type(s) {  /* black_mask is the bit mask of black-listed bytes   * set bits 0..6, 14..25, and 28..31   * 0xf3ffc07f = binary 11110011111111111100000001111111   */  var black_mask = 0xf3ffc07f;  var n;  /* Check for non-textual ("black-listed") bytes. */  for (n = 0; n <= 31; n++, black_mask >>>= 1) {    if ((black_mask & 1) && (s.dyn_ltree[n * 2]/*.Freq*/ !== 0)) {      return Z_BINARY;    }  }  /* Check for textual ("white-listed") bytes. */  if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 ||      s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) {    return Z_TEXT;  }  for (n = 32; n < LITERALS; n++) {    if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) {      return Z_TEXT;    }  }  /* There are no "black-listed" or "white-listed" bytes:   * this stream either is empty or has tolerated ("gray-listed") bytes only.   */  return Z_BINARY;}var static_init_done = false;/* =========================================================================== * Initialize the tree data structures for a new zlib stream. */function _tr_init(s){  if (!static_init_done) {    tr_static_init();    static_init_done = true;  }  s.l_desc  = new TreeDesc(s.dyn_ltree, static_l_desc);  s.d_desc  = new TreeDesc(s.dyn_dtree, static_d_desc);  s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc);  s.bi_buf = 0;  s.bi_valid = 0;  /* Initialize the first block of the first file: */  init_block(s);}/* =========================================================================== * Send a stored block */function _tr_stored_block(s, buf, stored_len, last)//DeflateState *s;//charf *buf;       /* input block *///ulg stored_len;   /* length of input block *///int last;         /* one if this is the last block for a file */{  send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3);    /* send block type */  copy_block(s, buf, stored_len, true); /* with header */}/* =========================================================================== * Send one empty static block to give enough lookahead for inflate. * This takes 10 bits, of which 7 may remain in the bit buffer. */function _tr_align(s) {  send_bits(s, STATIC_TREES << 1, 3);  send_code(s, END_BLOCK, static_ltree);  bi_flush(s);}/* =========================================================================== * Determine the best encoding for the current block: dynamic trees, static * trees or store, and output the encoded block to the zip file. */function _tr_flush_block(s, buf, stored_len, last)//DeflateState *s;//charf *buf;       /* input block, or NULL if too old *///ulg stored_len;   /* length of input block *///int last;         /* one if this is the last block for a file */{  var opt_lenb, static_lenb;  /* opt_len and static_len in bytes */  var max_blindex = 0;        /* index of last bit length code of non zero freq */  /* Build the Huffman trees unless a stored block is forced */  if (s.level > 0) {    /* Check if the file is binary or text */    if (s.strm.data_type === Z_UNKNOWN) {      s.strm.data_type = detect_data_type(s);    }    /* Construct the literal and distance trees */    build_tree(s, s.l_desc);    // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,    //        s->static_len));    build_tree(s, s.d_desc);    // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,    //        s->static_len));    /* At this point, opt_len and static_len are the total bit lengths of     * the compressed block data, excluding the tree representations.     */    /* Build the bit length tree for the above two trees, and get the index     * in bl_order of the last bit length code to send.     */    max_blindex = build_bl_tree(s);    /* Determine the best encoding. Compute the block lengths in bytes. */    opt_lenb = (s.opt_len + 3 + 7) >>> 3;    static_lenb = (s.static_len + 3 + 7) >>> 3;    // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",    //        opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,    //        s->last_lit));    if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; }  } else {    // Assert(buf != (char*)0, "lost buf");    opt_lenb = static_lenb = stored_len + 5; /* force a stored block */  }  if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) {    /* 4: two words for the lengths */    /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.     * Otherwise we can't have processed more than WSIZE input bytes since     * the last block flush, because compression would have been     * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to     * transform a block into a stored block.     */    _tr_stored_block(s, buf, stored_len, last);  } else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) {    send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3);    compress_block(s, static_ltree, static_dtree);  } else {    send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3);    send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1);    compress_block(s, s.dyn_ltree, s.dyn_dtree);  }  // Assert (s->compressed_len == s->bits_sent, "bad compressed size");  /* The above check is made mod 2^32, for files larger than 512 MB   * and uLong implemented on 32 bits.   */  init_block(s);  if (last) {    bi_windup(s);  }  // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,  //       s->compressed_len-7*last));}/* =========================================================================== * Save the match info and tally the frequency counts. Return true if * the current block must be flushed. */function _tr_tally(s, dist, lc)//    deflate_state *s;//    unsigned dist;  /* distance of matched string *///    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */{  //var out_length, in_length, dcode;  s.pending_buf[s.d_buf + s.last_lit * 2]     = (dist >>> 8) & 0xff;  s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff;  s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff;  s.last_lit++;  if (dist === 0) {    /* lc is the unmatched char */    s.dyn_ltree[lc * 2]/*.Freq*/++;  } else {    s.matches++;    /* Here, lc is the match length - MIN_MATCH */    dist--;             /* dist = match distance - 1 */    //Assert((ush)dist < (ush)MAX_DIST(s) &&    //       (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&    //       (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");    s.dyn_ltree[(_length_code[lc] + LITERALS + 1) * 2]/*.Freq*/++;    s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++;  }// (!) This block is disabled in zlib defaults,// don't enable it for binary compatibility//#ifdef TRUNCATE_BLOCK//  /* Try to guess if it is profitable to stop the current block here *///  if ((s.last_lit & 0x1fff) === 0 && s.level > 2) {//    /* Compute an upper bound for the compressed length *///    out_length = s.last_lit*8;//    in_length = s.strstart - s.block_start;////    for (dcode = 0; dcode < D_CODES; dcode++) {//      out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]);//    }//    out_length >>>= 3;//    //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",//    //       s->last_lit, in_length, out_length,//    //       100L - out_length*100L/in_length));//    if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) {//      return true;//    }//  }//#endif  return (s.last_lit === s.lit_bufsize - 1);  /* We avoid equality with lit_bufsize because of wraparound at 64K   * on 16 bit machines and because stored blocks are restricted to   * 64K-1 bytes.   */}exports._tr_init  = _tr_init;exports._tr_stored_block = _tr_stored_block;exports._tr_flush_block  = _tr_flush_block;exports._tr_tally = _tr_tally;exports._tr_align = _tr_align;},{"../utils/common":202}],214:[function(require,module,exports){'use strict';// (C) 1995-2013 Jean-loup Gailly and Mark Adler// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin//// This software is provided 'as-is', without any express or implied// warranty. In no event will the authors be held liable for any damages// arising from the use of this software.//// Permission is granted to anyone to use this software for any purpose,// including commercial applications, and to alter it and redistribute it// freely, subject to the following restrictions://// 1. The origin of this software must not be misrepresented; you must not//   claim that you wrote the original software. If you use this software//   in a product, an acknowledgment in the product documentation would be//   appreciated but is not required.// 2. Altered source versions must be plainly marked as such, and must not be//   misrepresented as being the original software.// 3. This notice may not be removed or altered from any source distribution.function ZStream() {  /* next input byte */  this.input = null; // JS specific, because we have no pointers  this.next_in = 0;  /* number of bytes available at input */  this.avail_in = 0;  /* total number of input bytes read so far */  this.total_in = 0;  /* next output byte should be put there */  this.output = null; // JS specific, because we have no pointers  this.next_out = 0;  /* remaining free space at output */  this.avail_out = 0;  /* total number of bytes output so far */  this.total_out = 0;  /* last error message, NULL if no error */  this.msg = ''/*Z_NULL*/;  /* not visible by applications */  this.state = null;  /* best guess about the data type: binary or text */  this.data_type = 2/*Z_UNKNOWN*/;  /* adler32 value of the uncompressed data */  this.adler = 0;}module.exports = ZStream;},{}],215:[function(require,module,exports){module.exports={"2.16.840.1.101.3.4.1.1": "aes-128-ecb","2.16.840.1.101.3.4.1.2": "aes-128-cbc","2.16.840.1.101.3.4.1.3": "aes-128-ofb","2.16.840.1.101.3.4.1.4": "aes-128-cfb","2.16.840.1.101.3.4.1.21": "aes-192-ecb","2.16.840.1.101.3.4.1.22": "aes-192-cbc","2.16.840.1.101.3.4.1.23": "aes-192-ofb","2.16.840.1.101.3.4.1.24": "aes-192-cfb","2.16.840.1.101.3.4.1.41": "aes-256-ecb","2.16.840.1.101.3.4.1.42": "aes-256-cbc","2.16.840.1.101.3.4.1.43": "aes-256-ofb","2.16.840.1.101.3.4.1.44": "aes-256-cfb"}},{}],216:[function(require,module,exports){// from https://github.com/indutny/self-signed/blob/gh-pages/lib/asn1.js// Fedor, you are amazing.'use strict'var asn1 = require('asn1.js')exports.certificate = require('./certificate')var RSAPrivateKey = asn1.define('RSAPrivateKey', function () {  this.seq().obj(    this.key('version').int(),    this.key('modulus').int(),    this.key('publicExponent').int(),    this.key('privateExponent').int(),    this.key('prime1').int(),    this.key('prime2').int(),    this.key('exponent1').int(),    this.key('exponent2').int(),    this.key('coefficient').int()  )})exports.RSAPrivateKey = RSAPrivateKeyvar RSAPublicKey = asn1.define('RSAPublicKey', function () {  this.seq().obj(    this.key('modulus').int(),    this.key('publicExponent').int()  )})exports.RSAPublicKey = RSAPublicKeyvar PublicKey = asn1.define('SubjectPublicKeyInfo', function () {  this.seq().obj(    this.key('algorithm').use(AlgorithmIdentifier),    this.key('subjectPublicKey').bitstr()  )})exports.PublicKey = PublicKeyvar AlgorithmIdentifier = asn1.define('AlgorithmIdentifier', function () {  this.seq().obj(    this.key('algorithm').objid(),    this.key('none').null_().optional(),    this.key('curve').objid().optional(),    this.key('params').seq().obj(      this.key('p').int(),      this.key('q').int(),      this.key('g').int()    ).optional()  )})var PrivateKeyInfo = asn1.define('PrivateKeyInfo', function () {  this.seq().obj(    this.key('version').int(),    this.key('algorithm').use(AlgorithmIdentifier),    this.key('subjectPrivateKey').octstr()  )})exports.PrivateKey = PrivateKeyInfovar EncryptedPrivateKeyInfo = asn1.define('EncryptedPrivateKeyInfo', function () {  this.seq().obj(    this.key('algorithm').seq().obj(      this.key('id').objid(),      this.key('decrypt').seq().obj(        this.key('kde').seq().obj(          this.key('id').objid(),          this.key('kdeparams').seq().obj(            this.key('salt').octstr(),            this.key('iters').int()          )        ),        this.key('cipher').seq().obj(          this.key('algo').objid(),          this.key('iv').octstr()        )      )    ),    this.key('subjectPrivateKey').octstr()  )})exports.EncryptedPrivateKey = EncryptedPrivateKeyInfovar DSAPrivateKey = asn1.define('DSAPrivateKey', function () {  this.seq().obj(    this.key('version').int(),    this.key('p').int(),    this.key('q').int(),    this.key('g').int(),    this.key('pub_key').int(),    this.key('priv_key').int()  )})exports.DSAPrivateKey = DSAPrivateKeyexports.DSAparam = asn1.define('DSAparam', function () {  this.int()})var ECPrivateKey = asn1.define('ECPrivateKey', function () {  this.seq().obj(    this.key('version').int(),    this.key('privateKey').octstr(),    this.key('parameters').optional().explicit(0).use(ECParameters),    this.key('publicKey').optional().explicit(1).bitstr()  )})exports.ECPrivateKey = ECPrivateKeyvar ECParameters = asn1.define('ECParameters', function () {  this.choice({    namedCurve: this.objid()  })})exports.signature = asn1.define('signature', function () {  this.seq().obj(    this.key('r').int(),    this.key('s').int()  )})},{"./certificate":217,"asn1.js":30}],217:[function(require,module,exports){// from https://github.com/Rantanen/node-dtls/blob/25a7dc861bda38cfeac93a723500eea4f0ac2e86/Certificate.js// thanks to @Rantanen'use strict'var asn = require('asn1.js')var Time = asn.define('Time', function () {  this.choice({    utcTime: this.utctime(),    generalTime: this.gentime()  })})var AttributeTypeValue = asn.define('AttributeTypeValue', function () {  this.seq().obj(    this.key('type').objid(),    this.key('value').any()  )})var AlgorithmIdentifier = asn.define('AlgorithmIdentifier', function () {  this.seq().obj(    this.key('algorithm').objid(),    this.key('parameters').optional(),    this.key('curve').objid().optional()  )})var SubjectPublicKeyInfo = asn.define('SubjectPublicKeyInfo', function () {  this.seq().obj(    this.key('algorithm').use(AlgorithmIdentifier),    this.key('subjectPublicKey').bitstr()  )})var RelativeDistinguishedName = asn.define('RelativeDistinguishedName', function () {  this.setof(AttributeTypeValue)})var RDNSequence = asn.define('RDNSequence', function () {  this.seqof(RelativeDistinguishedName)})var Name = asn.define('Name', function () {  this.choice({    rdnSequence: this.use(RDNSequence)  })})var Validity = asn.define('Validity', function () {  this.seq().obj(    this.key('notBefore').use(Time),    this.key('notAfter').use(Time)  )})var Extension = asn.define('Extension', function () {  this.seq().obj(    this.key('extnID').objid(),    this.key('critical').bool().def(false),    this.key('extnValue').octstr()  )})var TBSCertificate = asn.define('TBSCertificate', function () {  this.seq().obj(    this.key('version').explicit(0).int().optional(),    this.key('serialNumber').int(),    this.key('signature').use(AlgorithmIdentifier),    this.key('issuer').use(Name),    this.key('validity').use(Validity),    this.key('subject').use(Name),    this.key('subjectPublicKeyInfo').use(SubjectPublicKeyInfo),    this.key('issuerUniqueID').implicit(1).bitstr().optional(),    this.key('subjectUniqueID').implicit(2).bitstr().optional(),    this.key('extensions').explicit(3).seqof(Extension).optional()  )})var X509Certificate = asn.define('X509Certificate', function () {  this.seq().obj(    this.key('tbsCertificate').use(TBSCertificate),    this.key('signatureAlgorithm').use(AlgorithmIdentifier),    this.key('signatureValue').bitstr()  )})module.exports = X509Certificate},{"asn1.js":30}],218:[function(require,module,exports){(function (Buffer){// adapted from https://github.com/apatil/pemstripvar findProc = /Proc-Type: 4,ENCRYPTED[\n\r]+DEK-Info: AES-((?:128)|(?:192)|(?:256))-CBC,([0-9A-H]+)[\n\r]+([0-9A-z\n\r\+\/\=]+)[\n\r]+/mvar startRegex = /^-----BEGIN ((?:.* KEY)|CERTIFICATE)-----/mvar fullRegex = /^-----BEGIN ((?:.* KEY)|CERTIFICATE)-----([0-9A-z\n\r\+\/\=]+)-----END \1-----$/mvar evp = require('evp_bytestokey')var ciphers = require('browserify-aes')module.exports = function (okey, password) {  var key = okey.toString()  var match = key.match(findProc)  var decrypted  if (!match) {    var match2 = key.match(fullRegex)    decrypted = new Buffer(match2[2].replace(/[\r\n]/g, ''), 'base64')  } else {    var suite = 'aes' + match[1]    var iv = new Buffer(match[2], 'hex')    var cipherText = new Buffer(match[3].replace(/[\r\n]/g, ''), 'base64')    var cipherKey = evp(password, iv.slice(0, 8), parseInt(match[1], 10)).key    var out = []    var cipher = ciphers.createDecipheriv(suite, cipherKey, iv)    out.push(cipher.update(cipherText))    out.push(cipher.final())    decrypted = Buffer.concat(out)  }  var tag = key.match(startRegex)[1]  return {    tag: tag,    data: decrypted  }}}).call(this,require("buffer").Buffer)},{"browserify-aes":50,"buffer":79,"evp_bytestokey":137}],219:[function(require,module,exports){var asn1 = require('./asn1')var aesid = require('./aesid.json')var fixProc = require('./fixProc')var ciphers = require('browserify-aes')var compat = require('pbkdf2')var Buffer = require('safe-buffer').Buffermodule.exports = parseKeysfunction parseKeys (buffer) {  var password  if (typeof buffer === 'object' && !Buffer.isBuffer(buffer)) {    password = buffer.passphrase    buffer = buffer.key  }  if (typeof buffer === 'string') {    buffer = Buffer.from(buffer)  }  var stripped = fixProc(buffer, password)  var type = stripped.tag  var data = stripped.data  var subtype, ndata  switch (type) {    case 'CERTIFICATE':      ndata = asn1.certificate.decode(data, 'der').tbsCertificate.subjectPublicKeyInfo      // falls through    case 'PUBLIC KEY':      if (!ndata) {        ndata = asn1.PublicKey.decode(data, 'der')      }      subtype = ndata.algorithm.algorithm.join('.')      switch (subtype) {        case '1.2.840.113549.1.1.1':          return asn1.RSAPublicKey.decode(ndata.subjectPublicKey.data, 'der')        case '1.2.840.10045.2.1':          ndata.subjectPrivateKey = ndata.subjectPublicKey          return {            type: 'ec',            data: ndata          }        case '1.2.840.10040.4.1':          ndata.algorithm.params.pub_key = asn1.DSAparam.decode(ndata.subjectPublicKey.data, 'der')          return {            type: 'dsa',            data: ndata.algorithm.params          }        default: throw new Error('unknown key id ' + subtype)      }      throw new Error('unknown key type ' + type)    case 'ENCRYPTED PRIVATE KEY':      data = asn1.EncryptedPrivateKey.decode(data, 'der')      data = decrypt(data, password)      // falls through    case 'PRIVATE KEY':      ndata = asn1.PrivateKey.decode(data, 'der')      subtype = ndata.algorithm.algorithm.join('.')      switch (subtype) {        case '1.2.840.113549.1.1.1':          return asn1.RSAPrivateKey.decode(ndata.subjectPrivateKey, 'der')        case '1.2.840.10045.2.1':          return {            curve: ndata.algorithm.curve,            privateKey: asn1.ECPrivateKey.decode(ndata.subjectPrivateKey, 'der').privateKey          }        case '1.2.840.10040.4.1':          ndata.algorithm.params.priv_key = asn1.DSAparam.decode(ndata.subjectPrivateKey, 'der')          return {            type: 'dsa',            params: ndata.algorithm.params          }        default: throw new Error('unknown key id ' + subtype)      }      throw new Error('unknown key type ' + type)    case 'RSA PUBLIC KEY':      return asn1.RSAPublicKey.decode(data, 'der')    case 'RSA PRIVATE KEY':      return asn1.RSAPrivateKey.decode(data, 'der')    case 'DSA PRIVATE KEY':      return {        type: 'dsa',        params: asn1.DSAPrivateKey.decode(data, 'der')      }    case 'EC PRIVATE KEY':      data = asn1.ECPrivateKey.decode(data, 'der')      return {        curve: data.parameters.value,        privateKey: data.privateKey      }    default: throw new Error('unknown key type ' + type)  }}parseKeys.signature = asn1.signaturefunction decrypt (data, password) {  var salt = data.algorithm.decrypt.kde.kdeparams.salt  var iters = parseInt(data.algorithm.decrypt.kde.kdeparams.iters.toString(), 10)  var algo = aesid[data.algorithm.decrypt.cipher.algo.join('.')]  var iv = data.algorithm.decrypt.cipher.iv  var cipherText = data.subjectPrivateKey  var keylen = parseInt(algo.split('-')[1], 10) / 8  var key = compat.pbkdf2Sync(password, salt, iters, keylen, 'sha1')  var cipher = ciphers.createDecipheriv(algo, key, iv)  var out = []  out.push(cipher.update(cipherText))  out.push(cipher.final())  return Buffer.concat(out)}},{"./aesid.json":215,"./asn1":216,"./fixProc":218,"browserify-aes":50,"pbkdf2":220,"safe-buffer":247}],220:[function(require,module,exports){exports.pbkdf2 = require('./lib/async')exports.pbkdf2Sync = require('./lib/sync')},{"./lib/async":221,"./lib/sync":224}],221:[function(require,module,exports){(function (process,global){var checkParameters = require('./precondition')var defaultEncoding = require('./default-encoding')var sync = require('./sync')var Buffer = require('safe-buffer').Buffervar ZERO_BUFvar subtle = global.crypto && global.crypto.subtlevar toBrowser = {  'sha': 'SHA-1',  'sha-1': 'SHA-1',  'sha1': 'SHA-1',  'sha256': 'SHA-256',  'sha-256': 'SHA-256',  'sha384': 'SHA-384',  'sha-384': 'SHA-384',  'sha-512': 'SHA-512',  'sha512': 'SHA-512'}var checks = []function checkNative (algo) {  if (global.process && !global.process.browser) {    return Promise.resolve(false)  }  if (!subtle || !subtle.importKey || !subtle.deriveBits) {    return Promise.resolve(false)  }  if (checks[algo] !== undefined) {    return checks[algo]  }  ZERO_BUF = ZERO_BUF || Buffer.alloc(8)  var prom = browserPbkdf2(ZERO_BUF, ZERO_BUF, 10, 128, algo)    .then(function () {      return true    }).catch(function () {      return false    })  checks[algo] = prom  return prom}function browserPbkdf2 (password, salt, iterations, length, algo) {  return subtle.importKey(    'raw', password, {name: 'PBKDF2'}, false, ['deriveBits']  ).then(function (key) {    return subtle.deriveBits({      name: 'PBKDF2',      salt: salt,      iterations: iterations,      hash: {        name: algo      }    }, key, length << 3)  }).then(function (res) {    return Buffer.from(res)  })}function resolvePromise (promise, callback) {  promise.then(function (out) {    process.nextTick(function () {      callback(null, out)    })  }, function (e) {    process.nextTick(function () {      callback(e)    })  })}module.exports = function (password, salt, iterations, keylen, digest, callback) {  if (typeof digest === 'function') {    callback = digest    digest = undefined  }  digest = digest || 'sha1'  var algo = toBrowser[digest.toLowerCase()]  if (!algo || typeof global.Promise !== 'function') {    return process.nextTick(function () {      var out      try {        out = sync(password, salt, iterations, keylen, digest)      } catch (e) {        return callback(e)      }      callback(null, out)    })  }  checkParameters(password, salt, iterations, keylen)  if (typeof callback !== 'function') throw new Error('No callback provided to pbkdf2')  if (!Buffer.isBuffer(password)) password = Buffer.from(password, defaultEncoding)  if (!Buffer.isBuffer(salt)) salt = Buffer.from(salt, defaultEncoding)  resolvePromise(checkNative(algo).then(function (resp) {    if (resp) return browserPbkdf2(password, salt, iterations, keylen, algo)    return sync(password, salt, iterations, keylen, digest)  }), callback)}}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})},{"./default-encoding":222,"./precondition":223,"./sync":224,"_process":226,"safe-buffer":247}],222:[function(require,module,exports){(function (process){var defaultEncoding/* istanbul ignore next */if (process.browser) {  defaultEncoding = 'utf-8'} else {  var pVersionMajor = parseInt(process.version.split('.')[0].slice(1), 10)  defaultEncoding = pVersionMajor >= 6 ? 'utf-8' : 'binary'}module.exports = defaultEncoding}).call(this,require('_process'))},{"_process":226}],223:[function(require,module,exports){(function (Buffer){var MAX_ALLOC = Math.pow(2, 30) - 1 // default in iojsfunction checkBuffer (buf, name) {  if (typeof buf !== 'string' && !Buffer.isBuffer(buf)) {    throw new TypeError(name + ' must be a buffer or string')  }}module.exports = function (password, salt, iterations, keylen) {  checkBuffer(password, 'Password')  checkBuffer(salt, 'Salt')  if (typeof iterations !== 'number') {    throw new TypeError('Iterations not a number')  }  if (iterations < 0) {    throw new TypeError('Bad iterations')  }  if (typeof keylen !== 'number') {    throw new TypeError('Key length not a number')  }  if (keylen < 0 || keylen > MAX_ALLOC || keylen !== keylen) { /* eslint no-self-compare: 0 */    throw new TypeError('Bad key length')  }}}).call(this,{"isBuffer":require("../../is-buffer/index.js")})},{"../../is-buffer/index.js":155}],224:[function(require,module,exports){var md5 = require('create-hash/md5')var RIPEMD160 = require('ripemd160')var sha = require('sha.js')var checkParameters = require('./precondition')var defaultEncoding = require('./default-encoding')var Buffer = require('safe-buffer').Buffervar ZEROS = Buffer.alloc(128)var sizes = {  md5: 16,  sha1: 20,  sha224: 28,  sha256: 32,  sha384: 48,  sha512: 64,  rmd160: 20,  ripemd160: 20}function Hmac (alg, key, saltLen) {  var hash = getDigest(alg)  var blocksize = (alg === 'sha512' || alg === 'sha384') ? 128 : 64  if (key.length > blocksize) {    key = hash(key)  } else if (key.length < blocksize) {    key = Buffer.concat([key, ZEROS], blocksize)  }  var ipad = Buffer.allocUnsafe(blocksize + sizes[alg])  var opad = Buffer.allocUnsafe(blocksize + sizes[alg])  for (var i = 0; i < blocksize; i++) {    ipad[i] = key[i] ^ 0x36    opad[i] = key[i] ^ 0x5C  }  var ipad1 = Buffer.allocUnsafe(blocksize + saltLen + 4)  ipad.copy(ipad1, 0, 0, blocksize)  this.ipad1 = ipad1  this.ipad2 = ipad  this.opad = opad  this.alg = alg  this.blocksize = blocksize  this.hash = hash  this.size = sizes[alg]}Hmac.prototype.run = function (data, ipad) {  data.copy(ipad, this.blocksize)  var h = this.hash(ipad)  h.copy(this.opad, this.blocksize)  return this.hash(this.opad)}function getDigest (alg) {  function shaFunc (data) {    return sha(alg).update(data).digest()  }  function rmd160Func (data) {    return new RIPEMD160().update(data).digest()  }  if (alg === 'rmd160' || alg === 'ripemd160') return rmd160Func  if (alg === 'md5') return md5  return shaFunc}function pbkdf2 (password, salt, iterations, keylen, digest) {  checkParameters(password, salt, iterations, keylen)  if (!Buffer.isBuffer(password)) password = Buffer.from(password, defaultEncoding)  if (!Buffer.isBuffer(salt)) salt = Buffer.from(salt, defaultEncoding)  digest = digest || 'sha1'  var hmac = new Hmac(digest, password, salt.length)  var DK = Buffer.allocUnsafe(keylen)  var block1 = Buffer.allocUnsafe(salt.length + 4)  salt.copy(block1, 0, 0, salt.length)  var destPos = 0  var hLen = sizes[digest]  var l = Math.ceil(keylen / hLen)  for (var i = 1; i <= l; i++) {    block1.writeUInt32BE(i, salt.length)    var T = hmac.run(block1, hmac.ipad1)    var U = T    for (var j = 1; j < iterations; j++) {      U = hmac.run(U, hmac.ipad2)      for (var k = 0; k < hLen; k++) T[k] ^= U[k]    }    T.copy(DK, destPos)    destPos += hLen  }  return DK}module.exports = pbkdf2},{"./default-encoding":222,"./precondition":223,"create-hash/md5":106,"ripemd160":246,"safe-buffer":247,"sha.js":250}],225:[function(require,module,exports){(function (process){'use strict';if (!process.version ||    process.version.indexOf('v0.') === 0 ||    process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {  module.exports = nextTick;} else {  module.exports = process.nextTick;}function nextTick(fn, arg1, arg2, arg3) {  if (typeof fn !== 'function') {    throw new TypeError('"callback" argument must be a function');  }  var len = arguments.length;  var args, i;  switch (len) {  case 0:  case 1:    return process.nextTick(fn);  case 2:    return process.nextTick(function afterTickOne() {      fn.call(null, arg1);    });  case 3:    return process.nextTick(function afterTickTwo() {      fn.call(null, arg1, arg2);    });  case 4:    return process.nextTick(function afterTickThree() {      fn.call(null, arg1, arg2, arg3);    });  default:    args = new Array(len - 1);    i = 0;    while (i < args.length) {      args[i++] = arguments[i];    }    return process.nextTick(function afterTick() {      fn.apply(null, args);    });  }}}).call(this,require('_process'))},{"_process":226}],226:[function(require,module,exports){// shim for using process in browservar process = module.exports = {};// cached from whatever global is present so that test runners that stub it// don't break things.  But we need to wrap it in a try catch in case it is// wrapped in strict mode code which doesn't define any globals.  It's inside a// function because try/catches deoptimize in certain engines.var cachedSetTimeout;var cachedClearTimeout;function defaultSetTimout() {    throw new Error('setTimeout has not been defined');}function defaultClearTimeout () {    throw new Error('clearTimeout has not been defined');}(function () {    try {        if (typeof setTimeout === 'function') {            cachedSetTimeout = setTimeout;        } else {            cachedSetTimeout = defaultSetTimout;        }    } catch (e) {        cachedSetTimeout = defaultSetTimout;    }    try {        if (typeof clearTimeout === 'function') {            cachedClearTimeout = clearTimeout;        } else {            cachedClearTimeout = defaultClearTimeout;        }    } catch (e) {        cachedClearTimeout = defaultClearTimeout;    }} ())function runTimeout(fun) {    if (cachedSetTimeout === setTimeout) {        //normal enviroments in sane situations        return setTimeout(fun, 0);    }    // if setTimeout wasn't available but was latter defined    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {        cachedSetTimeout = setTimeout;        return setTimeout(fun, 0);    }    try {        // when when somebody has screwed with setTimeout but no I.E. maddness        return cachedSetTimeout(fun, 0);    } catch(e){        try {            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally            return cachedSetTimeout.call(null, fun, 0);        } catch(e){            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error            return cachedSetTimeout.call(this, fun, 0);        }    }}function runClearTimeout(marker) {    if (cachedClearTimeout === clearTimeout) {        //normal enviroments in sane situations        return clearTimeout(marker);    }    // if clearTimeout wasn't available but was latter defined    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {        cachedClearTimeout = clearTimeout;        return clearTimeout(marker);    }    try {        // when when somebody has screwed with setTimeout but no I.E. maddness        return cachedClearTimeout(marker);    } catch (e){        try {            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally            return cachedClearTimeout.call(null, marker);        } catch (e){            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.            // Some versions of I.E. have different rules for clearTimeout vs setTimeout            return cachedClearTimeout.call(this, marker);        }    }}var queue = [];var draining = false;var currentQueue;var queueIndex = -1;function cleanUpNextTick() {    if (!draining || !currentQueue) {        return;    }    draining = false;    if (currentQueue.length) {        queue = currentQueue.concat(queue);    } else {        queueIndex = -1;    }    if (queue.length) {        drainQueue();    }}function drainQueue() {    if (draining) {        return;    }    var timeout = runTimeout(cleanUpNextTick);    draining = true;    var len = queue.length;    while(len) {        currentQueue = queue;        queue = [];        while (++queueIndex < len) {            if (currentQueue) {                currentQueue[queueIndex].run();            }        }        queueIndex = -1;        len = queue.length;    }    currentQueue = null;    draining = false;    runClearTimeout(timeout);}process.nextTick = function (fun) {    var args = new Array(arguments.length - 1);    if (arguments.length > 1) {        for (var i = 1; i < arguments.length; i++) {            args[i - 1] = arguments[i];        }    }    queue.push(new Item(fun, args));    if (queue.length === 1 && !draining) {        runTimeout(drainQueue);    }};// v8 likes predictible objectsfunction Item(fun, array) {    this.fun = fun;    this.array = array;}Item.prototype.run = function () {    this.fun.apply(null, this.array);};process.title = 'browser';process.browser = true;process.env = {};process.argv = [];process.version = ''; // empty string to avoid regexp issuesprocess.versions = {};function noop() {}process.on = noop;process.addListener = noop;process.once = noop;process.off = noop;process.removeListener = noop;process.removeAllListeners = noop;process.emit = noop;process.prependListener = noop;process.prependOnceListener = noop;process.listeners = function (name) { return [] }process.binding = function (name) {    throw new Error('process.binding is not supported');};process.cwd = function () { return '/' };process.chdir = function (dir) {    throw new Error('process.chdir is not supported');};process.umask = function() { return 0; };},{}],227:[function(require,module,exports){exports.publicEncrypt = require('./publicEncrypt')exports.privateDecrypt = require('./privateDecrypt')exports.privateEncrypt = function privateEncrypt (key, buf) {  return exports.publicEncrypt(key, buf, true)}exports.publicDecrypt = function publicDecrypt (key, buf) {  return exports.privateDecrypt(key, buf, true)}},{"./privateDecrypt":230,"./publicEncrypt":231}],228:[function(require,module,exports){var createHash = require('create-hash')var Buffer = require('safe-buffer').Buffermodule.exports = function (seed, len) {  var t = Buffer.alloc(0)  var i = 0  var c  while (t.length < len) {    c = i2ops(i++)    t = Buffer.concat([t, createHash('sha1').update(seed).update(c).digest()])  }  return t.slice(0, len)}function i2ops (c) {  var out = Buffer.allocUnsafe(4)  out.writeUInt32BE(c, 0)  return out}},{"create-hash":105,"safe-buffer":229}],229:[function(require,module,exports){arguments[4][68][0].apply(exports,arguments)},{"buffer":79,"dup":68}],230:[function(require,module,exports){var parseKeys = require('parse-asn1')var mgf = require('./mgf')var xor = require('./xor')var BN = require('bn.js')var crt = require('browserify-rsa')var createHash = require('create-hash')var withPublic = require('./withPublic')var Buffer = require('safe-buffer').Buffermodule.exports = function privateDecrypt (privateKey, enc, reverse) {  var padding  if (privateKey.padding) {    padding = privateKey.padding  } else if (reverse) {    padding = 1  } else {    padding = 4  }  var key = parseKeys(privateKey)  var k = key.modulus.byteLength()  if (enc.length > k || new BN(enc).cmp(key.modulus) >= 0) {    throw new Error('decryption error')  }  var msg  if (reverse) {    msg = withPublic(new BN(enc), key)  } else {    msg = crt(enc, key)  }  var zBuffer = Buffer.alloc(k - msg.length)  msg = Buffer.concat([zBuffer, msg], k)  if (padding === 4) {    return oaep(key, msg)  } else if (padding === 1) {    return pkcs1(key, msg, reverse)  } else if (padding === 3) {    return msg  } else {    throw new Error('unknown padding')  }}function oaep (key, msg) {  var k = key.modulus.byteLength()  var iHash = createHash('sha1').update(Buffer.alloc(0)).digest()  var hLen = iHash.length  if (msg[0] !== 0) {    throw new Error('decryption error')  }  var maskedSeed = msg.slice(1, hLen + 1)  var maskedDb = msg.slice(hLen + 1)  var seed = xor(maskedSeed, mgf(maskedDb, hLen))  var db = xor(maskedDb, mgf(seed, k - hLen - 1))  if (compare(iHash, db.slice(0, hLen))) {    throw new Error('decryption error')  }  var i = hLen  while (db[i] === 0) {    i++  }  if (db[i++] !== 1) {    throw new Error('decryption error')  }  return db.slice(i)}function pkcs1 (key, msg, reverse) {  var p1 = msg.slice(0, 2)  var i = 2  var status = 0  while (msg[i++] !== 0) {    if (i >= msg.length) {      status++      break    }  }  var ps = msg.slice(2, i - 1)  if ((p1.toString('hex') !== '0002' && !reverse) || (p1.toString('hex') !== '0001' && reverse)) {    status++  }  if (ps.length < 8) {    status++  }  if (status) {    throw new Error('decryption error')  }  return msg.slice(i)}function compare (a, b) {  a = Buffer.from(a)  b = Buffer.from(b)  var dif = 0  var len = a.length  if (a.length !== b.length) {    dif++    len = Math.min(a.length, b.length)  }  var i = -1  while (++i < len) {    dif += (a[i] ^ b[i])  }  return dif}},{"./mgf":228,"./withPublic":232,"./xor":233,"bn.js":45,"browserify-rsa":69,"create-hash":105,"parse-asn1":219,"safe-buffer":229}],231:[function(require,module,exports){var parseKeys = require('parse-asn1')var randomBytes = require('randombytes')var createHash = require('create-hash')var mgf = require('./mgf')var xor = require('./xor')var BN = require('bn.js')var withPublic = require('./withPublic')var crt = require('browserify-rsa')var Buffer = require('safe-buffer').Buffermodule.exports = function publicEncrypt (publicKey, msg, reverse) {  var padding  if (publicKey.padding) {    padding = publicKey.padding  } else if (reverse) {    padding = 1  } else {    padding = 4  }  var key = parseKeys(publicKey)  var paddedMsg  if (padding === 4) {    paddedMsg = oaep(key, msg)  } else if (padding === 1) {    paddedMsg = pkcs1(key, msg, reverse)  } else if (padding === 3) {    paddedMsg = new BN(msg)    if (paddedMsg.cmp(key.modulus) >= 0) {      throw new Error('data too long for modulus')    }  } else {    throw new Error('unknown padding')  }  if (reverse) {    return crt(paddedMsg, key)  } else {    return withPublic(paddedMsg, key)  }}function oaep (key, msg) {  var k = key.modulus.byteLength()  var mLen = msg.length  var iHash = createHash('sha1').update(Buffer.alloc(0)).digest()  var hLen = iHash.length  var hLen2 = 2 * hLen  if (mLen > k - hLen2 - 2) {    throw new Error('message too long')  }  var ps = Buffer.alloc(k - mLen - hLen2 - 2)  var dblen = k - hLen - 1  var seed = randomBytes(hLen)  var maskedDb = xor(Buffer.concat([iHash, ps, Buffer.alloc(1, 1), msg], dblen), mgf(seed, dblen))  var maskedSeed = xor(seed, mgf(maskedDb, hLen))  return new BN(Buffer.concat([Buffer.alloc(1), maskedSeed, maskedDb], k))}function pkcs1 (key, msg, reverse) {  var mLen = msg.length  var k = key.modulus.byteLength()  if (mLen > k - 11) {    throw new Error('message too long')  }  var ps  if (reverse) {    ps = Buffer.alloc(k - mLen - 3, 0xff)  } else {    ps = nonZero(k - mLen - 3)  }  return new BN(Buffer.concat([Buffer.from([0, reverse ? 1 : 2]), ps, Buffer.alloc(1), msg], k))}function nonZero (len) {  var out = Buffer.allocUnsafe(len)  var i = 0  var cache = randomBytes(len * 2)  var cur = 0  var num  while (i < len) {    if (cur === cache.length) {      cache = randomBytes(len * 2)      cur = 0    }    num = cache[cur++]    if (num) {      out[i++] = num    }  }  return out}},{"./mgf":228,"./withPublic":232,"./xor":233,"bn.js":45,"browserify-rsa":69,"create-hash":105,"parse-asn1":219,"randombytes":234,"safe-buffer":229}],232:[function(require,module,exports){var BN = require('bn.js')var Buffer = require('safe-buffer').Bufferfunction withPublic (paddedMsg, key) {  return Buffer.from(paddedMsg    .toRed(BN.mont(key.modulus))    .redPow(new BN(key.publicExponent))    .fromRed()    .toArray())}module.exports = withPublic},{"bn.js":45,"safe-buffer":229}],233:[function(require,module,exports){module.exports = function xor (a, b) {  var len = a.length  var i = -1  while (++i < len) {    a[i] ^= b[i]  }  return a}},{}],234:[function(require,module,exports){(function (process,global){'use strict'function oldBrowser () {  throw new Error('Secure random number generation is not supported by this browser.\nUse Chrome, Firefox or Internet Explorer 11')}var Buffer = require('safe-buffer').Buffervar crypto = global.crypto || global.msCryptoif (crypto && crypto.getRandomValues) {  module.exports = randomBytes} else {  module.exports = oldBrowser}function randomBytes (size, cb) {  // phantomjs needs to throw  if (size > 65536) throw new Error('requested too many random bytes')  // in case browserify  isn't using the Uint8Array version  var rawBytes = new global.Uint8Array(size)  // This will not work in older browsers.  // See https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues  if (size > 0) {  // getRandomValues fails on IE if size == 0    crypto.getRandomValues(rawBytes)  }  // XXX: phantomjs doesn't like a buffer being passed here  var bytes = Buffer.from(rawBytes.buffer)  if (typeof cb === 'function') {    return process.nextTick(function () {      cb(null, bytes)    })  }  return bytes}}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})},{"_process":226,"safe-buffer":247}],235:[function(require,module,exports){(function (process,global){'use strict'function oldBrowser () {  throw new Error('secure random number generation not supported by this browser\nuse chrome, FireFox or Internet Explorer 11')}var safeBuffer = require('safe-buffer')var randombytes = require('randombytes')var Buffer = safeBuffer.Buffervar kBufferMaxLength = safeBuffer.kMaxLengthvar crypto = global.crypto || global.msCryptovar kMaxUint32 = Math.pow(2, 32) - 1function assertOffset (offset, length) {  if (typeof offset !== 'number' || offset !== offset) { // eslint-disable-line no-self-compare    throw new TypeError('offset must be a number')  }  if (offset > kMaxUint32 || offset < 0) {    throw new TypeError('offset must be a uint32')  }  if (offset > kBufferMaxLength || offset > length) {    throw new RangeError('offset out of range')  }}function assertSize (size, offset, length) {  if (typeof size !== 'number' || size !== size) { // eslint-disable-line no-self-compare    throw new TypeError('size must be a number')  }  if (size > kMaxUint32 || size < 0) {    throw new TypeError('size must be a uint32')  }  if (size + offset > length || size > kBufferMaxLength) {    throw new RangeError('buffer too small')  }}if ((crypto && crypto.getRandomValues) || !process.browser) {  exports.randomFill = randomFill  exports.randomFillSync = randomFillSync} else {  exports.randomFill = oldBrowser  exports.randomFillSync = oldBrowser}function randomFill (buf, offset, size, cb) {  if (!Buffer.isBuffer(buf) && !(buf instanceof global.Uint8Array)) {    throw new TypeError('"buf" argument must be a Buffer or Uint8Array')  }  if (typeof offset === 'function') {    cb = offset    offset = 0    size = buf.length  } else if (typeof size === 'function') {    cb = size    size = buf.length - offset  } else if (typeof cb !== 'function') {    throw new TypeError('"cb" argument must be a function')  }  assertOffset(offset, buf.length)  assertSize(size, offset, buf.length)  return actualFill(buf, offset, size, cb)}function actualFill (buf, offset, size, cb) {  if (process.browser) {    var ourBuf = buf.buffer    var uint = new Uint8Array(ourBuf, offset, size)    crypto.getRandomValues(uint)    if (cb) {      process.nextTick(function () {        cb(null, buf)      })      return    }    return buf  }  if (cb) {    randombytes(size, function (err, bytes) {      if (err) {        return cb(err)      }      bytes.copy(buf, offset)      cb(null, buf)    })    return  }  var bytes = randombytes(size)  bytes.copy(buf, offset)  return buf}function randomFillSync (buf, offset, size) {  if (typeof offset === 'undefined') {    offset = 0  }  if (!Buffer.isBuffer(buf) && !(buf instanceof global.Uint8Array)) {    throw new TypeError('"buf" argument must be a Buffer or Uint8Array')  }  assertOffset(offset, buf.length)  if (size === undefined) size = buf.length - offset  assertSize(size, offset, buf.length)  return actualFill(buf, offset, size)}}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})},{"_process":226,"randombytes":234,"safe-buffer":247}],236:[function(require,module,exports){module.exports = require("./lib/_stream_duplex.js")},{"./lib/_stream_duplex.js":237}],237:[function(require,module,exports){// a duplex stream is just a stream that is both readable and writable.// Since JS doesn't have multiple prototypal inheritance, this class// prototypally inherits from Readable, and then parasitically from// Writable.'use strict';/*<replacement>*/var objectKeys = Object.keys || function (obj) {  var keys = [];  for (var key in obj) {    keys.push(key);  }return keys;};/*</replacement>*/module.exports = Duplex;/*<replacement>*/var processNextTick = require('process-nextick-args');/*</replacement>*//*<replacement>*/var util = require('core-util-is');util.inherits = require('inherits');/*</replacement>*/var Readable = require('./_stream_readable');var Writable = require('./_stream_writable');util.inherits(Duplex, Readable);var keys = objectKeys(Writable.prototype);for (var v = 0; v < keys.length; v++) {  var method = keys[v];  if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];}function Duplex(options) {  if (!(this instanceof Duplex)) return new Duplex(options);  Readable.call(this, options);  Writable.call(this, options);  if (options && options.readable === false) this.readable = false;  if (options && options.writable === false) this.writable = false;  this.allowHalfOpen = true;  if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;  this.once('end', onend);}// the no-half-open enforcerfunction onend() {  // if we allow half-open state, or if the writable side ended,  // then we're ok.  if (this.allowHalfOpen || this._writableState.ended) return;  // no more data can be written.  // But allow more writes to happen in this tick.  processNextTick(onEndNT, this);}function onEndNT(self) {  self.end();}function forEach(xs, f) {  for (var i = 0, l = xs.length; i < l; i++) {    f(xs[i], i);  }}},{"./_stream_readable":239,"./_stream_writable":241,"core-util-is":103,"inherits":154,"process-nextick-args":225}],238:[function(require,module,exports){// a passthrough stream.// basically just the most minimal sort of Transform stream.// Every written chunk gets output as-is.'use strict';module.exports = PassThrough;var Transform = require('./_stream_transform');/*<replacement>*/var util = require('core-util-is');util.inherits = require('inherits');/*</replacement>*/util.inherits(PassThrough, Transform);function PassThrough(options) {  if (!(this instanceof PassThrough)) return new PassThrough(options);  Transform.call(this, options);}PassThrough.prototype._transform = function (chunk, encoding, cb) {  cb(null, chunk);};},{"./_stream_transform":240,"core-util-is":103,"inherits":154}],239:[function(require,module,exports){(function (process){'use strict';module.exports = Readable;/*<replacement>*/var processNextTick = require('process-nextick-args');/*</replacement>*//*<replacement>*/var isArray = require('isarray');/*</replacement>*//*<replacement>*/var Buffer = require('buffer').Buffer;/*</replacement>*/Readable.ReadableState = ReadableState;var EE = require('events');/*<replacement>*/var EElistenerCount = function (emitter, type) {  return emitter.listeners(type).length;};/*</replacement>*//*<replacement>*/var Stream;(function () {  try {    Stream = require('st' + 'ream');  } catch (_) {} finally {    if (!Stream) Stream = require('events').EventEmitter;  }})();/*</replacement>*/var Buffer = require('buffer').Buffer;/*<replacement>*/var util = require('core-util-is');util.inherits = require('inherits');/*</replacement>*//*<replacement>*/var debugUtil = require('util');var debug = undefined;if (debugUtil && debugUtil.debuglog) {  debug = debugUtil.debuglog('stream');} else {  debug = function () {};}/*</replacement>*/var StringDecoder;util.inherits(Readable, Stream);var Duplex;function ReadableState(options, stream) {  Duplex = Duplex || require('./_stream_duplex');  options = options || {};  // object stream flag. Used to make read(n) ignore n and to  // make all the buffer merging and length checks go away  this.objectMode = !!options.objectMode;  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;  // the point at which it stops calling _read() to fill the buffer  // Note: 0 is a valid value, means "don't call _read preemptively ever"  var hwm = options.highWaterMark;  var defaultHwm = this.objectMode ? 16 : 16 * 1024;  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;  // cast to ints.  this.highWaterMark = ~ ~this.highWaterMark;  this.buffer = [];  this.length = 0;  this.pipes = null;  this.pipesCount = 0;  this.flowing = null;  this.ended = false;  this.endEmitted = false;  this.reading = false;  // a flag to be able to tell if the onwrite cb is called immediately,  // or on a later tick.  We set this to true at first, because any  // actions that shouldn't happen until "later" should generally also  // not happen before the first write call.  this.sync = true;  // whenever we return null, then we set a flag to say  // that we're awaiting a 'readable' event emission.  this.needReadable = false;  this.emittedReadable = false;  this.readableListening = false;  this.resumeScheduled = false;  // Crypto is kind of old and crusty.  Historically, its default string  // encoding is 'binary' so we have to make this configurable.  // Everything else in the universe uses 'utf8', though.  this.defaultEncoding = options.defaultEncoding || 'utf8';  // when piping, we only care about 'readable' events that happen  // after read()ing all the bytes and not getting any pushback.  this.ranOut = false;  // the number of writers that are awaiting a drain event in .pipe()s  this.awaitDrain = 0;  // if true, a maybeReadMore has been scheduled  this.readingMore = false;  this.decoder = null;  this.encoding = null;  if (options.encoding) {    if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;    this.decoder = new StringDecoder(options.encoding);    this.encoding = options.encoding;  }}var Duplex;function Readable(options) {  Duplex = Duplex || require('./_stream_duplex');  if (!(this instanceof Readable)) return new Readable(options);  this._readableState = new ReadableState(options, this);  // legacy  this.readable = true;  if (options && typeof options.read === 'function') this._read = options.read;  Stream.call(this);}// Manually shove something into the read() buffer.// This returns true if the highWaterMark has not been hit yet,// similar to how Writable.write() returns true if you should// write() some more.Readable.prototype.push = function (chunk, encoding) {  var state = this._readableState;  if (!state.objectMode && typeof chunk === 'string') {    encoding = encoding || state.defaultEncoding;    if (encoding !== state.encoding) {      chunk = new Buffer(chunk, encoding);      encoding = '';    }  }  return readableAddChunk(this, state, chunk, encoding, false);};// Unshift should *always* be something directly out of read()Readable.prototype.unshift = function (chunk) {  var state = this._readableState;  return readableAddChunk(this, state, chunk, '', true);};Readable.prototype.isPaused = function () {  return this._readableState.flowing === false;};function readableAddChunk(stream, state, chunk, encoding, addToFront) {  var er = chunkInvalid(state, chunk);  if (er) {    stream.emit('error', er);  } else if (chunk === null) {    state.reading = false;    onEofChunk(stream, state);  } else if (state.objectMode || chunk && chunk.length > 0) {    if (state.ended && !addToFront) {      var e = new Error('stream.push() after EOF');      stream.emit('error', e);    } else if (state.endEmitted && addToFront) {      var e = new Error('stream.unshift() after end event');      stream.emit('error', e);    } else {      var skipAdd;      if (state.decoder && !addToFront && !encoding) {        chunk = state.decoder.write(chunk);        skipAdd = !state.objectMode && chunk.length === 0;      }      if (!addToFront) state.reading = false;      // Don't add to the buffer if we've decoded to an empty string chunk and      // we're not in object mode      if (!skipAdd) {        // if we want the data now, just emit it.        if (state.flowing && state.length === 0 && !state.sync) {          stream.emit('data', chunk);          stream.read(0);        } else {          // update the buffer info.          state.length += state.objectMode ? 1 : chunk.length;          if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);          if (state.needReadable) emitReadable(stream);        }      }      maybeReadMore(stream, state);    }  } else if (!addToFront) {    state.reading = false;  }  return needMoreData(state);}// if it's past the high water mark, we can push in some more.// Also, if we have no data yet, we can stand some// more bytes.  This is to work around cases where hwm=0,// such as the repl.  Also, if the push() triggered a// readable event, and the user called read(largeNumber) such that// needReadable was set, then we ought to push more, so that another// 'readable' event will be triggered.function needMoreData(state) {  return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);}// backwards compatibility.Readable.prototype.setEncoding = function (enc) {  if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;  this._readableState.decoder = new StringDecoder(enc);  this._readableState.encoding = enc;  return this;};// Don't raise the hwm > 8MBvar MAX_HWM = 0x800000;function computeNewHighWaterMark(n) {  if (n >= MAX_HWM) {    n = MAX_HWM;  } else {    // Get the next highest power of 2    n--;    n |= n >>> 1;    n |= n >>> 2;    n |= n >>> 4;    n |= n >>> 8;    n |= n >>> 16;    n++;  }  return n;}function howMuchToRead(n, state) {  if (state.length === 0 && state.ended) return 0;  if (state.objectMode) return n === 0 ? 0 : 1;  if (n === null || isNaN(n)) {    // only flow one buffer at a time    if (state.flowing && state.buffer.length) return state.buffer[0].length;else return state.length;  }  if (n <= 0) return 0;  // If we're asking for more than the target buffer level,  // then raise the water mark.  Bump up to the next highest  // power of 2, to prevent increasing it excessively in tiny  // amounts.  if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);  // don't have that much.  return null, unless we've ended.  if (n > state.length) {    if (!state.ended) {      state.needReadable = true;      return 0;    } else {      return state.length;    }  }  return n;}// you can override either this method, or the async _read(n) below.Readable.prototype.read = function (n) {  debug('read', n);  var state = this._readableState;  var nOrig = n;  if (typeof n !== 'number' || n > 0) state.emittedReadable = false;  // if we're doing read(0) to trigger a readable event, but we  // already have a bunch of data in the buffer, then just trigger  // the 'readable' event and move on.  if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {    debug('read: emitReadable', state.length, state.ended);    if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);    return null;  }  n = howMuchToRead(n, state);  // if we've ended, and we're now clear, then finish it up.  if (n === 0 && state.ended) {    if (state.length === 0) endReadable(this);    return null;  }  // All the actual chunk generation logic needs to be  // *below* the call to _read.  The reason is that in certain  // synthetic stream cases, such as passthrough streams, _read  // may be a completely synchronous operation which may change  // the state of the read buffer, providing enough data when  // before there was *not* enough.  //  // So, the steps are:  // 1. Figure out what the state of things will be after we do  // a read from the buffer.  //  // 2. If that resulting state will trigger a _read, then call _read.  // Note that this may be asynchronous, or synchronous.  Yes, it is  // deeply ugly to write APIs this way, but that still doesn't mean  // that the Readable class should behave improperly, as streams are  // designed to be sync/async agnostic.  // Take note if the _read call is sync or async (ie, if the read call  // has returned yet), so that we know whether or not it's safe to emit  // 'readable' etc.  //  // 3. Actually pull the requested chunks out of the buffer and return.  // if we need a readable event, then we need to do some reading.  var doRead = state.needReadable;  debug('need readable', doRead);  // if we currently have less than the highWaterMark, then also read some  if (state.length === 0 || state.length - n < state.highWaterMark) {    doRead = true;    debug('length less than watermark', doRead);  }  // however, if we've ended, then there's no point, and if we're already  // reading, then it's unnecessary.  if (state.ended || state.reading) {    doRead = false;    debug('reading or ended', doRead);  }  if (doRead) {    debug('do read');    state.reading = true;    state.sync = true;    // if the length is currently zero, then we *need* a readable event.    if (state.length === 0) state.needReadable = true;    // call internal read method    this._read(state.highWaterMark);    state.sync = false;  }  // If _read pushed data synchronously, then `reading` will be false,  // and we need to re-evaluate how much data we can return to the user.  if (doRead && !state.reading) n = howMuchToRead(nOrig, state);  var ret;  if (n > 0) ret = fromList(n, state);else ret = null;  if (ret === null) {    state.needReadable = true;    n = 0;  }  state.length -= n;  // If we have nothing in the buffer, then we want to know  // as soon as we *do* get something into the buffer.  if (state.length === 0 && !state.ended) state.needReadable = true;  // If we tried to read() past the EOF, then emit end on the next tick.  if (nOrig !== n && state.ended && state.length === 0) endReadable(this);  if (ret !== null) this.emit('data', ret);  return ret;};function chunkInvalid(state, chunk) {  var er = null;  if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {    er = new TypeError('Invalid non-string/buffer chunk');  }  return er;}function onEofChunk(stream, state) {  if (state.ended) return;  if (state.decoder) {    var chunk = state.decoder.end();    if (chunk && chunk.length) {      state.buffer.push(chunk);      state.length += state.objectMode ? 1 : chunk.length;    }  }  state.ended = true;  // emit 'readable' now to make sure it gets picked up.  emitReadable(stream);}// Don't emit readable right away in sync mode, because this can trigger// another read() call => stack overflow.  This way, it might trigger// a nextTick recursion warning, but that's not so bad.function emitReadable(stream) {  var state = stream._readableState;  state.needReadable = false;  if (!state.emittedReadable) {    debug('emitReadable', state.flowing);    state.emittedReadable = true;    if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);  }}function emitReadable_(stream) {  debug('emit readable');  stream.emit('readable');  flow(stream);}// at this point, the user has presumably seen the 'readable' event,// and called read() to consume some data.  that may have triggered// in turn another _read(n) call, in which case reading = true if// it's in progress.// However, if we're not ended, or reading, and the length < hwm,// then go ahead and try to read some more preemptively.function maybeReadMore(stream, state) {  if (!state.readingMore) {    state.readingMore = true;    processNextTick(maybeReadMore_, stream, state);  }}function maybeReadMore_(stream, state) {  var len = state.length;  while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {    debug('maybeReadMore read 0');    stream.read(0);    if (len === state.length)      // didn't get any data, stop spinning.      break;else len = state.length;  }  state.readingMore = false;}// abstract method.  to be overridden in specific implementation classes.// call cb(er, data) where data is <= n in length.// for virtual (non-string, non-buffer) streams, "length" is somewhat// arbitrary, and perhaps not very meaningful.Readable.prototype._read = function (n) {  this.emit('error', new Error('not implemented'));};Readable.prototype.pipe = function (dest, pipeOpts) {  var src = this;  var state = this._readableState;  switch (state.pipesCount) {    case 0:      state.pipes = dest;      break;    case 1:      state.pipes = [state.pipes, dest];      break;    default:      state.pipes.push(dest);      break;  }  state.pipesCount += 1;  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);  var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;  var endFn = doEnd ? onend : cleanup;  if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);  dest.on('unpipe', onunpipe);  function onunpipe(readable) {    debug('onunpipe');    if (readable === src) {      cleanup();    }  }  function onend() {    debug('onend');    dest.end();  }  // when the dest drains, it reduces the awaitDrain counter  // on the source.  This would be more elegant with a .once()  // handler in flow(), but adding and removing repeatedly is  // too slow.  var ondrain = pipeOnDrain(src);  dest.on('drain', ondrain);  var cleanedUp = false;  function cleanup() {    debug('cleanup');    // cleanup event handlers once the pipe is broken    dest.removeListener('close', onclose);    dest.removeListener('finish', onfinish);    dest.removeListener('drain', ondrain);    dest.removeListener('error', onerror);    dest.removeListener('unpipe', onunpipe);    src.removeListener('end', onend);    src.removeListener('end', cleanup);    src.removeListener('data', ondata);    cleanedUp = true;    // if the reader is waiting for a drain event from this    // specific writer, then it would cause it to never start    // flowing again.    // So, if this is awaiting a drain, then we just call it now.    // If we don't know, then assume that we are waiting for one.    if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();  }  src.on('data', ondata);  function ondata(chunk) {    debug('ondata');    var ret = dest.write(chunk);    if (false === ret) {      // If the user unpiped during `dest.write()`, it is possible      // to get stuck in a permanently paused state if that write      // also returned false.      if (state.pipesCount === 1 && state.pipes[0] === dest && src.listenerCount('data') === 1 && !cleanedUp) {        debug('false write response, pause', src._readableState.awaitDrain);        src._readableState.awaitDrain++;      }      src.pause();    }  }  // if the dest has an error, then stop piping into it.  // however, don't suppress the throwing behavior for this.  function onerror(er) {    debug('onerror', er);    unpipe();    dest.removeListener('error', onerror);    if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);  }  // This is a brutally ugly hack to make sure that our error handler  // is attached before any userland ones.  NEVER DO THIS.  if (!dest._events || !dest._events.error) dest.on('error', onerror);else if (isArray(dest._events.error)) dest._events.error.unshift(onerror);else dest._events.error = [onerror, dest._events.error];  // Both close and finish should trigger unpipe, but only once.  function onclose() {    dest.removeListener('finish', onfinish);    unpipe();  }  dest.once('close', onclose);  function onfinish() {    debug('onfinish');    dest.removeListener('close', onclose);    unpipe();  }  dest.once('finish', onfinish);  function unpipe() {    debug('unpipe');    src.unpipe(dest);  }  // tell the dest that it's being piped to  dest.emit('pipe', src);  // start the flow if it hasn't been started already.  if (!state.flowing) {    debug('pipe resume');    src.resume();  }  return dest;};function pipeOnDrain(src) {  return function () {    var state = src._readableState;    debug('pipeOnDrain', state.awaitDrain);    if (state.awaitDrain) state.awaitDrain--;    if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {      state.flowing = true;      flow(src);    }  };}Readable.prototype.unpipe = function (dest) {  var state = this._readableState;  // if we're not piping anywhere, then do nothing.  if (state.pipesCount === 0) return this;  // just one destination.  most common case.  if (state.pipesCount === 1) {    // passed in one, but it's not the right one.    if (dest && dest !== state.pipes) return this;    if (!dest) dest = state.pipes;    // got a match.    state.pipes = null;    state.pipesCount = 0;    state.flowing = false;    if (dest) dest.emit('unpipe', this);    return this;  }  // slow case. multiple pipe destinations.  if (!dest) {    // remove all.    var dests = state.pipes;    var len = state.pipesCount;    state.pipes = null;    state.pipesCount = 0;    state.flowing = false;    for (var _i = 0; _i < len; _i++) {      dests[_i].emit('unpipe', this);    }return this;  }  // try to find the right one.  var i = indexOf(state.pipes, dest);  if (i === -1) return this;  state.pipes.splice(i, 1);  state.pipesCount -= 1;  if (state.pipesCount === 1) state.pipes = state.pipes[0];  dest.emit('unpipe', this);  return this;};// set up data events if they are asked for// Ensure readable listeners eventually get somethingReadable.prototype.on = function (ev, fn) {  var res = Stream.prototype.on.call(this, ev, fn);  // If listening to data, and it has not explicitly been paused,  // then call resume to start the flow of data on the next tick.  if (ev === 'data' && false !== this._readableState.flowing) {    this.resume();  }  if (ev === 'readable' && !this._readableState.endEmitted) {    var state = this._readableState;    if (!state.readableListening) {      state.readableListening = true;      state.emittedReadable = false;      state.needReadable = true;      if (!state.reading) {        processNextTick(nReadingNextTick, this);      } else if (state.length) {        emitReadable(this, state);      }    }  }  return res;};Readable.prototype.addListener = Readable.prototype.on;function nReadingNextTick(self) {  debug('readable nexttick read 0');  self.read(0);}// pause() and resume() are remnants of the legacy readable stream API// If the user uses them, then switch into old mode.Readable.prototype.resume = function () {  var state = this._readableState;  if (!state.flowing) {    debug('resume');    state.flowing = true;    resume(this, state);  }  return this;};function resume(stream, state) {  if (!state.resumeScheduled) {    state.resumeScheduled = true;    processNextTick(resume_, stream, state);  }}function resume_(stream, state) {  if (!state.reading) {    debug('resume read 0');    stream.read(0);  }  state.resumeScheduled = false;  stream.emit('resume');  flow(stream);  if (state.flowing && !state.reading) stream.read(0);}Readable.prototype.pause = function () {  debug('call pause flowing=%j', this._readableState.flowing);  if (false !== this._readableState.flowing) {    debug('pause');    this._readableState.flowing = false;    this.emit('pause');  }  return this;};function flow(stream) {  var state = stream._readableState;  debug('flow', state.flowing);  if (state.flowing) {    do {      var chunk = stream.read();    } while (null !== chunk && state.flowing);  }}// wrap an old-style stream as the async data source.// This is *not* part of the readable stream interface.// It is an ugly unfortunate mess of history.Readable.prototype.wrap = function (stream) {  var state = this._readableState;  var paused = false;  var self = this;  stream.on('end', function () {    debug('wrapped end');    if (state.decoder && !state.ended) {      var chunk = state.decoder.end();      if (chunk && chunk.length) self.push(chunk);    }    self.push(null);  });  stream.on('data', function (chunk) {    debug('wrapped data');    if (state.decoder) chunk = state.decoder.write(chunk);    // don't skip over falsy values in objectMode    if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;    var ret = self.push(chunk);    if (!ret) {      paused = true;      stream.pause();    }  });  // proxy all the other methods.  // important when wrapping filters and duplexes.  for (var i in stream) {    if (this[i] === undefined && typeof stream[i] === 'function') {      this[i] = function (method) {        return function () {          return stream[method].apply(stream, arguments);        };      }(i);    }  }  // proxy certain important events.  var events = ['error', 'close', 'destroy', 'pause', 'resume'];  forEach(events, function (ev) {    stream.on(ev, self.emit.bind(self, ev));  });  // when we try to consume some more bytes, simply unpause the  // underlying stream.  self._read = function (n) {    debug('wrapped _read', n);    if (paused) {      paused = false;      stream.resume();    }  };  return self;};// exposed for testing purposes only.Readable._fromList = fromList;// Pluck off n bytes from an array of buffers.// Length is the combined lengths of all the buffers in the list.function fromList(n, state) {  var list = state.buffer;  var length = state.length;  var stringMode = !!state.decoder;  var objectMode = !!state.objectMode;  var ret;  // nothing in the list, definitely empty.  if (list.length === 0) return null;  if (length === 0) ret = null;else if (objectMode) ret = list.shift();else if (!n || n >= length) {    // read it all, truncate the array.    if (stringMode) ret = list.join('');else if (list.length === 1) ret = list[0];else ret = Buffer.concat(list, length);    list.length = 0;  } else {    // read just some of it.    if (n < list[0].length) {      // just take a part of the first list item.      // slice is the same for buffers and strings.      var buf = list[0];      ret = buf.slice(0, n);      list[0] = buf.slice(n);    } else if (n === list[0].length) {      // first list is a perfect match      ret = list.shift();    } else {      // complex case.      // we have enough to cover it, but it spans past the first buffer.      if (stringMode) ret = '';else ret = new Buffer(n);      var c = 0;      for (var i = 0, l = list.length; i < l && c < n; i++) {        var buf = list[0];        var cpy = Math.min(n - c, buf.length);        if (stringMode) ret += buf.slice(0, cpy);else buf.copy(ret, c, 0, cpy);        if (cpy < buf.length) list[0] = buf.slice(cpy);else list.shift();        c += cpy;      }    }  }  return ret;}function endReadable(stream) {  var state = stream._readableState;  // If we get here before consuming all the bytes, then that is a  // bug in node.  Should never happen.  if (state.length > 0) throw new Error('endReadable called on non-empty stream');  if (!state.endEmitted) {    state.ended = true;    processNextTick(endReadableNT, state, stream);  }}function endReadableNT(state, stream) {  // Check that we didn't get one last unshift.  if (!state.endEmitted && state.length === 0) {    state.endEmitted = true;    stream.readable = false;    stream.emit('end');  }}function forEach(xs, f) {  for (var i = 0, l = xs.length; i < l; i++) {    f(xs[i], i);  }}function indexOf(xs, x) {  for (var i = 0, l = xs.length; i < l; i++) {    if (xs[i] === x) return i;  }  return -1;}}).call(this,require('_process'))},{"./_stream_duplex":237,"_process":226,"buffer":79,"core-util-is":103,"events":136,"inherits":154,"isarray":156,"process-nextick-args":225,"string_decoder/":258,"util":47}],240:[function(require,module,exports){// a transform stream is a readable/writable stream where you do// something with the data.  Sometimes it's called a "filter",// but that's not a great name for it, since that implies a thing where// some bits pass through, and others are simply ignored.  (That would// be a valid example of a transform, of course.)//// While the output is causally related to the input, it's not a// necessarily symmetric or synchronous transformation.  For example,// a zlib stream might take multiple plain-text writes(), and then// emit a single compressed chunk some time in the future.//// Here's how this works://// The Transform stream has all the aspects of the readable and writable// stream classes.  When you write(chunk), that calls _write(chunk,cb)// internally, and returns false if there's a lot of pending writes// buffered up.  When you call read(), that calls _read(n) until// there's enough pending readable data buffered up.//// In a transform stream, the written data is placed in a buffer.  When// _read(n) is called, it transforms the queued up data, calling the// buffered _write cb's as it consumes chunks.  If consuming a single// written chunk would result in multiple output chunks, then the first// outputted bit calls the readcb, and subsequent chunks just go into// the read buffer, and will cause it to emit 'readable' if necessary.//// This way, back-pressure is actually determined by the reading side,// since _read has to be called to start processing a new chunk.  However,// a pathological inflate type of transform can cause excessive buffering// here.  For example, imagine a stream where every byte of input is// interpreted as an integer from 0-255, and then results in that many// bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in// 1kb of data being output.  In this case, you could write a very small// amount of input, and end up with a very large amount of output.  In// such a pathological inflating mechanism, there'd be no way to tell// the system to stop doing the transform.  A single 4MB write could// cause the system to run out of memory.//// However, even in such a pathological case, only a single written chunk// would be consumed, and then the rest would wait (un-transformed) until// the results of the previous transformed chunk were consumed.'use strict';module.exports = Transform;var Duplex = require('./_stream_duplex');/*<replacement>*/var util = require('core-util-is');util.inherits = require('inherits');/*</replacement>*/util.inherits(Transform, Duplex);function TransformState(stream) {  this.afterTransform = function (er, data) {    return afterTransform(stream, er, data);  };  this.needTransform = false;  this.transforming = false;  this.writecb = null;  this.writechunk = null;  this.writeencoding = null;}function afterTransform(stream, er, data) {  var ts = stream._transformState;  ts.transforming = false;  var cb = ts.writecb;  if (!cb) return stream.emit('error', new Error('no writecb in Transform class'));  ts.writechunk = null;  ts.writecb = null;  if (data !== null && data !== undefined) stream.push(data);  cb(er);  var rs = stream._readableState;  rs.reading = false;  if (rs.needReadable || rs.length < rs.highWaterMark) {    stream._read(rs.highWaterMark);  }}function Transform(options) {  if (!(this instanceof Transform)) return new Transform(options);  Duplex.call(this, options);  this._transformState = new TransformState(this);  // when the writable side finishes, then flush out anything remaining.  var stream = this;  // start out asking for a readable event once data is transformed.  this._readableState.needReadable = true;  // we have implemented the _read method, and done the other things  // that Readable wants before the first _read call, so unset the  // sync guard flag.  this._readableState.sync = false;  if (options) {    if (typeof options.transform === 'function') this._transform = options.transform;    if (typeof options.flush === 'function') this._flush = options.flush;  }  this.once('prefinish', function () {    if (typeof this._flush === 'function') this._flush(function (er) {      done(stream, er);    });else done(stream);  });}Transform.prototype.push = function (chunk, encoding) {  this._transformState.needTransform = false;  return Duplex.prototype.push.call(this, chunk, encoding);};// This is the part where you do stuff!// override this function in implementation classes.// 'chunk' is an input chunk.//// Call `push(newChunk)` to pass along transformed output// to the readable side.  You may call 'push' zero or more times.//// Call `cb(err)` when you are done with this chunk.  If you pass// an error, then that'll put the hurt on the whole operation.  If you// never call cb(), then you'll never get another chunk.Transform.prototype._transform = function (chunk, encoding, cb) {  throw new Error('not implemented');};Transform.prototype._write = function (chunk, encoding, cb) {  var ts = this._transformState;  ts.writecb = cb;  ts.writechunk = chunk;  ts.writeencoding = encoding;  if (!ts.transforming) {    var rs = this._readableState;    if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);  }};// Doesn't matter what the args are here.// _transform does all the work.// That we got here means that the readable side wants more data.Transform.prototype._read = function (n) {  var ts = this._transformState;  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {    ts.transforming = true;    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);  } else {    // mark that we need a transform, so that any data that comes in    // will get processed, now that we've asked for it.    ts.needTransform = true;  }};function done(stream, er) {  if (er) return stream.emit('error', er);  // if there's nothing in the write buffer, then that means  // that nothing more will ever be provided  var ws = stream._writableState;  var ts = stream._transformState;  if (ws.length) throw new Error('calling transform done when ws.length != 0');  if (ts.transforming) throw new Error('calling transform done when still transforming');  return stream.push(null);}},{"./_stream_duplex":237,"core-util-is":103,"inherits":154}],241:[function(require,module,exports){(function (process,setImmediate){// A bit simpler than readable streams.// Implement an async ._write(chunk, encoding, cb), and it'll handle all// the drain event emission and buffering.'use strict';module.exports = Writable;/*<replacement>*/var processNextTick = require('process-nextick-args');/*</replacement>*//*<replacement>*/var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;/*</replacement>*//*<replacement>*/var Buffer = require('buffer').Buffer;/*</replacement>*/Writable.WritableState = WritableState;/*<replacement>*/var util = require('core-util-is');util.inherits = require('inherits');/*</replacement>*//*<replacement>*/var internalUtil = {  deprecate: require('util-deprecate')};/*</replacement>*//*<replacement>*/var Stream;(function () {  try {    Stream = require('st' + 'ream');  } catch (_) {} finally {    if (!Stream) Stream = require('events').EventEmitter;  }})();/*</replacement>*/var Buffer = require('buffer').Buffer;util.inherits(Writable, Stream);function nop() {}function WriteReq(chunk, encoding, cb) {  this.chunk = chunk;  this.encoding = encoding;  this.callback = cb;  this.next = null;}var Duplex;function WritableState(options, stream) {  Duplex = Duplex || require('./_stream_duplex');  options = options || {};  // object stream flag to indicate whether or not this stream  // contains buffers or objects.  this.objectMode = !!options.objectMode;  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;  // the point at which write() starts returning false  // Note: 0 is a valid value, means that we always return false if  // the entire buffer is not flushed immediately on write()  var hwm = options.highWaterMark;  var defaultHwm = this.objectMode ? 16 : 16 * 1024;  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;  // cast to ints.  this.highWaterMark = ~ ~this.highWaterMark;  this.needDrain = false;  // at the start of calling end()  this.ending = false;  // when end() has been called, and returned  this.ended = false;  // when 'finish' is emitted  this.finished = false;  // should we decode strings into buffers before passing to _write?  // this is here so that some node-core streams can optimize string  // handling at a lower level.  var noDecode = options.decodeStrings === false;  this.decodeStrings = !noDecode;  // Crypto is kind of old and crusty.  Historically, its default string  // encoding is 'binary' so we have to make this configurable.  // Everything else in the universe uses 'utf8', though.  this.defaultEncoding = options.defaultEncoding || 'utf8';  // not an actual buffer we keep track of, but a measurement  // of how much we're waiting to get pushed to some underlying  // socket or file.  this.length = 0;  // a flag to see when we're in the middle of a write.  this.writing = false;  // when true all writes will be buffered until .uncork() call  this.corked = 0;  // a flag to be able to tell if the onwrite cb is called immediately,  // or on a later tick.  We set this to true at first, because any  // actions that shouldn't happen until "later" should generally also  // not happen before the first write call.  this.sync = true;  // a flag to know if we're processing previously buffered items, which  // may call the _write() callback in the same tick, so that we don't  // end up in an overlapped onwrite situation.  this.bufferProcessing = false;  // the callback that's passed to _write(chunk,cb)  this.onwrite = function (er) {    onwrite(stream, er);  };  // the callback that the user supplies to write(chunk,encoding,cb)  this.writecb = null;  // the amount that is being written when _write is called.  this.writelen = 0;  this.bufferedRequest = null;  this.lastBufferedRequest = null;  // number of pending user-supplied write callbacks  // this must be 0 before 'finish' can be emitted  this.pendingcb = 0;  // emit prefinish if the only thing we're waiting for is _write cbs  // This is relevant for synchronous Transform streams  this.prefinished = false;  // True if the error was already emitted and should not be thrown again  this.errorEmitted = false;  // count buffered requests  this.bufferedRequestCount = 0;  // create the two objects needed to store the corked requests  // they are not a linked list, as no new elements are inserted in there  this.corkedRequestsFree = new CorkedRequest(this);  this.corkedRequestsFree.next = new CorkedRequest(this);}WritableState.prototype.getBuffer = function writableStateGetBuffer() {  var current = this.bufferedRequest;  var out = [];  while (current) {    out.push(current);    current = current.next;  }  return out;};(function () {  try {    Object.defineProperty(WritableState.prototype, 'buffer', {      get: internalUtil.deprecate(function () {        return this.getBuffer();      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')    });  } catch (_) {}})();var Duplex;function Writable(options) {  Duplex = Duplex || require('./_stream_duplex');  // Writable ctor is applied to Duplexes, though they're not  // instanceof Writable, they're instanceof Readable.  if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options);  this._writableState = new WritableState(options, this);  // legacy.  this.writable = true;  if (options) {    if (typeof options.write === 'function') this._write = options.write;    if (typeof options.writev === 'function') this._writev = options.writev;  }  Stream.call(this);}// Otherwise people can pipe Writable streams, which is just wrong.Writable.prototype.pipe = function () {  this.emit('error', new Error('Cannot pipe. Not readable.'));};function writeAfterEnd(stream, cb) {  var er = new Error('write after end');  // TODO: defer error events consistently everywhere, not just the cb  stream.emit('error', er);  processNextTick(cb, er);}// If we get something that is not a buffer, string, null, or undefined,// and we're not in objectMode, then that's an error.// Otherwise stream chunks are all considered to be of length=1, and the// watermarks determine how many objects to keep in the buffer, rather than// how many bytes or characters.function validChunk(stream, state, chunk, cb) {  var valid = true;  if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {    var er = new TypeError('Invalid non-string/buffer chunk');    stream.emit('error', er);    processNextTick(cb, er);    valid = false;  }  return valid;}Writable.prototype.write = function (chunk, encoding, cb) {  var state = this._writableState;  var ret = false;  if (typeof encoding === 'function') {    cb = encoding;    encoding = null;  }  if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;  if (typeof cb !== 'function') cb = nop;  if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) {    state.pendingcb++;    ret = writeOrBuffer(this, state, chunk, encoding, cb);  }  return ret;};Writable.prototype.cork = function () {  var state = this._writableState;  state.corked++;};Writable.prototype.uncork = function () {  var state = this._writableState;  if (state.corked) {    state.corked--;    if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);  }};Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {  // node::ParseEncoding() requires lower case.  if (typeof encoding === 'string') encoding = encoding.toLowerCase();  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);  this._writableState.defaultEncoding = encoding;};function decodeChunk(state, chunk, encoding) {  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {    chunk = new Buffer(chunk, encoding);  }  return chunk;}// if we're already writing something, then just put this// in the queue, and wait our turn.  Otherwise, call _write// If we return false, then we need a drain event, so set that flag.function writeOrBuffer(stream, state, chunk, encoding, cb) {  chunk = decodeChunk(state, chunk, encoding);  if (Buffer.isBuffer(chunk)) encoding = 'buffer';  var len = state.objectMode ? 1 : chunk.length;  state.length += len;  var ret = state.length < state.highWaterMark;  // we must ensure that previous needDrain will not be reset to false.  if (!ret) state.needDrain = true;  if (state.writing || state.corked) {    var last = state.lastBufferedRequest;    state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);    if (last) {      last.next = state.lastBufferedRequest;    } else {      state.bufferedRequest = state.lastBufferedRequest;    }    state.bufferedRequestCount += 1;  } else {    doWrite(stream, state, false, len, chunk, encoding, cb);  }  return ret;}function doWrite(stream, state, writev, len, chunk, encoding, cb) {  state.writelen = len;  state.writecb = cb;  state.writing = true;  state.sync = true;  if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);  state.sync = false;}function onwriteError(stream, state, sync, er, cb) {  --state.pendingcb;  if (sync) processNextTick(cb, er);else cb(er);  stream._writableState.errorEmitted = true;  stream.emit('error', er);}function onwriteStateUpdate(state) {  state.writing = false;  state.writecb = null;  state.length -= state.writelen;  state.writelen = 0;}function onwrite(stream, er) {  var state = stream._writableState;  var sync = state.sync;  var cb = state.writecb;  onwriteStateUpdate(state);  if (er) onwriteError(stream, state, sync, er, cb);else {    // Check if we're actually ready to finish, but don't emit yet    var finished = needFinish(state);    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {      clearBuffer(stream, state);    }    if (sync) {      /*<replacement>*/      asyncWrite(afterWrite, stream, state, finished, cb);      /*</replacement>*/    } else {        afterWrite(stream, state, finished, cb);      }  }}function afterWrite(stream, state, finished, cb) {  if (!finished) onwriteDrain(stream, state);  state.pendingcb--;  cb();  finishMaybe(stream, state);}// Must force callback to be called on nextTick, so that we don't// emit 'drain' before the write() consumer gets the 'false' return// value, and has a chance to attach a 'drain' listener.function onwriteDrain(stream, state) {  if (state.length === 0 && state.needDrain) {    state.needDrain = false;    stream.emit('drain');  }}// if there's something in the buffer waiting, then process itfunction clearBuffer(stream, state) {  state.bufferProcessing = true;  var entry = state.bufferedRequest;  if (stream._writev && entry && entry.next) {    // Fast case, write everything using _writev()    var l = state.bufferedRequestCount;    var buffer = new Array(l);    var holder = state.corkedRequestsFree;    holder.entry = entry;    var count = 0;    while (entry) {      buffer[count] = entry;      entry = entry.next;      count += 1;    }    doWrite(stream, state, true, state.length, buffer, '', holder.finish);    // doWrite is always async, defer these to save a bit of time    // as the hot path ends with doWrite    state.pendingcb++;    state.lastBufferedRequest = null;    state.corkedRequestsFree = holder.next;    holder.next = null;  } else {    // Slow case, write chunks one-by-one    while (entry) {      var chunk = entry.chunk;      var encoding = entry.encoding;      var cb = entry.callback;      var len = state.objectMode ? 1 : chunk.length;      doWrite(stream, state, false, len, chunk, encoding, cb);      entry = entry.next;      // if we didn't call the onwrite immediately, then      // it means that we need to wait until it does.      // also, that means that the chunk and cb are currently      // being processed, so move the buffer counter past them.      if (state.writing) {        break;      }    }    if (entry === null) state.lastBufferedRequest = null;  }  state.bufferedRequestCount = 0;  state.bufferedRequest = entry;  state.bufferProcessing = false;}Writable.prototype._write = function (chunk, encoding, cb) {  cb(new Error('not implemented'));};Writable.prototype._writev = null;Writable.prototype.end = function (chunk, encoding, cb) {  var state = this._writableState;  if (typeof chunk === 'function') {    cb = chunk;    chunk = null;    encoding = null;  } else if (typeof encoding === 'function') {    cb = encoding;    encoding = null;  }  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);  // .end() fully uncorks  if (state.corked) {    state.corked = 1;    this.uncork();  }  // ignore unnecessary end() calls.  if (!state.ending && !state.finished) endWritable(this, state, cb);};function needFinish(state) {  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;}function prefinish(stream, state) {  if (!state.prefinished) {    state.prefinished = true;    stream.emit('prefinish');  }}function finishMaybe(stream, state) {  var need = needFinish(state);  if (need) {    if (state.pendingcb === 0) {      prefinish(stream, state);      state.finished = true;      stream.emit('finish');    } else {      prefinish(stream, state);    }  }  return need;}function endWritable(stream, state, cb) {  state.ending = true;  finishMaybe(stream, state);  if (cb) {    if (state.finished) processNextTick(cb);else stream.once('finish', cb);  }  state.ended = true;  stream.writable = false;}// It seems a linked list but it is not// there will be only 2 of these for each streamfunction CorkedRequest(state) {  var _this = this;  this.next = null;  this.entry = null;  this.finish = function (err) {    var entry = _this.entry;    _this.entry = null;    while (entry) {      var cb = entry.callback;      state.pendingcb--;      cb(err);      entry = entry.next;    }    if (state.corkedRequestsFree) {      state.corkedRequestsFree.next = _this;    } else {      state.corkedRequestsFree = _this;    }  };}}).call(this,require('_process'),require("timers").setImmediate)},{"./_stream_duplex":237,"_process":226,"buffer":79,"core-util-is":103,"events":136,"inherits":154,"process-nextick-args":225,"timers":259,"util-deprecate":260}],242:[function(require,module,exports){module.exports = require("./lib/_stream_passthrough.js")},{"./lib/_stream_passthrough.js":238}],243:[function(require,module,exports){var Stream = (function (){  try {    return require('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify  } catch(_){}}());exports = module.exports = require('./lib/_stream_readable.js');exports.Stream = Stream || exports;exports.Readable = exports;exports.Writable = require('./lib/_stream_writable.js');exports.Duplex = require('./lib/_stream_duplex.js');exports.Transform = require('./lib/_stream_transform.js');exports.PassThrough = require('./lib/_stream_passthrough.js');},{"./lib/_stream_duplex.js":237,"./lib/_stream_passthrough.js":238,"./lib/_stream_readable.js":239,"./lib/_stream_transform.js":240,"./lib/_stream_writable.js":241}],244:[function(require,module,exports){module.exports = require("./lib/_stream_transform.js")},{"./lib/_stream_transform.js":240}],245:[function(require,module,exports){module.exports = require("./lib/_stream_writable.js")},{"./lib/_stream_writable.js":241}],246:[function(require,module,exports){'use strict'var Buffer = require('buffer').Buffervar inherits = require('inherits')var HashBase = require('hash-base')var ARRAY16 = new Array(16)var zl = [  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,  7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,  3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,  1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,  4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13]var zr = [  5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,  6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,  15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,  8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,  12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11]var sl = [  11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,  7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,  11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,  11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,  9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6]var sr = [  8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,  9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,  9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,  15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,  8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11]var hl = [0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e]var hr = [0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000]function RIPEMD160 () {  HashBase.call(this, 64)  // state  this._a = 0x67452301  this._b = 0xefcdab89  this._c = 0x98badcfe  this._d = 0x10325476  this._e = 0xc3d2e1f0}inherits(RIPEMD160, HashBase)RIPEMD160.prototype._update = function () {  var words = ARRAY16  for (var j = 0; j < 16; ++j) words[j] = this._block.readInt32LE(j * 4)  var al = this._a | 0  var bl = this._b | 0  var cl = this._c | 0  var dl = this._d | 0  var el = this._e | 0  var ar = this._a | 0  var br = this._b | 0  var cr = this._c | 0  var dr = this._d | 0  var er = this._e | 0  // computation  for (var i = 0; i < 80; i += 1) {    var tl    var tr    if (i < 16) {      tl = fn1(al, bl, cl, dl, el, words[zl[i]], hl[0], sl[i])      tr = fn5(ar, br, cr, dr, er, words[zr[i]], hr[0], sr[i])    } else if (i < 32) {      tl = fn2(al, bl, cl, dl, el, words[zl[i]], hl[1], sl[i])      tr = fn4(ar, br, cr, dr, er, words[zr[i]], hr[1], sr[i])    } else if (i < 48) {      tl = fn3(al, bl, cl, dl, el, words[zl[i]], hl[2], sl[i])      tr = fn3(ar, br, cr, dr, er, words[zr[i]], hr[2], sr[i])    } else if (i < 64) {      tl = fn4(al, bl, cl, dl, el, words[zl[i]], hl[3], sl[i])      tr = fn2(ar, br, cr, dr, er, words[zr[i]], hr[3], sr[i])    } else { // if (i<80) {      tl = fn5(al, bl, cl, dl, el, words[zl[i]], hl[4], sl[i])      tr = fn1(ar, br, cr, dr, er, words[zr[i]], hr[4], sr[i])    }    al = el    el = dl    dl = rotl(cl, 10)    cl = bl    bl = tl    ar = er    er = dr    dr = rotl(cr, 10)    cr = br    br = tr  }  // update state  var t = (this._b + cl + dr) | 0  this._b = (this._c + dl + er) | 0  this._c = (this._d + el + ar) | 0  this._d = (this._e + al + br) | 0  this._e = (this._a + bl + cr) | 0  this._a = t}RIPEMD160.prototype._digest = function () {  // create padding and handle blocks  this._block[this._blockOffset++] = 0x80  if (this._blockOffset > 56) {    this._block.fill(0, this._blockOffset, 64)    this._update()    this._blockOffset = 0  }  this._block.fill(0, this._blockOffset, 56)  this._block.writeUInt32LE(this._length[0], 56)  this._block.writeUInt32LE(this._length[1], 60)  this._update()  // produce result  var buffer = Buffer.alloc ? Buffer.alloc(20) : new Buffer(20)  buffer.writeInt32LE(this._a, 0)  buffer.writeInt32LE(this._b, 4)  buffer.writeInt32LE(this._c, 8)  buffer.writeInt32LE(this._d, 12)  buffer.writeInt32LE(this._e, 16)  return buffer}function rotl (x, n) {  return (x << n) | (x >>> (32 - n))}function fn1 (a, b, c, d, e, m, k, s) {  return (rotl((a + (b ^ c ^ d) + m + k) | 0, s) + e) | 0}function fn2 (a, b, c, d, e, m, k, s) {  return (rotl((a + ((b & c) | ((~b) & d)) + m + k) | 0, s) + e) | 0}function fn3 (a, b, c, d, e, m, k, s) {  return (rotl((a + ((b | (~c)) ^ d) + m + k) | 0, s) + e) | 0}function fn4 (a, b, c, d, e, m, k, s) {  return (rotl((a + ((b & d) | (c & (~d))) + m + k) | 0, s) + e) | 0}function fn5 (a, b, c, d, e, m, k, s) {  return (rotl((a + (b ^ (c | (~d))) + m + k) | 0, s) + e) | 0}module.exports = RIPEMD160},{"buffer":79,"hash-base":138,"inherits":154}],247:[function(require,module,exports){arguments[4][68][0].apply(exports,arguments)},{"buffer":79,"dup":68}],248:[function(require,module,exports){(function (Buffer){;(function (sax) { // wrapper for non-node envs  sax.parser = function (strict, opt) { return new SAXParser(strict, opt) }  sax.SAXParser = SAXParser  sax.SAXStream = SAXStream  sax.createStream = createStream  // When we pass the MAX_BUFFER_LENGTH position, start checking for buffer overruns.  // When we check, schedule the next check for MAX_BUFFER_LENGTH - (max(buffer lengths)),  // since that's the earliest that a buffer overrun could occur.  This way, checks are  // as rare as required, but as often as necessary to ensure never crossing this bound.  // Furthermore, buffers are only tested at most once per write(), so passing a very  // large string into write() might have undesirable effects, but this is manageable by  // the caller, so it is assumed to be safe.  Thus, a call to write() may, in the extreme  // edge case, result in creating at most one complete copy of the string passed in.  // Set to Infinity to have unlimited buffers.  sax.MAX_BUFFER_LENGTH = 64 * 1024  var buffers = [    'comment', 'sgmlDecl', 'textNode', 'tagName', 'doctype',    'procInstName', 'procInstBody', 'entity', 'attribName',    'attribValue', 'cdata', 'script'  ]  sax.EVENTS = [    'text',    'processinginstruction',    'sgmldeclaration',    'doctype',    'comment',    'opentagstart',    'attribute',    'opentag',    'closetag',    'opencdata',    'cdata',    'closecdata',    'error',    'end',    'ready',    'script',    'opennamespace',    'closenamespace'  ]  function SAXParser (strict, opt) {    if (!(this instanceof SAXParser)) {      return new SAXParser(strict, opt)    }    var parser = this    clearBuffers(parser)    parser.q = parser.c = ''    parser.bufferCheckPosition = sax.MAX_BUFFER_LENGTH    parser.opt = opt || {}    parser.opt.lowercase = parser.opt.lowercase || parser.opt.lowercasetags    parser.looseCase = parser.opt.lowercase ? 'toLowerCase' : 'toUpperCase'    parser.tags = []    parser.closed = parser.closedRoot = parser.sawRoot = false    parser.tag = parser.error = null    parser.strict = !!strict    parser.noscript = !!(strict || parser.opt.noscript)    parser.state = S.BEGIN    parser.strictEntities = parser.opt.strictEntities    parser.ENTITIES = parser.strictEntities ? Object.create(sax.XML_ENTITIES) : Object.create(sax.ENTITIES)    parser.attribList = []    // namespaces form a prototype chain.    // it always points at the current tag,    // which protos to its parent tag.    if (parser.opt.xmlns) {      parser.ns = Object.create(rootNS)    }    // mostly just for error reporting    parser.trackPosition = parser.opt.position !== false    if (parser.trackPosition) {      parser.position = parser.line = parser.column = 0    }    emit(parser, 'onready')  }  if (!Object.create) {    Object.create = function (o) {      function F () {}      F.prototype = o      var newf = new F()      return newf    }  }  if (!Object.keys) {    Object.keys = function (o) {      var a = []      for (var i in o) if (o.hasOwnProperty(i)) a.push(i)      return a    }  }  function checkBufferLength (parser) {    var maxAllowed = Math.max(sax.MAX_BUFFER_LENGTH, 10)    var maxActual = 0    for (var i = 0, l = buffers.length; i < l; i++) {      var len = parser[buffers[i]].length      if (len > maxAllowed) {        // Text/cdata nodes can get big, and since they're buffered,        // we can get here under normal conditions.        // Avoid issues by emitting the text node now,        // so at least it won't get any bigger.        switch (buffers[i]) {          case 'textNode':            closeText(parser)            break          case 'cdata':            emitNode(parser, 'oncdata', parser.cdata)            parser.cdata = ''            break          case 'script':            emitNode(parser, 'onscript', parser.script)            parser.script = ''            break          default:            error(parser, 'Max buffer length exceeded: ' + buffers[i])        }      }      maxActual = Math.max(maxActual, len)    }    // schedule the next check for the earliest possible buffer overrun.    var m = sax.MAX_BUFFER_LENGTH - maxActual    parser.bufferCheckPosition = m + parser.position  }  function clearBuffers (parser) {    for (var i = 0, l = buffers.length; i < l; i++) {      parser[buffers[i]] = ''    }  }  function flushBuffers (parser) {    closeText(parser)    if (parser.cdata !== '') {      emitNode(parser, 'oncdata', parser.cdata)      parser.cdata = ''    }    if (parser.script !== '') {      emitNode(parser, 'onscript', parser.script)      parser.script = ''    }  }  SAXParser.prototype = {    end: function () { end(this) },    write: write,    resume: function () { this.error = null; return this },    close: function () { return this.write(null) },    flush: function () { flushBuffers(this) }  }  var Stream  try {    Stream = require('stream').Stream  } catch (ex) {    Stream = function () {}  }  var streamWraps = sax.EVENTS.filter(function (ev) {    return ev !== 'error' && ev !== 'end'  })  function createStream (strict, opt) {    return new SAXStream(strict, opt)  }  function SAXStream (strict, opt) {    if (!(this instanceof SAXStream)) {      return new SAXStream(strict, opt)    }    Stream.apply(this)    this._parser = new SAXParser(strict, opt)    this.writable = true    this.readable = true    var me = this    this._parser.onend = function () {      me.emit('end')    }    this._parser.onerror = function (er) {      me.emit('error', er)      // if didn't throw, then means error was handled.      // go ahead and clear error, so we can write again.      me._parser.error = null    }    this._decoder = null    streamWraps.forEach(function (ev) {      Object.defineProperty(me, 'on' + ev, {        get: function () {          return me._parser['on' + ev]        },        set: function (h) {          if (!h) {            me.removeAllListeners(ev)            me._parser['on' + ev] = h            return h          }          me.on(ev, h)        },        enumerable: true,        configurable: false      })    })  }  SAXStream.prototype = Object.create(Stream.prototype, {    constructor: {      value: SAXStream    }  })  SAXStream.prototype.write = function (data) {    if (typeof Buffer === 'function' &&      typeof Buffer.isBuffer === 'function' &&      Buffer.isBuffer(data)) {      if (!this._decoder) {        var SD = require('string_decoder').StringDecoder        this._decoder = new SD('utf8')      }      data = this._decoder.write(data)    }    this._parser.write(data.toString())    this.emit('data', data)    return true  }  SAXStream.prototype.end = function (chunk) {    if (chunk && chunk.length) {      this.write(chunk)    }    this._parser.end()    return true  }  SAXStream.prototype.on = function (ev, handler) {    var me = this    if (!me._parser['on' + ev] && streamWraps.indexOf(ev) !== -1) {      me._parser['on' + ev] = function () {        var args = arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments)        args.splice(0, 0, ev)        me.emit.apply(me, args)      }    }    return Stream.prototype.on.call(me, ev, handler)  }  // this really needs to be replaced with character classes.  // XML allows all manner of ridiculous numbers and digits.  var CDATA = '[CDATA['  var DOCTYPE = 'DOCTYPE'  var XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace'  var XMLNS_NAMESPACE = 'http://www.w3.org/2000/xmlns/'  var rootNS = { xml: XML_NAMESPACE, xmlns: XMLNS_NAMESPACE }  // http://www.w3.org/TR/REC-xml/#NT-NameStartChar  // This implementation works on strings, a single character at a time  // as such, it cannot ever support astral-plane characters (10000-EFFFF)  // without a significant breaking change to either this  parser, or the  // JavaScript language.  Implementation of an emoji-capable xml parser  // is left as an exercise for the reader.  var nameStart = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/  var nameBody = /[:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040.\d-]/  var entityStart = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/  var entityBody = /[#:_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u00B7\u0300-\u036F\u203F-\u2040.\d-]/  function isWhitespace (c) {    return c === ' ' || c === '\n' || c === '\r' || c === '\t'  }  function isQuote (c) {    return c === '"' || c === '\''  }  function isAttribEnd (c) {    return c === '>' || isWhitespace(c)  }  function isMatch (regex, c) {    return regex.test(c)  }  function notMatch (regex, c) {    return !isMatch(regex, c)  }  var S = 0  sax.STATE = {    BEGIN: S++, // leading byte order mark or whitespace    BEGIN_WHITESPACE: S++, // leading whitespace    TEXT: S++, // general stuff    TEXT_ENTITY: S++, // & and such.    OPEN_WAKA: S++, // <    SGML_DECL: S++, // <!BLARG    SGML_DECL_QUOTED: S++, // <!BLARG foo "bar    DOCTYPE: S++, // <!DOCTYPE    DOCTYPE_QUOTED: S++, // <!DOCTYPE "//blah    DOCTYPE_DTD: S++, // <!DOCTYPE "//blah" [ ...    DOCTYPE_DTD_QUOTED: S++, // <!DOCTYPE "//blah" [ "foo    COMMENT_STARTING: S++, // <!-    COMMENT: S++, // <!--    COMMENT_ENDING: S++, // <!-- blah -    COMMENT_ENDED: S++, // <!-- blah --    CDATA: S++, // <![CDATA[ something    CDATA_ENDING: S++, // ]    CDATA_ENDING_2: S++, // ]]    PROC_INST: S++, // <?hi    PROC_INST_BODY: S++, // <?hi there    PROC_INST_ENDING: S++, // <?hi "there" ?    OPEN_TAG: S++, // <strong    OPEN_TAG_SLASH: S++, // <strong /    ATTRIB: S++, // <a    ATTRIB_NAME: S++, // <a foo    ATTRIB_NAME_SAW_WHITE: S++, // <a foo _    ATTRIB_VALUE: S++, // <a foo=    ATTRIB_VALUE_QUOTED: S++, // <a foo="bar    ATTRIB_VALUE_CLOSED: S++, // <a foo="bar"    ATTRIB_VALUE_UNQUOTED: S++, // <a foo=bar    ATTRIB_VALUE_ENTITY_Q: S++, // <foo bar="""    ATTRIB_VALUE_ENTITY_U: S++, // <foo bar="    CLOSE_TAG: S++, // </a    CLOSE_TAG_SAW_WHITE: S++, // </a   >    SCRIPT: S++, // <script> ...    SCRIPT_ENDING: S++ // <script> ... <  }  sax.XML_ENTITIES = {    'amp': '&',    'gt': '>',    'lt': '<',    'quot': '"',    'apos': "'"  }  sax.ENTITIES = {    'amp': '&',    'gt': '>',    'lt': '<',    'quot': '"',    'apos': "'",    'AElig': 198,    'Aacute': 193,    'Acirc': 194,    'Agrave': 192,    'Aring': 197,    'Atilde': 195,    'Auml': 196,    'Ccedil': 199,    'ETH': 208,    'Eacute': 201,    'Ecirc': 202,    'Egrave': 200,    'Euml': 203,    'Iacute': 205,    'Icirc': 206,    'Igrave': 204,    'Iuml': 207,    'Ntilde': 209,    'Oacute': 211,    'Ocirc': 212,    'Ograve': 210,    'Oslash': 216,    'Otilde': 213,    'Ouml': 214,    'THORN': 222,    'Uacute': 218,    'Ucirc': 219,    'Ugrave': 217,    'Uuml': 220,    'Yacute': 221,    'aacute': 225,    'acirc': 226,    'aelig': 230,    'agrave': 224,    'aring': 229,    'atilde': 227,    'auml': 228,    'ccedil': 231,    'eacute': 233,    'ecirc': 234,    'egrave': 232,    'eth': 240,    'euml': 235,    'iacute': 237,    'icirc': 238,    'igrave': 236,    'iuml': 239,    'ntilde': 241,    'oacute': 243,    'ocirc': 244,    'ograve': 242,    'oslash': 248,    'otilde': 245,    'ouml': 246,    'szlig': 223,    'thorn': 254,    'uacute': 250,    'ucirc': 251,    'ugrave': 249,    'uuml': 252,    'yacute': 253,    'yuml': 255,    'copy': 169,    'reg': 174,    'nbsp': 160,    'iexcl': 161,    'cent': 162,    'pound': 163,    'curren': 164,    'yen': 165,    'brvbar': 166,    'sect': 167,    'uml': 168,    'ordf': 170,    'laquo': 171,    'not': 172,    'shy': 173,    'macr': 175,    'deg': 176,    'plusmn': 177,    'sup1': 185,    'sup2': 178,    'sup3': 179,    'acute': 180,    'micro': 181,    'para': 182,    'middot': 183,    'cedil': 184,    'ordm': 186,    'raquo': 187,    'frac14': 188,    'frac12': 189,    'frac34': 190,    'iquest': 191,    'times': 215,    'divide': 247,    'OElig': 338,    'oelig': 339,    'Scaron': 352,    'scaron': 353,    'Yuml': 376,    'fnof': 402,    'circ': 710,    'tilde': 732,    'Alpha': 913,    'Beta': 914,    'Gamma': 915,    'Delta': 916,    'Epsilon': 917,    'Zeta': 918,    'Eta': 919,    'Theta': 920,    'Iota': 921,    'Kappa': 922,    'Lambda': 923,    'Mu': 924,    'Nu': 925,    'Xi': 926,    'Omicron': 927,    'Pi': 928,    'Rho': 929,    'Sigma': 931,    'Tau': 932,    'Upsilon': 933,    'Phi': 934,    'Chi': 935,    'Psi': 936,    'Omega': 937,    'alpha': 945,    'beta': 946,    'gamma': 947,    'delta': 948,    'epsilon': 949,    'zeta': 950,    'eta': 951,    'theta': 952,    'iota': 953,    'kappa': 954,    'lambda': 955,    'mu': 956,    'nu': 957,    'xi': 958,    'omicron': 959,    'pi': 960,    'rho': 961,    'sigmaf': 962,    'sigma': 963,    'tau': 964,    'upsilon': 965,    'phi': 966,    'chi': 967,    'psi': 968,    'omega': 969,    'thetasym': 977,    'upsih': 978,    'piv': 982,    'ensp': 8194,    'emsp': 8195,    'thinsp': 8201,    'zwnj': 8204,    'zwj': 8205,    'lrm': 8206,    'rlm': 8207,    'ndash': 8211,    'mdash': 8212,    'lsquo': 8216,    'rsquo': 8217,    'sbquo': 8218,    'ldquo': 8220,    'rdquo': 8221,    'bdquo': 8222,    'dagger': 8224,    'Dagger': 8225,    'bull': 8226,    'hellip': 8230,    'permil': 8240,    'prime': 8242,    'Prime': 8243,    'lsaquo': 8249,    'rsaquo': 8250,    'oline': 8254,    'frasl': 8260,    'euro': 8364,    'image': 8465,    'weierp': 8472,    'real': 8476,    'trade': 8482,    'alefsym': 8501,    'larr': 8592,    'uarr': 8593,    'rarr': 8594,    'darr': 8595,    'harr': 8596,    'crarr': 8629,    'lArr': 8656,    'uArr': 8657,    'rArr': 8658,    'dArr': 8659,    'hArr': 8660,    'forall': 8704,    'part': 8706,    'exist': 8707,    'empty': 8709,    'nabla': 8711,    'isin': 8712,    'notin': 8713,    'ni': 8715,    'prod': 8719,    'sum': 8721,    'minus': 8722,    'lowast': 8727,    'radic': 8730,    'prop': 8733,    'infin': 8734,    'ang': 8736,    'and': 8743,    'or': 8744,    'cap': 8745,    'cup': 8746,    'int': 8747,    'there4': 8756,    'sim': 8764,    'cong': 8773,    'asymp': 8776,    'ne': 8800,    'equiv': 8801,    'le': 8804,    'ge': 8805,    'sub': 8834,    'sup': 8835,    'nsub': 8836,    'sube': 8838,    'supe': 8839,    'oplus': 8853,    'otimes': 8855,    'perp': 8869,    'sdot': 8901,    'lceil': 8968,    'rceil': 8969,    'lfloor': 8970,    'rfloor': 8971,    'lang': 9001,    'rang': 9002,    'loz': 9674,    'spades': 9824,    'clubs': 9827,    'hearts': 9829,    'diams': 9830  }  Object.keys(sax.ENTITIES).forEach(function (key) {    var e = sax.ENTITIES[key]    var s = typeof e === 'number' ? String.fromCharCode(e) : e    sax.ENTITIES[key] = s  })  for (var s in sax.STATE) {    sax.STATE[sax.STATE[s]] = s  }  // shorthand  S = sax.STATE  function emit (parser, event, data) {    parser[event] && parser[event](data)  }  function emitNode (parser, nodeType, data) {    if (parser.textNode) closeText(parser)    emit(parser, nodeType, data)  }  function closeText (parser) {    parser.textNode = textopts(parser.opt, parser.textNode)    if (parser.textNode) emit(parser, 'ontext', parser.textNode)    parser.textNode = ''  }  function textopts (opt, text) {    if (opt.trim) text = text.trim()    if (opt.normalize) text = text.replace(/\s+/g, ' ')    return text  }  function error (parser, er) {    closeText(parser)    if (parser.trackPosition) {      er += '\nLine: ' + parser.line +        '\nColumn: ' + parser.column +        '\nChar: ' + parser.c    }    er = new Error(er)    parser.error = er    emit(parser, 'onerror', er)    return parser  }  function end (parser) {    if (parser.sawRoot && !parser.closedRoot) strictFail(parser, 'Unclosed root tag')    if ((parser.state !== S.BEGIN) &&      (parser.state !== S.BEGIN_WHITESPACE) &&      (parser.state !== S.TEXT)) {      error(parser, 'Unexpected end')    }    closeText(parser)    parser.c = ''    parser.closed = true    emit(parser, 'onend')    SAXParser.call(parser, parser.strict, parser.opt)    return parser  }  function strictFail (parser, message) {    if (typeof parser !== 'object' || !(parser instanceof SAXParser)) {      throw new Error('bad call to strictFail')    }    if (parser.strict) {      error(parser, message)    }  }  function newTag (parser) {    if (!parser.strict) parser.tagName = parser.tagName[parser.looseCase]()    var parent = parser.tags[parser.tags.length - 1] || parser    var tag = parser.tag = { name: parser.tagName, attributes: {} }    // will be overridden if tag contails an xmlns="foo" or xmlns:foo="bar"    if (parser.opt.xmlns) {      tag.ns = parent.ns    }    parser.attribList.length = 0    emitNode(parser, 'onopentagstart', tag)  }  function qname (name, attribute) {    var i = name.indexOf(':')    var qualName = i < 0 ? [ '', name ] : name.split(':')    var prefix = qualName[0]    var local = qualName[1]    // <x "xmlns"="http://foo">    if (attribute && name === 'xmlns') {      prefix = 'xmlns'      local = ''    }    return { prefix: prefix, local: local }  }  function attrib (parser) {    if (!parser.strict) {      parser.attribName = parser.attribName[parser.looseCase]()    }    if (parser.attribList.indexOf(parser.attribName) !== -1 ||      parser.tag.attributes.hasOwnProperty(parser.attribName)) {      parser.attribName = parser.attribValue = ''      return    }    if (parser.opt.xmlns) {      var qn = qname(parser.attribName, true)      var prefix = qn.prefix      var local = qn.local      if (prefix === 'xmlns') {        // namespace binding attribute. push the binding into scope        if (local === 'xml' && parser.attribValue !== XML_NAMESPACE) {          strictFail(parser,            'xml: prefix must be bound to ' + XML_NAMESPACE + '\n' +            'Actual: ' + parser.attribValue)        } else if (local === 'xmlns' && parser.attribValue !== XMLNS_NAMESPACE) {          strictFail(parser,            'xmlns: prefix must be bound to ' + XMLNS_NAMESPACE + '\n' +            'Actual: ' + parser.attribValue)        } else {          var tag = parser.tag          var parent = parser.tags[parser.tags.length - 1] || parser          if (tag.ns === parent.ns) {            tag.ns = Object.create(parent.ns)          }          tag.ns[local] = parser.attribValue        }      }      // defer onattribute events until all attributes have been seen      // so any new bindings can take effect. preserve attribute order      // so deferred events can be emitted in document order      parser.attribList.push([parser.attribName, parser.attribValue])    } else {      // in non-xmlns mode, we can emit the event right away      parser.tag.attributes[parser.attribName] = parser.attribValue      emitNode(parser, 'onattribute', {        name: parser.attribName,        value: parser.attribValue      })    }    parser.attribName = parser.attribValue = ''  }  function openTag (parser, selfClosing) {    if (parser.opt.xmlns) {      // emit namespace binding events      var tag = parser.tag      // add namespace info to tag      var qn = qname(parser.tagName)      tag.prefix = qn.prefix      tag.local = qn.local      tag.uri = tag.ns[qn.prefix] || ''      if (tag.prefix && !tag.uri) {        strictFail(parser, 'Unbound namespace prefix: ' +          JSON.stringify(parser.tagName))        tag.uri = qn.prefix      }      var parent = parser.tags[parser.tags.length - 1] || parser      if (tag.ns && parent.ns !== tag.ns) {        Object.keys(tag.ns).forEach(function (p) {          emitNode(parser, 'onopennamespace', {            prefix: p,            uri: tag.ns[p]          })        })      }      // handle deferred onattribute events      // Note: do not apply default ns to attributes:      //   http://www.w3.org/TR/REC-xml-names/#defaulting      for (var i = 0, l = parser.attribList.length; i < l; i++) {        var nv = parser.attribList[i]        var name = nv[0]        var value = nv[1]        var qualName = qname(name, true)        var prefix = qualName.prefix        var local = qualName.local        var uri = prefix === '' ? '' : (tag.ns[prefix] || '')        var a = {          name: name,          value: value,          prefix: prefix,          local: local,          uri: uri        }        // if there's any attributes with an undefined namespace,        // then fail on them now.        if (prefix && prefix !== 'xmlns' && !uri) {          strictFail(parser, 'Unbound namespace prefix: ' +            JSON.stringify(prefix))          a.uri = prefix        }        parser.tag.attributes[name] = a        emitNode(parser, 'onattribute', a)      }      parser.attribList.length = 0    }    parser.tag.isSelfClosing = !!selfClosing    // process the tag    parser.sawRoot = true    parser.tags.push(parser.tag)    emitNode(parser, 'onopentag', parser.tag)    if (!selfClosing) {      // special case for <script> in non-strict mode.      if (!parser.noscript && parser.tagName.toLowerCase() === 'script') {        parser.state = S.SCRIPT      } else {        parser.state = S.TEXT      }      parser.tag = null      parser.tagName = ''    }    parser.attribName = parser.attribValue = ''    parser.attribList.length = 0  }  function closeTag (parser) {    if (!parser.tagName) {      strictFail(parser, 'Weird empty close tag.')      parser.textNode += '</>'      parser.state = S.TEXT      return    }    if (parser.script) {      if (parser.tagName !== 'script') {        parser.script += '</' + parser.tagName + '>'        parser.tagName = ''        parser.state = S.SCRIPT        return      }      emitNode(parser, 'onscript', parser.script)      parser.script = ''    }    // first make sure that the closing tag actually exists.    // <a><b></c></b></a> will close everything, otherwise.    var t = parser.tags.length    var tagName = parser.tagName    if (!parser.strict) {      tagName = tagName[parser.looseCase]()    }    var closeTo = tagName    while (t--) {      var close = parser.tags[t]      if (close.name !== closeTo) {        // fail the first time in strict mode        strictFail(parser, 'Unexpected close tag')      } else {        break      }    }    // didn't find it.  we already failed for strict, so just abort.    if (t < 0) {      strictFail(parser, 'Unmatched closing tag: ' + parser.tagName)      parser.textNode += '</' + parser.tagName + '>'      parser.state = S.TEXT      return    }    parser.tagName = tagName    var s = parser.tags.length    while (s-- > t) {      var tag = parser.tag = parser.tags.pop()      parser.tagName = parser.tag.name      emitNode(parser, 'onclosetag', parser.tagName)      var x = {}      for (var i in tag.ns) {        x[i] = tag.ns[i]      }      var parent = parser.tags[parser.tags.length - 1] || parser      if (parser.opt.xmlns && tag.ns !== parent.ns) {        // remove namespace bindings introduced by tag        Object.keys(tag.ns).forEach(function (p) {          var n = tag.ns[p]          emitNode(parser, 'onclosenamespace', { prefix: p, uri: n })        })      }    }    if (t === 0) parser.closedRoot = true    parser.tagName = parser.attribValue = parser.attribName = ''    parser.attribList.length = 0    parser.state = S.TEXT  }  function parseEntity (parser) {    var entity = parser.entity    var entityLC = entity.toLowerCase()    var num    var numStr = ''    if (parser.ENTITIES[entity]) {      return parser.ENTITIES[entity]    }    if (parser.ENTITIES[entityLC]) {      return parser.ENTITIES[entityLC]    }    entity = entityLC    if (entity.charAt(0) === '#') {      if (entity.charAt(1) === 'x') {        entity = entity.slice(2)        num = parseInt(entity, 16)        numStr = num.toString(16)      } else {        entity = entity.slice(1)        num = parseInt(entity, 10)        numStr = num.toString(10)      }    }    entity = entity.replace(/^0+/, '')    if (isNaN(num) || numStr.toLowerCase() !== entity) {      strictFail(parser, 'Invalid character entity')      return '&' + parser.entity + ';'    }    return String.fromCodePoint(num)  }  function beginWhiteSpace (parser, c) {    if (c === '<') {      parser.state = S.OPEN_WAKA      parser.startTagPosition = parser.position    } else if (!isWhitespace(c)) {      // have to process this as a text node.      // weird, but happens.      strictFail(parser, 'Non-whitespace before first tag.')      parser.textNode = c      parser.state = S.TEXT    }  }  function charAt (chunk, i) {    var result = ''    if (i < chunk.length) {      result = chunk.charAt(i)    }    return result  }  function write (chunk) {    var parser = this    if (this.error) {      throw this.error    }    if (parser.closed) {      return error(parser,        'Cannot write after close. Assign an onready handler.')    }    if (chunk === null) {      return end(parser)    }    if (typeof chunk === 'object') {      chunk = chunk.toString()    }    var i = 0    var c = ''    while (true) {      c = charAt(chunk, i++)      parser.c = c      if (!c) {        break      }      if (parser.trackPosition) {        parser.position++        if (c === '\n') {          parser.line++          parser.column = 0        } else {          parser.column++        }      }      switch (parser.state) {        case S.BEGIN:          parser.state = S.BEGIN_WHITESPACE          if (c === '\uFEFF') {            continue          }          beginWhiteSpace(parser, c)          continue        case S.BEGIN_WHITESPACE:          beginWhiteSpace(parser, c)          continue        case S.TEXT:          if (parser.sawRoot && !parser.closedRoot) {            var starti = i - 1            while (c && c !== '<' && c !== '&') {              c = charAt(chunk, i++)              if (c && parser.trackPosition) {                parser.position++                if (c === '\n') {                  parser.line++                  parser.column = 0                } else {                  parser.column++                }              }            }            parser.textNode += chunk.substring(starti, i - 1)          }          if (c === '<' && !(parser.sawRoot && parser.closedRoot && !parser.strict)) {            parser.state = S.OPEN_WAKA            parser.startTagPosition = parser.position          } else {            if (!isWhitespace(c) && (!parser.sawRoot || parser.closedRoot)) {              strictFail(parser, 'Text data outside of root node.')            }            if (c === '&') {              parser.state = S.TEXT_ENTITY            } else {              parser.textNode += c            }          }          continue        case S.SCRIPT:          // only non-strict          if (c === '<') {            parser.state = S.SCRIPT_ENDING          } else {            parser.script += c          }          continue        case S.SCRIPT_ENDING:          if (c === '/') {            parser.state = S.CLOSE_TAG          } else {            parser.script += '<' + c            parser.state = S.SCRIPT          }          continue        case S.OPEN_WAKA:          // either a /, ?, !, or text is coming next.          if (c === '!') {            parser.state = S.SGML_DECL            parser.sgmlDecl = ''          } else if (isWhitespace(c)) {            // wait for it...          } else if (isMatch(nameStart, c)) {            parser.state = S.OPEN_TAG            parser.tagName = c          } else if (c === '/') {            parser.state = S.CLOSE_TAG            parser.tagName = ''          } else if (c === '?') {            parser.state = S.PROC_INST            parser.procInstName = parser.procInstBody = ''          } else {            strictFail(parser, 'Unencoded <')            // if there was some whitespace, then add that in.            if (parser.startTagPosition + 1 < parser.position) {              var pad = parser.position - parser.startTagPosition              c = new Array(pad).join(' ') + c            }            parser.textNode += '<' + c            parser.state = S.TEXT          }          continue        case S.SGML_DECL:          if ((parser.sgmlDecl + c).toUpperCase() === CDATA) {            emitNode(parser, 'onopencdata')            parser.state = S.CDATA            parser.sgmlDecl = ''            parser.cdata = ''          } else if (parser.sgmlDecl + c === '--') {            parser.state = S.COMMENT            parser.comment = ''            parser.sgmlDecl = ''          } else if ((parser.sgmlDecl + c).toUpperCase() === DOCTYPE) {            parser.state = S.DOCTYPE            if (parser.doctype || parser.sawRoot) {              strictFail(parser,                'Inappropriately located doctype declaration')            }            parser.doctype = ''            parser.sgmlDecl = ''          } else if (c === '>') {            emitNode(parser, 'onsgmldeclaration', parser.sgmlDecl)            parser.sgmlDecl = ''            parser.state = S.TEXT          } else if (isQuote(c)) {            parser.state = S.SGML_DECL_QUOTED            parser.sgmlDecl += c          } else {            parser.sgmlDecl += c          }          continue        case S.SGML_DECL_QUOTED:          if (c === parser.q) {            parser.state = S.SGML_DECL            parser.q = ''          }          parser.sgmlDecl += c          continue        case S.DOCTYPE:          if (c === '>') {            parser.state = S.TEXT            emitNode(parser, 'ondoctype', parser.doctype)            parser.doctype = true // just remember that we saw it.          } else {            parser.doctype += c            if (c === '[') {              parser.state = S.DOCTYPE_DTD            } else if (isQuote(c)) {              parser.state = S.DOCTYPE_QUOTED              parser.q = c            }          }          continue        case S.DOCTYPE_QUOTED:          parser.doctype += c          if (c === parser.q) {            parser.q = ''            parser.state = S.DOCTYPE          }          continue        case S.DOCTYPE_DTD:          parser.doctype += c          if (c === ']') {            parser.state = S.DOCTYPE          } else if (isQuote(c)) {            parser.state = S.DOCTYPE_DTD_QUOTED            parser.q = c          }          continue        case S.DOCTYPE_DTD_QUOTED:          parser.doctype += c          if (c === parser.q) {            parser.state = S.DOCTYPE_DTD            parser.q = ''          }          continue        case S.COMMENT:          if (c === '-') {            parser.state = S.COMMENT_ENDING          } else {            parser.comment += c          }          continue        case S.COMMENT_ENDING:          if (c === '-') {            parser.state = S.COMMENT_ENDED            parser.comment = textopts(parser.opt, parser.comment)            if (parser.comment) {              emitNode(parser, 'oncomment', parser.comment)            }            parser.comment = ''          } else {            parser.comment += '-' + c            parser.state = S.COMMENT          }          continue        case S.COMMENT_ENDED:          if (c !== '>') {            strictFail(parser, 'Malformed comment')            // allow <!-- blah -- bloo --> in non-strict mode,            // which is a comment of " blah -- bloo "            parser.comment += '--' + c            parser.state = S.COMMENT          } else {            parser.state = S.TEXT          }          continue        case S.CDATA:          if (c === ']') {            parser.state = S.CDATA_ENDING          } else {            parser.cdata += c          }          continue        case S.CDATA_ENDING:          if (c === ']') {            parser.state = S.CDATA_ENDING_2          } else {            parser.cdata += ']' + c            parser.state = S.CDATA          }          continue        case S.CDATA_ENDING_2:          if (c === '>') {            if (parser.cdata) {              emitNode(parser, 'oncdata', parser.cdata)            }            emitNode(parser, 'onclosecdata')            parser.cdata = ''            parser.state = S.TEXT          } else if (c === ']') {            parser.cdata += ']'          } else {            parser.cdata += ']]' + c            parser.state = S.CDATA          }          continue        case S.PROC_INST:          if (c === '?') {            parser.state = S.PROC_INST_ENDING          } else if (isWhitespace(c)) {            parser.state = S.PROC_INST_BODY          } else {            parser.procInstName += c          }          continue        case S.PROC_INST_BODY:          if (!parser.procInstBody && isWhitespace(c)) {            continue          } else if (c === '?') {            parser.state = S.PROC_INST_ENDING          } else {            parser.procInstBody += c          }          continue        case S.PROC_INST_ENDING:          if (c === '>') {            emitNode(parser, 'onprocessinginstruction', {              name: parser.procInstName,              body: parser.procInstBody            })            parser.procInstName = parser.procInstBody = ''            parser.state = S.TEXT          } else {            parser.procInstBody += '?' + c            parser.state = S.PROC_INST_BODY          }          continue        case S.OPEN_TAG:          if (isMatch(nameBody, c)) {            parser.tagName += c          } else {            newTag(parser)            if (c === '>') {              openTag(parser)            } else if (c === '/') {              parser.state = S.OPEN_TAG_SLASH            } else {              if (!isWhitespace(c)) {                strictFail(parser, 'Invalid character in tag name')              }              parser.state = S.ATTRIB            }          }          continue        case S.OPEN_TAG_SLASH:          if (c === '>') {            openTag(parser, true)            closeTag(parser)          } else {            strictFail(parser, 'Forward-slash in opening tag not followed by >')            parser.state = S.ATTRIB          }          continue        case S.ATTRIB:          // haven't read the attribute name yet.          if (isWhitespace(c)) {            continue          } else if (c === '>') {            openTag(parser)          } else if (c === '/') {            parser.state = S.OPEN_TAG_SLASH          } else if (isMatch(nameStart, c)) {            parser.attribName = c            parser.attribValue = ''            parser.state = S.ATTRIB_NAME          } else {            strictFail(parser, 'Invalid attribute name')          }          continue        case S.ATTRIB_NAME:          if (c === '=') {            parser.state = S.ATTRIB_VALUE          } else if (c === '>') {            strictFail(parser, 'Attribute without value')            parser.attribValue = parser.attribName            attrib(parser)            openTag(parser)          } else if (isWhitespace(c)) {            parser.state = S.ATTRIB_NAME_SAW_WHITE          } else if (isMatch(nameBody, c)) {            parser.attribName += c          } else {            strictFail(parser, 'Invalid attribute name')          }          continue        case S.ATTRIB_NAME_SAW_WHITE:          if (c === '=') {            parser.state = S.ATTRIB_VALUE          } else if (isWhitespace(c)) {            continue          } else {            strictFail(parser, 'Attribute without value')            parser.tag.attributes[parser.attribName] = ''            parser.attribValue = ''            emitNode(parser, 'onattribute', {              name: parser.attribName,              value: ''            })            parser.attribName = ''            if (c === '>') {              openTag(parser)            } else if (isMatch(nameStart, c)) {              parser.attribName = c              parser.state = S.ATTRIB_NAME            } else {              strictFail(parser, 'Invalid attribute name')              parser.state = S.ATTRIB            }          }          continue        case S.ATTRIB_VALUE:          if (isWhitespace(c)) {            continue          } else if (isQuote(c)) {            parser.q = c            parser.state = S.ATTRIB_VALUE_QUOTED          } else {            strictFail(parser, 'Unquoted attribute value')            parser.state = S.ATTRIB_VALUE_UNQUOTED            parser.attribValue = c          }          continue        case S.ATTRIB_VALUE_QUOTED:          if (c !== parser.q) {            if (c === '&') {              parser.state = S.ATTRIB_VALUE_ENTITY_Q            } else {              parser.attribValue += c            }            continue          }          attrib(parser)          parser.q = ''          parser.state = S.ATTRIB_VALUE_CLOSED          continue        case S.ATTRIB_VALUE_CLOSED:          if (isWhitespace(c)) {            parser.state = S.ATTRIB          } else if (c === '>') {            openTag(parser)          } else if (c === '/') {            parser.state = S.OPEN_TAG_SLASH          } else if (isMatch(nameStart, c)) {            strictFail(parser, 'No whitespace between attributes')            parser.attribName = c            parser.attribValue = ''            parser.state = S.ATTRIB_NAME          } else {            strictFail(parser, 'Invalid attribute name')          }          continue        case S.ATTRIB_VALUE_UNQUOTED:          if (!isAttribEnd(c)) {            if (c === '&') {              parser.state = S.ATTRIB_VALUE_ENTITY_U            } else {              parser.attribValue += c            }            continue          }          attrib(parser)          if (c === '>') {            openTag(parser)          } else {            parser.state = S.ATTRIB          }          continue        case S.CLOSE_TAG:          if (!parser.tagName) {            if (isWhitespace(c)) {              continue            } else if (notMatch(nameStart, c)) {              if (parser.script) {                parser.script += '</' + c                parser.state = S.SCRIPT              } else {                strictFail(parser, 'Invalid tagname in closing tag.')              }            } else {              parser.tagName = c            }          } else if (c === '>') {            closeTag(parser)          } else if (isMatch(nameBody, c)) {            parser.tagName += c          } else if (parser.script) {            parser.script += '</' + parser.tagName            parser.tagName = ''            parser.state = S.SCRIPT          } else {            if (!isWhitespace(c)) {              strictFail(parser, 'Invalid tagname in closing tag')            }            parser.state = S.CLOSE_TAG_SAW_WHITE          }          continue        case S.CLOSE_TAG_SAW_WHITE:          if (isWhitespace(c)) {            continue          }          if (c === '>') {            closeTag(parser)          } else {            strictFail(parser, 'Invalid characters in closing tag')          }          continue        case S.TEXT_ENTITY:        case S.ATTRIB_VALUE_ENTITY_Q:        case S.ATTRIB_VALUE_ENTITY_U:          var returnState          var buffer          switch (parser.state) {            case S.TEXT_ENTITY:              returnState = S.TEXT              buffer = 'textNode'              break            case S.ATTRIB_VALUE_ENTITY_Q:              returnState = S.ATTRIB_VALUE_QUOTED              buffer = 'attribValue'              break            case S.ATTRIB_VALUE_ENTITY_U:              returnState = S.ATTRIB_VALUE_UNQUOTED              buffer = 'attribValue'              break          }          if (c === ';') {            parser[buffer] += parseEntity(parser)            parser.entity = ''            parser.state = returnState          } else if (isMatch(parser.entity.length ? entityBody : entityStart, c)) {            parser.entity += c          } else {            strictFail(parser, 'Invalid character in entity name')            parser[buffer] += '&' + parser.entity + c            parser.entity = ''            parser.state = returnState          }          continue        default:          throw new Error(parser, 'Unknown state: ' + parser.state)      }    } // while    if (parser.position >= parser.bufferCheckPosition) {      checkBufferLength(parser)    }    return parser  }  /*! http://mths.be/fromcodepoint v0.1.0 by @mathias */  /* istanbul ignore next */  if (!String.fromCodePoint) {    (function () {      var stringFromCharCode = String.fromCharCode      var floor = Math.floor      var fromCodePoint = function () {        var MAX_SIZE = 0x4000        var codeUnits = []        var highSurrogate        var lowSurrogate        var index = -1        var length = arguments.length        if (!length) {          return ''        }        var result = ''        while (++index < length) {          var codePoint = Number(arguments[index])          if (            !isFinite(codePoint) || // `NaN`, `+Infinity`, or `-Infinity`            codePoint < 0 || // not a valid Unicode code point            codePoint > 0x10FFFF || // not a valid Unicode code point            floor(codePoint) !== codePoint // not an integer          ) {            throw RangeError('Invalid code point: ' + codePoint)          }          if (codePoint <= 0xFFFF) { // BMP code point            codeUnits.push(codePoint)          } else { // Astral code point; split in surrogate halves            // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae            codePoint -= 0x10000            highSurrogate = (codePoint >> 10) + 0xD800            lowSurrogate = (codePoint % 0x400) + 0xDC00            codeUnits.push(highSurrogate, lowSurrogate)          }          if (index + 1 === length || codeUnits.length > MAX_SIZE) {            result += stringFromCharCode.apply(null, codeUnits)            codeUnits.length = 0          }        }        return result      }      /* istanbul ignore next */      if (Object.defineProperty) {        Object.defineProperty(String, 'fromCodePoint', {          value: fromCodePoint,          configurable: true,          writable: true        })      } else {        String.fromCodePoint = fromCodePoint      }    }())  }})(typeof exports === 'undefined' ? this.sax = {} : exports)}).call(this,require("buffer").Buffer)},{"buffer":79,"stream":257,"string_decoder":77}],249:[function(require,module,exports){var Buffer = require('safe-buffer').Buffer// prototype class for hash functionsfunction Hash (blockSize, finalSize) {  this._block = Buffer.alloc(blockSize)  this._finalSize = finalSize  this._blockSize = blockSize  this._len = 0}Hash.prototype.update = function (data, enc) {  if (typeof data === 'string') {    enc = enc || 'utf8'    data = Buffer.from(data, enc)  }  var block = this._block  var blockSize = this._blockSize  var length = data.length  var accum = this._len  for (var offset = 0; offset < length;) {    var assigned = accum % blockSize    var remainder = Math.min(length - offset, blockSize - assigned)    for (var i = 0; i < remainder; i++) {      block[assigned + i] = data[offset + i]    }    accum += remainder    offset += remainder    if ((accum % blockSize) === 0) {      this._update(block)    }  }  this._len += length  return this}Hash.prototype.digest = function (enc) {  var rem = this._len % this._blockSize  this._block[rem] = 0x80  // zero (rem + 1) trailing bits, where (rem + 1) is the smallest  // non-negative solution to the equation (length + 1 + (rem + 1)) === finalSize mod blockSize  this._block.fill(0, rem + 1)  if (rem >= this._finalSize) {    this._update(this._block)    this._block.fill(0)  }  var bits = this._len * 8  // uint32  if (bits <= 0xffffffff) {    this._block.writeUInt32BE(bits, this._blockSize - 4)  // uint64  } else {    var lowBits = (bits & 0xffffffff) >>> 0    var highBits = (bits - lowBits) / 0x100000000    this._block.writeUInt32BE(highBits, this._blockSize - 8)    this._block.writeUInt32BE(lowBits, this._blockSize - 4)  }  this._update(this._block)  var hash = this._hash()  return enc ? hash.toString(enc) : hash}Hash.prototype._update = function () {  throw new Error('_update must be implemented by subclass')}module.exports = Hash},{"safe-buffer":247}],250:[function(require,module,exports){var exports = module.exports = function SHA (algorithm) {  algorithm = algorithm.toLowerCase()  var Algorithm = exports[algorithm]  if (!Algorithm) throw new Error(algorithm + ' is not supported (we accept pull requests)')  return new Algorithm()}exports.sha = require('./sha')exports.sha1 = require('./sha1')exports.sha224 = require('./sha224')exports.sha256 = require('./sha256')exports.sha384 = require('./sha384')exports.sha512 = require('./sha512')},{"./sha":251,"./sha1":252,"./sha224":253,"./sha256":254,"./sha384":255,"./sha512":256}],251:[function(require,module,exports){/* * A JavaScript implementation of the Secure Hash Algorithm, SHA-0, as defined * in FIPS PUB 180-1 * This source code is derived from sha1.js of the same repository. * The difference between SHA-0 and SHA-1 is just a bitwise rotate left * operation was added. */var inherits = require('inherits')var Hash = require('./hash')var Buffer = require('safe-buffer').Buffervar K = [  0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0]var W = new Array(80)function Sha () {  this.init()  this._w = W  Hash.call(this, 64, 56)}inherits(Sha, Hash)Sha.prototype.init = function () {  this._a = 0x67452301  this._b = 0xefcdab89  this._c = 0x98badcfe  this._d = 0x10325476  this._e = 0xc3d2e1f0  return this}function rotl5 (num) {  return (num << 5) | (num >>> 27)}function rotl30 (num) {  return (num << 30) | (num >>> 2)}function ft (s, b, c, d) {  if (s === 0) return (b & c) | ((~b) & d)  if (s === 2) return (b & c) | (b & d) | (c & d)  return b ^ c ^ d}Sha.prototype._update = function (M) {  var W = this._w  var a = this._a | 0  var b = this._b | 0  var c = this._c | 0  var d = this._d | 0  var e = this._e | 0  for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)  for (; i < 80; ++i) W[i] = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]  for (var j = 0; j < 80; ++j) {    var s = ~~(j / 20)    var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0    e = d    d = c    c = rotl30(b)    b = a    a = t  }  this._a = (a + this._a) | 0  this._b = (b + this._b) | 0  this._c = (c + this._c) | 0  this._d = (d + this._d) | 0  this._e = (e + this._e) | 0}Sha.prototype._hash = function () {  var H = Buffer.allocUnsafe(20)  H.writeInt32BE(this._a | 0, 0)  H.writeInt32BE(this._b | 0, 4)  H.writeInt32BE(this._c | 0, 8)  H.writeInt32BE(this._d | 0, 12)  H.writeInt32BE(this._e | 0, 16)  return H}module.exports = Sha},{"./hash":249,"inherits":154,"safe-buffer":247}],252:[function(require,module,exports){/* * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined * in FIPS PUB 180-1 * Version 2.1a Copyright Paul Johnston 2000 - 2002. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for details. */var inherits = require('inherits')var Hash = require('./hash')var Buffer = require('safe-buffer').Buffervar K = [  0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0]var W = new Array(80)function Sha1 () {  this.init()  this._w = W  Hash.call(this, 64, 56)}inherits(Sha1, Hash)Sha1.prototype.init = function () {  this._a = 0x67452301  this._b = 0xefcdab89  this._c = 0x98badcfe  this._d = 0x10325476  this._e = 0xc3d2e1f0  return this}function rotl1 (num) {  return (num << 1) | (num >>> 31)}function rotl5 (num) {  return (num << 5) | (num >>> 27)}function rotl30 (num) {  return (num << 30) | (num >>> 2)}function ft (s, b, c, d) {  if (s === 0) return (b & c) | ((~b) & d)  if (s === 2) return (b & c) | (b & d) | (c & d)  return b ^ c ^ d}Sha1.prototype._update = function (M) {  var W = this._w  var a = this._a | 0  var b = this._b | 0  var c = this._c | 0  var d = this._d | 0  var e = this._e | 0  for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)  for (; i < 80; ++i) W[i] = rotl1(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16])  for (var j = 0; j < 80; ++j) {    var s = ~~(j / 20)    var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0    e = d    d = c    c = rotl30(b)    b = a    a = t  }  this._a = (a + this._a) | 0  this._b = (b + this._b) | 0  this._c = (c + this._c) | 0  this._d = (d + this._d) | 0  this._e = (e + this._e) | 0}Sha1.prototype._hash = function () {  var H = Buffer.allocUnsafe(20)  H.writeInt32BE(this._a | 0, 0)  H.writeInt32BE(this._b | 0, 4)  H.writeInt32BE(this._c | 0, 8)  H.writeInt32BE(this._d | 0, 12)  H.writeInt32BE(this._e | 0, 16)  return H}module.exports = Sha1},{"./hash":249,"inherits":154,"safe-buffer":247}],253:[function(require,module,exports){/** * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined * in FIPS 180-2 * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * */var inherits = require('inherits')var Sha256 = require('./sha256')var Hash = require('./hash')var Buffer = require('safe-buffer').Buffervar W = new Array(64)function Sha224 () {  this.init()  this._w = W // new Array(64)  Hash.call(this, 64, 56)}inherits(Sha224, Sha256)Sha224.prototype.init = function () {  this._a = 0xc1059ed8  this._b = 0x367cd507  this._c = 0x3070dd17  this._d = 0xf70e5939  this._e = 0xffc00b31  this._f = 0x68581511  this._g = 0x64f98fa7  this._h = 0xbefa4fa4  return this}Sha224.prototype._hash = function () {  var H = Buffer.allocUnsafe(28)  H.writeInt32BE(this._a, 0)  H.writeInt32BE(this._b, 4)  H.writeInt32BE(this._c, 8)  H.writeInt32BE(this._d, 12)  H.writeInt32BE(this._e, 16)  H.writeInt32BE(this._f, 20)  H.writeInt32BE(this._g, 24)  return H}module.exports = Sha224},{"./hash":249,"./sha256":254,"inherits":154,"safe-buffer":247}],254:[function(require,module,exports){/** * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined * in FIPS 180-2 * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * */var inherits = require('inherits')var Hash = require('./hash')var Buffer = require('safe-buffer').Buffervar K = [  0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,  0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,  0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,  0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,  0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,  0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,  0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,  0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,  0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,  0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,  0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,  0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,  0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,  0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,  0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,  0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2]var W = new Array(64)function Sha256 () {  this.init()  this._w = W // new Array(64)  Hash.call(this, 64, 56)}inherits(Sha256, Hash)Sha256.prototype.init = function () {  this._a = 0x6a09e667  this._b = 0xbb67ae85  this._c = 0x3c6ef372  this._d = 0xa54ff53a  this._e = 0x510e527f  this._f = 0x9b05688c  this._g = 0x1f83d9ab  this._h = 0x5be0cd19  return this}function ch (x, y, z) {  return z ^ (x & (y ^ z))}function maj (x, y, z) {  return (x & y) | (z & (x | y))}function sigma0 (x) {  return (x >>> 2 | x << 30) ^ (x >>> 13 | x << 19) ^ (x >>> 22 | x << 10)}function sigma1 (x) {  return (x >>> 6 | x << 26) ^ (x >>> 11 | x << 21) ^ (x >>> 25 | x << 7)}function gamma0 (x) {  return (x >>> 7 | x << 25) ^ (x >>> 18 | x << 14) ^ (x >>> 3)}function gamma1 (x) {  return (x >>> 17 | x << 15) ^ (x >>> 19 | x << 13) ^ (x >>> 10)}Sha256.prototype._update = function (M) {  var W = this._w  var a = this._a | 0  var b = this._b | 0  var c = this._c | 0  var d = this._d | 0  var e = this._e | 0  var f = this._f | 0  var g = this._g | 0  var h = this._h | 0  for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)  for (; i < 64; ++i) W[i] = (gamma1(W[i - 2]) + W[i - 7] + gamma0(W[i - 15]) + W[i - 16]) | 0  for (var j = 0; j < 64; ++j) {    var T1 = (h + sigma1(e) + ch(e, f, g) + K[j] + W[j]) | 0    var T2 = (sigma0(a) + maj(a, b, c)) | 0    h = g    g = f    f = e    e = (d + T1) | 0    d = c    c = b    b = a    a = (T1 + T2) | 0  }  this._a = (a + this._a) | 0  this._b = (b + this._b) | 0  this._c = (c + this._c) | 0  this._d = (d + this._d) | 0  this._e = (e + this._e) | 0  this._f = (f + this._f) | 0  this._g = (g + this._g) | 0  this._h = (h + this._h) | 0}Sha256.prototype._hash = function () {  var H = Buffer.allocUnsafe(32)  H.writeInt32BE(this._a, 0)  H.writeInt32BE(this._b, 4)  H.writeInt32BE(this._c, 8)  H.writeInt32BE(this._d, 12)  H.writeInt32BE(this._e, 16)  H.writeInt32BE(this._f, 20)  H.writeInt32BE(this._g, 24)  H.writeInt32BE(this._h, 28)  return H}module.exports = Sha256},{"./hash":249,"inherits":154,"safe-buffer":247}],255:[function(require,module,exports){var inherits = require('inherits')var SHA512 = require('./sha512')var Hash = require('./hash')var Buffer = require('safe-buffer').Buffervar W = new Array(160)function Sha384 () {  this.init()  this._w = W  Hash.call(this, 128, 112)}inherits(Sha384, SHA512)Sha384.prototype.init = function () {  this._ah = 0xcbbb9d5d  this._bh = 0x629a292a  this._ch = 0x9159015a  this._dh = 0x152fecd8  this._eh = 0x67332667  this._fh = 0x8eb44a87  this._gh = 0xdb0c2e0d  this._hh = 0x47b5481d  this._al = 0xc1059ed8  this._bl = 0x367cd507  this._cl = 0x3070dd17  this._dl = 0xf70e5939  this._el = 0xffc00b31  this._fl = 0x68581511  this._gl = 0x64f98fa7  this._hl = 0xbefa4fa4  return this}Sha384.prototype._hash = function () {  var H = Buffer.allocUnsafe(48)  function writeInt64BE (h, l, offset) {    H.writeInt32BE(h, offset)    H.writeInt32BE(l, offset + 4)  }  writeInt64BE(this._ah, this._al, 0)  writeInt64BE(this._bh, this._bl, 8)  writeInt64BE(this._ch, this._cl, 16)  writeInt64BE(this._dh, this._dl, 24)  writeInt64BE(this._eh, this._el, 32)  writeInt64BE(this._fh, this._fl, 40)  return H}module.exports = Sha384},{"./hash":249,"./sha512":256,"inherits":154,"safe-buffer":247}],256:[function(require,module,exports){var inherits = require('inherits')var Hash = require('./hash')var Buffer = require('safe-buffer').Buffervar K = [  0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,  0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,  0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,  0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,  0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,  0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,  0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,  0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,  0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,  0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,  0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,  0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,  0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,  0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,  0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,  0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,  0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,  0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,  0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,  0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,  0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,  0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,  0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,  0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,  0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,  0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,  0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,  0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,  0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,  0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,  0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,  0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,  0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,  0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,  0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,  0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,  0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,  0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,  0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,  0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817]var W = new Array(160)function Sha512 () {  this.init()  this._w = W  Hash.call(this, 128, 112)}inherits(Sha512, Hash)Sha512.prototype.init = function () {  this._ah = 0x6a09e667  this._bh = 0xbb67ae85  this._ch = 0x3c6ef372  this._dh = 0xa54ff53a  this._eh = 0x510e527f  this._fh = 0x9b05688c  this._gh = 0x1f83d9ab  this._hh = 0x5be0cd19  this._al = 0xf3bcc908  this._bl = 0x84caa73b  this._cl = 0xfe94f82b  this._dl = 0x5f1d36f1  this._el = 0xade682d1  this._fl = 0x2b3e6c1f  this._gl = 0xfb41bd6b  this._hl = 0x137e2179  return this}function Ch (x, y, z) {  return z ^ (x & (y ^ z))}function maj (x, y, z) {  return (x & y) | (z & (x | y))}function sigma0 (x, xl) {  return (x >>> 28 | xl << 4) ^ (xl >>> 2 | x << 30) ^ (xl >>> 7 | x << 25)}function sigma1 (x, xl) {  return (x >>> 14 | xl << 18) ^ (x >>> 18 | xl << 14) ^ (xl >>> 9 | x << 23)}function Gamma0 (x, xl) {  return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7)}function Gamma0l (x, xl) {  return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7 | xl << 25)}function Gamma1 (x, xl) {  return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6)}function Gamma1l (x, xl) {  return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6 | xl << 26)}function getCarry (a, b) {  return (a >>> 0) < (b >>> 0) ? 1 : 0}Sha512.prototype._update = function (M) {  var W = this._w  var ah = this._ah | 0  var bh = this._bh | 0  var ch = this._ch | 0  var dh = this._dh | 0  var eh = this._eh | 0  var fh = this._fh | 0  var gh = this._gh | 0  var hh = this._hh | 0  var al = this._al | 0  var bl = this._bl | 0  var cl = this._cl | 0  var dl = this._dl | 0  var el = this._el | 0  var fl = this._fl | 0  var gl = this._gl | 0  var hl = this._hl | 0  for (var i = 0; i < 32; i += 2) {    W[i] = M.readInt32BE(i * 4)    W[i + 1] = M.readInt32BE(i * 4 + 4)  }  for (; i < 160; i += 2) {    var xh = W[i - 15 * 2]    var xl = W[i - 15 * 2 + 1]    var gamma0 = Gamma0(xh, xl)    var gamma0l = Gamma0l(xl, xh)    xh = W[i - 2 * 2]    xl = W[i - 2 * 2 + 1]    var gamma1 = Gamma1(xh, xl)    var gamma1l = Gamma1l(xl, xh)    // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]    var Wi7h = W[i - 7 * 2]    var Wi7l = W[i - 7 * 2 + 1]    var Wi16h = W[i - 16 * 2]    var Wi16l = W[i - 16 * 2 + 1]    var Wil = (gamma0l + Wi7l) | 0    var Wih = (gamma0 + Wi7h + getCarry(Wil, gamma0l)) | 0    Wil = (Wil + gamma1l) | 0    Wih = (Wih + gamma1 + getCarry(Wil, gamma1l)) | 0    Wil = (Wil + Wi16l) | 0    Wih = (Wih + Wi16h + getCarry(Wil, Wi16l)) | 0    W[i] = Wih    W[i + 1] = Wil  }  for (var j = 0; j < 160; j += 2) {    Wih = W[j]    Wil = W[j + 1]    var majh = maj(ah, bh, ch)    var majl = maj(al, bl, cl)    var sigma0h = sigma0(ah, al)    var sigma0l = sigma0(al, ah)    var sigma1h = sigma1(eh, el)    var sigma1l = sigma1(el, eh)    // t1 = h + sigma1 + ch + K[j] + W[j]    var Kih = K[j]    var Kil = K[j + 1]    var chh = Ch(eh, fh, gh)    var chl = Ch(el, fl, gl)    var t1l = (hl + sigma1l) | 0    var t1h = (hh + sigma1h + getCarry(t1l, hl)) | 0    t1l = (t1l + chl) | 0    t1h = (t1h + chh + getCarry(t1l, chl)) | 0    t1l = (t1l + Kil) | 0    t1h = (t1h + Kih + getCarry(t1l, Kil)) | 0    t1l = (t1l + Wil) | 0    t1h = (t1h + Wih + getCarry(t1l, Wil)) | 0    // t2 = sigma0 + maj    var t2l = (sigma0l + majl) | 0    var t2h = (sigma0h + majh + getCarry(t2l, sigma0l)) | 0    hh = gh    hl = gl    gh = fh    gl = fl    fh = eh    fl = el    el = (dl + t1l) | 0    eh = (dh + t1h + getCarry(el, dl)) | 0    dh = ch    dl = cl    ch = bh    cl = bl    bh = ah    bl = al    al = (t1l + t2l) | 0    ah = (t1h + t2h + getCarry(al, t1l)) | 0  }  this._al = (this._al + al) | 0  this._bl = (this._bl + bl) | 0  this._cl = (this._cl + cl) | 0  this._dl = (this._dl + dl) | 0  this._el = (this._el + el) | 0  this._fl = (this._fl + fl) | 0  this._gl = (this._gl + gl) | 0  this._hl = (this._hl + hl) | 0  this._ah = (this._ah + ah + getCarry(this._al, al)) | 0  this._bh = (this._bh + bh + getCarry(this._bl, bl)) | 0  this._ch = (this._ch + ch + getCarry(this._cl, cl)) | 0  this._dh = (this._dh + dh + getCarry(this._dl, dl)) | 0  this._eh = (this._eh + eh + getCarry(this._el, el)) | 0  this._fh = (this._fh + fh + getCarry(this._fl, fl)) | 0  this._gh = (this._gh + gh + getCarry(this._gl, gl)) | 0  this._hh = (this._hh + hh + getCarry(this._hl, hl)) | 0}Sha512.prototype._hash = function () {  var H = Buffer.allocUnsafe(64)  function writeInt64BE (h, l, offset) {    H.writeInt32BE(h, offset)    H.writeInt32BE(l, offset + 4)  }  writeInt64BE(this._ah, this._al, 0)  writeInt64BE(this._bh, this._bl, 8)  writeInt64BE(this._ch, this._cl, 16)  writeInt64BE(this._dh, this._dl, 24)  writeInt64BE(this._eh, this._el, 32)  writeInt64BE(this._fh, this._fl, 40)  writeInt64BE(this._gh, this._gl, 48)  writeInt64BE(this._hh, this._hl, 56)  return H}module.exports = Sha512},{"./hash":249,"inherits":154,"safe-buffer":247}],257:[function(require,module,exports){// Copyright Joyent, Inc. and other Node contributors.//// Permission is hereby granted, free of charge, to any person obtaining a// copy of this software and associated documentation files (the// "Software"), to deal in the Software without restriction, including// without limitation the rights to use, copy, modify, merge, publish,// distribute, sublicense, and/or sell copies of the Software, and to permit// persons to whom the Software is furnished to do so, subject to the// following conditions://// The above copyright notice and this permission notice shall be included// in all copies or substantial portions of the Software.//// THE SOFTWARE IS 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. IN// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE// USE OR OTHER DEALINGS IN THE SOFTWARE.module.exports = Stream;var EE = require('events').EventEmitter;var inherits = require('inherits');inherits(Stream, EE);Stream.Readable = require('readable-stream/readable.js');Stream.Writable = require('readable-stream/writable.js');Stream.Duplex = require('readable-stream/duplex.js');Stream.Transform = require('readable-stream/transform.js');Stream.PassThrough = require('readable-stream/passthrough.js');// Backwards-compat with node 0.4.xStream.Stream = Stream;// old-style streams.  Note that the pipe method (the only relevant// part of this class) is overridden in the Readable class.function Stream() {  EE.call(this);}Stream.prototype.pipe = function(dest, options) {  var source = this;  function ondata(chunk) {    if (dest.writable) {      if (false === dest.write(chunk) && source.pause) {        source.pause();      }    }  }  source.on('data', ondata);  function ondrain() {    if (source.readable && source.resume) {      source.resume();    }  }  dest.on('drain', ondrain);  // If the 'end' option is not supplied, dest.end() will be called when  // source gets the 'end' or 'close' events.  Only dest.end() once.  if (!dest._isStdio && (!options || options.end !== false)) {    source.on('end', onend);    source.on('close', onclose);  }  var didOnEnd = false;  function onend() {    if (didOnEnd) return;    didOnEnd = true;    dest.end();  }  function onclose() {    if (didOnEnd) return;    didOnEnd = true;    if (typeof dest.destroy === 'function') dest.destroy();  }  // don't leave dangling pipes when there are errors.  function onerror(er) {    cleanup();    if (EE.listenerCount(this, 'error') === 0) {      throw er; // Unhandled stream error in pipe.    }  }  source.on('error', onerror);  dest.on('error', onerror);  // remove all the event listeners that were added.  function cleanup() {    source.removeListener('data', ondata);    dest.removeListener('drain', ondrain);    source.removeListener('end', onend);    source.removeListener('close', onclose);    source.removeListener('error', onerror);    dest.removeListener('error', onerror);    source.removeListener('end', cleanup);    source.removeListener('close', cleanup);    dest.removeListener('close', cleanup);  }  source.on('end', cleanup);  source.on('close', cleanup);  dest.on('close', cleanup);  dest.emit('pipe', source);  // Allow for unix-like usage: A.pipe(B).pipe(C)  return dest;};},{"events":136,"inherits":154,"readable-stream/duplex.js":236,"readable-stream/passthrough.js":242,"readable-stream/readable.js":243,"readable-stream/transform.js":244,"readable-stream/writable.js":245}],258:[function(require,module,exports){// Copyright Joyent, Inc. and other Node contributors.//// Permission is hereby granted, free of charge, to any person obtaining a// copy of this software and associated documentation files (the// "Software"), to deal in the Software without restriction, including// without limitation the rights to use, copy, modify, merge, publish,// distribute, sublicense, and/or sell copies of the Software, and to permit// persons to whom the Software is furnished to do so, subject to the// following conditions://// The above copyright notice and this permission notice shall be included// in all copies or substantial portions of the Software.//// THE SOFTWARE IS 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. IN// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE// USE OR OTHER DEALINGS IN THE SOFTWARE.var Buffer = require('buffer').Buffer;var isBufferEncoding = Buffer.isEncoding  || function(encoding) {       switch (encoding && encoding.toLowerCase()) {         case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;         default: return false;       }     }function assertEncoding(encoding) {  if (encoding && !isBufferEncoding(encoding)) {    throw new Error('Unknown encoding: ' + encoding);  }}// StringDecoder provides an interface for efficiently splitting a series of// buffers into a series of JS strings without breaking apart multi-byte// characters. CESU-8 is handled as part of the UTF-8 encoding.//// @TODO Handling all encodings inside a single object makes it very difficult// to reason about this code, so it should be split up in the future.// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code// points as used by CESU-8.var StringDecoder = exports.StringDecoder = function(encoding) {  this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');  assertEncoding(encoding);  switch (this.encoding) {    case 'utf8':      // CESU-8 represents each of Surrogate Pair by 3-bytes      this.surrogateSize = 3;      break;    case 'ucs2':    case 'utf16le':      // UTF-16 represents each of Surrogate Pair by 2-bytes      this.surrogateSize = 2;      this.detectIncompleteChar = utf16DetectIncompleteChar;      break;    case 'base64':      // Base-64 stores 3 bytes in 4 chars, and pads the remainder.      this.surrogateSize = 3;      this.detectIncompleteChar = base64DetectIncompleteChar;      break;    default:      this.write = passThroughWrite;      return;  }  // Enough space to store all bytes of a single character. UTF-8 needs 4  // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).  this.charBuffer = new Buffer(6);  // Number of bytes received for the current incomplete multi-byte character.  this.charReceived = 0;  // Number of bytes expected for the current incomplete multi-byte character.  this.charLength = 0;};// write decodes the given buffer and returns it as JS string that is// guaranteed to not contain any partial multi-byte characters. Any partial// character found at the end of the buffer is buffered up, and will be// returned when calling write again with the remaining bytes.//// Note: Converting a Buffer containing an orphan surrogate to a String// currently works, but converting a String to a Buffer (via `new Buffer`, or// Buffer#write) will replace incomplete surrogates with the unicode// replacement character. See https://codereview.chromium.org/121173009/ .StringDecoder.prototype.write = function(buffer) {  var charStr = '';  // if our last write ended with an incomplete multibyte character  while (this.charLength) {    // determine how many remaining bytes this buffer has to offer for this char    var available = (buffer.length >= this.charLength - this.charReceived) ?        this.charLength - this.charReceived :        buffer.length;    // add the new bytes to the char buffer    buffer.copy(this.charBuffer, this.charReceived, 0, available);    this.charReceived += available;    if (this.charReceived < this.charLength) {      // still not enough chars in this buffer? wait for more ...      return '';    }    // remove bytes belonging to the current character from the buffer    buffer = buffer.slice(available, buffer.length);    // get the character that was split    charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);    // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character    var charCode = charStr.charCodeAt(charStr.length - 1);    if (charCode >= 0xD800 && charCode <= 0xDBFF) {      this.charLength += this.surrogateSize;      charStr = '';      continue;    }    this.charReceived = this.charLength = 0;    // if there are no more bytes in this buffer, just emit our char    if (buffer.length === 0) {      return charStr;    }    break;  }  // determine and set charLength / charReceived  this.detectIncompleteChar(buffer);  var end = buffer.length;  if (this.charLength) {    // buffer the incomplete character bytes we got    buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);    end -= this.charReceived;  }  charStr += buffer.toString(this.encoding, 0, end);  var end = charStr.length - 1;  var charCode = charStr.charCodeAt(end);  // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character  if (charCode >= 0xD800 && charCode <= 0xDBFF) {    var size = this.surrogateSize;    this.charLength += size;    this.charReceived += size;    this.charBuffer.copy(this.charBuffer, size, 0, size);    buffer.copy(this.charBuffer, 0, 0, size);    return charStr.substring(0, end);  }  // or just emit the charStr  return charStr;};// detectIncompleteChar determines if there is an incomplete UTF-8 character at// the end of the given buffer. If so, it sets this.charLength to the byte// length that character, and sets this.charReceived to the number of bytes// that are available for this character.StringDecoder.prototype.detectIncompleteChar = function(buffer) {  // determine how many bytes we have to check at the end of this buffer  var i = (buffer.length >= 3) ? 3 : buffer.length;  // Figure out if one of the last i bytes of our buffer announces an  // incomplete char.  for (; i > 0; i--) {    var c = buffer[buffer.length - i];    // See http://en.wikipedia.org/wiki/UTF-8#Description    // 110XXXXX    if (i == 1 && c >> 5 == 0x06) {      this.charLength = 2;      break;    }    // 1110XXXX    if (i <= 2 && c >> 4 == 0x0E) {      this.charLength = 3;      break;    }    // 11110XXX    if (i <= 3 && c >> 3 == 0x1E) {      this.charLength = 4;      break;    }  }  this.charReceived = i;};StringDecoder.prototype.end = function(buffer) {  var res = '';  if (buffer && buffer.length)    res = this.write(buffer);  if (this.charReceived) {    var cr = this.charReceived;    var buf = this.charBuffer;    var enc = this.encoding;    res += buf.slice(0, cr).toString(enc);  }  return res;};function passThroughWrite(buffer) {  return buffer.toString(this.encoding);}function utf16DetectIncompleteChar(buffer) {  this.charReceived = buffer.length % 2;  this.charLength = this.charReceived ? 2 : 0;}function base64DetectIncompleteChar(buffer) {  this.charReceived = buffer.length % 3;  this.charLength = this.charReceived ? 3 : 0;}},{"buffer":79}],259:[function(require,module,exports){(function (setImmediate,clearImmediate){var nextTick = require('process/browser.js').nextTick;var apply = Function.prototype.apply;var slice = Array.prototype.slice;var immediateIds = {};var nextImmediateId = 0;// DOM APIs, for completenessexports.setTimeout = function() {  return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);};exports.setInterval = function() {  return new Timeout(apply.call(setInterval, window, arguments), clearInterval);};exports.clearTimeout =exports.clearInterval = function(timeout) { timeout.close(); };function Timeout(id, clearFn) {  this._id = id;  this._clearFn = clearFn;}Timeout.prototype.unref = Timeout.prototype.ref = function() {};Timeout.prototype.close = function() {  this._clearFn.call(window, this._id);};// Does not start the time, just sets up the members needed.exports.enroll = function(item, msecs) {  clearTimeout(item._idleTimeoutId);  item._idleTimeout = msecs;};exports.unenroll = function(item) {  clearTimeout(item._idleTimeoutId);  item._idleTimeout = -1;};exports._unrefActive = exports.active = function(item) {  clearTimeout(item._idleTimeoutId);  var msecs = item._idleTimeout;  if (msecs >= 0) {    item._idleTimeoutId = setTimeout(function onTimeout() {      if (item._onTimeout)        item._onTimeout();    }, msecs);  }};// That's not how node.js implements it but the exposed api is the same.exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) {  var id = nextImmediateId++;  var args = arguments.length < 2 ? false : slice.call(arguments, 1);  immediateIds[id] = true;  nextTick(function onNextTick() {    if (immediateIds[id]) {      // fn.call() is faster so we optimize for the common use-case      // @see http://jsperf.com/call-apply-segu      if (args) {        fn.apply(null, args);      } else {        fn.call(null);      }      // Prevent ids from leaking      exports.clearImmediate(id);    }  });  return id;};exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate : function(id) {  delete immediateIds[id];};}).call(this,require("timers").setImmediate,require("timers").clearImmediate)},{"process/browser.js":226,"timers":259}],260:[function(require,module,exports){(function (global){/** * Module exports. */module.exports = deprecate;/** * Mark that a method should not be used. * Returns a modified function which warns once by default. * * If `localStorage.noDeprecation = true` is set, then it is a no-op. * * If `localStorage.throwDeprecation = true` is set, then deprecated functions * will throw an Error when invoked. * * If `localStorage.traceDeprecation = true` is set, then deprecated functions * will invoke `console.trace()` instead of `console.error()`. * * @param {Function} fn - the function to deprecate * @param {String} msg - the string to print to the console when `fn` is invoked * @returns {Function} a new "deprecated" version of `fn` * @api public */function deprecate (fn, msg) {  if (config('noDeprecation')) {    return fn;  }  var warned = false;  function deprecated() {    if (!warned) {      if (config('throwDeprecation')) {        throw new Error(msg);      } else if (config('traceDeprecation')) {        console.trace(msg);      } else {        console.warn(msg);      }      warned = true;    }    return fn.apply(this, arguments);  }  return deprecated;}/** * Checks `localStorage` for boolean values for the given `name`. * * @param {String} name * @returns {Boolean} * @api private */function config (name) {  // accessing global.localStorage can trigger a DOMException in sandboxed iframes  try {    if (!global.localStorage) return false;  } catch (_) {    return false;  }  var val = global.localStorage[name];  if (null == val) return false;  return String(val).toLowerCase() === 'true';}}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})},{}],261:[function(require,module,exports){var indexOf = function (xs, item) {    if (xs.indexOf) return xs.indexOf(item);    else for (var i = 0; i < xs.length; i++) {        if (xs[i] === item) return i;    }    return -1;};var Object_keys = function (obj) {    if (Object.keys) return Object.keys(obj)    else {        var res = [];        for (var key in obj) res.push(key)        return res;    }};var forEach = function (xs, fn) {    if (xs.forEach) return xs.forEach(fn)    else for (var i = 0; i < xs.length; i++) {        fn(xs[i], i, xs);    }};var defineProp = (function() {    try {        Object.defineProperty({}, '_', {});        return function(obj, name, value) {            Object.defineProperty(obj, name, {                writable: true,                enumerable: false,                configurable: true,                value: value            })        };    } catch(e) {        return function(obj, name, value) {            obj[name] = value;        };    }}());var globals = ['Array', 'Boolean', 'Date', 'Error', 'EvalError', 'Function','Infinity', 'JSON', 'Math', 'NaN', 'Number', 'Object', 'RangeError','ReferenceError', 'RegExp', 'String', 'SyntaxError', 'TypeError', 'URIError','decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape','eval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'undefined', 'unescape'];function Context() {}Context.prototype = {};var Script = exports.Script = function NodeScript (code) {    if (!(this instanceof Script)) return new Script(code);    this.code = code;};Script.prototype.runInContext = function (context) {    if (!(context instanceof Context)) {        throw new TypeError("needs a 'context' argument.");    }        var iframe = document.createElement('iframe');    if (!iframe.style) iframe.style = {};    iframe.style.display = 'none';        document.body.appendChild(iframe);        var win = iframe.contentWindow;    var wEval = win.eval, wExecScript = win.execScript;    if (!wEval && wExecScript) {        // win.eval() magically appears when this is called in IE:        wExecScript.call(win, 'null');        wEval = win.eval;    }        forEach(Object_keys(context), function (key) {        win[key] = context[key];    });    forEach(globals, function (key) {        if (context[key]) {            win[key] = context[key];        }    });        var winKeys = Object_keys(win);    var res = wEval.call(win, this.code);        forEach(Object_keys(win), function (key) {        // Avoid copying circular objects like `top` and `window` by only        // updating existing context properties or new properties in the `win`        // that was only introduced after the eval.        if (key in context || indexOf(winKeys, key) === -1) {            context[key] = win[key];        }    });    forEach(globals, function (key) {        if (!(key in context)) {            defineProp(context, key, win[key]);        }    });        document.body.removeChild(iframe);        return res;};Script.prototype.runInThisContext = function () {    return eval(this.code); // maybe...};Script.prototype.runInNewContext = function (context) {    var ctx = Script.createContext(context);    var res = this.runInContext(ctx);    if (context) {        forEach(Object_keys(ctx), function (key) {            context[key] = ctx[key];        });    }    return res;};forEach(Object_keys(Script.prototype), function (name) {    exports[name] = Script[name] = function (code) {        var s = Script(code);        return s[name].apply(s, [].slice.call(arguments, 1));    };});exports.isContext = function (context) {    return context instanceof Context;};exports.createScript = function (code) {    return exports.Script(code);};exports.createContext = Script.createContext = function (context) {    var copy = new Context();    if(typeof context === 'object') {        forEach(Object_keys(context), function (key) {            copy[key] = context[key];        });    }    return copy;};},{}]},{},[20])(20)});//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJsaWIvQXBwUHJvcGVydGllcy5qcyIsImxpYi9BcmdIYW5kbGVyLmpzIiwibGliL0NlbGwuanMiLCJsaWIvQ29sdW1uLmpzIiwibGliL0NvbnRlbnRUeXBlcy5qcyIsImxpYi9Db3JlUHJvcGVydGllcy5qcyIsImxpYi9FbmNyeXB0b3IuanMiLCJsaWIvRm9ybXVsYUVycm9yLmpzIiwibGliL1BhZ2VCcmVha3MuanMiLCJsaWIvUmFuZ2UuanMiLCJsaWIvUmVsYXRpb25zaGlwcy5qcyIsImxpYi9SaWNoVGV4dC5qcyIsImxpYi9SaWNoVGV4dEZyYWdtZW50LmpzIiwibGliL1Jvdy5qcyIsImxpYi9TaGFyZWRTdHJpbmdzLmpzIiwibGliL1NoZWV0LmpzIiwibGliL1N0eWxlLmpzIiwibGliL1N0eWxlU2hlZXQuanMiLCJsaWIvV29ya2Jvb2suanMiLCJsaWIvWGxzeFBvcHVsYXRlLmpzIiwibGliL1htbEJ1aWxkZXIuanMiLCJsaWIvWG1sUGFyc2VyLmpzIiwibGliL2FkZHJlc3NDb252ZXJ0ZXIuanMiLCJsaWIvYmxhbmsuanMiLCJsaWIvY29sb3JJbmRleGVzLmpzIiwibGliL2RhdGVDb252ZXJ0ZXIuanMiLCJsaWIvZXh0ZXJuYWxzLmpzIiwibGliL3JlZ2V4aWZ5LmpzIiwibGliL3htbHEuanMiLCJub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS5qcyIsIm5vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2FwaS5qcyIsIm5vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2Jhc2UvYnVmZmVyLmpzIiwibm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvYmFzZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2Jhc2Uvbm9kZS5qcyIsIm5vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2Jhc2UvcmVwb3J0ZXIuanMiLCJub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9jb25zdGFudHMvZGVyLmpzIiwibm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvY29uc3RhbnRzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvZGVjb2RlcnMvZGVyLmpzIiwibm9kZV9tb2R1bGVzL2FzbjEuanMvbGliL2FzbjEvZGVjb2RlcnMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9kZWNvZGVycy9wZW0uanMiLCJub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9lbmNvZGVycy9kZXIuanMiLCJub2RlX21vZHVsZXMvYXNuMS5qcy9saWIvYXNuMS9lbmNvZGVycy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9hc24xLmpzL2xpYi9hc24xL2VuY29kZXJzL3BlbS5qcyIsIm5vZGVfbW9kdWxlcy9iYXNlNjQtanMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYm4uanMvbGliL2JuLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3JhbmQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3Nlci1yZXNvbHZlL2VtcHR5LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2Flcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9hdXRoQ2lwaGVyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvZGVjcnlwdGVyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL2VuY3J5cHRlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9naGFzaC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9pbmNyMzIuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvY2JjLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL2NmYi5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9jZmIxLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL2NmYjguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvY3RyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL21vZGVzL2VjYi5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWFlcy9tb2Rlcy9saXN0Lmpzb24iLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1hZXMvbW9kZXMvb2ZiLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktYWVzL3N0cmVhbUNpcGhlci5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWNpcGhlci9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktZGVzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktZGVzL21vZGVzLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktZGVzL25vZGVfbW9kdWxlcy9zYWZlLWJ1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXJzYS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5LXNpZ24vYWxnb3MuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL2Jyb3dzZXIvYWxnb3JpdGhtcy5qc29uIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9icm93c2VyL2N1cnZlcy5qc29uIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9icm93c2VyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktc2lnbi9icm93c2VyL3NpZ24uanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1zaWduL2Jyb3dzZXIvdmVyaWZ5LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyL2xpYi9zdHJpbmdfZGVjb2Rlci5qcyIsIm5vZGVfbW9kdWxlcy9idWZmZXIteG9yL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9jZmIvY2ZiLmpzIiwibm9kZV9tb2R1bGVzL2NpcGhlci1iYXNlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9mbi9zZXQtaW1tZWRpYXRlLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19hLWZ1bmN0aW9uLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19hbi1vYmplY3QuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX2NvZi5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fY29yZS5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fY3R4LmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19kZXNjcmlwdG9ycy5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fZG9tLWNyZWF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fZXhwb3J0LmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19mYWlscy5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fZ2xvYmFsLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19oaWRlLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19odG1sLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19pZTgtZG9tLWRlZmluZS5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9faW52b2tlLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL19pcy1vYmplY3QuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvX29iamVjdC1kcC5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fcHJvcGVydHktZGVzYy5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fdGFzay5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9fdG8tcHJpbWl0aXZlLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL3dlYi5pbW1lZGlhdGUuanMiLCJub2RlX21vZHVsZXMvY29yZS11dGlsLWlzL2xpYi91dGlsLmpzIiwibm9kZV9tb2R1bGVzL2NyZWF0ZS1lY2RoL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvY3JlYXRlLWhhc2gvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9jcmVhdGUtaGFzaC9tZDUuanMiLCJub2RlX21vZHVsZXMvY3JlYXRlLWhtYWMvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9jcmVhdGUtaG1hYy9sZWdhY3kuanMiLCJub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvZGVzLmpzL2xpYi9kZXMuanMiLCJub2RlX21vZHVsZXMvZGVzLmpzL2xpYi9kZXMvY2JjLmpzIiwibm9kZV9tb2R1bGVzL2Rlcy5qcy9saWIvZGVzL2NpcGhlci5qcyIsIm5vZGVfbW9kdWxlcy9kZXMuanMvbGliL2Rlcy9kZXMuanMiLCJub2RlX21vZHVsZXMvZGVzLmpzL2xpYi9kZXMvZWRlLmpzIiwibm9kZV9tb2R1bGVzL2Rlcy5qcy9saWIvZGVzL3V0aWxzLmpzIiwibm9kZV9tb2R1bGVzL2RpZmZpZS1oZWxsbWFuL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvZGlmZmllLWhlbGxtYW4vbGliL2RoLmpzIiwibm9kZV9tb2R1bGVzL2RpZmZpZS1oZWxsbWFuL2xpYi9nZW5lcmF0ZVByaW1lLmpzIiwibm9kZV9tb2R1bGVzL2RpZmZpZS1oZWxsbWFuL2xpYi9wcmltZXMuanNvbiIsIm5vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMuanMiLCJub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2N1cnZlL2Jhc2UuanMiLCJub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2N1cnZlL2Vkd2FyZHMuanMiLCJub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2N1cnZlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy9jdXJ2ZS9tb250LmpzIiwibm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy9jdXJ2ZS9zaG9ydC5qcyIsIm5vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvY3VydmVzLmpzIiwibm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy9lYy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvZWMva2V5LmpzIiwibm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy9lYy9zaWduYXR1cmUuanMiLCJub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2VkZHNhL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy9lZGRzYS9rZXkuanMiLCJub2RlX21vZHVsZXMvZWxsaXB0aWMvbGliL2VsbGlwdGljL2VkZHNhL3NpZ25hdHVyZS5qcyIsIm5vZGVfbW9kdWxlcy9lbGxpcHRpYy9saWIvZWxsaXB0aWMvcHJlY29tcHV0ZWQvc2VjcDI1NmsxLmpzIiwibm9kZV9tb2R1bGVzL2VsbGlwdGljL2xpYi9lbGxpcHRpYy91dGlscy5qcyIsIm5vZGVfbW9kdWxlcy9lbGxpcHRpYy9wYWNrYWdlLmpzb24iLCJub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIm5vZGVfbW9kdWxlcy9ldnBfYnl0ZXN0b2tleS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9oYXNoLWJhc2UvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC5qcyIsIm5vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL2NvbW1vbi5qcyIsIm5vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL2htYWMuanMiLCJub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC9yaXBlbWQuanMiLCJub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC9zaGEuanMiLCJub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC9zaGEvMS5qcyIsIm5vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS8yMjQuanMiLCJub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC9zaGEvMjU2LmpzIiwibm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvc2hhLzM4NC5qcyIsIm5vZGVfbW9kdWxlcy9oYXNoLmpzL2xpYi9oYXNoL3NoYS81MTIuanMiLCJub2RlX21vZHVsZXMvaGFzaC5qcy9saWIvaGFzaC9zaGEvY29tbW9uLmpzIiwibm9kZV9tb2R1bGVzL2hhc2guanMvbGliL2hhc2gvdXRpbHMuanMiLCJub2RlX21vZHVsZXMvaG1hYy1kcmJnL2xpYi9obWFjLWRyYmcuanMiLCJub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9pbW1lZGlhdGUvbGliL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9pcy1idWZmZXIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaXNhcnJheS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9qc3ppcC9saWIvYmFzZTY0LmpzIiwibm9kZV9tb2R1bGVzL2pzemlwL2xpYi9jb21wcmVzc2VkT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2pzemlwL2xpYi9jb21wcmVzc2lvbnMuanMiLCJub2RlX21vZHVsZXMvanN6aXAvbGliL2NyYzMyLmpzIiwibm9kZV9tb2R1bGVzL2pzemlwL2xpYi9kZWZhdWx0cy5qcyIsIm5vZGVfbW9kdWxlcy9qc3ppcC9saWIvZXh0ZXJuYWwuanMiLCJub2RlX21vZHVsZXMvanN6aXAvbGliL2ZsYXRlLmpzIiwibm9kZV9tb2R1bGVzL2pzemlwL2xpYi9nZW5lcmF0ZS9aaXBGaWxlV29ya2VyLmpzIiwibm9kZV9tb2R1bGVzL2pzemlwL2xpYi9nZW5lcmF0ZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9qc3ppcC9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvanN6aXAvbGliL2xvYWQuanMiLCJub2RlX21vZHVsZXMvanN6aXAvbGliL25vZGVqc1V0aWxzLmpzIiwibm9kZV9tb2R1bGVzL2pzemlwL2xpYi9ub2RlanMvTm9kZWpzU3RyZWFtSW5wdXRBZGFwdGVyLmpzIiwibm9kZV9tb2R1bGVzL2pzemlwL2xpYi9ub2RlanMvTm9kZWpzU3RyZWFtT3V0cHV0QWRhcHRlci5qcyIsIm5vZGVfbW9kdWxlcy9qc3ppcC9saWIvb2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2pzemlwL2xpYi9yZWFkYWJsZS1zdHJlYW0tYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9qc3ppcC9saWIvcmVhZGVyL0FycmF5UmVhZGVyLmpzIiwibm9kZV9tb2R1bGVzL2pzemlwL2xpYi9yZWFkZXIvRGF0YVJlYWRlci5qcyIsIm5vZGVfbW9kdWxlcy9qc3ppcC9saWIvcmVhZGVyL05vZGVCdWZmZXJSZWFkZXIuanMiLCJub2RlX21vZHVsZXMvanN6aXAvbGliL3JlYWRlci9TdHJpbmdSZWFkZXIuanMiLCJub2RlX21vZHVsZXMvanN6aXAvbGliL3JlYWRlci9VaW50OEFycmF5UmVhZGVyLmpzIiwibm9kZV9tb2R1bGVzL2pzemlwL2xpYi9yZWFkZXIvcmVhZGVyRm9yLmpzIiwibm9kZV9tb2R1bGVzL2pzemlwL2xpYi9zaWduYXR1cmUuanMiLCJub2RlX21vZHVsZXMvanN6aXAvbGliL3N0cmVhbS9Db252ZXJ0V29ya2VyLmpzIiwibm9kZV9tb2R1bGVzL2pzemlwL2xpYi9zdHJlYW0vQ3JjMzJQcm9iZS5qcyIsIm5vZGVfbW9kdWxlcy9qc3ppcC9saWIvc3RyZWFtL0RhdGFMZW5ndGhQcm9iZS5qcyIsIm5vZGVfbW9kdWxlcy9qc3ppcC9saWIvc3RyZWFtL0RhdGFXb3JrZXIuanMiLCJub2RlX21vZHVsZXMvanN6aXAvbGliL3N0cmVhbS9HZW5lcmljV29ya2VyLmpzIiwibm9kZV9tb2R1bGVzL2pzemlwL2xpYi9zdHJlYW0vU3RyZWFtSGVscGVyLmpzIiwibm9kZV9tb2R1bGVzL2pzemlwL2xpYi9zdXBwb3J0LmpzIiwibm9kZV9tb2R1bGVzL2pzemlwL2xpYi91dGY4LmpzIiwibm9kZV9tb2R1bGVzL2pzemlwL2xpYi91dGlscy5qcyIsIm5vZGVfbW9kdWxlcy9qc3ppcC9saWIvemlwRW50cmllcy5qcyIsIm5vZGVfbW9kdWxlcy9qc3ppcC9saWIvemlwRW50cnkuanMiLCJub2RlX21vZHVsZXMvanN6aXAvbGliL3ppcE9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9saWUvbGliL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2xvZGFzaC5qcyIsIm5vZGVfbW9kdWxlcy9tZDUuanMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvbWlsbGVyLXJhYmluL2xpYi9tci5qcyIsIm5vZGVfbW9kdWxlcy9taW5pbWFsaXN0aWMtYXNzZXJ0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL21pbmltYWxpc3RpYy1jcnlwdG8tdXRpbHMvbGliL3V0aWxzLmpzIiwibm9kZV9tb2R1bGVzL3Bha28vaW5kZXguanMiLCJub2RlX21vZHVsZXMvcGFrby9saWIvZGVmbGF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9wYWtvL2xpYi9pbmZsYXRlLmpzIiwibm9kZV9tb2R1bGVzL3Bha28vbGliL3V0aWxzL2NvbW1vbi5qcyIsIm5vZGVfbW9kdWxlcy9wYWtvL2xpYi91dGlscy9zdHJpbmdzLmpzIiwibm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvYWRsZXIzMi5qcyIsIm5vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliL2NvbnN0YW50cy5qcyIsIm5vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliL2NyYzMyLmpzIiwibm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvZGVmbGF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliL2d6aGVhZGVyLmpzIiwibm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvaW5mZmFzdC5qcyIsIm5vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliL2luZmxhdGUuanMiLCJub2RlX21vZHVsZXMvcGFrby9saWIvemxpYi9pbmZ0cmVlcy5qcyIsIm5vZGVfbW9kdWxlcy9wYWtvL2xpYi96bGliL21lc3NhZ2VzLmpzIiwibm9kZV9tb2R1bGVzL3Bha28vbGliL3psaWIvdHJlZXMuanMiLCJub2RlX21vZHVsZXMvcGFrby9saWIvemxpYi96c3RyZWFtLmpzIiwibm9kZV9tb2R1bGVzL3BhcnNlLWFzbjEvYWVzaWQuanNvbiIsIm5vZGVfbW9kdWxlcy9wYXJzZS1hc24xL2FzbjEuanMiLCJub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9jZXJ0aWZpY2F0ZS5qcyIsIm5vZGVfbW9kdWxlcy9wYXJzZS1hc24xL2ZpeFByb2MuanMiLCJub2RlX21vZHVsZXMvcGFyc2UtYXNuMS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9wYmtkZjIvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9wYmtkZjIvbGliL2FzeW5jLmpzIiwibm9kZV9tb2R1bGVzL3Bia2RmMi9saWIvZGVmYXVsdC1lbmNvZGluZy5qcyIsIm5vZGVfbW9kdWxlcy9wYmtkZjIvbGliL3ByZWNvbmRpdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9wYmtkZjIvbGliL3N5bmMtYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9wcm9jZXNzLW5leHRpY2stYXJncy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC9tZ2YuanMiLCJub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvcHJpdmF0ZURlY3J5cHQuanMiLCJub2RlX21vZHVsZXMvcHVibGljLWVuY3J5cHQvcHVibGljRW5jcnlwdC5qcyIsIm5vZGVfbW9kdWxlcy9wdWJsaWMtZW5jcnlwdC93aXRoUHVibGljLmpzIiwibm9kZV9tb2R1bGVzL3B1YmxpYy1lbmNyeXB0L3hvci5qcyIsIm5vZGVfbW9kdWxlcy9yYW5kb21ieXRlcy9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL3JhbmRvbWZpbGwvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vZHVwbGV4LmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9kdXBsZXguanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL2xpYi9fc3RyZWFtX3Bhc3N0aHJvdWdoLmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV9yZWFkYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS9saWIvX3N0cmVhbV93cml0YWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9yZWFkYWJsZS1zdHJlYW0vcGFzc3Rocm91Z2guanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL3JlYWRhYmxlLmpzIiwibm9kZV9tb2R1bGVzL3JlYWRhYmxlLXN0cmVhbS90cmFuc2Zvcm0uanMiLCJub2RlX21vZHVsZXMvcmVhZGFibGUtc3RyZWFtL3dyaXRhYmxlLmpzIiwibm9kZV9tb2R1bGVzL3JpcGVtZDE2MC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9zYXgvbGliL3NheC5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvaGFzaC5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc2hhLmpzL3NoYS5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvc2hhMS5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvc2hhMjI0LmpzIiwibm9kZV9tb2R1bGVzL3NoYS5qcy9zaGEyNTYuanMiLCJub2RlX21vZHVsZXMvc2hhLmpzL3NoYTM4NC5qcyIsIm5vZGVfbW9kdWxlcy9zaGEuanMvc2hhNTEyLmpzIiwibm9kZV9tb2R1bGVzL3N0cmVhbS1icm93c2VyaWZ5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3N0cmluZ19kZWNvZGVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3RpbWVycy1icm93c2VyaWZ5L21haW4uanMiLCJub2RlX21vZHVsZXMvdXRpbC1kZXByZWNhdGUvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy92bS1icm93c2VyaWZ5L2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7Ozs7OztBQUVBLElBQU0sSUFBSSxRQUFRLFFBQVIsQ0FBVjtBQUNBLElBQU0sT0FBTyxRQUFRLFFBQVIsQ0FBYjtBQUNBLElBQU0sYUFBYSxRQUFRLGNBQVIsQ0FBbkI7O0FBRUE7Ozs7O0lBSU0sYTtBQUNGOzs7O0FBSUEsMkJBQVksSUFBWixFQUFrQjtBQUFBOztBQUNkLGFBQUssS0FBTCxHQUFhLElBQWI7QUFDSDs7OztpQ0FFUSxLLEVBQU87QUFBQTs7QUFDWixtQkFBTyxJQUFJLFVBQUosQ0FBZSxlQUFmLEVBQ0YsSUFERSxDQUNHLFlBQU07QUFDUixvQkFBTSxrQkFBa0IsS0FBSyxTQUFMLENBQWUsTUFBSyxLQUFwQixFQUEyQixhQUEzQixDQUF4QjtBQUNBLG9CQUFJLENBQUMsZUFBTCxFQUFzQixPQUFPLEtBQVA7QUFDdEIsdUJBQU8sZ0JBQWdCLFFBQWhCLENBQXlCLENBQXpCLE1BQWdDLENBQXZDO0FBQ0gsYUFMRSxFQU1GLElBTkUsQ0FNRyxTQU5ILEVBTWMsaUJBQVM7QUFDdEIsb0JBQU0sa0JBQWtCLEtBQUsscUJBQUwsQ0FBMkIsTUFBSyxLQUFoQyxFQUF1QyxhQUF2QyxDQUF4QjtBQUNBLGdDQUFnQixRQUFoQixHQUEyQixDQUFDLFFBQVEsQ0FBUixHQUFZLENBQWIsQ0FBM0I7QUFDQSx1QkFBTyxLQUFQO0FBQ0gsYUFWRSxFQVdGLE1BWEUsQ0FXSyxTQVhMLENBQVA7QUFZSDs7QUFFRDs7Ozs7OztnQ0FJUTtBQUNKLG1CQUFPLEtBQUssS0FBWjtBQUNIOzs7Ozs7QUFHTCxPQUFPLE9BQVAsR0FBaUIsYUFBakI7O0FBRUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDN0NBOzs7Ozs7QUFFQSxJQUFNLElBQUksUUFBUSxRQUFSLENBQVY7O0FBRUE7Ozs7O0lBSU0sVTtBQUNGOzs7O0FBSUEsd0JBQVksSUFBWixFQUFrQjtBQUFBOztBQUNkLGFBQUssS0FBTCxHQUFhLElBQWI7QUFDQSxhQUFLLE1BQUwsR0FBYyxFQUFkO0FBQ0g7O0FBRUQ7Ozs7Ozs7Ozs7OEJBTUssSyxFQUFPLE8sRUFBUztBQUNqQixnQkFBSSxVQUFVLE1BQVYsS0FBcUIsQ0FBekIsRUFBNEI7QUFDeEIsMEJBQVUsS0FBVjtBQUNBLHdCQUFRLEVBQVI7QUFDSDs7QUFFRCxnQkFBSSxDQUFDLE1BQU0sT0FBTixDQUFjLEtBQWQsQ0FBTCxFQUEyQixRQUFRLENBQUMsS0FBRCxDQUFSO0FBQzNCLGlCQUFLLE1BQUwsQ0FBWSxJQUFaLENBQWlCLEVBQUUsWUFBRixFQUFTLGdCQUFULEVBQWpCO0FBQ0EsbUJBQU8sSUFBUDtBQUNIOztBQUVEOzs7Ozs7Ozs7K0JBTU8sSSxFQUFNO0FBQ1QsaUJBQUssSUFBSSxJQUFJLENBQWIsRUFBZ0IsSUFBSSxLQUFLLE1BQUwsQ0FBWSxNQUFoQyxFQUF3QyxHQUF4QyxFQUE2QztBQUN6QyxvQkFBTSxJQUFJLEtBQUssTUFBTCxDQUFZLENBQVosQ0FBVjtBQUNBLG9CQUFJLEtBQUssZUFBTCxDQUFxQixJQUFyQixFQUEyQixFQUFFLEtBQTdCLENBQUosRUFBeUM7QUFDckMsMkJBQU8sRUFBRSxPQUFGLENBQVUsS0FBVixDQUFnQixJQUFoQixFQUFzQixJQUF0QixDQUFQO0FBQ0g7QUFDSjs7QUFFRCxrQkFBTSxJQUFJLEtBQUosQ0FBYSxLQUFLLEtBQWxCLDBCQUFOO0FBQ0g7O0FBRUQ7Ozs7Ozs7Ozs7O3dDQVFnQixJLEVBQU0sSyxFQUFPO0FBQ3pCLGdCQUFJLEtBQUssTUFBTCxLQUFnQixNQUFNLE1BQTFCLEVBQWtDLE9BQU8sS0FBUDs7QUFFbEMsbUJBQU8sRUFBRSxLQUFGLENBQVEsSUFBUixFQUFjLFVBQUMsR0FBRCxFQUFNLENBQU4sRUFBWTtBQUM3QixvQkFBTSxPQUFPLE1BQU0sQ0FBTixDQUFiOztBQUVBLG9CQUFJLFNBQVMsR0FBYixFQUFrQixPQUFPLElBQVA7QUFDbEIsb0JBQUksU0FBUyxLQUFiLEVBQW9CLE9BQU8sRUFBRSxLQUFGLENBQVEsR0FBUixDQUFQO0FBQ3BCLG9CQUFJLFNBQVMsUUFBYixFQUF1QixPQUFPLE9BQU8sR0FBUCxLQUFlLFFBQXRCO0FBQ3ZCLG9CQUFJLFNBQVMsU0FBYixFQUF3QixPQUFPLE9BQU8sR0FBUCxLQUFlLFNBQXRCO0FBQ3hCLG9CQUFJLFNBQVMsUUFBYixFQUF1QixPQUFPLE9BQU8sR0FBUCxLQUFlLFFBQXRCO0FBQ3ZCLG9CQUFJLFNBQVMsU0FBYixFQUF3QixPQUFPLE9BQU8sR0FBUCxLQUFlLFFBQWYsSUFBMkIsRUFBRSxTQUFGLENBQVksR0FBWixDQUFsQztBQUN4QixvQkFBSSxTQUFTLFVBQWIsRUFBeUIsT0FBTyxPQUFPLEdBQVAsS0FBZSxVQUF0QjtBQUN6QixvQkFBSSxTQUFTLE9BQWIsRUFBc0IsT0FBTyxNQUFNLE9BQU4sQ0FBYyxHQUFkLENBQVA7QUFDdEIsb0JBQUksU0FBUyxNQUFiLEVBQXFCLE9BQU8sT0FBTyxJQUFJLFdBQUosS0FBb0IsSUFBbEM7QUFDckIsb0JBQUksU0FBUyxRQUFiLEVBQXVCLE9BQU8sT0FBTyxJQUFJLFdBQUosS0FBb0IsTUFBbEM7QUFDdkIsb0JBQUksT0FBTyxJQUFJLFdBQVgsSUFBMEIsSUFBSSxXQUFKLENBQWdCLElBQWhCLEtBQXlCLElBQXZELEVBQTZELE9BQU8sSUFBUDs7QUFFN0Qsc0JBQU0sSUFBSSxLQUFKLG9CQUEyQixJQUEzQixDQUFOO0FBQ0gsYUFoQk0sQ0FBUDtBQWlCSDs7Ozs7O0FBR0wsT0FBTyxPQUFQLEdBQWlCLFVBQWpCOzs7QUNuRkE7Ozs7Ozs7O0FBRUEsSUFBTSxJQUFJLFFBQVEsUUFBUixDQUFWO0FBQ0EsSUFBTSxhQUFhLFFBQVEsY0FBUixDQUFuQjtBQUNBLElBQU0sbUJBQW1CLFFBQVEsb0JBQVIsQ0FBekI7QUFDQSxJQUFNLGdCQUFnQixRQUFRLGlCQUFSLENBQXRCO0FBQ0EsSUFBTSxXQUFXLFFBQVEsWUFBUixDQUFqQjtBQUNBLElBQU0sT0FBTyxRQUFRLFFBQVIsQ0FBYjtBQUNBLElBQU0sZUFBZSxRQUFRLGdCQUFSLENBQXJCO0FBQ0EsSUFBTSxRQUFRLFFBQVEsU0FBUixDQUFkO0FBQ0EsSUFBTSxXQUFXLFFBQVEsWUFBUixDQUFqQjs7QUFFQTs7OztJQUdNLEk7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQVksR0FBWixFQUFpQixJQUFqQixFQUF1QixPQUF2QixFQUFnQztBQUFBOztBQUM1QixhQUFLLElBQUwsR0FBWSxHQUFaO0FBQ0EsYUFBSyxLQUFMLENBQVcsSUFBWCxFQUFpQixPQUFqQjtBQUNIOztBQUVEOztBQUVBOzs7UUFHRzs7Ozs7Ozs7O2lDQUtNO0FBQUE7O0FBQ0wsbUJBQU8sSUFBSSxVQUFKLENBQWUsYUFBZixFQUNGLElBREUsQ0FDRyxZQUFNO0FBQ1IsdUJBQU8sTUFBSyxLQUFMLEdBQWEsVUFBYixPQUE4QixLQUFyQztBQUNILGFBSEUsRUFJRixJQUpFLENBSUcsU0FKSCxFQUljLGtCQUFVO0FBQ3ZCLG9CQUFJLENBQUMsTUFBTCxFQUFhLE1BQU0sSUFBSSxLQUFKLENBQVUsOEVBQVYsQ0FBTjtBQUNiLHNCQUFLLEtBQUwsR0FBYSxVQUFiLENBQXdCLEtBQXhCO0FBQ0EsdUJBQU8sS0FBUDtBQUNILGFBUkUsRUFTRixNQVRFLENBU0ssU0FUTCxDQUFQO0FBVUg7O0FBRUQ7Ozs7Ozs7Ozs7OztnQ0FTUSxJLEVBQU07QUFDVixtQkFBTyxpQkFBaUIsU0FBakIsQ0FBMkI7QUFDOUIsc0JBQU0sTUFEd0I7QUFFOUIsMkJBQVcsS0FBSyxTQUFMLEVBRm1CO0FBRzlCLDhCQUFjLEtBQUssWUFBTCxFQUhnQjtBQUk5QiwyQkFBVyxRQUFRLEtBQUssZ0JBQWIsSUFBaUMsS0FBSyxLQUFMLEdBQWEsSUFBYixFQUpkO0FBSzlCLDZCQUFhLFNBQVMsS0FBSyxXQUFMLElBQW9CLEtBQUssUUFBbEMsQ0FMaUI7QUFNOUIsZ0NBQWdCLFNBQVMsS0FBSyxjQUFMLElBQXVCLEtBQUssUUFBckM7QUFOYyxhQUEzQixDQUFQO0FBUUg7O0FBRUQ7Ozs7Ozs7aUNBSVM7QUFDTCxtQkFBTyxLQUFLLEtBQUwsR0FBYSxNQUFiLENBQW9CLEtBQUssWUFBTCxFQUFwQixDQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7Z0NBSVE7QUFDSixnQkFBTSxzQkFBc0IsS0FBSyxXQUFMLElBQW9CLEtBQUssZ0JBQXJEOztBQUVBLG1CQUFPLEtBQUssTUFBWjtBQUNBLG1CQUFPLEtBQUssWUFBWjtBQUNBLG1CQUFPLEtBQUssUUFBWjtBQUNBLG1CQUFPLEtBQUssZ0JBQVo7QUFDQSxtQkFBTyxLQUFLLFdBQVo7O0FBRUE7QUFDQSxnQkFBSSxDQUFDLEVBQUUsS0FBRixDQUFRLG1CQUFSLENBQUwsRUFBbUMsS0FBSyxLQUFMLEdBQWEsNEJBQWIsQ0FBMEMsbUJBQTFDOztBQUVuQyxtQkFBTyxJQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7cUNBSWE7QUFDVCxtQkFBTyxpQkFBaUIsa0JBQWpCLENBQW9DLEtBQUssWUFBTCxFQUFwQyxDQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7dUNBSWU7QUFDWCxtQkFBTyxLQUFLLGFBQVo7QUFDSDs7QUFFRDs7Ozs7Ozs7OzZCQU1LLE8sRUFBUyxXLEVBQWE7QUFDdkIsc0JBQVUsU0FBUyxPQUFULENBQVY7O0FBRUEsZ0JBQU0sUUFBUSxLQUFLLEtBQUwsRUFBZDtBQUNBLGdCQUFJLE9BQU8sS0FBUCxLQUFpQixRQUFyQixFQUErQixPQUFPLEtBQVA7O0FBRS9CLGdCQUFJLEVBQUUsS0FBRixDQUFRLFdBQVIsQ0FBSixFQUEwQjtBQUN0Qix1QkFBTyxRQUFRLElBQVIsQ0FBYSxLQUFiLENBQVA7QUFDSCxhQUZELE1BRU87QUFDSCxvQkFBTSxXQUFXLE1BQU0sT0FBTixDQUFjLE9BQWQsRUFBdUIsV0FBdkIsQ0FBakI7QUFDQSxvQkFBSSxhQUFhLEtBQWpCLEVBQXdCLE9BQU8sS0FBUDtBQUN4QixxQkFBSyxLQUFMLENBQVcsUUFBWDtBQUNBLHVCQUFPLElBQVA7QUFDSDtBQUNKOztBQUVEOzs7WUFHRzs7Ozs7Ozs7a0NBS087QUFBQTs7QUFDTixtQkFBTyxJQUFJLFVBQUosQ0FBZSxjQUFmLEVBQ0YsSUFERSxDQUNHLFlBQU07QUFDUjtBQUNBLG9CQUFJLE9BQUssWUFBTCxLQUFzQixRQUF0QixJQUFrQyxDQUFDLE9BQUssV0FBNUMsRUFBeUQsT0FBTyxRQUFQO0FBQ3pELHVCQUFPLE9BQUssUUFBWjtBQUNILGFBTEUsRUFNRixJQU5FLENBTUcsS0FOSCxFQU1VLFlBQU07QUFDZix1QkFBSyxLQUFMO0FBQ0EsdUJBQU8sTUFBUDtBQUNILGFBVEUsRUFVRixJQVZFLENBVUcsUUFWSCxFQVVhLG1CQUFXO0FBQ3ZCLHVCQUFLLEtBQUw7QUFDQSx1QkFBSyxZQUFMLEdBQW9CLFFBQXBCO0FBQ0EsdUJBQUssUUFBTCxHQUFnQixPQUFoQjtBQUNBLHVCQUFPLE1BQVA7QUFDSCxhQWZFLEVBZ0JGLE1BaEJFLENBZ0JLLFNBaEJMLENBQVA7QUFpQkg7O0FBRUQ7OztZQUdHOzs7O2VBSUE7Ozs7Ozs7Ozs7OztvQ0FTUztBQUFBOztBQUNSLG1CQUFPLElBQUksVUFBSixDQUFlLGdCQUFmLEVBQ0YsSUFERSxDQUNHLFlBQU07QUFDUix1QkFBTyxPQUFLLEtBQUwsR0FBYSxTQUFiLENBQXVCLE9BQUssT0FBTCxFQUF2QixDQUFQO0FBQ0gsYUFIRSxFQUlGLElBSkUsQ0FJRyxRQUpILEVBSWEscUJBQWE7QUFDekIsdUJBQUssS0FBTCxHQUFhLFNBQWIsQ0FBdUIsT0FBSyxPQUFMLEVBQXZCLEVBQXVDLFNBQXZDO0FBQ0EsdUJBQU8sTUFBUDtBQUNILGFBUEUsRUFRRixJQVJFLENBUUcsQ0FBQyxRQUFELENBUkgsRUFRZSxnQkFBUTtBQUN0Qix1QkFBSyxLQUFMLEdBQWEsU0FBYixDQUF1QixPQUFLLE9BQUwsRUFBdkIsRUFBdUMsSUFBdkM7QUFDQSx1QkFBTyxNQUFQO0FBQ0gsYUFYRSxFQVlGLE1BWkUsQ0FZSyxTQVpMLENBQVA7QUFhSDs7QUFHRDs7O1lBR0c7Ozs7Ozs7O3lDQUtjO0FBQUE7O0FBQ2IsbUJBQU8sSUFBSSxVQUFKLENBQWUscUJBQWYsRUFDRixJQURFLENBQ0csWUFBTTtBQUNSLHVCQUFPLE9BQUssS0FBTCxHQUFhLGNBQWIsQ0FBNEIsT0FBSyxPQUFMLEVBQTVCLENBQVA7QUFDSCxhQUhFLEVBSUYsSUFKRSxDQUlHLFNBSkgsRUFJYyxlQUFPO0FBQ3BCLHVCQUFPLE9BQUssS0FBTCxHQUFhLGNBQWIsQ0FBNEIsT0FBSyxPQUFMLEVBQTVCLEVBQTRDLEdBQTVDLENBQVA7QUFDSCxhQU5FLEVBT0YsSUFQRSxDQU9HLEdBUEgsRUFPUSxlQUFPO0FBQ2QsdUJBQUssS0FBTCxHQUFhLGNBQWIsQ0FBNEIsT0FBSyxPQUFMLEVBQTVCLEVBQTRDLEdBQTVDO0FBQ0EsdUJBQU8sTUFBUDtBQUNILGFBVkUsRUFXRixNQVhFLENBV0ssU0FYTCxDQUFQO0FBWUg7O0FBRUQ7Ozs7O1lBS0c7Ozs7Ozs7OzRCQUtDLFEsRUFBVTtBQUNWLHFCQUFTLElBQVQ7QUFDQSxtQkFBTyxJQUFQO0FBQ0g7O0FBRUQ7Ozs7O1lBS0c7Ozs7Ozs7OzZCQUtFLFEsRUFBVTtBQUNYLG1CQUFPLFNBQVMsSUFBVCxDQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7O2dDQUtRLEksRUFBTTtBQUNWLG1CQUFPLEtBQUssS0FBTCxHQUFhLEtBQWIsQ0FBbUIsSUFBbkIsRUFBeUIsSUFBekIsQ0FBUDtBQUNIOztBQUVEOzs7Ozs7Ozs7cUNBTWEsUyxFQUFXLFksRUFBYztBQUNsQyxnQkFBTSxNQUFNLFlBQVksS0FBSyxTQUFMLEVBQXhCO0FBQ0EsZ0JBQU0sU0FBUyxlQUFlLEtBQUssWUFBTCxFQUE5QjtBQUNBLG1CQUFPLEtBQUssS0FBTCxHQUFhLElBQWIsQ0FBa0IsR0FBbEIsRUFBdUIsTUFBdkIsQ0FBUDtBQUNIOztBQUVEOzs7Ozs7OzhCQUlNO0FBQ0YsbUJBQU8sS0FBSyxJQUFaO0FBQ0g7O0FBRUQ7Ozs7Ozs7b0NBSVk7QUFDUixtQkFBTyxLQUFLLEdBQUwsR0FBVyxTQUFYLEVBQVA7QUFDSDs7QUFFRDs7Ozs7OztnQ0FJUTtBQUNKLG1CQUFPLEtBQUssR0FBTCxHQUFXLEtBQVgsRUFBUDtBQUNIOztBQUVEOzs7O1lBSUc7Ozs7ZUFJQTs7Ozs7a0JBS0E7Ozs7O3FCQUtBOzs7O3dCQUlBOzs7Ozs7OztnQ0FLSztBQUFBOztBQUNKLGdCQUFJLENBQUMsS0FBSyxNQUFOLElBQWdCLEVBQUUsVUFBVSxDQUFWLGFBQXdCLEtBQTFCLENBQXBCLEVBQXNEO0FBQ2xELHFCQUFLLE1BQUwsR0FBYyxLQUFLLFFBQUwsR0FBZ0IsVUFBaEIsR0FBNkIsV0FBN0IsQ0FBeUMsS0FBSyxRQUE5QyxDQUFkO0FBQ0g7O0FBRUQsbUJBQU8sSUFBSSxVQUFKLENBQWUsWUFBZixFQUNGLElBREUsQ0FDRyxRQURILEVBQ2EsZ0JBQVE7QUFDcEI7QUFDQSx1QkFBTyxPQUFLLE1BQUwsQ0FBWSxLQUFaLENBQWtCLElBQWxCLENBQVA7QUFDSCxhQUpFLEVBS0YsSUFMRSxDQUtHLE9BTEgsRUFLWSxpQkFBUztBQUNwQjtBQUNBLG9CQUFNLFNBQVMsRUFBZjtBQUNBLHNCQUFNLE9BQU4sQ0FBYyxnQkFBUTtBQUNsQiwyQkFBTyxJQUFQLElBQWUsT0FBSyxLQUFMLENBQVcsSUFBWCxDQUFmO0FBQ0gsaUJBRkQ7O0FBSUEsdUJBQU8sTUFBUDtBQUNILGFBYkUsRUFjRixJQWRFLENBY0csQ0FBQyxRQUFELEVBQVcsT0FBWCxDQWRILEVBY3dCLFVBQUMsSUFBRCxFQUFPLE1BQVAsRUFBa0I7QUFDekMsb0JBQU0sVUFBVSxPQUFPLE1BQXZCO0FBQ0Esb0JBQU0sVUFBVSxPQUFPLENBQVAsRUFBVSxNQUExQjtBQUNBLG9CQUFNLFFBQVEsT0FBSyxPQUFMLENBQWEsT0FBSyxZQUFMLENBQWtCLFVBQVUsQ0FBNUIsRUFBK0IsVUFBVSxDQUF6QyxDQUFiLENBQWQ7QUFDQSx1QkFBTyxNQUFNLEtBQU4sQ0FBWSxJQUFaLEVBQWtCLE1BQWxCLENBQVA7QUFDSCxhQW5CRSxFQW9CRixJQXBCRSxDQW9CRyxDQUFDLFFBQUQsRUFBVyxHQUFYLENBcEJILEVBb0JvQixVQUFDLElBQUQsRUFBTyxLQUFQLEVBQWlCO0FBQ3BDO0FBQ0EsdUJBQUssTUFBTCxDQUFZLEtBQVosQ0FBa0IsSUFBbEIsRUFBd0IsS0FBeEI7QUFDQSx1QkFBTyxNQUFQO0FBQ0gsYUF4QkUsRUF5QkYsSUF6QkUsQ0F5QkcsUUF6QkgsRUF5QmEsc0JBQWM7QUFDMUI7QUFDQSxxQkFBSyxJQUFNLElBQVgsSUFBbUIsVUFBbkIsRUFBK0I7QUFDM0Isd0JBQUksQ0FBQyxXQUFXLGNBQVgsQ0FBMEIsSUFBMUIsQ0FBTCxFQUFzQztBQUN0Qyx3QkFBTSxRQUFRLFdBQVcsSUFBWCxDQUFkO0FBQ0EsMkJBQUssS0FBTCxDQUFXLElBQVgsRUFBaUIsS0FBakI7QUFDSDs7QUFFRCx1QkFBTyxNQUFQO0FBQ0gsYUFsQ0UsRUFtQ0YsSUFuQ0UsQ0FtQ0csT0FuQ0gsRUFtQ1ksaUJBQVM7QUFDcEIsdUJBQUssTUFBTCxHQUFjLEtBQWQ7QUFDQSx1QkFBSyxRQUFMLEdBQWdCLE1BQU0sRUFBTixFQUFoQjs7QUFFQSx1QkFBTyxNQUFQO0FBQ0gsYUF4Q0UsRUF5Q0YsTUF6Q0UsQ0F5Q0ssU0F6Q0wsQ0FBUDtBQTBDSDs7QUFFRDs7O1lBR0c7Ozs7ZUFJQTs7Ozs7Ozs7Z0NBS0s7QUFBQTs7QUFDSixtQkFBTyxJQUFJLFVBQUosQ0FBZSxZQUFmLEVBQ0YsSUFERSxDQUNHLFlBQU07QUFDUixvQkFBSSxPQUFLLE1BQUwsWUFBdUIsUUFBM0IsRUFBcUM7QUFDakMsMkJBQU8sT0FBSyxNQUFMLENBQVksc0JBQVosQ0FBbUMsTUFBbkMsQ0FBUDtBQUNIO0FBQ0QsdUJBQU8sT0FBSyxNQUFaO0FBQ0gsYUFORSxFQU9GLElBUEUsQ0FPRyxPQVBILEVBT1ksa0JBQVU7QUFDckIsb0JBQU0sVUFBVSxPQUFPLE1BQXZCO0FBQ0Esb0JBQU0sVUFBVSxPQUFPLENBQVAsRUFBVSxNQUExQjtBQUNBLG9CQUFNLFFBQVEsT0FBSyxPQUFMLENBQWEsT0FBSyxZQUFMLENBQWtCLFVBQVUsQ0FBNUIsRUFBK0IsVUFBVSxDQUF6QyxDQUFiLENBQWQ7QUFDQSx1QkFBTyxNQUFNLEtBQU4sQ0FBWSxNQUFaLENBQVA7QUFDSCxhQVpFLEVBYUYsSUFiRSxDQWFHLEdBYkgsRUFhUSxpQkFBUztBQUNoQix1QkFBSyxLQUFMO0FBQ0Esb0JBQUksaUJBQWlCLFFBQXJCLEVBQStCO0FBQzNCLDJCQUFLLE1BQUwsR0FBYyxNQUFNLElBQU4sQ0FBVyxNQUFYLENBQWQ7QUFDSCxpQkFGRCxNQUVPO0FBQ0gsMkJBQUssTUFBTCxHQUFjLEtBQWQ7QUFDSDtBQUNELHVCQUFPLE1BQVA7QUFDSCxhQXJCRSxFQXNCRixNQXRCRSxDQXNCSyxTQXRCTCxDQUFQO0FBdUJIOztBQUVEOzs7Ozs7O21DQUlXO0FBQ1AsbUJBQU8sS0FBSyxHQUFMLEdBQVcsUUFBWCxFQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7aURBSXlCO0FBQ3JCLGlCQUFLLEdBQUwsR0FBVyxZQUFYO0FBQ0EsbUJBQU8sSUFBUDtBQUNIOztBQUVEOztBQUVBOzs7Ozs7Ozs4Q0FLc0I7QUFDbEIsbUJBQU8sS0FBSyxZQUFMLEtBQXNCLFFBQXRCLEdBQWlDLEtBQUssV0FBTCxJQUFvQixLQUFLLFFBQTFELEdBQXFFLFNBQTVFO0FBQ0g7O0FBRUQ7Ozs7Ozs7OztzQ0FNYyxFLEVBQUk7QUFDZCxtQkFBTyxLQUFLLFlBQUwsS0FBc0IsUUFBdEIsSUFBa0MsS0FBSyxnQkFBTCxLQUEwQixFQUFuRTtBQUNIOztBQUVEOzs7Ozs7Ozs7Ozt5Q0FRaUIsRSxFQUFJLE8sRUFBUyxTLEVBQVc7QUFDckMsaUJBQUssS0FBTDs7QUFFQSxpQkFBSyxZQUFMLEdBQW9CLFFBQXBCO0FBQ0EsaUJBQUssZ0JBQUwsR0FBd0IsRUFBeEI7QUFDQSxpQkFBSyxRQUFMLEdBQWdCLE9BQWhCO0FBQ0EsaUJBQUssV0FBTCxHQUFtQixTQUFuQjtBQUNIOztBQUVEOzs7Ozs7OztnQ0FLUTtBQUNKO0FBQ0EsZ0JBQU0sT0FBTztBQUNULHNCQUFNLEdBREc7QUFFVCw0QkFBWSxLQUFLLG9CQUFMLElBQTZCLEVBRmhDLEVBRW9DO0FBQzdDLDBCQUFVO0FBSEQsYUFBYjs7QUFNQTtBQUNBLGlCQUFLLFVBQUwsQ0FBZ0IsQ0FBaEIsR0FBb0IsS0FBSyxPQUFMLEVBQXBCOztBQUVBLGdCQUFJLENBQUMsRUFBRSxLQUFGLENBQVEsS0FBSyxZQUFiLENBQUwsRUFBaUM7QUFDN0I7QUFDQSxvQkFBTSxRQUFRO0FBQ1YsMEJBQU0sR0FESTtBQUVWLGdDQUFZLEtBQUssMkJBQUwsSUFBb0M7QUFGdEMsaUJBQWQ7O0FBS0Esb0JBQUksS0FBSyxZQUFMLEtBQXNCLFFBQTFCLEVBQW9DLE1BQU0sVUFBTixDQUFpQixDQUFqQixHQUFxQixLQUFLLFlBQTFCO0FBQ3BDLG9CQUFJLENBQUMsRUFBRSxLQUFGLENBQVEsS0FBSyxXQUFiLENBQUwsRUFBZ0MsTUFBTSxVQUFOLENBQWlCLEdBQWpCLEdBQXVCLEtBQUssV0FBNUI7QUFDaEMsb0JBQUksQ0FBQyxFQUFFLEtBQUYsQ0FBUSxLQUFLLGdCQUFiLENBQUwsRUFBcUMsTUFBTSxVQUFOLENBQWlCLEVBQWpCLEdBQXNCLEtBQUssZ0JBQTNCO0FBQ3JDLG9CQUFJLENBQUMsRUFBRSxLQUFGLENBQVEsS0FBSyxRQUFiLENBQUwsRUFBNkIsTUFBTSxRQUFOLEdBQWlCLENBQUMsS0FBSyxRQUFOLENBQWpCOztBQUU3QixxQkFBSyxRQUFMLENBQWMsSUFBZCxDQUFtQixLQUFuQjtBQUNILGFBYkQsTUFhTyxJQUFJLENBQUMsRUFBRSxLQUFGLENBQVEsS0FBSyxNQUFiLENBQUwsRUFBMkI7QUFDOUI7QUFDQSxvQkFBSSxhQUFKO0FBQUEsb0JBQVUsYUFBVjtBQUNBLG9CQUFJLE9BQU8sS0FBSyxNQUFaLEtBQXVCLFFBQTNCLEVBQXFDO0FBQ2pDLDJCQUFPLEdBQVA7QUFDQSwyQkFBTyxLQUFLLFFBQUwsR0FBZ0IsYUFBaEIsR0FBZ0MsaUJBQWhDLENBQWtELEtBQUssTUFBdkQsQ0FBUDtBQUNILGlCQUhELE1BR08sSUFBSSxPQUFPLEtBQUssTUFBWixLQUF1QixTQUEzQixFQUFzQztBQUN6QywyQkFBTyxHQUFQO0FBQ0EsMkJBQU8sS0FBSyxNQUFMLEdBQWMsQ0FBZCxHQUFrQixDQUF6QjtBQUNILGlCQUhNLE1BR0EsSUFBSSxPQUFPLEtBQUssTUFBWixLQUF1QixRQUEzQixFQUFxQztBQUN4QywyQkFBTyxLQUFLLE1BQVo7QUFDSCxpQkFGTSxNQUVBLElBQUksS0FBSyxNQUFMLFlBQXVCLElBQTNCLEVBQWlDO0FBQ3BDLDJCQUFPLGNBQWMsWUFBZCxDQUEyQixLQUFLLE1BQWhDLENBQVA7QUFDSCxpQkFGTSxNQUVBLElBQUksS0FBSyxNQUFMLFlBQXVCLFFBQXZCLElBQW1DLFFBQU8sS0FBSyxNQUFaLE1BQXVCLFFBQXZCLElBQW1DLEtBQUssTUFBTCxDQUFZLFdBQVosQ0FBd0IsSUFBeEIsS0FBaUMsVUFBM0csRUFBdUg7QUFBRTtBQUM1SCwyQkFBTyxHQUFQO0FBQ0EsMkJBQU8sS0FBSyxRQUFMLEdBQWdCLGFBQWhCLEdBQWdDLGlCQUFoQyxDQUFrRCxLQUFLLE1BQUwsQ0FBWSxLQUFaLEVBQWxELENBQVA7QUFDSDs7QUFFRCxvQkFBSSxJQUFKLEVBQVUsS0FBSyxVQUFMLENBQWdCLENBQWhCLEdBQW9CLElBQXBCO0FBQ1Ysb0JBQU0sUUFBUSxFQUFFLE1BQU0sR0FBUixFQUFhLFVBQVUsQ0FBQyxJQUFELENBQXZCLEVBQWQ7QUFDQSxxQkFBSyxRQUFMLENBQWMsSUFBZCxDQUFtQixLQUFuQjtBQUNIOztBQUVEO0FBQ0EsZ0JBQUksQ0FBQyxFQUFFLEtBQUYsQ0FBUSxLQUFLLE1BQWIsQ0FBTCxFQUEyQjtBQUN2QixxQkFBSyxVQUFMLENBQWdCLENBQWhCLEdBQW9CLEtBQUssTUFBTCxDQUFZLEVBQVosRUFBcEI7QUFDSCxhQUZELE1BRU8sSUFBSSxDQUFDLEVBQUUsS0FBRixDQUFRLEtBQUssUUFBYixDQUFMLEVBQTZCO0FBQ2hDLHFCQUFLLFVBQUwsQ0FBZ0IsQ0FBaEIsR0FBb0IsS0FBSyxRQUF6QjtBQUNIOztBQUVEO0FBQ0EsZ0JBQUksS0FBSyxrQkFBVCxFQUE2QjtBQUN6QixxQkFBSyxRQUFMLEdBQWdCLEtBQUssUUFBTCxDQUFjLE1BQWQsQ0FBcUIsS0FBSyxrQkFBMUIsQ0FBaEI7QUFDSDs7QUFFRCxtQkFBTyxJQUFQO0FBQ0g7O0FBRUQ7O0FBRUE7Ozs7Ozs7Ozs7OEJBT00sa0IsRUFBb0IsTyxFQUFTO0FBQy9CLGdCQUFJLEVBQUUsUUFBRixDQUFXLGtCQUFYLENBQUosRUFBb0M7QUFDaEM7QUFDQSxxQkFBSyxVQUFMLENBQWdCLGtCQUFoQjtBQUNILGFBSEQsTUFHTztBQUNIO0FBQ0EscUJBQUssYUFBTCxHQUFxQixrQkFBckI7QUFDQSxvQkFBSSxDQUFDLEVBQUUsS0FBRixDQUFRLE9BQVIsQ0FBTCxFQUF1QixLQUFLLFFBQUwsR0FBZ0IsT0FBaEI7QUFDMUI7QUFDSjs7QUFFRDs7Ozs7Ozs7O21DQU1XLEksRUFBTTtBQUNiO0FBQ0EsZ0JBQU0sTUFBTSxpQkFBaUIsV0FBakIsQ0FBNkIsS0FBSyxVQUFMLENBQWdCLENBQTdDLENBQVo7QUFDQSxpQkFBSyxhQUFMLEdBQXFCLElBQUksWUFBekI7O0FBRUE7QUFDQSxnQkFBSSxDQUFDLEVBQUUsS0FBRixDQUFRLEtBQUssVUFBTCxDQUFnQixDQUF4QixDQUFMLEVBQWlDLEtBQUssUUFBTCxHQUFnQixLQUFLLFVBQUwsQ0FBZ0IsQ0FBaEM7O0FBRWpDO0FBQ0EsZ0JBQU0sUUFBUSxLQUFLLFNBQUwsQ0FBZSxJQUFmLEVBQXFCLEdBQXJCLENBQWQ7QUFDQSxnQkFBSSxLQUFKLEVBQVc7QUFDUCxxQkFBSyxZQUFMLEdBQW9CLE1BQU0sVUFBTixDQUFpQixDQUFqQixJQUFzQixRQUExQztBQUNBLHFCQUFLLFdBQUwsR0FBbUIsTUFBTSxVQUFOLENBQWlCLEdBQXBDO0FBQ0EscUJBQUssUUFBTCxHQUFnQixNQUFNLFFBQU4sQ0FBZSxDQUFmLENBQWhCOztBQUVBLHFCQUFLLGdCQUFMLEdBQXdCLE1BQU0sVUFBTixDQUFpQixFQUF6QztBQUNBLG9CQUFJLENBQUMsRUFBRSxLQUFGLENBQVEsS0FBSyxnQkFBYixDQUFMLEVBQXFDO0FBQ2pDO0FBQ0EseUJBQUssS0FBTCxHQUFhLHdCQUFiLENBQXNDLEtBQUssZ0JBQTNDO0FBQ0g7O0FBRUQ7QUFDQSx1QkFBTyxNQUFNLFVBQU4sQ0FBaUIsQ0FBeEI7QUFDQSx1QkFBTyxNQUFNLFVBQU4sQ0FBaUIsR0FBeEI7QUFDQSx1QkFBTyxNQUFNLFVBQU4sQ0FBaUIsRUFBeEI7O0FBRUE7QUFDQSxvQkFBSSxDQUFDLEVBQUUsT0FBRixDQUFVLE1BQU0sVUFBaEIsQ0FBTCxFQUFrQyxLQUFLLDJCQUFMLEdBQW1DLE1BQU0sVUFBekM7QUFDckM7O0FBRUQ7QUFDQSxnQkFBTSxPQUFPLEtBQUssVUFBTCxDQUFnQixDQUE3QjtBQUNBLGdCQUFJLFNBQVMsR0FBYixFQUFrQjtBQUNkO0FBQ0Esb0JBQU0sUUFBUSxLQUFLLFNBQUwsQ0FBZSxJQUFmLEVBQXFCLEdBQXJCLENBQWQ7QUFDQSxvQkFBSSxLQUFKLEVBQVc7QUFDUCx3QkFBTSxjQUFjLE1BQU0sUUFBTixDQUFlLENBQWYsQ0FBcEI7QUFDQSx5QkFBSyxNQUFMLEdBQWMsS0FBSyxRQUFMLEdBQWdCLGFBQWhCLEdBQWdDLGdCQUFoQyxDQUFpRCxXQUFqRCxDQUFkOztBQUVBO0FBQ0Esd0JBQUksRUFBRSxPQUFGLENBQVUsS0FBSyxNQUFmLENBQUosRUFBNEI7QUFDeEIsNkJBQUssTUFBTCxHQUFjLElBQUksUUFBSixDQUFhLEtBQUssTUFBbEIsQ0FBZDtBQUNIO0FBQ0osaUJBUkQsTUFRTztBQUNILHlCQUFLLE1BQUwsR0FBYyxFQUFkO0FBQ0g7QUFDSixhQWRELE1BY08sSUFBSSxTQUFTLEtBQWIsRUFBb0I7QUFDdkI7QUFDQSxvQkFBTSxTQUFRLEtBQUssU0FBTCxDQUFlLElBQWYsRUFBcUIsR0FBckIsQ0FBZDtBQUNBLHFCQUFLLE1BQUwsR0FBYyxVQUFTLE9BQU0sUUFBTixDQUFlLENBQWYsQ0FBdkI7QUFDSCxhQUpNLE1BSUEsSUFBSSxTQUFTLFdBQWIsRUFBMEI7QUFDN0I7QUFDQSxvQkFBTSxTQUFTLEtBQUssU0FBTCxDQUFlLElBQWYsRUFBcUIsSUFBckIsQ0FBZjtBQUNBLG9CQUFJLE9BQU8sUUFBUCxDQUFnQixDQUFoQixFQUFtQixJQUFuQixLQUE0QixHQUFoQyxFQUFxQztBQUNqQyx3QkFBTSxRQUFRLE9BQU8sUUFBUCxDQUFnQixDQUFoQixDQUFkO0FBQ0EseUJBQUssTUFBTCxHQUFjLE1BQU0sUUFBTixDQUFlLENBQWYsQ0FBZDtBQUNILGlCQUhELE1BR087QUFDSCx5QkFBSyxNQUFMLEdBQWMsT0FBTyxRQUFyQjtBQUNIO0FBQ0osYUFUTSxNQVNBLElBQUksU0FBUyxHQUFiLEVBQWtCO0FBQ3JCO0FBQ0EscUJBQUssTUFBTCxHQUFjLEtBQUssU0FBTCxDQUFlLElBQWYsRUFBcUIsR0FBckIsRUFBMEIsUUFBMUIsQ0FBbUMsQ0FBbkMsTUFBMEMsQ0FBeEQ7QUFDSCxhQUhNLE1BR0EsSUFBSSxTQUFTLEdBQWIsRUFBa0I7QUFDckI7QUFDQSxvQkFBTSxRQUFRLEtBQUssU0FBTCxDQUFlLElBQWYsRUFBcUIsR0FBckIsRUFBMEIsUUFBMUIsQ0FBbUMsQ0FBbkMsQ0FBZDtBQUNBLHFCQUFLLE1BQUwsR0FBYyxhQUFhLFFBQWIsQ0FBc0IsS0FBdEIsQ0FBZDtBQUNILGFBSk0sTUFJQTtBQUNIO0FBQ0Esb0JBQU0sVUFBUSxLQUFLLFNBQUwsQ0FBZSxJQUFmLEVBQXFCLEdBQXJCLENBQWQ7QUFDQSxxQkFBSyxNQUFMLEdBQWMsV0FBUyxPQUFPLFFBQU0sUUFBTixDQUFlLENBQWYsQ0FBUCxDQUF2QjtBQUNIOztBQUVEO0FBQ0EsbUJBQU8sS0FBSyxVQUFMLENBQWdCLENBQXZCO0FBQ0EsbUJBQU8sS0FBSyxVQUFMLENBQWdCLENBQXZCO0FBQ0EsbUJBQU8sS0FBSyxVQUFMLENBQWdCLENBQXZCOztBQUVBO0FBQ0EsZ0JBQUksQ0FBQyxFQUFFLE9BQUYsQ0FBVSxLQUFLLFVBQWYsQ0FBTCxFQUFpQyxLQUFLLG9CQUFMLEdBQTRCLEtBQUssVUFBakM7O0FBRWpDO0FBQ0EsaUJBQUssV0FBTCxDQUFpQixJQUFqQixFQUF1QixHQUF2QjtBQUNBLGlCQUFLLFdBQUwsQ0FBaUIsSUFBakIsRUFBdUIsR0FBdkI7QUFDQSxpQkFBSyxXQUFMLENBQWlCLElBQWpCLEVBQXVCLElBQXZCOztBQUVBO0FBQ0EsZ0JBQUksQ0FBQyxFQUFFLE9BQUYsQ0FBVSxLQUFLLFFBQWYsQ0FBTCxFQUErQixLQUFLLGtCQUFMLEdBQTBCLEtBQUssUUFBL0I7QUFDbEM7Ozs7OztBQUdMLE9BQU8sT0FBUCxHQUFpQixJQUFqQjs7QUFFQTs7Ozs7OztBQ3RvQkE7Ozs7OztBQUVBLElBQU0sYUFBYSxRQUFRLGNBQVIsQ0FBbkI7QUFDQSxJQUFNLG1CQUFtQixRQUFRLG9CQUFSLENBQXpCOztBQUVBO0FBQ0EsSUFBTSxxQkFBcUIsUUFBM0I7O0FBRUE7Ozs7SUFHTSxNO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFZLEtBQVosRUFBbUIsSUFBbkIsRUFBeUI7QUFBQTs7QUFDckIsYUFBSyxNQUFMLEdBQWMsS0FBZDtBQUNBLGFBQUssS0FBTCxHQUFhLElBQWI7QUFDSDs7QUFFRDs7QUFFQTs7Ozs7Ozs7Ozs7Z0NBT1EsSSxFQUFNO0FBQ1YsbUJBQU8saUJBQWlCLFNBQWpCLENBQTJCO0FBQzlCLHNCQUFNLFFBRHdCO0FBRTlCLDRCQUFZLEtBQUssVUFBTCxFQUZrQjtBQUc5QiwyQkFBVyxRQUFRLEtBQUssZ0JBQWIsSUFBaUMsS0FBSyxLQUFMLEdBQWEsSUFBYixFQUhkO0FBSTlCLGdDQUFnQixRQUFRLEtBQUs7QUFKQyxhQUEzQixDQUFQO0FBTUg7O0FBRUQ7Ozs7Ozs7OzZCQUtLLFMsRUFBVztBQUNaLG1CQUFPLEtBQUssS0FBTCxHQUFhLElBQWIsQ0FBa0IsU0FBbEIsRUFBNkIsS0FBSyxZQUFMLEVBQTdCLENBQVA7QUFDSDs7QUFFRDs7Ozs7OztxQ0FJYTtBQUNULG1CQUFPLGlCQUFpQixrQkFBakIsQ0FBb0MsS0FBSyxZQUFMLEVBQXBDLENBQVA7QUFDSDs7QUFFRDs7Ozs7Ozt1Q0FJZTtBQUNYLG1CQUFPLEtBQUssS0FBTCxDQUFXLFVBQVgsQ0FBc0IsR0FBN0I7QUFDSDs7QUFFRDs7O1lBR0c7Ozs7Ozs7O2lDQUtNO0FBQUE7O0FBQ0wsbUJBQU8sSUFBSSxVQUFKLENBQWUsZUFBZixFQUNGLElBREUsQ0FDRyxZQUFNO0FBQ1IsdUJBQU8sTUFBSyxLQUFMLENBQVcsVUFBWCxDQUFzQixNQUF0QixLQUFpQyxDQUF4QztBQUNILGFBSEUsRUFJRixJQUpFLENBSUcsU0FKSCxFQUljLGtCQUFVO0FBQ3ZCLG9CQUFJLE1BQUosRUFBWSxNQUFLLEtBQUwsQ0FBVyxVQUFYLENBQXNCLE1BQXRCLEdBQStCLENBQS9CLENBQVosS0FDSyxPQUFPLE1BQUssS0FBTCxDQUFXLFVBQVgsQ0FBc0IsTUFBN0I7QUFDTCx1QkFBTyxLQUFQO0FBQ0gsYUFSRSxFQVNGLE1BVEUsQ0FTSyxTQVRMLENBQVA7QUFVSDs7QUFFRDs7Ozs7OztnQ0FJUTtBQUNKLG1CQUFPLEtBQUssTUFBWjtBQUNIOztBQUVEOzs7O1lBSUc7Ozs7ZUFJQTs7Ozs7a0JBS0E7Ozs7cUJBSUE7Ozs7Ozs7O2dDQUtLO0FBQUE7O0FBQ0osbUJBQU8sSUFBSSxVQUFKLENBQWUsY0FBZixFQUNGLElBREUsQ0FDRyxRQURILEVBQ2EsZ0JBQVE7QUFDcEI7QUFDQSx1QkFBSyxvQkFBTDtBQUNBLHVCQUFPLE9BQUssTUFBTCxDQUFZLEtBQVosQ0FBa0IsSUFBbEIsQ0FBUDtBQUNILGFBTEUsRUFNRixJQU5FLENBTUcsT0FOSCxFQU1ZLGlCQUFTO0FBQ3BCO0FBQ0Esb0JBQU0sU0FBUyxFQUFmO0FBQ0Esc0JBQU0sT0FBTixDQUFjLGdCQUFRO0FBQ2xCLDJCQUFPLElBQVAsSUFBZSxPQUFLLEtBQUwsQ0FBVyxJQUFYLENBQWY7QUFDSCxpQkFGRDs7QUFJQSx1QkFBTyxNQUFQO0FBQ0gsYUFkRSxFQWVGLElBZkUsQ0FlRyxDQUFDLFFBQUQsRUFBVyxHQUFYLENBZkgsRUFlb0IsVUFBQyxJQUFELEVBQU8sS0FBUCxFQUFpQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQUssS0FBTCxHQUFhLGtCQUFiLENBQWdDLGVBQU87QUFDbkMsd0JBQUksSUFBSSxRQUFKLE1BQWtCLElBQUksT0FBSixDQUFZLE9BQUssWUFBTCxFQUFaLENBQXRCLEVBQXdEO0FBQ3BELDRCQUFJLElBQUosQ0FBUyxPQUFLLFlBQUwsRUFBVCxFQUE4QixLQUE5QixDQUFvQyxJQUFwQyxFQUEwQyxLQUExQztBQUNIO0FBQ0osaUJBSkQ7O0FBTUE7QUFDQSx1QkFBSyxvQkFBTDtBQUNBLHVCQUFLLE1BQUwsQ0FBWSxLQUFaLENBQWtCLElBQWxCLEVBQXdCLEtBQXhCOztBQUVBLHVCQUFPLE1BQVA7QUFDSCxhQWhDRSxFQWlDRixJQWpDRSxDQWlDRyxRQWpDSCxFQWlDYSxzQkFBYztBQUMxQjtBQUNBLHFCQUFLLElBQU0sSUFBWCxJQUFtQixVQUFuQixFQUErQjtBQUMzQix3QkFBSSxDQUFDLFdBQVcsY0FBWCxDQUEwQixJQUExQixDQUFMLEVBQXNDO0FBQ3RDLHdCQUFNLFFBQVEsV0FBVyxJQUFYLENBQWQ7QUFDQSwyQkFBSyxLQUFMLENBQVcsSUFBWCxFQUFpQixLQUFqQjtBQUNIOztBQUVELHVCQUFPLE1BQVA7QUFDSCxhQTFDRSxFQTJDRixJQTNDRSxDQTJDRyxPQTNDSCxFQTJDWSxpQkFBUztBQUNwQjtBQUNBLHVCQUFLLEtBQUwsR0FBYSxrQkFBYixDQUFnQyxlQUFPO0FBQ25DLHdCQUFJLElBQUksUUFBSixNQUFrQixJQUFJLE9BQUosQ0FBWSxPQUFLLFlBQUwsRUFBWixDQUF0QixFQUF3RDtBQUNwRCw0QkFBSSxJQUFKLENBQVMsT0FBSyxZQUFMLEVBQVQsRUFBOEIsS0FBOUIsQ0FBb0MsS0FBcEM7QUFDSDtBQUNKLGlCQUpEOztBQU1BLHVCQUFLLE1BQUwsR0FBYyxLQUFkO0FBQ0EsdUJBQUssS0FBTCxDQUFXLFVBQVgsQ0FBc0IsS0FBdEIsR0FBOEIsTUFBTSxFQUFOLEVBQTlCOztBQUVBLHVCQUFPLE1BQVA7QUFDSCxhQXZERSxFQXdERixNQXhERSxDQXdESyxTQXhETCxDQUFQO0FBeURIOztBQUVEOzs7WUFHRzs7Ozs7Ozs7OEJBS0csTSxFQUFPO0FBQUE7O0FBQ1QsbUJBQU8sSUFBSSxVQUFKLENBQWUsY0FBZixFQUNGLElBREUsQ0FDRyxZQUFNO0FBQ1IsdUJBQU8sT0FBSyxLQUFMLENBQVcsVUFBWCxDQUFzQixXQUF0QixHQUFvQyxPQUFLLEtBQUwsQ0FBVyxVQUFYLENBQXNCLEtBQTFELEdBQWtFLFNBQXpFO0FBQ0gsYUFIRSxFQUlGLElBSkUsQ0FJRyxRQUpILEVBSWEsaUJBQVM7QUFDckIsdUJBQUssS0FBTCxDQUFXLFVBQVgsQ0FBc0IsS0FBdEIsR0FBOEIsS0FBOUI7QUFDQSx1QkFBSyxLQUFMLENBQVcsVUFBWCxDQUFzQixXQUF0QixHQUFvQyxDQUFwQztBQUNBLHVCQUFPLE1BQVA7QUFDSCxhQVJFLEVBU0YsSUFURSxDQVNHLEtBVEgsRUFTVSxZQUFNO0FBQ2YsdUJBQU8sT0FBSyxLQUFMLENBQVcsVUFBWCxDQUFzQixLQUE3QjtBQUNBLHVCQUFPLE9BQUssS0FBTCxDQUFXLFVBQVgsQ0FBc0IsV0FBN0I7QUFDQSx1QkFBTyxNQUFQO0FBQ0gsYUFiRSxFQWNGLE1BZEUsQ0FjSyxTQWRMLENBQVA7QUFlSDs7QUFFRDs7Ozs7OzttQ0FJVztBQUNQLG1CQUFPLEtBQUssS0FBTCxHQUFhLFFBQWIsRUFBUDtBQUNIOztBQUVEOzs7Ozs7O3VDQUllO0FBQ1gsaUJBQUssS0FBTCxHQUFhLGtCQUFiLEdBQWtDLEdBQWxDLENBQXNDLEtBQUssWUFBTCxFQUF0QztBQUNBLG1CQUFPLElBQVA7QUFDSDs7QUFFRDs7QUFFQTs7Ozs7Ozs7Z0NBS1E7QUFDSixtQkFBTyxLQUFLLEtBQVo7QUFDSDs7QUFFRDs7QUFFQTs7Ozs7Ozs7K0NBS3VCO0FBQ25CLGdCQUFJLENBQUMsS0FBSyxNQUFWLEVBQWtCO0FBQ2Qsb0JBQU0sVUFBVSxLQUFLLEtBQUwsQ0FBVyxVQUFYLENBQXNCLEtBQXRDO0FBQ0EscUJBQUssTUFBTCxHQUFjLEtBQUssUUFBTCxHQUFnQixVQUFoQixHQUE2QixXQUE3QixDQUF5QyxPQUF6QyxDQUFkO0FBQ0EscUJBQUssS0FBTCxDQUFXLFVBQVgsQ0FBc0IsS0FBdEIsR0FBOEIsS0FBSyxNQUFMLENBQVksRUFBWixFQUE5Qjs7QUFFQSxvQkFBSSxDQUFDLEtBQUssS0FBTCxFQUFMLEVBQW1CLEtBQUssS0FBTCxDQUFXLGtCQUFYO0FBQ3RCO0FBQ0o7Ozs7OztBQUdMLE9BQU8sT0FBUCxHQUFpQixNQUFqQjs7O0FDM1BBOzs7Ozs7QUFFQSxJQUFNLElBQUksUUFBUSxRQUFSLENBQVY7O0FBRUE7Ozs7O0lBSU0sWTtBQUNGOzs7O0FBSUEsMEJBQVksSUFBWixFQUFrQjtBQUFBOztBQUNkLGFBQUssS0FBTCxHQUFhLElBQWI7QUFDSDs7QUFFRDs7Ozs7Ozs7Ozs0QkFNSSxRLEVBQVUsVyxFQUFhO0FBQ3ZCLGdCQUFNLE9BQU87QUFDVCxzQkFBTSxVQURHO0FBRVQsNEJBQVk7QUFDUiw4QkFBVSxRQURGO0FBRVIsaUNBQWE7QUFGTDtBQUZILGFBQWI7O0FBUUEsaUJBQUssS0FBTCxDQUFXLFFBQVgsQ0FBb0IsSUFBcEIsQ0FBeUIsSUFBekI7QUFDQSxtQkFBTyxJQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7O3VDQUtlLFEsRUFBVTtBQUNyQixtQkFBTyxFQUFFLElBQUYsQ0FBTyxLQUFLLEtBQUwsQ0FBVyxRQUFsQixFQUE0QjtBQUFBLHVCQUFRLEtBQUssVUFBTCxDQUFnQixRQUFoQixLQUE2QixRQUFyQztBQUFBLGFBQTVCLENBQVA7QUFDSDs7QUFFRDs7Ozs7OztnQ0FJUTtBQUNKLG1CQUFPLEtBQUssS0FBWjtBQUNIOzs7Ozs7QUFHTCxPQUFPLE9BQVAsR0FBaUIsWUFBakI7O0FBRUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDeERBOzs7Ozs7QUFFQSxJQUFNLG9CQUFvQjtBQUN0QixXQUFPLFVBRGU7QUFFdEIsYUFBUyxZQUZhO0FBR3RCLFlBQVEsWUFIYztBQUl0QixhQUFTLFlBSmE7QUFLdEIsaUJBQWEsZ0JBTFM7QUFNdEIsY0FBVSxhQU5ZO0FBT3RCLGNBQVU7QUFQWSxDQUExQjs7QUFVQTs7Ozs7SUFJTSxjO0FBQ0YsNEJBQVksSUFBWixFQUFrQjtBQUFBOztBQUNkLGFBQUssS0FBTCxHQUFhLElBQWI7QUFDQSxhQUFLLFdBQUwsR0FBbUIsRUFBbkI7QUFDSDs7QUFFRDs7Ozs7Ozs7Ozs0QkFNSSxJLEVBQU0sSyxFQUFPO0FBQ2IsZ0JBQU0sTUFBTSxLQUFLLFdBQUwsRUFBWjs7QUFFQSxnQkFBSSxPQUFPLGtCQUFrQixHQUFsQixDQUFQLEtBQWtDLFdBQXRDLEVBQW1EO0FBQy9DLHNCQUFNLElBQUksS0FBSiwrQkFBcUMsSUFBckMsUUFBTjtBQUNIOztBQUVELGlCQUFLLFdBQUwsQ0FBaUIsR0FBakIsSUFBd0IsS0FBeEI7O0FBRUEsbUJBQU8sSUFBUDtBQUNIOztBQUVEOzs7Ozs7Ozs0QkFLSSxJLEVBQU07QUFDTixnQkFBTSxNQUFNLEtBQUssV0FBTCxFQUFaOztBQUVBLGdCQUFJLE9BQU8sa0JBQWtCLEdBQWxCLENBQVAsS0FBa0MsV0FBdEMsRUFBbUQ7QUFDL0Msc0JBQU0sSUFBSSxLQUFKLCtCQUFxQyxJQUFyQyxRQUFOO0FBQ0g7O0FBRUQsbUJBQU8sS0FBSyxXQUFMLENBQWlCLEdBQWpCLENBQVA7QUFDSDs7QUFFRDs7Ozs7OztnQ0FJUTtBQUNKLGlCQUFLLElBQU0sR0FBWCxJQUFrQixLQUFLLFdBQXZCLEVBQW9DO0FBQ2hDLG9CQUFJLENBQUMsS0FBSyxXQUFMLENBQWlCLGNBQWpCLENBQWdDLEdBQWhDLENBQUwsRUFBMkM7QUFDM0MscUJBQUssS0FBTCxDQUFXLFFBQVgsQ0FBb0IsSUFBcEIsQ0FBeUI7QUFDckIsMEJBQU0sa0JBQWtCLEdBQWxCLENBRGU7QUFFckIsOEJBQVUsQ0FBQyxLQUFLLFdBQUwsQ0FBaUIsR0FBakIsQ0FBRDtBQUZXLGlCQUF6QjtBQUlIOztBQUVELG1CQUFPLEtBQUssS0FBWjtBQUNIOzs7Ozs7QUFHTCxPQUFPLE9BQVAsR0FBaUIsY0FBakI7O0FBRUE7Ozs7Ozs7Ozs7Ozs7Ozs7QUMxRUE7O0FBRUE7Ozs7Ozs7Ozs7OztBQVFBLElBQU0sSUFBSSxRQUFRLFFBQVIsQ0FBVjtBQUNBLElBQU0sTUFBTSxRQUFRLEtBQVIsQ0FBWjtBQUNBLElBQU0sU0FBUyxRQUFRLFFBQVIsQ0FBZjtBQUNBLElBQU0sWUFBWSxRQUFRLGFBQVIsQ0FBbEI7QUFDQSxJQUFNLFlBQVksUUFBUSxhQUFSLENBQWxCO0FBQ0EsSUFBTSxhQUFhLFFBQVEsY0FBUixDQUFuQjtBQUNBLElBQU0sT0FBTyxRQUFRLFFBQVIsQ0FBYjs7QUFFQSxJQUFNLHlCQUF5QixPQUFPLElBQVAsQ0FBWSxDQUFDLElBQUQsRUFBTyxJQUFQLEVBQWEsSUFBYixFQUFtQixJQUFuQixFQUF5QixJQUF6QixFQUErQixJQUEvQixFQUFxQyxJQUFyQyxFQUEyQyxJQUEzQyxDQUFaLENBQS9CLEMsQ0FBOEY7QUFDOUYsSUFBTSxnQ0FBZ0MsSUFBdEM7QUFDQSxJQUFNLGlCQUFpQixDQUF2QixDLENBQTBCOztBQUUxQjtBQUNBLElBQU0sYUFBYTtBQUNmLG1CQUFlO0FBQ1gsaUJBQVMsT0FBTyxJQUFQLENBQVksQ0FBQyxJQUFELEVBQU8sSUFBUCxFQUFhLElBQWIsRUFBbUIsSUFBbkIsRUFBeUIsSUFBekIsRUFBK0IsSUFBL0IsRUFBcUMsSUFBckMsRUFBMkMsSUFBM0MsQ0FBWixDQURFO0FBRVgsbUJBQVcsT0FBTyxJQUFQLENBQVksQ0FBQyxJQUFELEVBQU8sSUFBUCxFQUFhLElBQWIsRUFBbUIsSUFBbkIsRUFBeUIsSUFBekIsRUFBK0IsSUFBL0IsRUFBcUMsSUFBckMsRUFBMkMsSUFBM0MsQ0FBWjtBQUZBLEtBREE7QUFLZixTQUFLLE9BQU8sSUFBUCxDQUFZLENBQUMsSUFBRCxFQUFPLElBQVAsRUFBYSxJQUFiLEVBQW1CLElBQW5CLEVBQXlCLElBQXpCLEVBQStCLElBQS9CLEVBQXFDLElBQXJDLEVBQTJDLElBQTNDLENBQVosQ0FMVTtBQU1mLGtCQUFjO0FBQ1YsZUFBTyxPQUFPLElBQVAsQ0FBWSxDQUFDLElBQUQsRUFBTyxJQUFQLEVBQWEsSUFBYixFQUFtQixJQUFuQixFQUF5QixJQUF6QixFQUErQixJQUEvQixFQUFxQyxJQUFyQyxFQUEyQyxJQUEzQyxDQUFaLENBREc7QUFFVixlQUFPLE9BQU8sSUFBUCxDQUFZLENBQUMsSUFBRCxFQUFPLElBQVAsRUFBYSxJQUFiLEVBQW1CLElBQW5CLEVBQXlCLElBQXpCLEVBQStCLElBQS9CLEVBQXFDLElBQXJDLEVBQTJDLElBQTNDLENBQVo7QUFGRztBQU5DLENBQW5COztBQVlBOzs7OztJQUlNLFM7Ozs7Ozs7O0FBQ0Y7Ozs7OztnQ0FNUSxJLEVBQU0sUSxFQUFVO0FBQ3BCO0FBQ0E7QUFDQSxnQkFBTSxhQUFhLE9BQU8sV0FBUCxDQUFtQixFQUFuQixDQUFuQjs7QUFFQTtBQUNBLGdCQUFNLGlCQUFpQjtBQUNuQix5QkFBUyxFQUFFO0FBQ1AscUNBQWlCLEtBRFosRUFDbUI7QUFDeEIsb0NBQWdCLGlCQUZYLEVBRThCO0FBQ25DLCtCQUFXLE9BQU8sV0FBUCxDQUFtQixFQUFuQixDQUhOLEVBRzhCO0FBQ25DLG1DQUFlLFFBSlYsRUFJb0I7QUFDekIsOEJBQVUsRUFMTCxFQUtTO0FBQ2QsK0JBQVcsRUFOTixFQU1VO0FBQ2YsNkJBQVMsV0FBVyxNQUFYLEdBQW9CLENBUHhCLENBTzBCO0FBUDFCLGlCQURVO0FBVW5CLHFCQUFLLEVBQUU7QUFDSCxxQ0FBaUIsS0FEaEIsRUFDdUI7QUFDeEIsb0NBQWdCLGlCQUZmLEVBRWtDO0FBQ25DLCtCQUFXLE9BQU8sV0FBUCxDQUFtQixFQUFuQixDQUhWLEVBR2tDO0FBQ25DLG1DQUFlLFFBSmQsRUFJd0I7QUFDekIsOEJBQVUsRUFMVCxFQUthO0FBQ2QsK0JBQVcsRUFOVixFQU1jO0FBQ2YsK0JBQVcsTUFQVixFQU9rQjtBQUNuQiw2QkFBUyxHQVJSLENBUVk7QUFSWjtBQVZjLGFBQXZCOztBQXNCQTs7QUFFQTtBQUNBLGdCQUFNLG1CQUFtQixLQUFLLGFBQUwsQ0FDckIsSUFEcUIsRUFFckIsZUFBZSxPQUFmLENBQXVCLGVBRkYsRUFHckIsZUFBZSxPQUFmLENBQXVCLGNBSEYsRUFJckIsZUFBZSxPQUFmLENBQXVCLGFBSkYsRUFLckIsZUFBZSxPQUFmLENBQXVCLFNBTEYsRUFNckIsZUFBZSxPQUFmLENBQXVCLFNBTkYsRUFPckIsVUFQcUIsRUFRckIsSUFScUIsQ0FBekI7O0FBV0E7O0FBRUE7QUFDQTtBQUNBLGdCQUFNLFVBQVUsT0FBTyxXQUFQLENBQW1CLEVBQW5CLENBQWhCOztBQUVBO0FBQ0EsZ0JBQU0sWUFBWSxLQUFLLFNBQUwsQ0FDZCxlQUFlLE9BQWYsQ0FBdUIsYUFEVCxFQUVkLGVBQWUsT0FBZixDQUF1QixTQUZULEVBR2QsZUFBZSxPQUFmLENBQXVCLFNBSFQsRUFJZCxXQUFXLGFBQVgsQ0FBeUIsT0FKWCxDQUFsQjs7QUFPQTtBQUNBLGdCQUFNLG1CQUFtQixLQUFLLE1BQUwsQ0FDckIsSUFEcUIsRUFFckIsZUFBZSxPQUFmLENBQXVCLGVBRkYsRUFHckIsZUFBZSxPQUFmLENBQXVCLGNBSEYsRUFJckIsVUFKcUIsRUFLckIsU0FMcUIsRUFNckIsT0FOcUIsQ0FBekI7O0FBUUE7QUFDQSxnQkFBTSxZQUFZLEtBQUssS0FBTCxDQUFXLGVBQWUsT0FBZixDQUF1QixhQUFsQyxFQUFpRCxPQUFqRCxFQUEwRCxnQkFBMUQsQ0FBbEI7O0FBRUE7QUFDQSxnQkFBTSxjQUFjLEtBQUssU0FBTCxDQUNoQixlQUFlLE9BQWYsQ0FBdUIsYUFEUCxFQUVoQixlQUFlLE9BQWYsQ0FBdUIsU0FGUCxFQUdoQixlQUFlLE9BQWYsQ0FBdUIsU0FIUCxFQUloQixXQUFXLGFBQVgsQ0FBeUIsU0FKVCxDQUFwQjs7QUFPQTtBQUNBLGdCQUFNLHFCQUFxQixLQUFLLE1BQUwsQ0FDdkIsSUFEdUIsRUFFdkIsZUFBZSxPQUFmLENBQXVCLGVBRkEsRUFHdkIsZUFBZSxPQUFmLENBQXVCLGNBSEEsRUFJdkIsVUFKdUIsRUFLdkIsV0FMdUIsRUFNdkIsU0FOdUIsQ0FBM0I7O0FBU0E7QUFDQSwyQkFBZSxhQUFmLEdBQStCO0FBQzNCLGtEQUQyQjtBQUUzQjtBQUYyQixhQUEvQjs7QUFLQTs7QUFFQTtBQUNBLGdCQUFNLE1BQU0sS0FBSyxxQkFBTCxDQUNSLFFBRFEsRUFFUixlQUFlLEdBQWYsQ0FBbUIsYUFGWCxFQUdSLGVBQWUsR0FBZixDQUFtQixTQUhYLEVBSVIsZUFBZSxHQUFmLENBQW1CLFNBSlgsRUFLUixlQUFlLEdBQWYsQ0FBbUIsT0FMWCxFQU1SLFdBQVcsR0FOSCxDQUFaOztBQVNBO0FBQ0EsMkJBQWUsR0FBZixDQUFtQixpQkFBbkIsR0FBdUMsS0FBSyxNQUFMLENBQ25DLElBRG1DLEVBRW5DLGVBQWUsR0FBZixDQUFtQixlQUZnQixFQUduQyxlQUFlLEdBQWYsQ0FBbUIsY0FIZ0IsRUFJbkMsR0FKbUMsRUFLbkMsZUFBZSxHQUFmLENBQW1CLFNBTGdCLEVBTW5DLFVBTm1DLENBQXZDOztBQVFBOztBQUVBO0FBQ0EsZ0JBQU0sb0JBQW9CLE9BQU8sV0FBUCxDQUFtQixFQUFuQixDQUExQjs7QUFFQTtBQUNBLGdCQUFNLHVCQUF1QixLQUFLLHFCQUFMLENBQ3pCLFFBRHlCLEVBRXpCLGVBQWUsR0FBZixDQUFtQixhQUZNLEVBR3pCLGVBQWUsR0FBZixDQUFtQixTQUhNLEVBSXpCLGVBQWUsR0FBZixDQUFtQixTQUpNLEVBS3pCLGVBQWUsR0FBZixDQUFtQixPQUxNLEVBTXpCLFdBQVcsWUFBWCxDQUF3QixLQU5DLENBQTdCOztBQVNBO0FBQ0EsMkJBQWUsR0FBZixDQUFtQiwwQkFBbkIsR0FBZ0QsS0FBSyxNQUFMLENBQzVDLElBRDRDLEVBRTVDLGVBQWUsR0FBZixDQUFtQixlQUZ5QixFQUc1QyxlQUFlLEdBQWYsQ0FBbUIsY0FIeUIsRUFJNUMsb0JBSjRDLEVBSzVDLGVBQWUsR0FBZixDQUFtQixTQUx5QixFQU01QyxpQkFONEMsQ0FBaEQ7O0FBU0E7QUFDQSxnQkFBTSxvQkFBb0IsS0FBSyxLQUFMLENBQVcsZUFBZSxHQUFmLENBQW1CLGFBQTlCLEVBQTZDLGlCQUE3QyxDQUExQjs7QUFFQTtBQUNBLGdCQUFNLHVCQUF1QixLQUFLLHFCQUFMLENBQ3pCLFFBRHlCLEVBRXpCLGVBQWUsR0FBZixDQUFtQixhQUZNLEVBR3pCLGVBQWUsR0FBZixDQUFtQixTQUhNLEVBSXpCLGVBQWUsR0FBZixDQUFtQixTQUpNLEVBS3pCLGVBQWUsR0FBZixDQUFtQixPQUxNLEVBTXpCLFdBQVcsWUFBWCxDQUF3QixLQU5DLENBQTdCOztBQVNBO0FBQ0EsMkJBQWUsR0FBZixDQUFtQiwwQkFBbkIsR0FBZ0QsS0FBSyxNQUFMLENBQzVDLElBRDRDLEVBRTVDLGVBQWUsR0FBZixDQUFtQixlQUZ5QixFQUc1QyxlQUFlLEdBQWYsQ0FBbUIsY0FIeUIsRUFJNUMsb0JBSjRDLEVBSzVDLGVBQWUsR0FBZixDQUFtQixTQUx5QixFQU01QyxpQkFONEMsQ0FBaEQ7O0FBU0E7QUFDQSxnQkFBTSx1QkFBdUIsS0FBSyxvQkFBTCxDQUEwQixjQUExQixDQUE3Qjs7QUFFQTtBQUNBLGdCQUFJLFNBQVMsSUFBSSxLQUFKLENBQVUsT0FBVixFQUFiOztBQUVBO0FBQ0EsZ0JBQUksS0FBSixDQUFVLE9BQVYsQ0FBa0IsTUFBbEIsRUFBMEIsZ0JBQTFCLEVBQTRDLG9CQUE1QztBQUNBLGdCQUFJLEtBQUosQ0FBVSxPQUFWLENBQWtCLE1BQWxCLEVBQTBCLGtCQUExQixFQUE4QyxnQkFBOUM7O0FBRUE7QUFDQSxnQkFBSSxLQUFKLENBQVUsT0FBVixDQUFrQixNQUFsQixFQUEwQixhQUExQjs7QUFFQTtBQUNBLHFCQUFTLElBQUksS0FBSixDQUFVLE1BQVYsQ0FBVDs7QUFFQTtBQUNBLGdCQUFJLENBQUMsT0FBTyxRQUFQLENBQWdCLE1BQWhCLENBQUwsRUFBOEIsU0FBUyxPQUFPLElBQVAsQ0FBWSxNQUFaLENBQVQ7O0FBRTlCLG1CQUFPLE1BQVA7QUFDSDs7QUFFRDs7Ozs7Ozs7O3FDQU1hLEksRUFBTSxRLEVBQVU7QUFBQTs7QUFDekI7QUFDQSxnQkFBTSxTQUFTLElBQUksS0FBSixDQUFVLElBQVYsQ0FBZjtBQUNBLGdCQUFJLHVCQUF1QixFQUFFLElBQUYsQ0FBTyxPQUFPLFNBQWQsRUFBeUIsRUFBRSxNQUFNLGdCQUFSLEVBQXpCLEVBQXFELE9BQWhGO0FBQ0EsZ0JBQUkseUJBQXlCLEVBQUUsSUFBRixDQUFPLE9BQU8sU0FBZCxFQUF5QixFQUFFLE1BQU0sa0JBQVIsRUFBekIsRUFBdUQsT0FBcEY7O0FBRUE7QUFDQSxnQkFBSSxDQUFDLE9BQU8sUUFBUCxDQUFnQixvQkFBaEIsQ0FBTCxFQUE0Qyx1QkFBdUIsT0FBTyxJQUFQLENBQVksb0JBQVosQ0FBdkI7QUFDNUMsZ0JBQUksQ0FBQyxPQUFPLFFBQVAsQ0FBZ0Isc0JBQWhCLENBQUwsRUFBOEMseUJBQXlCLE9BQU8sSUFBUCxDQUFZLHNCQUFaLENBQXpCOztBQUU5QyxtQkFBTyxVQUFVLE9BQVYsQ0FBa0IsT0FBbEIsR0FDRixJQURFLENBQ0c7QUFBQSx1QkFBTSxNQUFLLHlCQUFMLENBQStCLG9CQUEvQixDQUFOO0FBQUEsYUFESCxFQUMrRDtBQUQvRCxhQUVGLElBRkUsQ0FFRywwQkFBa0I7QUFDcEI7QUFDQSxvQkFBTSxNQUFNLE1BQUsscUJBQUwsQ0FDUixRQURRLEVBRVIsZUFBZSxHQUFmLENBQW1CLGFBRlgsRUFHUixlQUFlLEdBQWYsQ0FBbUIsU0FIWCxFQUlSLGVBQWUsR0FBZixDQUFtQixTQUpYLEVBS1IsZUFBZSxHQUFmLENBQW1CLE9BTFgsRUFNUixXQUFXLEdBTkgsQ0FBWjs7QUFTQTtBQUNBLG9CQUFNLGFBQWEsTUFBSyxNQUFMLENBQ2YsS0FEZSxFQUVmLGVBQWUsR0FBZixDQUFtQixlQUZKLEVBR2YsZUFBZSxHQUFmLENBQW1CLGNBSEosRUFJZixHQUplLEVBS2YsZUFBZSxHQUFmLENBQW1CLFNBTEosRUFNZixlQUFlLEdBQWYsQ0FBbUIsaUJBTkosQ0FBbkI7O0FBU0E7QUFDQSx1QkFBTyxNQUFLLGFBQUwsQ0FDSCxLQURHLEVBRUgsZUFBZSxPQUFmLENBQXVCLGVBRnBCLEVBR0gsZUFBZSxPQUFmLENBQXVCLGNBSHBCLEVBSUgsZUFBZSxPQUFmLENBQXVCLGFBSnBCLEVBS0gsZUFBZSxPQUFmLENBQXVCLFNBTHBCLEVBTUgsZUFBZSxPQUFmLENBQXVCLFNBTnBCLEVBT0gsVUFQRyxFQVFILHNCQVJHLENBQVA7QUFTSCxhQWpDRSxDQUFQO0FBa0NIOztBQUVEOzs7Ozs7Ozs7NkNBTXFCLGMsRUFBZ0I7QUFDakM7QUFDQSxnQkFBTSxxQkFBcUI7QUFDdkIsc0JBQU0sWUFEaUI7QUFFdkIsNEJBQVk7QUFDUiwyQkFBTyxxREFEQztBQUVSLCtCQUFXLGdFQUZIO0FBR1IsK0JBQVc7QUFISCxpQkFGVztBQU92QiwwQkFBVSxDQUNOO0FBQ0ksMEJBQU0sU0FEVjtBQUVJLGdDQUFZO0FBQ1Isa0NBQVUsZUFBZSxPQUFmLENBQXVCLFNBQXZCLENBQWlDLE1BRG5DO0FBRVIsbUNBQVcsZUFBZSxPQUFmLENBQXVCLFNBRjFCO0FBR1IsaUNBQVMsZUFBZSxPQUFmLENBQXVCLE9BSHhCO0FBSVIsa0NBQVUsZUFBZSxPQUFmLENBQXVCLFFBSnpCO0FBS1IseUNBQWlCLGVBQWUsT0FBZixDQUF1QixlQUxoQztBQU1SLHdDQUFnQixlQUFlLE9BQWYsQ0FBdUIsY0FOL0I7QUFPUix1Q0FBZSxlQUFlLE9BQWYsQ0FBdUIsYUFQOUI7QUFRUixtQ0FBVyxlQUFlLE9BQWYsQ0FBdUIsU0FBdkIsQ0FBaUMsUUFBakMsQ0FBMEMsUUFBMUM7QUFSSDtBQUZoQixpQkFETSxFQWNOO0FBQ0ksMEJBQU0sZUFEVjtBQUVJLGdDQUFZO0FBQ1IsMENBQWtCLGVBQWUsYUFBZixDQUE2QixnQkFBN0IsQ0FBOEMsUUFBOUMsQ0FBdUQsUUFBdkQsQ0FEVjtBQUVSLDRDQUFvQixlQUFlLGFBQWYsQ0FBNkIsa0JBQTdCLENBQWdELFFBQWhELENBQXlELFFBQXpEO0FBRlo7QUFGaEIsaUJBZE0sRUFxQk47QUFDSSwwQkFBTSxlQURWO0FBRUksOEJBQVUsQ0FDTjtBQUNJLDhCQUFNLGNBRFY7QUFFSSxvQ0FBWTtBQUNSLGlDQUFLO0FBREcseUJBRmhCO0FBS0ksa0NBQVUsQ0FDTjtBQUNJLGtDQUFNLGdCQURWO0FBRUksd0NBQVk7QUFDUiwyQ0FBVyxlQUFlLEdBQWYsQ0FBbUIsU0FEdEI7QUFFUiwwQ0FBVSxlQUFlLEdBQWYsQ0FBbUIsU0FBbkIsQ0FBNkIsTUFGL0I7QUFHUiwyQ0FBVyxlQUFlLEdBQWYsQ0FBbUIsU0FIdEI7QUFJUix5Q0FBUyxlQUFlLEdBQWYsQ0FBbUIsT0FKcEI7QUFLUiwwQ0FBVSxlQUFlLEdBQWYsQ0FBbUIsUUFMckI7QUFNUixpREFBaUIsZUFBZSxHQUFmLENBQW1CLGVBTjVCO0FBT1IsZ0RBQWdCLGVBQWUsR0FBZixDQUFtQixjQVAzQjtBQVFSLCtDQUFlLGVBQWUsR0FBZixDQUFtQixhQVIxQjtBQVNSLDJDQUFXLGVBQWUsR0FBZixDQUFtQixTQUFuQixDQUE2QixRQUE3QixDQUFzQyxRQUF0QyxDQVRIO0FBVVIsNERBQTRCLGVBQWUsR0FBZixDQUFtQiwwQkFBbkIsQ0FBOEMsUUFBOUMsQ0FBdUQsUUFBdkQsQ0FWcEI7QUFXUiw0REFBNEIsZUFBZSxHQUFmLENBQW1CLDBCQUFuQixDQUE4QyxRQUE5QyxDQUF1RCxRQUF2RCxDQVhwQjtBQVlSLG1EQUFtQixlQUFlLEdBQWYsQ0FBbUIsaUJBQW5CLENBQXFDLFFBQXJDLENBQThDLFFBQTlDO0FBWlg7QUFGaEIseUJBRE07QUFMZCxxQkFETTtBQUZkLGlCQXJCTTtBQVBhLGFBQTNCOztBQTZEQTtBQUNBLGdCQUFNLGFBQWEsSUFBSSxVQUFKLEVBQW5CO0FBQ0EsZ0JBQU0sb0JBQW9CLFdBQVcsS0FBWCxDQUFpQixrQkFBakIsQ0FBMUI7O0FBRUE7QUFDQSxtQkFBTyxPQUFPLE1BQVAsQ0FBYyxDQUFDLHNCQUFELEVBQXlCLE9BQU8sSUFBUCxDQUFZLGlCQUFaLEVBQStCLE1BQS9CLENBQXpCLENBQWQsQ0FBUDtBQUNIOztBQUVEOzs7Ozs7Ozs7a0RBTTBCLE0sRUFBUTtBQUM5QjtBQUNBLGdCQUFNLE1BQU0sT0FBTyxLQUFQLENBQWEsdUJBQXVCLE1BQXBDLEVBQTRDLFFBQTVDLENBQXFELE1BQXJELENBQVo7O0FBRUE7QUFDQSxnQkFBTSxZQUFZLElBQUksU0FBSixFQUFsQjtBQUNBLG1CQUFPLFVBQVUsVUFBVixDQUFxQixHQUFyQixFQUNGLElBREUsQ0FDRyxlQUFPO0FBQ1Q7QUFDQSxvQkFBTSxjQUFjLEtBQUssU0FBTCxDQUFlLEdBQWYsRUFBb0IsU0FBcEIsQ0FBcEI7QUFDQSxvQkFBTSxvQkFBb0IsS0FBSyxTQUFMLENBQWUsR0FBZixFQUFvQixlQUFwQixDQUExQjtBQUNBLG9CQUFNLG1CQUFtQixLQUFLLFNBQUwsQ0FBZSxpQkFBZixFQUFrQyxjQUFsQyxDQUF6QjtBQUNBLG9CQUFNLG1CQUFtQixLQUFLLFNBQUwsQ0FBZSxnQkFBZixFQUFpQyxnQkFBakMsQ0FBekI7O0FBRUEsdUJBQU87QUFDSCw2QkFBUztBQUNMLHlDQUFpQixZQUFZLFVBQVosQ0FBdUIsZUFEbkM7QUFFTCx3Q0FBZ0IsWUFBWSxVQUFaLENBQXVCLGNBRmxDO0FBR0wsbUNBQVcsT0FBTyxJQUFQLENBQVksWUFBWSxVQUFaLENBQXVCLFNBQW5DLEVBQThDLFFBQTlDLENBSE47QUFJTCx1Q0FBZSxZQUFZLFVBQVosQ0FBdUIsYUFKakM7QUFLTCxtQ0FBVyxZQUFZLFVBQVosQ0FBdUI7QUFMN0IscUJBRE47QUFRSCx5QkFBSztBQUNELDJDQUFtQixPQUFPLElBQVAsQ0FBWSxpQkFBaUIsVUFBakIsQ0FBNEIsaUJBQXhDLEVBQTJELFFBQTNELENBRGxCO0FBRUQseUNBQWlCLGlCQUFpQixVQUFqQixDQUE0QixlQUY1QztBQUdELHdDQUFnQixpQkFBaUIsVUFBakIsQ0FBNEIsY0FIM0M7QUFJRCxtQ0FBVyxPQUFPLElBQVAsQ0FBWSxpQkFBaUIsVUFBakIsQ0FBNEIsU0FBeEMsRUFBbUQsUUFBbkQsQ0FKVjtBQUtELHVDQUFlLGlCQUFpQixVQUFqQixDQUE0QixhQUwxQztBQU1ELG1DQUFXLGlCQUFpQixVQUFqQixDQUE0QixTQU50QztBQU9ELGlDQUFTLGlCQUFpQixVQUFqQixDQUE0QjtBQVBwQztBQVJGLGlCQUFQO0FBa0JILGFBMUJFLENBQVA7QUEyQkg7O0FBRUQ7Ozs7Ozs7Ozs7OEJBT00sUyxFQUF1QjtBQUN6Qix3QkFBWSxVQUFVLFdBQVYsRUFBWjtBQUNBLGdCQUFNLFNBQVMsT0FBTyxTQUFQLEVBQWY7QUFDQSxnQkFBSSxPQUFPLE9BQVAsQ0FBZSxTQUFmLElBQTRCLENBQWhDLEVBQW1DLE1BQU0sSUFBSSxLQUFKLHNCQUE2QixTQUE3QixzQkFBTjs7QUFFbkMsZ0JBQU0sT0FBTyxPQUFPLFVBQVAsQ0FBa0IsU0FBbEIsQ0FBYjs7QUFMeUIsOENBQVQsT0FBUztBQUFULHVCQUFTO0FBQUE7O0FBTXpCLGlCQUFLLE1BQUwsQ0FBWSxPQUFPLE1BQVAsQ0FBYyxPQUFkLENBQVo7QUFDQSxtQkFBTyxLQUFLLE1BQUwsRUFBUDtBQUNIOztBQUVEOzs7Ozs7Ozs7Ozs4QkFRTSxTLEVBQVcsRyxFQUFpQjtBQUM5Qix3QkFBWSxVQUFVLFdBQVYsRUFBWjtBQUNBLGdCQUFNLFNBQVMsT0FBTyxTQUFQLEVBQWY7QUFDQSxnQkFBSSxPQUFPLE9BQVAsQ0FBZSxTQUFmLElBQTRCLENBQWhDLEVBQW1DLE1BQU0sSUFBSSxLQUFKLHNCQUE2QixTQUE3QixzQkFBTjs7QUFFbkMsZ0JBQU0sT0FBTyxPQUFPLFVBQVAsQ0FBa0IsU0FBbEIsRUFBNkIsR0FBN0IsQ0FBYjs7QUFMOEIsK0NBQVQsT0FBUztBQUFULHVCQUFTO0FBQUE7O0FBTTlCLGlCQUFLLE1BQUwsQ0FBWSxPQUFPLE1BQVAsQ0FBYyxPQUFkLENBQVo7QUFDQSxtQkFBTyxLQUFLLE1BQUwsRUFBUDtBQUNIOztBQUVEOzs7Ozs7Ozs7Ozs7OzsrQkFXTyxPLEVBQVMsZSxFQUFpQixjLEVBQWdCLEcsRUFBSyxFLEVBQUksSyxFQUFPO0FBQzdELGdCQUFJLFlBQWUsZ0JBQWdCLFdBQWhCLEVBQWYsU0FBZ0QsSUFBSSxNQUFKLEdBQWEsQ0FBakU7QUFDQSxnQkFBSSxtQkFBbUIsaUJBQXZCLEVBQTBDLGFBQWEsTUFBYixDQUExQyxLQUNLLE1BQU0sSUFBSSxLQUFKLCtCQUFzQyxjQUF0QyxDQUFOOztBQUVMLGdCQUFNLFNBQVMsT0FBTyxVQUFVLGdCQUFWLEdBQTZCLGtCQUFwQyxFQUF3RCxTQUF4RCxFQUFtRSxHQUFuRSxFQUF3RSxFQUF4RSxDQUFmO0FBQ0EsbUJBQU8sY0FBUCxDQUFzQixLQUF0QjtBQUNBLGdCQUFJLFNBQVMsT0FBTyxNQUFQLENBQWMsS0FBZCxDQUFiO0FBQ0EscUJBQVMsT0FBTyxNQUFQLENBQWMsQ0FBQyxNQUFELEVBQVMsT0FBTyxLQUFQLEVBQVQsQ0FBZCxDQUFUO0FBQ0EsbUJBQU8sTUFBUDtBQUNIOztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7O3NDQWFjLE8sRUFBUyxlLEVBQWlCLGMsRUFBZ0IsYSxFQUFlLFMsRUFBVyxTLEVBQVcsRyxFQUFLLEssRUFBTztBQUNyRztBQUNBLGdCQUFNLGVBQWUsRUFBckI7QUFDQSxnQkFBTSxTQUFTLFVBQVUsQ0FBVixHQUFjLGNBQTdCOztBQUVBO0FBQ0EsZ0JBQUksSUFBSSxDQUFSO0FBQUEsZ0JBQVcsUUFBUSxDQUFuQjtBQUFBLGdCQUFzQixNQUFNLENBQTVCO0FBQ0EsbUJBQU8sTUFBTSxNQUFNLE1BQW5CLEVBQTJCO0FBQ3ZCLHdCQUFRLEdBQVI7QUFDQSxzQkFBTSxRQUFRLDZCQUFkO0FBQ0Esb0JBQUksTUFBTSxNQUFNLE1BQWhCLEVBQXdCLE1BQU0sTUFBTSxNQUFaOztBQUV4QjtBQUNBLG9CQUFJLGFBQWEsTUFBTSxLQUFOLENBQVksUUFBUSxNQUFwQixFQUE0QixNQUFNLE1BQWxDLENBQWpCOztBQUVBO0FBQ0Esb0JBQU0sWUFBWSxXQUFXLE1BQVgsR0FBb0IsU0FBdEM7QUFDQSxvQkFBSSxTQUFKLEVBQWUsYUFBYSxPQUFPLE1BQVAsQ0FBYyxDQUFDLFVBQUQsRUFBYSxPQUFPLEtBQVAsQ0FBYSxZQUFZLFNBQXpCLENBQWIsQ0FBZCxDQUFiOztBQUVmO0FBQ0Esb0JBQU0sS0FBSyxLQUFLLFNBQUwsQ0FBZSxhQUFmLEVBQThCLFNBQTlCLEVBQXlDLFNBQXpDLEVBQW9ELENBQXBELENBQVg7O0FBRUE7QUFDQSxvQkFBTSxjQUFjLEtBQUssTUFBTCxDQUFZLE9BQVosRUFBcUIsZUFBckIsRUFBc0MsY0FBdEMsRUFBc0QsR0FBdEQsRUFBMkQsRUFBM0QsRUFBK0QsVUFBL0QsQ0FBcEI7QUFDQSw2QkFBYSxJQUFiLENBQWtCLFdBQWxCOztBQUVBO0FBQ0g7O0FBRUQ7QUFDQSxnQkFBSSxTQUFTLE9BQU8sTUFBUCxDQUFjLFlBQWQsQ0FBYjs7QUFFQSxnQkFBSSxPQUFKLEVBQWE7QUFDVDtBQUNBLHlCQUFTLE9BQU8sTUFBUCxDQUFjLENBQUMsS0FBSyxxQkFBTCxDQUEyQixNQUFNLE1BQWpDLEVBQXlDLGNBQXpDLENBQUQsRUFBMkQsTUFBM0QsQ0FBZCxDQUFUO0FBQ0gsYUFIRCxNQUdPO0FBQ0g7QUFDQSxvQkFBTSxTQUFTLE1BQU0sWUFBTixDQUFtQixDQUFuQixDQUFmO0FBQ0EseUJBQVMsT0FBTyxLQUFQLENBQWEsQ0FBYixFQUFnQixNQUFoQixDQUFUO0FBQ0g7O0FBRUQsbUJBQU8sTUFBUDtBQUNIOztBQUVEOzs7Ozs7Ozs7OzhDQU9zQixLLEVBQXVCO0FBQUEsZ0JBQWhCLFVBQWdCLHVFQUFILENBQUc7O0FBQ3pDLGdCQUFNLFNBQVMsT0FBTyxLQUFQLENBQWEsVUFBYixDQUFmO0FBQ0EsbUJBQU8sYUFBUCxDQUFxQixLQUFyQixFQUE0QixDQUE1QjtBQUNBLG1CQUFPLE1BQVA7QUFDSDs7QUFFRDs7Ozs7Ozs7Ozs7Ozs7OENBV3NCLFEsRUFBVSxhLEVBQWUsUyxFQUFXLFMsRUFBVyxPLEVBQVMsUSxFQUFVO0FBQ3BGO0FBQ0EsZ0JBQU0saUJBQWlCLE9BQU8sSUFBUCxDQUFZLFFBQVosRUFBc0IsU0FBdEIsQ0FBdkI7O0FBRUE7QUFDQSxnQkFBSSxNQUFNLEtBQUssS0FBTCxDQUFXLGFBQVgsRUFBMEIsU0FBMUIsRUFBcUMsY0FBckMsQ0FBVjs7QUFFQTtBQUNBLGlCQUFLLElBQUksSUFBSSxDQUFiLEVBQWdCLElBQUksU0FBcEIsRUFBK0IsR0FBL0IsRUFBb0M7QUFDaEMsb0JBQU0sV0FBVyxLQUFLLHFCQUFMLENBQTJCLENBQTNCLENBQWpCO0FBQ0Esc0JBQU0sS0FBSyxLQUFMLENBQVcsYUFBWCxFQUEwQixRQUExQixFQUFvQyxHQUFwQyxDQUFOO0FBQ0g7O0FBRUQ7QUFDQSxrQkFBTSxLQUFLLEtBQUwsQ0FBVyxhQUFYLEVBQTBCLEdBQTFCLEVBQStCLFFBQS9CLENBQU47O0FBRUE7QUFDQSxnQkFBTSxXQUFXLFVBQVUsQ0FBM0I7QUFDQSxnQkFBSSxJQUFJLE1BQUosR0FBYSxRQUFqQixFQUEyQjtBQUN2QixvQkFBTSxNQUFNLE9BQU8sS0FBUCxDQUFhLFFBQWIsRUFBdUIsSUFBdkIsQ0FBWjtBQUNBLG9CQUFJLElBQUosQ0FBUyxHQUFUO0FBQ0Esc0JBQU0sR0FBTjtBQUNILGFBSkQsTUFJTyxJQUFJLElBQUksTUFBSixHQUFhLFFBQWpCLEVBQTJCO0FBQzlCLHNCQUFNLElBQUksS0FBSixDQUFVLENBQVYsRUFBYSxRQUFiLENBQU47QUFDSDs7QUFFRCxtQkFBTyxHQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7Ozs7OztrQ0FTVSxhLEVBQWUsUyxFQUFXLFMsRUFBVyxRLEVBQVU7QUFDckQ7QUFDQSxnQkFBSSxPQUFPLFFBQVAsS0FBb0IsUUFBeEIsRUFBa0MsV0FBVyxLQUFLLHFCQUFMLENBQTJCLFFBQTNCLENBQVg7O0FBRWxDO0FBQ0E7QUFDQSxnQkFBSSxLQUFLLEtBQUssS0FBTCxDQUFXLGFBQVgsRUFBMEIsU0FBMUIsRUFBcUMsUUFBckMsQ0FBVDtBQUNBLGdCQUFJLEdBQUcsTUFBSCxHQUFZLFNBQWhCLEVBQTJCO0FBQ3ZCLG9CQUFNLE1BQU0sT0FBTyxLQUFQLENBQWEsU0FBYixFQUF3QixJQUF4QixDQUFaO0FBQ0EsbUJBQUcsSUFBSCxDQUFRLEdBQVI7QUFDQSxxQkFBSyxHQUFMO0FBQ0gsYUFKRCxNQUlPLElBQUksR0FBRyxNQUFILEdBQVksU0FBaEIsRUFBMkI7QUFDOUIscUJBQUssR0FBRyxLQUFILENBQVMsQ0FBVCxFQUFZLFNBQVosQ0FBTDtBQUNIOztBQUVELG1CQUFPLEVBQVA7QUFDSDs7Ozs7O0FBR0wsT0FBTyxPQUFQLEdBQWlCLFNBQWpCOzs7OztBQ25sQkE7Ozs7OztBQUVBLElBQU0sSUFBSSxRQUFRLFFBQVIsQ0FBVjs7QUFFQTs7OztJQUdNLFk7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUFZLEtBQVosRUFBbUI7QUFBQTs7QUFDZixTQUFLLE1BQUwsR0FBYyxLQUFkO0FBQ0g7O0FBRUQ7Ozs7Ozs7OzRCQUlRO0FBQ0osYUFBTyxLQUFLLE1BQVo7QUFDSDs7Ozs7O0FBR0w7Ozs7OztBQUlBLGFBQWEsSUFBYixHQUFvQixJQUFJLFlBQUosQ0FBaUIsU0FBakIsQ0FBcEI7O0FBRUE7Ozs7QUFJQSxhQUFhLEVBQWIsR0FBa0IsSUFBSSxZQUFKLENBQWlCLE1BQWpCLENBQWxCOztBQUVBOzs7O0FBSUEsYUFBYSxJQUFiLEdBQW9CLElBQUksWUFBSixDQUFpQixRQUFqQixDQUFwQjs7QUFFQTs7OztBQUlBLGFBQWEsSUFBYixHQUFvQixJQUFJLFlBQUosQ0FBaUIsUUFBakIsQ0FBcEI7O0FBRUE7Ozs7QUFJQSxhQUFhLEdBQWIsR0FBbUIsSUFBSSxZQUFKLENBQWlCLE9BQWpCLENBQW5COztBQUVBOzs7O0FBSUEsYUFBYSxHQUFiLEdBQW1CLElBQUksWUFBSixDQUFpQixPQUFqQixDQUFuQjs7QUFFQTs7OztBQUlBLGFBQWEsS0FBYixHQUFxQixJQUFJLFlBQUosQ0FBaUIsU0FBakIsQ0FBckI7O0FBRUE7Ozs7OztBQU1BLGFBQWEsUUFBYixHQUF3QixpQkFBUztBQUM3QixTQUFPLEVBQUUsSUFBRixDQUFPLFlBQVAsRUFBcUIsaUJBQVM7QUFDakMsV0FBTyxpQkFBaUIsWUFBakIsSUFBaUMsTUFBTSxLQUFOLE9BQWtCLEtBQTFEO0FBQ0gsR0FGTSxLQUVELElBQUksWUFBSixDQUFpQixLQUFqQixDQUZOO0FBR0gsQ0FKRDs7QUFNQSxPQUFPLE9BQVAsR0FBaUIsWUFBakI7OztBQy9FQTs7QUFFQTs7Ozs7Ozs7SUFHTSxVO0FBQ0Ysd0JBQVksSUFBWixFQUFrQjtBQUFBOztBQUNkLGFBQUssS0FBTCxHQUFhLElBQWI7QUFDSDs7QUFFRDs7Ozs7Ozs7OzRCQUtJLEUsRUFBSTtBQUNKLGlCQUFLLEtBQUwsQ0FBVyxRQUFYLENBQW9CLElBQXBCLENBQXlCO0FBQ3JCLHNCQUFNLEtBRGU7QUFFckIsMEJBQVUsRUFGVztBQUdyQiw0QkFBWTtBQUNSLDBCQURRO0FBRVIseUJBQUssS0FGRztBQUdSLHlCQUFLO0FBSEc7QUFIUyxhQUF6QjtBQVNBLGlCQUFLLEtBQUwsQ0FBVyxVQUFYLENBQXNCLEtBQXRCO0FBQ0EsaUJBQUssS0FBTCxDQUFXLFVBQVgsQ0FBc0IsZ0JBQXRCOztBQUVBLG1CQUFPLElBQVA7QUFDSDs7QUFFRDs7Ozs7Ozs7K0JBS08sSyxFQUFPO0FBQ1YsZ0JBQU0sTUFBTSxLQUFLLEtBQUwsQ0FBVyxRQUFYLENBQW9CLEtBQXBCLENBQVo7QUFDQSxnQkFBSSxHQUFKLEVBQVM7QUFDTCxxQkFBSyxLQUFMLENBQVcsUUFBWCxDQUFvQixNQUFwQixDQUEyQixLQUEzQixFQUFrQyxDQUFsQztBQUNBLHFCQUFLLEtBQUwsQ0FBVyxVQUFYLENBQXNCLEtBQXRCO0FBQ0Esb0JBQUksSUFBSSxHQUFSLEVBQWE7QUFDVCx5QkFBSyxLQUFMLENBQVcsVUFBWCxDQUFzQixnQkFBdEI7QUFDSDtBQUNKOztBQUVELG1CQUFPLElBQVA7QUFDSDs7QUFFRDs7Ozs7Ozs0QkFJWTtBQUNSLG1CQUFPLEtBQUssS0FBTCxDQUFXLFVBQVgsQ0FBc0IsS0FBN0I7QUFDSDs7QUFFRDs7Ozs7Ozs0QkFJVztBQUNQLG1CQUFPLEtBQUssS0FBTCxDQUFXLFFBQVgsQ0FBb0IsR0FBcEIsQ0FBd0I7QUFBQSx1QkFBUTtBQUNuQyx3QkFBSSxJQUFJLEVBRDJCO0FBRW5DLDhCQUFVLENBQUMsQ0FBQyxJQUFJO0FBRm1CLGlCQUFSO0FBQUEsYUFBeEIsQ0FBUDtBQUlIOzs7Ozs7QUFHTCxPQUFPLE9BQVAsR0FBaUIsVUFBakI7OztBQ3JFQTs7Ozs7O0FBRUEsSUFBTSxhQUFhLFFBQVEsY0FBUixDQUFuQjtBQUNBLElBQU0sbUJBQW1CLFFBQVEsb0JBQVIsQ0FBekI7O0FBRUE7Ozs7SUFHTSxLO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFZLFNBQVosRUFBdUIsT0FBdkIsRUFBZ0M7QUFBQTs7QUFDNUIsYUFBSyxVQUFMLEdBQWtCLFNBQWxCO0FBQ0EsYUFBSyxRQUFMLEdBQWdCLE9BQWhCO0FBQ0EsYUFBSyxnQkFBTCxDQUFzQixTQUF0QixFQUFpQyxPQUFqQztBQUNIOztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Z0NBV1EsSSxFQUFNO0FBQ1YsbUJBQU8saUJBQWlCLFNBQWpCLENBQTJCO0FBQzlCLHNCQUFNLE9BRHdCO0FBRTlCLGdDQUFnQixLQUFLLFNBQUwsR0FBaUIsU0FBakIsRUFGYztBQUc5QixrQ0FBa0IsU0FBUyxLQUFLLGdCQUFMLElBQXlCLEtBQUssUUFBdkMsQ0FIWTtBQUk5QixpQ0FBaUIsS0FBSyxTQUFMLEdBQWlCLFVBQWpCLEVBSmE7QUFLOUIscUNBQXFCLFNBQVMsS0FBSyxtQkFBTCxJQUE0QixLQUFLLFFBQTFDLENBTFM7QUFNOUIsOEJBQWMsS0FBSyxPQUFMLEdBQWUsU0FBZixFQU5nQjtBQU85QixnQ0FBZ0IsU0FBUyxLQUFLLGNBQUwsSUFBdUIsS0FBSyxRQUFyQyxDQVBjO0FBUTlCLCtCQUFlLEtBQUssT0FBTCxHQUFlLFVBQWYsRUFSZTtBQVM5QixtQ0FBbUIsU0FBUyxLQUFLLGlCQUFMLElBQTBCLEtBQUssUUFBeEMsQ0FUVztBQVU5QiwyQkFBVyxRQUFRLEtBQUssZ0JBQWIsSUFBaUMsS0FBSyxLQUFMLEdBQWEsSUFBYjtBQVZkLGFBQTNCLENBQVA7QUFZSDs7QUFFRDs7Ozs7Ozs7OzZCQU1LLEUsRUFBSSxFLEVBQUk7QUFDVCxtQkFBTyxLQUFLLEtBQUwsR0FBYSxJQUFiLENBQWtCLEtBQUssYUFBTCxHQUFxQixFQUF2QyxFQUEyQyxLQUFLLGdCQUFMLEdBQXdCLEVBQW5FLENBQVA7QUFDSDs7QUFFRDs7Ozs7OztxQ0FJYTtBQUNULGlCQUFLLEtBQUwsR0FBYSxVQUFiLENBQXdCLElBQXhCOztBQUVBLG1CQUFPLElBQVA7QUFDSDs7QUFFRDs7Ozs7OztnQ0FJUTtBQUNKLG1CQUFPLEtBQUssR0FBTCxDQUFTO0FBQUEsdUJBQVEsSUFBUjtBQUFBLGFBQVQsQ0FBUDtBQUNIOztBQUVEOzs7Ozs7O2dDQUlRO0FBQ0osbUJBQU8sS0FBSyxLQUFMLENBQVcsU0FBWCxDQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7a0NBSVU7QUFDTixtQkFBTyxLQUFLLFFBQVo7QUFDSDs7QUFFRDs7Ozs7Ozs7O0FBU0E7Ozs7Ozs7O2dDQUtRLFEsRUFBVTtBQUNkLGlCQUFLLElBQUksS0FBSyxDQUFkLEVBQWlCLEtBQUssS0FBSyxRQUEzQixFQUFxQyxJQUFyQyxFQUEyQztBQUN2QyxxQkFBSyxJQUFJLEtBQUssQ0FBZCxFQUFpQixLQUFLLEtBQUssV0FBM0IsRUFBd0MsSUFBeEMsRUFBOEM7QUFDMUMsNkJBQVMsS0FBSyxJQUFMLENBQVUsRUFBVixFQUFjLEVBQWQsQ0FBVCxFQUE0QixFQUE1QixFQUFnQyxFQUFoQyxFQUFvQyxJQUFwQztBQUNIO0FBQ0o7O0FBRUQsbUJBQU8sSUFBUDtBQUNIOztBQUVEOzs7WUFHRzs7Ozs7Ozs7a0NBS087QUFBQTs7QUFDTixtQkFBTyxJQUFJLFVBQUosQ0FBZSxlQUFmLEVBQ0YsSUFERSxDQUNHLFlBQU07QUFDUix1QkFBTyxNQUFLLFNBQUwsR0FBaUIsbUJBQWpCLEVBQVA7QUFDSCxhQUhFLEVBSUYsSUFKRSxDQUlHLFFBSkgsRUFJYSxtQkFBVztBQUN2QixvQkFBTSxrQkFBa0IsTUFBSyxLQUFMLEdBQWEsMkJBQWIsRUFBeEI7QUFDQSxzQkFBSyxPQUFMLENBQWEsVUFBQyxJQUFELEVBQU8sRUFBUCxFQUFXLEVBQVgsRUFBa0I7QUFDM0Isd0JBQUksT0FBTyxDQUFQLElBQVksT0FBTyxDQUF2QixFQUEwQjtBQUN0Qiw2QkFBSyxnQkFBTCxDQUFzQixlQUF0QixFQUF1QyxPQUF2QyxFQUFnRCxNQUFLLE9BQUwsRUFBaEQ7QUFDSCxxQkFGRCxNQUVPO0FBQ0gsNkJBQUssZ0JBQUwsQ0FBc0IsZUFBdEI7QUFDSDtBQUNKLGlCQU5EOztBQVFBLHVCQUFPLEtBQVA7QUFDSCxhQWZFLEVBZ0JGLE1BaEJFLENBZ0JLLFNBaEJMLENBQVA7QUFpQkg7O0FBRUQ7Ozs7Ozs7OztBQVNBOzs7Ozs7Ozs0QkFLSSxRLEVBQVU7QUFBQTs7QUFDVixnQkFBTSxTQUFTLEVBQWY7QUFDQSxpQkFBSyxPQUFMLENBQWEsVUFBQyxJQUFELEVBQU8sRUFBUCxFQUFXLEVBQVgsRUFBa0I7QUFDM0Isb0JBQUksQ0FBQyxPQUFPLEVBQVAsQ0FBTCxFQUFpQixPQUFPLEVBQVAsSUFBYSxFQUFiO0FBQ2pCLHVCQUFPLEVBQVAsRUFBVyxFQUFYLElBQWlCLFNBQVMsSUFBVCxFQUFlLEVBQWYsRUFBbUIsRUFBbkIsRUFBdUIsTUFBdkIsQ0FBakI7QUFDSCxhQUhEOztBQUtBLG1CQUFPLE1BQVA7QUFDSDs7QUFFRDs7O1lBR0c7Ozs7Ozs7OytCQUtJLE8sRUFBUTtBQUFBOztBQUNYLG1CQUFPLElBQUksVUFBSixDQUFlLGNBQWYsRUFDRixJQURFLENBQ0csWUFBTTtBQUNSLHVCQUFPLE9BQUssS0FBTCxHQUFhLE1BQWIsQ0FBb0IsT0FBSyxPQUFMLEVBQXBCLENBQVA7QUFDSCxhQUhFLEVBSUYsSUFKRSxDQUlHLEdBSkgsRUFJUSxrQkFBVTtBQUNqQix1QkFBSyxLQUFMLEdBQWEsTUFBYixDQUFvQixPQUFLLE9BQUwsRUFBcEIsRUFBb0MsTUFBcEM7QUFDQSx1QkFBTyxNQUFQO0FBQ0gsYUFQRSxFQVFGLE1BUkUsQ0FRSyxTQVJMLENBQVA7QUFTSDs7QUFFRDs7O1lBR0c7Ozs7Ozs7O3lDQUtjO0FBQUE7O0FBQ2IsbUJBQU8sSUFBSSxVQUFKLENBQWUsc0JBQWYsRUFDRixJQURFLENBQ0csWUFBTTtBQUNSLHVCQUFPLE9BQUssS0FBTCxHQUFhLGNBQWIsQ0FBNEIsT0FBSyxPQUFMLEVBQTVCLENBQVA7QUFDSCxhQUhFLEVBSUYsSUFKRSxDQUlHLFNBSkgsRUFJYyxlQUFPO0FBQ3BCLHVCQUFPLE9BQUssS0FBTCxHQUFhLGNBQWIsQ0FBNEIsT0FBSyxPQUFMLEVBQTVCLEVBQTRDLEdBQTVDLENBQVA7QUFDSCxhQU5FLEVBT0YsSUFQRSxDQU9HLEdBUEgsRUFPUSxlQUFPO0FBQ2QsdUJBQUssS0FBTCxHQUFhLGNBQWIsQ0FBNEIsT0FBSyxPQUFMLEVBQTVCLEVBQTRDLEdBQTVDO0FBQ0EsdUJBQU8sTUFBUDtBQUNILGFBVkUsRUFXRixNQVhFLENBV0ssU0FYTCxDQUFQO0FBWUg7O0FBRUQ7Ozs7Ozs7Ozs7QUFVQTs7Ozs7Ozs7OytCQU1PLFEsRUFBVSxZLEVBQWM7QUFBQTs7QUFDM0IsZ0JBQUksY0FBYyxZQUFsQjtBQUNBLGlCQUFLLE9BQUwsQ0FBYSxVQUFDLElBQUQsRUFBTyxFQUFQLEVBQVcsRUFBWCxFQUFrQjtBQUMzQiw4QkFBYyxTQUFTLFdBQVQsRUFBc0IsSUFBdEIsRUFBNEIsRUFBNUIsRUFBZ0MsRUFBaEMsRUFBb0MsTUFBcEMsQ0FBZDtBQUNILGFBRkQ7O0FBSUEsbUJBQU8sV0FBUDtBQUNIOztBQUVEOzs7Ozs7O2dDQUlRO0FBQ0osbUJBQU8sS0FBSyxTQUFMLEdBQWlCLEtBQWpCLEVBQVA7QUFDSDs7QUFFRDs7Ozs7OztvQ0FJWTtBQUNSLG1CQUFPLEtBQUssVUFBWjtBQUNIOztBQUVEOzs7O1lBSUc7Ozs7ZUFJQTs7Ozs7a0JBS0E7Ozs7O3FCQUtBOzs7Ozt3QkFLQTs7OzsyQkFJQTs7Ozs7Ozs7Z0NBS0s7QUFBQTs7QUFDSixtQkFBTyxJQUFJLFVBQUosQ0FBZSxhQUFmLEVBQ0YsSUFERSxDQUNHLFFBREgsRUFDYSxnQkFBUTtBQUNwQjtBQUNBLHVCQUFPLE9BQUssR0FBTCxDQUFTO0FBQUEsMkJBQVEsS0FBSyxLQUFMLENBQVcsSUFBWCxDQUFSO0FBQUEsaUJBQVQsQ0FBUDtBQUNILGFBSkUsRUFLRixJQUxFLENBS0csT0FMSCxFQUtZLGlCQUFTO0FBQ3BCO0FBQ0Esb0JBQU0sU0FBUyxFQUFmO0FBQ0Esc0JBQU0sT0FBTixDQUFjLGdCQUFRO0FBQ2xCLDJCQUFPLElBQVAsSUFBZSxPQUFLLEtBQUwsQ0FBVyxJQUFYLENBQWY7QUFDSCxpQkFGRDs7QUFJQSx1QkFBTyxNQUFQO0FBQ0gsYUFiRSxFQWNGLElBZEUsQ0FjRyxDQUFDLFFBQUQsRUFBVyxVQUFYLENBZEgsRUFjMkIsVUFBQyxJQUFELEVBQU8sUUFBUCxFQUFvQjtBQUM5QztBQUNBLHVCQUFPLE9BQUssT0FBTCxDQUFhLFVBQUMsSUFBRCxFQUFPLEVBQVAsRUFBVyxFQUFYLEVBQWtCO0FBQ2xDLHlCQUFLLEtBQUwsQ0FBVyxJQUFYLEVBQWlCLFNBQVMsSUFBVCxFQUFlLEVBQWYsRUFBbUIsRUFBbkIsRUFBdUIsTUFBdkIsQ0FBakI7QUFDSCxpQkFGTSxDQUFQO0FBR0gsYUFuQkUsRUFvQkYsSUFwQkUsQ0FvQkcsQ0FBQyxRQUFELEVBQVcsT0FBWCxDQXBCSCxFQW9Cd0IsVUFBQyxJQUFELEVBQU8sTUFBUCxFQUFrQjtBQUN6QztBQUNBLHVCQUFPLE9BQUssT0FBTCxDQUFhLFVBQUMsSUFBRCxFQUFPLEVBQVAsRUFBVyxFQUFYLEVBQWtCO0FBQ2xDLHdCQUFJLE9BQU8sRUFBUCxLQUFjLE9BQU8sRUFBUCxFQUFXLEVBQVgsTUFBbUIsU0FBckMsRUFBZ0Q7QUFDNUMsNkJBQUssS0FBTCxDQUFXLElBQVgsRUFBaUIsT0FBTyxFQUFQLEVBQVcsRUFBWCxDQUFqQjtBQUNIO0FBQ0osaUJBSk0sQ0FBUDtBQUtILGFBM0JFLEVBNEJGLElBNUJFLENBNEJHLENBQUMsUUFBRCxFQUFXLEdBQVgsQ0E1QkgsRUE0Qm9CLFVBQUMsSUFBRCxFQUFPLEtBQVAsRUFBaUI7QUFDcEM7QUFDQSx1QkFBTyxPQUFLLE9BQUwsQ0FBYTtBQUFBLDJCQUFRLEtBQUssS0FBTCxDQUFXLElBQVgsRUFBaUIsS0FBakIsQ0FBUjtBQUFBLGlCQUFiLENBQVA7QUFDSCxhQS9CRSxFQWdDRixJQWhDRSxDQWdDRyxRQWhDSCxFQWdDYSxzQkFBYztBQUMxQjtBQUNBLHFCQUFLLElBQU0sSUFBWCxJQUFtQixVQUFuQixFQUErQjtBQUMzQix3QkFBSSxDQUFDLFdBQVcsY0FBWCxDQUEwQixJQUExQixDQUFMLEVBQXNDO0FBQ3RDLHdCQUFNLFFBQVEsV0FBVyxJQUFYLENBQWQ7QUFDQSwyQkFBSyxLQUFMLENBQVcsSUFBWCxFQUFpQixLQUFqQjtBQUNIOztBQUVELHVCQUFPLE1BQVA7QUFDSCxhQXpDRSxFQTBDRixJQTFDRSxDQTBDRyxPQTFDSCxFQTBDWSxpQkFBUztBQUNwQix1QkFBSyxNQUFMLEdBQWMsS0FBZDtBQUNBLHVCQUFPLE9BQUssT0FBTCxDQUFhO0FBQUEsMkJBQVEsS0FBSyxLQUFMLENBQVcsS0FBWCxDQUFSO0FBQUEsaUJBQWIsQ0FBUDtBQUNILGFBN0NFLEVBOENGLE1BOUNFLENBOENLLFNBOUNMLENBQVA7QUErQ0g7O0FBRUQ7Ozs7OztBQU1BOzs7Ozs7Ozs0QkFLSSxRLEVBQVU7QUFDVixxQkFBUyxJQUFUO0FBQ0EsbUJBQU8sSUFBUDtBQUNIOztBQUVEOzs7Ozs7QUFNQTs7Ozs7Ozs7NkJBS0ssUSxFQUFVO0FBQ1gsbUJBQU8sU0FBUyxJQUFULENBQVA7QUFDSDs7QUFFRDs7O1lBR0c7Ozs7ZUFJQTs7OztrQkFJQTs7Ozs7Ozs7Z0NBS0s7QUFBQTs7QUFDSixtQkFBTyxJQUFJLFVBQUosQ0FBZSxhQUFmLEVBQ0YsSUFERSxDQUNHLFlBQU07QUFDUjtBQUNBLHVCQUFPLE9BQUssR0FBTCxDQUFTO0FBQUEsMkJBQVEsS0FBSyxLQUFMLEVBQVI7QUFBQSxpQkFBVCxDQUFQO0FBQ0gsYUFKRSxFQUtGLElBTEUsQ0FLRyxVQUxILEVBS2Usb0JBQVk7QUFDMUI7QUFDQSx1QkFBTyxPQUFLLE9BQUwsQ0FBYSxVQUFDLElBQUQsRUFBTyxFQUFQLEVBQVcsRUFBWCxFQUFrQjtBQUNsQyx5QkFBSyxLQUFMLENBQVcsU0FBUyxJQUFULEVBQWUsRUFBZixFQUFtQixFQUFuQixFQUF1QixNQUF2QixDQUFYO0FBQ0gsaUJBRk0sQ0FBUDtBQUdILGFBVkUsRUFXRixJQVhFLENBV0csT0FYSCxFQVdZLGtCQUFVO0FBQ3JCO0FBQ0EsdUJBQU8sT0FBSyxPQUFMLENBQWEsVUFBQyxJQUFELEVBQU8sRUFBUCxFQUFXLEVBQVgsRUFBa0I7QUFDbEMsd0JBQUksT0FBTyxFQUFQLEtBQWMsT0FBTyxFQUFQLEVBQVcsRUFBWCxNQUFtQixTQUFyQyxFQUFnRDtBQUM1Qyw2QkFBSyxLQUFMLENBQVcsT0FBTyxFQUFQLEVBQVcsRUFBWCxDQUFYO0FBQ0g7QUFDSixpQkFKTSxDQUFQO0FBS0gsYUFsQkUsRUFtQkYsSUFuQkUsQ0FtQkcsR0FuQkgsRUFtQlEsaUJBQVM7QUFDaEI7QUFDQSx1QkFBTyxPQUFLLE9BQUwsQ0FBYTtBQUFBLDJCQUFRLEtBQUssS0FBTCxDQUFXLEtBQVgsQ0FBUjtBQUFBLGlCQUFiLENBQVA7QUFDSCxhQXRCRSxFQXVCRixNQXZCRSxDQXVCSyxTQXZCTCxDQUFQO0FBd0JIOztBQUVEOzs7Ozs7O21DQUlXO0FBQ1AsbUJBQU8sS0FBSyxLQUFMLEdBQWEsUUFBYixFQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7OzJDQUttQjtBQUNmLGlCQUFLLGFBQUwsR0FBcUIsS0FBSyxHQUFMLENBQVMsS0FBSyxVQUFMLENBQWdCLFNBQWhCLEVBQVQsRUFBc0MsS0FBSyxRQUFMLENBQWMsU0FBZCxFQUF0QyxDQUFyQjtBQUNBLGlCQUFLLGFBQUwsR0FBcUIsS0FBSyxHQUFMLENBQVMsS0FBSyxVQUFMLENBQWdCLFNBQWhCLEVBQVQsRUFBc0MsS0FBSyxRQUFMLENBQWMsU0FBZCxFQUF0QyxDQUFyQjtBQUNBLGlCQUFLLGdCQUFMLEdBQXdCLEtBQUssR0FBTCxDQUFTLEtBQUssVUFBTCxDQUFnQixZQUFoQixFQUFULEVBQXlDLEtBQUssUUFBTCxDQUFjLFlBQWQsRUFBekMsQ0FBeEI7QUFDQSxpQkFBSyxnQkFBTCxHQUF3QixLQUFLLEdBQUwsQ0FBUyxLQUFLLFVBQUwsQ0FBZ0IsWUFBaEIsRUFBVCxFQUF5QyxLQUFLLFFBQUwsQ0FBYyxZQUFkLEVBQXpDLENBQXhCO0FBQ0EsaUJBQUssUUFBTCxHQUFnQixLQUFLLGFBQUwsR0FBcUIsS0FBSyxhQUExQixHQUEwQyxDQUExRDtBQUNBLGlCQUFLLFdBQUwsR0FBbUIsS0FBSyxnQkFBTCxHQUF3QixLQUFLLGdCQUE3QixHQUFnRCxDQUFuRTtBQUNIOzs7Ozs7QUFHTCxPQUFPLE9BQVAsR0FBaUIsS0FBakI7OztBQzdhQTs7Ozs7O0FBRUEsSUFBTSxJQUFJLFFBQVEsUUFBUixDQUFWOztBQUVBLElBQU0sNkJBQTZCLHNFQUFuQzs7QUFFQTs7Ozs7SUFJTSxhO0FBQ0Y7Ozs7QUFJQSwyQkFBWSxJQUFaLEVBQWtCO0FBQUE7O0FBQ2QsYUFBSyxLQUFMLENBQVcsSUFBWDtBQUNBLGFBQUssY0FBTDtBQUNIOztBQUVEOzs7Ozs7Ozs7Ozs0QkFPSSxJLEVBQU0sTSxFQUFRLFUsRUFBWTtBQUMxQixnQkFBTSxPQUFPO0FBQ1Qsc0JBQU0sY0FERztBQUVULDRCQUFZO0FBQ1IsZ0NBQVUsS0FBSyxPQUFMLEVBREY7QUFFUiwrQkFBUywwQkFBVCxHQUFzQyxJQUY5QjtBQUdSLDRCQUFRO0FBSEE7QUFGSCxhQUFiOztBQVNBLGdCQUFJLFVBQUosRUFBZ0I7QUFDWixxQkFBSyxVQUFMLENBQWdCLFVBQWhCLEdBQTZCLFVBQTdCO0FBQ0g7O0FBRUQsaUJBQUssS0FBTCxDQUFXLFFBQVgsQ0FBb0IsSUFBcEIsQ0FBeUIsSUFBekI7QUFDQSxtQkFBTyxJQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7O2lDQUtTLEUsRUFBSTtBQUNULG1CQUFPLEVBQUUsSUFBRixDQUFPLEtBQUssS0FBTCxDQUFXLFFBQWxCLEVBQTRCO0FBQUEsdUJBQVEsS0FBSyxVQUFMLENBQWdCLEVBQWhCLEtBQXVCLEVBQS9CO0FBQUEsYUFBNUIsQ0FBUDtBQUNIOztBQUVEOzs7Ozs7OzttQ0FLVyxJLEVBQU07QUFDYixtQkFBTyxFQUFFLElBQUYsQ0FBTyxLQUFLLEtBQUwsQ0FBVyxRQUFsQixFQUE0QjtBQUFBLHVCQUFRLEtBQUssVUFBTCxDQUFnQixJQUFoQixVQUE0QiwwQkFBNUIsR0FBeUQsSUFBakU7QUFBQSxhQUE1QixDQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7Z0NBSVE7QUFDSixnQkFBSSxDQUFDLEtBQUssS0FBTCxDQUFXLFFBQVgsQ0FBb0IsTUFBekIsRUFBaUM7QUFDakMsbUJBQU8sS0FBSyxLQUFaO0FBQ0g7O0FBRUQ7Ozs7Ozs7O3lDQUtpQjtBQUFBOztBQUNiLGlCQUFLLE9BQUwsR0FBZSxDQUFmO0FBQ0EsaUJBQUssS0FBTCxDQUFXLFFBQVgsQ0FBb0IsT0FBcEIsQ0FBNEIsZ0JBQVE7QUFDaEMsb0JBQU0sS0FBSyxTQUFTLEtBQUssVUFBTCxDQUFnQixFQUFoQixDQUFtQixNQUFuQixDQUEwQixDQUExQixDQUFULENBQVg7QUFDQSxvQkFBSSxNQUFNLE1BQUssT0FBZixFQUF3QixNQUFLLE9BQUwsR0FBZSxLQUFLLENBQXBCO0FBQzNCLGFBSEQ7QUFJSDs7QUFFRDs7Ozs7Ozs7OzhCQU1NLEksRUFBTTtBQUNSLGdCQUFJLENBQUMsSUFBTCxFQUFXLE9BQU87QUFDZCxzQkFBTSxlQURRO0FBRWQsNEJBQVk7QUFDUiwyQkFBTztBQURDLGlCQUZFO0FBS2QsMEJBQVU7QUFMSSxhQUFQOztBQVFYLGlCQUFLLEtBQUwsR0FBYSxJQUFiO0FBQ0g7Ozs7OztBQUdMLE9BQU8sT0FBUCxHQUFpQixhQUFqQjs7QUFFQTs7Ozs7Ozs7Ozs7Ozs7QUMxR0E7Ozs7OztBQUVBLElBQU0sSUFBSSxRQUFRLFFBQVIsQ0FBVjtBQUNBLElBQU0sbUJBQW1CLFFBQVEsb0JBQVIsQ0FBekI7O0FBRUE7Ozs7SUFHTSxRO0FBQ0Y7Ozs7Ozs7O0FBUUEsc0JBQVksSUFBWixFQUFrQjtBQUFBOztBQUNkLGFBQUssS0FBTCxHQUFhLEVBQWI7QUFDQSxhQUFLLEtBQUwsR0FBYSxJQUFiO0FBQ0EsYUFBSyxlQUFMLEdBQXVCLEVBQXZCO0FBQ0EsWUFBSSxJQUFKLEVBQVU7QUFDTixpQkFBSyxJQUFJLElBQUksQ0FBYixFQUFnQixJQUFJLEtBQUssTUFBekIsRUFBaUMsR0FBakMsRUFBc0M7QUFDbEMsb0JBQU0sV0FBVyxLQUFLLENBQUwsQ0FBakI7QUFDQSxvQkFBSSxTQUFTLElBQVQsS0FBa0IsR0FBdEIsRUFBMkI7QUFDdkIseUJBQUssS0FBTCxDQUFXLElBQVgsQ0FBZ0IsSUFBSSxnQkFBSixDQUFxQixRQUFyQixFQUErQixJQUEvQixFQUFxQyxJQUFyQyxDQUFoQjtBQUNILGlCQUZELE1BRU87QUFDSDtBQUNBLHlCQUFLLGVBQUwsQ0FBcUIsSUFBckIsQ0FBMEIsUUFBMUI7QUFDSDtBQUNKO0FBQ0o7QUFDSjs7QUFFRDs7Ozs7Ozs7OztBQWdCQTs7OzsrQkFJTztBQUNILGdCQUFJLE9BQU8sRUFBWDtBQUNBLGlCQUFLLElBQUksSUFBSSxDQUFiLEVBQWdCLElBQUksS0FBSyxLQUFMLENBQVcsTUFBL0IsRUFBdUMsR0FBdkMsRUFBNEM7QUFDeEMsd0JBQVEsS0FBSyxHQUFMLENBQVMsQ0FBVCxFQUFZLEtBQVosRUFBUjtBQUNIO0FBQ0QsbUJBQU8sSUFBUDtBQUNIOztBQUVEOzs7Ozs7OzsrQ0FLdUIsSSxFQUFNO0FBQ3pCLGlCQUFLLEtBQUwsR0FBYSxJQUFiO0FBQ0EsbUJBQU8sSUFBUDtBQUNIOztBQUVEOzs7Ozs7Ozs7OzZCQU9LLEksRUFBTTtBQUNQLGdCQUFNLGNBQWMsSUFBSSxRQUFKLENBQWEsRUFBRSxTQUFGLENBQVksS0FBSyxLQUFMLEVBQVosQ0FBYixDQUFwQjtBQUNBLGdCQUFJLFFBQVEsRUFBRSxRQUFGLENBQVcsS0FBSyxJQUFMLEVBQVgsRUFBd0IsSUFBeEIsQ0FBWixFQUEyQztBQUN2QyxxQkFBSyxLQUFMLENBQVcsVUFBWCxFQUF1QixJQUF2QjtBQUNIO0FBQ0QsbUJBQU8sV0FBUDtBQUNIOztBQUVEOzs7Ozs7Ozs0QkFLSSxLLEVBQU87QUFDUCxtQkFBTyxLQUFLLEtBQUwsQ0FBVyxLQUFYLENBQVA7QUFDSDs7QUFFRDs7Ozs7Ozs7K0JBS08sSyxFQUFPO0FBQ1YsaUJBQUssS0FBTCxDQUFXLE1BQVgsQ0FBa0IsS0FBbEIsRUFBeUIsQ0FBekI7QUFDQSxpQkFBSyxzQkFBTDtBQUNBLG1CQUFPLElBQVA7QUFDSDs7QUFFRDs7Ozs7Ozs7Ozs0QkFPSSxJLEVBQU0sTSxFQUFRLEssRUFBTztBQUNyQixnQkFBSSxVQUFVLFNBQVYsSUFBdUIsVUFBVSxJQUFyQyxFQUEyQztBQUN2QyxxQkFBSyxLQUFMLENBQVcsSUFBWCxDQUFnQixJQUFJLGdCQUFKLENBQXFCLElBQXJCLEVBQTJCLE1BQTNCLEVBQW1DLElBQW5DLENBQWhCO0FBQ0gsYUFGRCxNQUVPO0FBQ0gscUJBQUssS0FBTCxDQUFXLE1BQVgsQ0FBa0IsS0FBbEIsRUFBeUIsQ0FBekIsRUFBNEIsSUFBSSxnQkFBSixDQUFxQixJQUFyQixFQUEyQixNQUEzQixFQUFtQyxJQUFuQyxDQUE1QjtBQUNIO0FBQ0QsaUJBQUssc0JBQUw7QUFDQSxtQkFBTyxJQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7Z0NBSVE7QUFDSixpQkFBSyxLQUFMLEdBQWEsRUFBYjtBQUNBLGlCQUFLLGVBQUwsR0FBdUIsRUFBdkI7QUFDQSxpQkFBSyxLQUFMLEdBQWEsU0FBYjtBQUNBLG1CQUFPLElBQVA7QUFDSDs7QUFFRDs7Ozs7OztpREFJeUI7QUFDckIsaUJBQUssZUFBTCxHQUF1QixFQUF2QjtBQUNIOztBQUVEOzs7Ozs7OztnQ0FLUTtBQUNKLGdCQUFNLE9BQU8sRUFBYjtBQUNBLGlCQUFLLElBQUksSUFBSSxDQUFiLEVBQWdCLElBQUksS0FBSyxLQUFMLENBQVcsTUFBL0IsRUFBdUMsR0FBdkMsRUFBNEM7QUFDeEMscUJBQUssSUFBTCxDQUFVLEtBQUssS0FBTCxDQUFXLENBQVgsRUFBYyxLQUFkLEVBQVY7QUFDSDtBQUNELG1CQUFPLEtBQUssTUFBTCxDQUFZLEtBQUssZUFBakIsQ0FBUDtBQUNIOzs7NEJBcEhVO0FBQ1AsbUJBQU8sS0FBSyxLQUFaO0FBQ0g7O0FBRUQ7Ozs7Ozs7NEJBSWE7QUFDVCxtQkFBTyxLQUFLLEtBQUwsQ0FBVyxNQUFsQjtBQUNIOzs7Ozs7QUE2R0w7OztBQUNBLElBQUksQ0FBQyxTQUFTLElBQWQsRUFBb0IsU0FBUyxJQUFULEdBQWdCLFVBQWhCOztBQUVwQixPQUFPLE9BQVAsR0FBaUIsUUFBakI7OztBQ2hLQTs7QUFFQTs7Ozs7O0FBRUEsSUFBTSxhQUFhLFFBQVEsY0FBUixDQUFuQjtBQUNBLElBQU0sSUFBSSxRQUFRLFFBQVIsQ0FBVjtBQUNBLElBQU0sT0FBTyxRQUFRLFFBQVIsQ0FBYjtBQUNBLElBQU0sZUFBZSxRQUFRLGdCQUFSLENBQXJCOztBQUVBOzs7O0lBR00sZ0I7QUFDRjs7Ozs7OztBQU9BLDhCQUFZLEtBQVosRUFBbUIsTUFBbkIsRUFBMkIsUUFBM0IsRUFBcUM7QUFBQTs7QUFDakMsYUFBSyxTQUFMLEdBQWlCLFFBQWpCO0FBQ0EsWUFBSSxNQUFNLElBQU4sS0FBZSxHQUFuQixFQUF3QjtBQUNwQixpQkFBSyxLQUFMLEdBQWEsS0FBYjtBQUNBLGlCQUFLLFNBQUwsR0FBaUIsS0FBSyxTQUFMLENBQWUsS0FBSyxLQUFwQixFQUEyQixLQUEzQixDQUFqQjtBQUNBLGdCQUFJLENBQUMsS0FBSyxTQUFWLEVBQXFCO0FBQ2pCLHFCQUFLLFNBQUwsR0FBaUIsRUFBRSxNQUFNLEtBQVIsRUFBZSxZQUFZLEVBQTNCLEVBQStCLFVBQVUsRUFBekMsRUFBakI7QUFDQSxxQkFBSyxLQUFMLENBQVcsUUFBWCxDQUFvQixPQUFwQixDQUE0QixLQUFLLFNBQWpDO0FBQ0g7QUFDRCxpQkFBSyxVQUFMLEdBQWtCLEtBQUssU0FBTCxDQUFlLEtBQUssS0FBcEIsRUFBMkIsR0FBM0IsQ0FBbEI7QUFDSCxTQVJELE1BUU87QUFDSCxpQkFBSyxLQUFMLEdBQWE7QUFDVCxzQkFBTSxHQURHO0FBRVQsNEJBQVksRUFGSDtBQUdULDBCQUFVLENBQ04sRUFBRSxNQUFNLEtBQVIsRUFBZSxZQUFZLEVBQTNCLEVBQStCLFVBQVUsRUFBekMsRUFETSxFQUVOLEVBQUUsTUFBTSxHQUFSLEVBQWEsWUFBWSxFQUF6QixFQUE2QixVQUFVLEVBQXZDLEVBRk07QUFIRCxhQUFiO0FBUUEsaUJBQUssU0FBTCxHQUFpQixLQUFLLFNBQUwsQ0FBZSxLQUFLLEtBQXBCLEVBQTJCLEtBQTNCLENBQWpCO0FBQ0EsaUJBQUssVUFBTCxHQUFrQixLQUFLLFNBQUwsQ0FBZSxLQUFLLEtBQXBCLEVBQTJCLEdBQTNCLENBQWxCO0FBQ0EsaUJBQUssS0FBTCxDQUFXLEtBQVg7QUFDQSxnQkFBSSxNQUFKLEVBQVk7QUFDUixxQkFBSyxLQUFMLENBQVcsTUFBWDtBQUNIO0FBQ0o7QUFDSjs7QUFFRDs7O1FBR0c7Ozs7Ozs7OztnQ0FLSztBQUFBOztBQUNKLG1CQUFPLElBQUksVUFBSixDQUFlLGlCQUFmLEVBQ0YsSUFERSxDQUNHLFlBQU07QUFDUix1QkFBTyxNQUFLLFVBQUwsQ0FBZ0IsUUFBaEIsQ0FBeUIsQ0FBekIsQ0FBUDtBQUNILGFBSEUsRUFJRixJQUpFLENBSUcsUUFKSCxFQUlhLGlCQUFTO0FBQ3JCLHdCQUFRLE1BQU0sT0FBTixDQUFjLGlCQUFkLEVBQWlDLE1BQWpDLENBQVI7QUFDQSxvQkFBTSxtQkFBbUIsTUFBTSxPQUFOLENBQWMsTUFBZCxNQUEwQixDQUFDLENBQXBEO0FBQ0Esc0JBQUssVUFBTCxDQUFnQixRQUFoQixDQUF5QixDQUF6QixJQUE4QixLQUE5QjtBQUNBLG9CQUFJLE1BQU0sTUFBTixDQUFhLENBQWIsTUFBb0IsR0FBeEIsRUFBNkIsS0FBSyxhQUFMLENBQW1CLE1BQUssVUFBeEIsRUFBb0MsRUFBRSxhQUFhLFVBQWYsRUFBcEM7O0FBRTdCLG9CQUFJLE1BQUssU0FBVCxFQUFvQixNQUFLLFNBQUwsQ0FBZSxzQkFBZjtBQUNwQixvQkFBSSxnQkFBSixFQUFzQjtBQUNsQjtBQUNBLHdCQUFJLE1BQUssU0FBTCxDQUFlLElBQW5CLEVBQXlCO0FBQ3JCLDhCQUFLLFNBQUwsQ0FBZSxJQUFmLENBQW9CLEtBQXBCLENBQTBCLFVBQTFCLEVBQXNDLElBQXRDO0FBQ0g7QUFDRCx5QkFBSyxhQUFMLENBQW1CLE1BQUssVUFBeEIsRUFBb0MsRUFBRSxhQUFhLFVBQWYsRUFBcEM7QUFDSDtBQUNELHVCQUFPLEtBQVA7QUFDSCxhQW5CRSxFQW9CRixNQXBCRSxDQW9CSyxTQXBCTCxDQUFQO0FBcUJIOztBQUVEOzs7Ozs7OztnQ0FLUTtBQUNKLG1CQUFPLEtBQUssS0FBWjtBQUNIOztBQUVEOzs7O1lBSUc7Ozs7ZUFJQTs7Ozs7a0JBS0E7Ozs7Ozs7O2dDQUtLO0FBQUE7O0FBQ0osbUJBQU8sSUFBSSxVQUFKLENBQWUsaUJBQWYsRUFDRixJQURFLENBQ0csUUFESCxFQUNhLGdCQUFRO0FBQ3BCO0FBQ0Esb0JBQU0sdUJBQXFCLElBQTNCO0FBQ0Esb0JBQUksQ0FBQyxPQUFLLFVBQUwsQ0FBTCxFQUF1QixNQUFNLElBQUksS0FBSix3QkFBK0IsSUFBL0IsNEJBQU47QUFDdkIsdUJBQU8sT0FBSyxVQUFMLEdBQVA7QUFDSCxhQU5FLEVBT0YsSUFQRSxDQU9HLE9BUEgsRUFPWSxpQkFBUztBQUNwQjtBQUNBLG9CQUFNLFNBQVMsRUFBZjtBQUNBLHNCQUFNLE9BQU4sQ0FBYyxnQkFBUTtBQUNsQiwyQkFBTyxJQUFQLElBQWUsT0FBSyxLQUFMLENBQVcsSUFBWCxDQUFmO0FBQ0gsaUJBRkQ7QUFHQSx1QkFBTyxNQUFQO0FBQ0gsYUFkRSxFQWVGLElBZkUsQ0FlRyxDQUFDLFFBQUQsRUFBVyxHQUFYLENBZkgsRUFlb0IsVUFBQyxJQUFELEVBQU8sS0FBUCxFQUFpQjtBQUNwQztBQUNBLG9CQUFNLHVCQUFxQixJQUEzQjtBQUNBLG9CQUFJLENBQUMsT0FBSyxVQUFMLENBQUwsRUFBdUIsTUFBTSxJQUFJLEtBQUosd0JBQStCLElBQS9CLDRCQUFOO0FBQ3ZCLHVCQUFPLE9BQUssVUFBTCxFQUFpQixLQUFqQixDQUFQO0FBQ0gsYUFwQkUsRUFxQkYsSUFyQkUsQ0FxQkcsUUFyQkgsRUFxQmEsc0JBQWM7QUFDMUI7QUFDQSxxQkFBSyxJQUFNLElBQVgsSUFBbUIsVUFBbkIsRUFBK0I7QUFDM0Isd0JBQUksQ0FBQyxXQUFXLGNBQVgsQ0FBMEIsSUFBMUIsQ0FBTCxFQUFzQztBQUN0Qyx3QkFBTSxRQUFRLFdBQVcsSUFBWCxDQUFkO0FBQ0EsMkJBQUssS0FBTCxDQUFXLElBQVgsRUFBaUIsS0FBakI7QUFDSDtBQUNELHVCQUFPLE1BQVA7QUFDSCxhQTdCRSxFQThCRixNQTlCRSxDQThCSyxTQTlCTCxDQUFQO0FBK0JIOzs7a0NBRVMsSSxFQUFNLEksRUFBTTtBQUNsQixnQkFBTSxRQUFRLEtBQUssU0FBTCxDQUFlLElBQWYsRUFBcUIsSUFBckIsQ0FBZDtBQUNBLGdCQUFJLENBQUMsS0FBRCxJQUFVLENBQUMsTUFBTSxVQUFyQixFQUFpQzs7QUFFakMsZ0JBQU0sUUFBUSxFQUFkO0FBQ0EsZ0JBQUksTUFBTSxVQUFOLENBQWlCLGNBQWpCLENBQWdDLEtBQWhDLENBQUosRUFBNEMsTUFBTSxHQUFOLEdBQVksTUFBTSxVQUFOLENBQWlCLEdBQTdCLENBQTVDLEtBQ0ssSUFBSSxNQUFNLFVBQU4sQ0FBaUIsY0FBakIsQ0FBZ0MsT0FBaEMsQ0FBSixFQUE4QyxNQUFNLEtBQU4sR0FBYyxNQUFNLFVBQU4sQ0FBaUIsS0FBL0IsQ0FBOUMsS0FDQSxJQUFJLE1BQU0sVUFBTixDQUFpQixjQUFqQixDQUFnQyxTQUFoQyxDQUFKLEVBQWdELE1BQU0sR0FBTixHQUFZLGFBQWEsTUFBTSxVQUFOLENBQWlCLE9BQTlCLENBQVo7O0FBRXJELGdCQUFJLE1BQU0sVUFBTixDQUFpQixjQUFqQixDQUFnQyxNQUFoQyxDQUFKLEVBQTZDLE1BQU0sSUFBTixHQUFhLE1BQU0sVUFBTixDQUFpQixJQUE5Qjs7QUFFN0MsZ0JBQUksRUFBRSxPQUFGLENBQVUsS0FBVixDQUFKLEVBQXNCOztBQUV0QixtQkFBTyxLQUFQO0FBQ0g7OztrQ0FFUyxJLEVBQU0sSSxFQUFNLEssRUFBTztBQUN6QixnQkFBSSxPQUFPLEtBQVAsS0FBaUIsUUFBckIsRUFBK0IsUUFBUSxFQUFFLEtBQUssS0FBUCxFQUFSLENBQS9CLEtBQ0ssSUFBSSxPQUFPLEtBQVAsS0FBaUIsUUFBckIsRUFBK0IsUUFBUSxFQUFFLE9BQU8sS0FBVCxFQUFSOztBQUVwQyxpQkFBSyxrQkFBTCxDQUF3QixJQUF4QixFQUE4QixJQUE5QixFQUFvQztBQUNoQyxxQkFBSyxTQUFTLE1BQU0sR0FBZixJQUFzQixNQUFNLEdBQU4sQ0FBVSxXQUFWLEVBREs7QUFFaEMseUJBQVMsSUFGdUI7QUFHaEMsdUJBQU8sU0FBUyxNQUFNLEtBSFU7QUFJaEMsc0JBQU0sU0FBUyxNQUFNO0FBSlcsYUFBcEM7O0FBT0EsaUJBQUssa0JBQUwsQ0FBd0IsSUFBeEIsRUFBOEIsT0FBOUI7QUFDSDs7O29DQUVXO0FBQ1IsbUJBQU8sS0FBSyxRQUFMLENBQWMsS0FBSyxTQUFuQixFQUE4QixHQUE5QixDQUFQO0FBQ0g7OztrQ0FFUyxJLEVBQU07QUFDWixnQkFBSSxJQUFKLEVBQVUsS0FBSyxxQkFBTCxDQUEyQixLQUFLLFNBQWhDLEVBQTJDLEdBQTNDLEVBQVYsS0FDSyxLQUFLLFdBQUwsQ0FBaUIsS0FBSyxTQUF0QixFQUFpQyxHQUFqQztBQUNSOzs7c0NBRWE7QUFDVixtQkFBTyxLQUFLLFFBQUwsQ0FBYyxLQUFLLFNBQW5CLEVBQThCLEdBQTlCLENBQVA7QUFDSDs7O29DQUVXLE0sRUFBUTtBQUNoQixnQkFBSSxNQUFKLEVBQVksS0FBSyxxQkFBTCxDQUEyQixLQUFLLFNBQWhDLEVBQTJDLEdBQTNDLEVBQVosS0FDSyxLQUFLLFdBQUwsQ0FBaUIsS0FBSyxTQUF0QixFQUFpQyxHQUFqQztBQUNSOzs7eUNBRWdCO0FBQ2IsZ0JBQU0sUUFBUSxLQUFLLFNBQUwsQ0FBZSxLQUFLLFNBQXBCLEVBQStCLEdBQS9CLENBQWQ7QUFDQSxtQkFBTyxRQUFRLE1BQU0sVUFBTixDQUFpQixHQUFqQixJQUF3QixJQUFoQyxHQUF1QyxLQUE5QztBQUNIOzs7dUNBRWMsUyxFQUFXO0FBQ3RCLGdCQUFJLFNBQUosRUFBZTtBQUNYLG9CQUFNLFFBQVEsS0FBSyxxQkFBTCxDQUEyQixLQUFLLFNBQWhDLEVBQTJDLEdBQTNDLENBQWQ7QUFDQSxvQkFBTSxNQUFNLE9BQU8sU0FBUCxLQUFxQixRQUFyQixHQUFnQyxTQUFoQyxHQUE0QyxJQUF4RDtBQUNBLHFCQUFLLGFBQUwsQ0FBbUIsS0FBbkIsRUFBMEIsRUFBRSxRQUFGLEVBQTFCO0FBQ0gsYUFKRCxNQUlPO0FBQ0gscUJBQUssV0FBTCxDQUFpQixLQUFLLFNBQXRCLEVBQWlDLEdBQWpDO0FBQ0g7QUFDSjs7OzZDQUVvQjtBQUNqQixtQkFBTyxLQUFLLFFBQUwsQ0FBYyxLQUFLLFNBQW5CLEVBQThCLFFBQTlCLENBQVA7QUFDSDs7OzJDQUVrQixhLEVBQWU7QUFDOUIsZ0JBQUksYUFBSixFQUFtQixLQUFLLHFCQUFMLENBQTJCLEtBQUssU0FBaEMsRUFBMkMsUUFBM0MsRUFBbkIsS0FDSyxLQUFLLFdBQUwsQ0FBaUIsS0FBSyxTQUF0QixFQUFpQyxRQUFqQztBQUNSOzs7b0RBRTJCO0FBQ3hCLG1CQUFPLEtBQUssaUJBQUwsQ0FBdUIsS0FBSyxTQUE1QixFQUF1QyxXQUF2QyxFQUFvRCxLQUFwRCxDQUFQO0FBQ0g7OztrREFFeUIsUyxFQUFXO0FBQ2pDLGlCQUFLLGtCQUFMLENBQXdCLEtBQUssU0FBN0IsRUFBd0MsV0FBeEMsRUFBcUQsRUFBRSxLQUFLLFNBQVAsRUFBckQ7QUFDQSxpQkFBSyxrQkFBTCxDQUF3QixLQUFLLFNBQTdCLEVBQXdDLFdBQXhDO0FBQ0g7Ozt5Q0FFZ0I7QUFDYixtQkFBTyxLQUFLLHlCQUFMLE9BQXFDLFdBQTVDO0FBQ0g7Ozt1Q0FFYyxTLEVBQVc7QUFDdEIsaUJBQUsseUJBQUwsQ0FBK0IsWUFBWSxXQUFaLEdBQTBCLElBQXpEO0FBQ0g7OzsyQ0FFa0I7QUFDZixtQkFBTyxLQUFLLHlCQUFMLE9BQXFDLGFBQTVDO0FBQ0g7Ozt5Q0FFZ0IsVyxFQUFhO0FBQzFCLGlCQUFLLHlCQUFMLENBQStCLGNBQWMsYUFBZCxHQUE4QixJQUE3RDtBQUNIOzs7d0NBRWU7QUFDWixtQkFBTyxLQUFLLGlCQUFMLENBQXVCLEtBQUssU0FBNUIsRUFBdUMsSUFBdkMsRUFBNkMsS0FBN0MsQ0FBUDtBQUNIOzs7c0NBRWEsSSxFQUFNO0FBQ2hCLGlCQUFLLGtCQUFMLENBQXdCLEtBQUssU0FBN0IsRUFBd0MsSUFBeEMsRUFBOEMsRUFBRSxLQUFLLElBQVAsRUFBOUM7QUFDQSxpQkFBSyxrQkFBTCxDQUF3QixLQUFLLFNBQTdCLEVBQXdDLElBQXhDO0FBQ0g7OzswQ0FFaUI7QUFDZCxtQkFBTyxLQUFLLGlCQUFMLENBQXVCLEtBQUssU0FBNUIsRUFBdUMsT0FBdkMsRUFBZ0QsS0FBaEQsQ0FBUDtBQUNIOzs7d0NBRWUsTSxFQUFRO0FBQ3BCLGlCQUFLLGtCQUFMLENBQXdCLEtBQUssU0FBN0IsRUFBd0MsT0FBeEMsRUFBaUQsRUFBRSxLQUFLLE1BQVAsRUFBakQ7QUFDQSxpQkFBSyxrQkFBTCxDQUF3QixLQUFLLFNBQTdCLEVBQXdDLE9BQXhDO0FBQ0g7OztpREFFd0I7QUFDckIsbUJBQU8sS0FBSyxpQkFBTCxDQUF1QixLQUFLLFNBQTVCLEVBQXVDLFFBQXZDLEVBQWlELEtBQWpELENBQVA7QUFDSDs7QUFFRDs7Ozs7Ozs7K0NBS3VCLGEsRUFBZTtBQUNsQyxpQkFBSyxrQkFBTCxDQUF3QixLQUFLLFNBQTdCLEVBQXdDLFFBQXhDLEVBQWtELEVBQUUsS0FBSyxhQUFQLEVBQWxEO0FBQ0EsaUJBQUssa0JBQUwsQ0FBd0IsS0FBSyxTQUE3QixFQUF3QyxRQUF4QztBQUNIOzs7eUNBRWdCO0FBQ2IsbUJBQU8sS0FBSyxTQUFMLENBQWUsS0FBSyxTQUFwQixFQUErQixPQUEvQixDQUFQO0FBQ0g7Ozt1Q0FFYyxLLEVBQU87QUFDbEIsaUJBQUssU0FBTCxDQUFlLEtBQUssU0FBcEIsRUFBK0IsT0FBL0IsRUFBd0MsS0FBeEM7QUFDSDs7OzBDQUVpQjtBQUNkO0FBQ0EsbUJBQU8sS0FBSyxpQkFBTCxDQUF1QixLQUFLLFNBQTVCLEVBQXVDLFFBQXZDLEVBQWlELEtBQWpELENBQVA7QUFDSDs7QUFFRDs7Ozs7Ozs7d0NBS2dCLE0sRUFBUTtBQUNwQixpQkFBSyxrQkFBTCxDQUF3QixLQUFLLFNBQTdCLEVBQXdDLFFBQXhDLEVBQWtELEVBQUUsS0FBSyxNQUFQLEVBQWxEO0FBQ0EsaUJBQUssa0JBQUwsQ0FBd0IsS0FBSyxTQUE3QixFQUF3QyxRQUF4QztBQUNIOzs7Ozs7QUFHTDs7O0FBQ0EsSUFBSSxDQUFDLGlCQUFpQixJQUF0QixFQUE0QixpQkFBaUIsSUFBakIsR0FBd0Isa0JBQXhCOztBQUU1QixPQUFPLE9BQVAsR0FBaUIsZ0JBQWpCOzs7QUN6U0E7Ozs7OztBQUVBLElBQU0sSUFBSSxRQUFRLFFBQVIsQ0FBVjtBQUNBLElBQU0sT0FBTyxRQUFRLFFBQVIsQ0FBYjtBQUNBLElBQU0sV0FBVyxRQUFRLFlBQVIsQ0FBakI7QUFDQSxJQUFNLGFBQWEsUUFBUSxjQUFSLENBQW5CO0FBQ0EsSUFBTSxtQkFBbUIsUUFBUSxvQkFBUixDQUF6Qjs7QUFFQTs7OztJQUdNLEc7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQVksS0FBWixFQUFtQixJQUFuQixFQUF5QjtBQUFBOztBQUNyQixhQUFLLE1BQUwsR0FBYyxLQUFkO0FBQ0EsYUFBSyxLQUFMLENBQVcsSUFBWDtBQUNIOztBQUVEOztBQUVBOzs7Ozs7Ozs7OztnQ0FPUSxJLEVBQU07QUFDVixtQkFBTyxpQkFBaUIsU0FBakIsQ0FBMkI7QUFDOUIsc0JBQU0sS0FEd0I7QUFFOUIsMkJBQVcsS0FBSyxTQUFMLEVBRm1CO0FBRzlCLDJCQUFXLFFBQVEsS0FBSyxnQkFBYixJQUFpQyxLQUFLLEtBQUwsR0FBYSxJQUFiLEVBSGQ7QUFJOUIsNkJBQWEsUUFBUSxLQUFLO0FBSkksYUFBM0IsQ0FBUDtBQU1IOztBQUVEOzs7Ozs7Ozs2QkFLSyxrQixFQUFvQjtBQUNyQixnQkFBSSxlQUFlLGtCQUFuQjtBQUNBLGdCQUFJLE9BQU8sa0JBQVAsS0FBOEIsUUFBbEMsRUFBNEM7QUFDeEMsK0JBQWUsaUJBQWlCLGtCQUFqQixDQUFvQyxrQkFBcEMsQ0FBZjtBQUNIOztBQUVELGdCQUFJLGVBQWUsQ0FBbkIsRUFBc0IsTUFBTSxJQUFJLFVBQUosNEJBQXdDLFlBQXhDLHdEQUFOOztBQUV0QjtBQUNBLGdCQUFJLEtBQUssTUFBTCxDQUFZLFlBQVosQ0FBSixFQUErQixPQUFPLEtBQUssTUFBTCxDQUFZLFlBQVosQ0FBUDs7QUFFL0I7QUFDQTtBQUNBLGdCQUFJLGdCQUFKO0FBQ0EsZ0JBQU0sYUFBYSxLQUFLLEtBQUwsQ0FBVyxVQUFYLENBQXNCLENBQXpDO0FBQ0EsZ0JBQU0sZ0JBQWdCLEtBQUssS0FBTCxHQUFhLHFCQUFiLENBQW1DLFlBQW5DLENBQXRCOztBQUVBO0FBQ0EsZ0JBQUksQ0FBQyxFQUFFLEtBQUYsQ0FBUSxVQUFSLENBQUwsRUFBMEIsVUFBVSxVQUFWLENBQTFCLEtBQ0ssSUFBSSxDQUFDLEVBQUUsS0FBRixDQUFRLGFBQVIsQ0FBTCxFQUE2QixVQUFVLGFBQVY7O0FBRWxDO0FBQ0EsZ0JBQU0sT0FBTyxJQUFJLElBQUosQ0FBUyxJQUFULEVBQWUsWUFBZixFQUE2QixPQUE3QixDQUFiO0FBQ0EsaUJBQUssTUFBTCxDQUFZLFlBQVosSUFBNEIsSUFBNUI7QUFDQSxtQkFBTyxJQUFQO0FBQ0g7O0FBRUQ7OztZQUdHOzs7Ozs7OztpQ0FLTTtBQUFBOztBQUNMLG1CQUFPLElBQUksVUFBSixDQUFlLFlBQWYsRUFDRixJQURFLENBQ0csWUFBTTtBQUNSLHVCQUFPLE1BQUssS0FBTCxDQUFXLFVBQVgsQ0FBc0IsWUFBdEIsR0FBcUMsTUFBSyxLQUFMLENBQVcsVUFBWCxDQUFzQixFQUEzRCxHQUFnRSxTQUF2RTtBQUNILGFBSEUsRUFJRixJQUpFLENBSUcsUUFKSCxFQUlhLGtCQUFVO0FBQ3RCLHNCQUFLLEtBQUwsQ0FBVyxVQUFYLENBQXNCLEVBQXRCLEdBQTJCLE1BQTNCO0FBQ0Esc0JBQUssS0FBTCxDQUFXLFVBQVgsQ0FBc0IsWUFBdEIsR0FBcUMsQ0FBckM7QUFDQSx1QkFBTyxLQUFQO0FBQ0gsYUFSRSxFQVNGLElBVEUsQ0FTRyxLQVRILEVBU1UsWUFBTTtBQUNmLHVCQUFPLE1BQUssS0FBTCxDQUFXLFVBQVgsQ0FBc0IsRUFBN0I7QUFDQSx1QkFBTyxNQUFLLEtBQUwsQ0FBVyxVQUFYLENBQXNCLFlBQTdCO0FBQ0EsdUJBQU8sS0FBUDtBQUNILGFBYkUsRUFjRixNQWRFLENBY0ssU0FkTCxDQUFQO0FBZUg7O0FBRUQ7OztZQUdHOzs7Ozs7OztpQ0FLTTtBQUFBOztBQUNMLG1CQUFPLElBQUksVUFBSixDQUFlLFlBQWYsRUFDRixJQURFLENBQ0csWUFBTTtBQUNSLHVCQUFPLE9BQUssS0FBTCxDQUFXLFVBQVgsQ0FBc0IsTUFBdEIsS0FBaUMsQ0FBeEM7QUFDSCxhQUhFLEVBSUYsSUFKRSxDQUlHLFNBSkgsRUFJYyxrQkFBVTtBQUN2QixvQkFBSSxNQUFKLEVBQVksT0FBSyxLQUFMLENBQVcsVUFBWCxDQUFzQixNQUF0QixHQUErQixDQUEvQixDQUFaLEtBQ0ssT0FBTyxPQUFLLEtBQUwsQ0FBVyxVQUFYLENBQXNCLE1BQTdCO0FBQ0wsdUJBQU8sTUFBUDtBQUNILGFBUkUsRUFTRixNQVRFLENBU0ssU0FUTCxDQUFQO0FBVUg7O0FBRUQ7Ozs7Ozs7b0NBSVk7QUFDUixtQkFBTyxLQUFLLEtBQUwsQ0FBVyxVQUFYLENBQXNCLENBQTdCO0FBQ0g7O0FBRUQ7Ozs7Ozs7Z0NBSVE7QUFDSixtQkFBTyxLQUFLLE1BQVo7QUFDSDs7QUFFRDs7OztZQUlHOzs7O2VBSUE7Ozs7O2tCQUtBOzs7O3FCQUlBOzs7Ozs7OztnQ0FLSztBQUFBOztBQUNKLG1CQUFPLElBQUksVUFBSixDQUFlLFdBQWYsRUFDRixJQURFLENBQ0csUUFESCxFQUNhLGdCQUFRO0FBQ3BCO0FBQ0EsdUJBQUssb0JBQUw7QUFDQSx1QkFBTyxPQUFLLE1BQUwsQ0FBWSxLQUFaLENBQWtCLElBQWxCLENBQVA7QUFDSCxhQUxFLEVBTUYsSUFORSxDQU1HLE9BTkgsRUFNWSxpQkFBUztBQUNwQjtBQUNBLG9CQUFNLFNBQVMsRUFBZjtBQUNBLHNCQUFNLE9BQU4sQ0FBYyxnQkFBUTtBQUNsQiwyQkFBTyxJQUFQLElBQWUsT0FBSyxLQUFMLENBQVcsSUFBWCxDQUFmO0FBQ0gsaUJBRkQ7O0FBSUEsdUJBQU8sTUFBUDtBQUNILGFBZEUsRUFlRixJQWZFLENBZUcsQ0FBQyxRQUFELEVBQVcsR0FBWCxDQWZILEVBZW9CLFVBQUMsSUFBRCxFQUFPLEtBQVAsRUFBaUI7QUFDcEMsdUJBQUsseUJBQUw7O0FBRUE7QUFDQSxrQkFBRSxPQUFGLENBQVUsT0FBSyxNQUFmLEVBQXVCLGdCQUFRO0FBQzNCLHdCQUFJLElBQUosRUFBVSxLQUFLLEtBQUwsQ0FBVyxJQUFYLEVBQWlCLEtBQWpCO0FBQ2IsaUJBRkQ7O0FBSUE7QUFDQSx1QkFBSyxvQkFBTDtBQUNBLHVCQUFLLE1BQUwsQ0FBWSxLQUFaLENBQWtCLElBQWxCLEVBQXdCLEtBQXhCOztBQUVBLHVCQUFPLE1BQVA7QUFDSCxhQTVCRSxFQTZCRixJQTdCRSxDQTZCRyxRQTdCSCxFQTZCYSxzQkFBYztBQUMxQjtBQUNBLHFCQUFLLElBQU0sSUFBWCxJQUFtQixVQUFuQixFQUErQjtBQUMzQix3QkFBSSxDQUFDLFdBQVcsY0FBWCxDQUEwQixJQUExQixDQUFMLEVBQXNDO0FBQ3RDLHdCQUFNLFFBQVEsV0FBVyxJQUFYLENBQWQ7QUFDQSwyQkFBSyxLQUFMLENBQVcsSUFBWCxFQUFpQixLQUFqQjtBQUNIOztBQUVELHVCQUFPLE1BQVA7QUFDSCxhQXRDRSxFQXVDRixJQXZDRSxDQXVDRyxPQXZDSCxFQXVDWSxpQkFBUztBQUNwQix1QkFBSyx5QkFBTDs7QUFFQTtBQUNBLGtCQUFFLE9BQUYsQ0FBVSxPQUFLLE1BQWYsRUFBdUIsZ0JBQVE7QUFDM0Isd0JBQUksSUFBSixFQUFVLEtBQUssS0FBTCxDQUFXLEtBQVg7QUFDYixpQkFGRDs7QUFJQSx1QkFBSyxNQUFMLEdBQWMsS0FBZDtBQUNBLHVCQUFLLEtBQUwsQ0FBVyxVQUFYLENBQXNCLENBQXRCLEdBQTBCLE1BQU0sRUFBTixFQUExQjtBQUNBLHVCQUFLLEtBQUwsQ0FBVyxVQUFYLENBQXNCLFlBQXRCLEdBQXFDLENBQXJDOztBQUVBLHVCQUFPLE1BQVA7QUFDSCxhQXBERSxFQXFERixNQXJERSxDQXFESyxTQXJETCxDQUFQO0FBc0RIOztBQUVEOzs7Ozs7O21DQUlXO0FBQ1AsbUJBQU8sS0FBSyxLQUFMLEdBQWEsUUFBYixFQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7dUNBSWU7QUFDWCxpQkFBSyxLQUFMLEdBQWEsb0JBQWIsR0FBb0MsR0FBcEMsQ0FBd0MsS0FBSyxTQUFMLEVBQXhDO0FBQ0EsbUJBQU8sSUFBUDtBQUNIOztBQUVEOztBQUVBOzs7Ozs7Ozs7cURBTTZCLGUsRUFBaUI7QUFDMUMsaUJBQUssTUFBTCxDQUFZLE9BQVosQ0FBb0IsZ0JBQVE7QUFDeEIsb0JBQUksQ0FBQyxJQUFMLEVBQVc7QUFDWCxvQkFBSSxLQUFLLGFBQUwsQ0FBbUIsZUFBbkIsQ0FBSixFQUF5QyxLQUFLLEtBQUw7QUFDNUMsYUFIRDtBQUlIOztBQUVEOzs7Ozs7Ozs7OzZCQU9LLE8sRUFBUyxXLEVBQWE7QUFDdkIsc0JBQVUsU0FBUyxPQUFULENBQVY7O0FBRUEsZ0JBQU0sVUFBVSxFQUFoQjtBQUNBLGlCQUFLLE1BQUwsQ0FBWSxPQUFaLENBQW9CLGdCQUFRO0FBQ3hCLG9CQUFJLENBQUMsSUFBTCxFQUFXO0FBQ1gsb0JBQUksS0FBSyxJQUFMLENBQVUsT0FBVixFQUFtQixXQUFuQixDQUFKLEVBQXFDLFFBQVEsSUFBUixDQUFhLElBQWI7QUFDeEMsYUFIRDs7QUFLQSxtQkFBTyxPQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7OztnQ0FNUSxZLEVBQWM7QUFDbEIsZ0JBQUksZUFBZSxDQUFuQixFQUFzQixNQUFNLElBQUksVUFBSiw0QkFBd0MsWUFBeEMsd0RBQU47QUFDdEIsbUJBQU8sQ0FBQyxDQUFDLEtBQUssTUFBTCxDQUFZLFlBQVosQ0FBVDtBQUNIOztBQUVEOzs7Ozs7OzttQ0FLVztBQUNQLG1CQUFPLENBQUMsRUFBRSxLQUFGLENBQVEsS0FBSyxLQUFMLENBQVcsVUFBWCxDQUFzQixDQUE5QixDQUFSO0FBQ0g7O0FBRUQ7Ozs7Ozs7OzhDQUtzQjtBQUNsQixtQkFBTyxFQUFFLFNBQUYsQ0FBWSxLQUFLLE1BQWpCLENBQVA7QUFDSDs7QUFFRDs7Ozs7Ozs7OENBS3NCO0FBQ2xCLG1CQUFPLEtBQUssTUFBTCxDQUFZLE1BQVosR0FBcUIsQ0FBNUI7QUFDSDs7QUFFRDs7Ozs7Ozs7Z0NBS1E7QUFDSixtQkFBTyxLQUFLLEtBQVo7QUFDSDs7QUFFRDs7QUFFQTs7Ozs7Ozs7OztvREFPNEI7QUFBQTs7QUFDeEIsaUJBQUssS0FBTCxHQUFhLDJCQUFiLENBQXlDLHdCQUFnQjtBQUNyRCxvQkFBSSxDQUFDLEVBQUUsS0FBRixDQUFRLE9BQUssS0FBTCxHQUFhLHFCQUFiLENBQW1DLFlBQW5DLENBQVIsQ0FBTCxFQUFnRSxPQUFLLElBQUwsQ0FBVSxZQUFWO0FBQ25FLGFBRkQ7QUFHSDs7QUFFRDs7Ozs7Ozs7K0NBS3VCO0FBQ25CLGdCQUFJLENBQUMsS0FBSyxNQUFWLEVBQWtCO0FBQ2Qsb0JBQU0sVUFBVSxLQUFLLEtBQUwsQ0FBVyxVQUFYLENBQXNCLENBQXRDO0FBQ0EscUJBQUssTUFBTCxHQUFjLEtBQUssUUFBTCxHQUFnQixVQUFoQixHQUE2QixXQUE3QixDQUF5QyxPQUF6QyxDQUFkO0FBQ0EscUJBQUssS0FBTCxDQUFXLFVBQVgsQ0FBc0IsQ0FBdEIsR0FBMEIsS0FBSyxNQUFMLENBQVksRUFBWixFQUExQjtBQUNBLHFCQUFLLEtBQUwsQ0FBVyxVQUFYLENBQXNCLFlBQXRCLEdBQXFDLENBQXJDO0FBQ0g7QUFDSjs7QUFFRDs7Ozs7Ozs7OzhCQU1NLEksRUFBTTtBQUFBOztBQUNSLGlCQUFLLEtBQUwsR0FBYSxJQUFiO0FBQ0EsaUJBQUssTUFBTCxHQUFjLEVBQWQ7QUFDQSxpQkFBSyxLQUFMLENBQVcsUUFBWCxDQUFvQixPQUFwQixDQUE0QixvQkFBWTtBQUNwQyxvQkFBTSxPQUFPLElBQUksSUFBSixDQUFTLE1BQVQsRUFBZSxRQUFmLENBQWI7QUFDQSx1QkFBSyxNQUFMLENBQVksS0FBSyxZQUFMLEVBQVosSUFBbUMsSUFBbkM7QUFDSCxhQUhEO0FBSUEsaUJBQUssS0FBTCxDQUFXLFFBQVgsR0FBc0IsS0FBSyxNQUEzQjtBQUNIOzs7Ozs7QUFHTCxPQUFPLE9BQVAsR0FBaUIsR0FBakI7O0FBRUE7Ozs7Ozs7Ozs7O0FDeFdBOzs7Ozs7QUFFQSxJQUFNLElBQUksUUFBUSxRQUFSLENBQVY7O0FBRUE7Ozs7O0lBSU0sYTtBQUNGOzs7O0FBSUEsMkJBQVksSUFBWixFQUFrQjtBQUFBOztBQUNkLGFBQUssWUFBTCxHQUFvQixFQUFwQjtBQUNBLGFBQUssU0FBTCxHQUFpQixFQUFqQjs7QUFFQSxhQUFLLEtBQUwsQ0FBVyxJQUFYO0FBQ0EsYUFBSywyQkFBTDtBQUNIOztBQUVEOzs7Ozs7Ozs7MENBS2tCLE0sRUFBUTtBQUN0QjtBQUNBLGdCQUFNLE1BQU0sRUFBRSxPQUFGLENBQVUsTUFBVixJQUFvQixLQUFLLFNBQUwsQ0FBZSxNQUFmLENBQXBCLEdBQTZDLE1BQXpEO0FBQ0EsZ0JBQUksUUFBUSxLQUFLLFNBQUwsQ0FBZSxHQUFmLENBQVo7QUFDQSxnQkFBSSxTQUFTLENBQWIsRUFBZ0IsT0FBTyxLQUFQOztBQUVoQjtBQUNBLG9CQUFRLEtBQUssWUFBTCxDQUFrQixNQUExQjtBQUNBLGlCQUFLLFlBQUwsQ0FBa0IsSUFBbEIsQ0FBdUIsTUFBdkI7QUFDQSxpQkFBSyxTQUFMLENBQWUsR0FBZixJQUFzQixLQUF0Qjs7QUFFQTtBQUNBLGlCQUFLLEtBQUwsQ0FBVyxRQUFYLENBQW9CLElBQXBCLENBQXlCO0FBQ3JCLHNCQUFNLElBRGU7QUFFckIsMEJBQVUsRUFBRSxPQUFGLENBQVUsTUFBVixJQUFvQixNQUFwQixHQUE2QixDQUNuQztBQUNJLDBCQUFNLEdBRFY7QUFFSSxnQ0FBWSxFQUFFLGFBQWEsVUFBZixFQUZoQjtBQUdJLDhCQUFVLENBQUMsTUFBRDtBQUhkLGlCQURtQztBQUZsQixhQUF6Qjs7QUFXQSxtQkFBTyxLQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7O3lDQUtpQixLLEVBQU87QUFDcEIsbUJBQU8sS0FBSyxZQUFMLENBQWtCLEtBQWxCLENBQVA7QUFDSDs7QUFFRDs7Ozs7OztnQ0FJUTtBQUNKLG1CQUFPLEtBQUssS0FBWjtBQUNIOztBQUVEOzs7Ozs7OztzREFLOEI7QUFBQTs7QUFDMUIsaUJBQUssS0FBTCxDQUFXLFFBQVgsQ0FBb0IsT0FBcEIsQ0FBNEIsVUFBQyxJQUFELEVBQU8sQ0FBUCxFQUFhO0FBQ3JDLG9CQUFNLFVBQVUsS0FBSyxRQUFMLENBQWMsQ0FBZCxDQUFoQjtBQUNBLG9CQUFJLFFBQVEsSUFBUixLQUFpQixHQUFyQixFQUEwQjtBQUN0Qix3QkFBTSxTQUFTLFFBQVEsUUFBUixDQUFpQixDQUFqQixDQUFmO0FBQ0EsMEJBQUssWUFBTCxDQUFrQixJQUFsQixDQUF1QixNQUF2QjtBQUNBLDBCQUFLLFNBQUwsQ0FBZSxNQUFmLElBQXlCLENBQXpCO0FBQ0gsaUJBSkQsTUFJTztBQUNIO0FBQ0EsMEJBQUssWUFBTCxDQUFrQixJQUFsQixDQUF1QixLQUFLLFFBQTVCO0FBQ0EsMEJBQUssU0FBTCxDQUFlLEtBQUssU0FBTCxDQUFlLEtBQUssUUFBcEIsQ0FBZixJQUFnRCxDQUFoRDtBQUNIO0FBQ0osYUFYRDtBQVlIOztBQUVEOzs7Ozs7Ozs7OEJBTU0sSSxFQUFNO0FBQ1IsZ0JBQUksQ0FBQyxJQUFMLEVBQVcsT0FBTztBQUNkLHNCQUFNLEtBRFE7QUFFZCw0QkFBWTtBQUNSLDJCQUFPO0FBREMsaUJBRkU7QUFLZCwwQkFBVTtBQUxJLGFBQVA7O0FBUVgsaUJBQUssS0FBTCxHQUFhLElBQWI7O0FBRUEsbUJBQU8sS0FBSyxLQUFMLENBQVcsVUFBWCxDQUFzQixLQUE3QjtBQUNBLG1CQUFPLEtBQUssS0FBTCxDQUFXLFVBQVgsQ0FBc0IsV0FBN0I7QUFDSDs7Ozs7O0FBR0wsT0FBTyxPQUFQLEdBQWlCLGFBQWpCOztBQUVBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDakhBOzs7Ozs7OztBQUVBLElBQU0sSUFBSSxRQUFRLFFBQVIsQ0FBVjtBQUNBLElBQU0sT0FBTyxRQUFRLFFBQVIsQ0FBYjtBQUNBLElBQU0sTUFBTSxRQUFRLE9BQVIsQ0FBWjtBQUNBLElBQU0sU0FBUyxRQUFRLFVBQVIsQ0FBZjtBQUNBLElBQU0sUUFBUSxRQUFRLFNBQVIsQ0FBZDtBQUNBLElBQU0sZ0JBQWdCLFFBQVEsaUJBQVIsQ0FBdEI7QUFDQSxJQUFNLE9BQU8sUUFBUSxRQUFSLENBQWI7QUFDQSxJQUFNLFdBQVcsUUFBUSxZQUFSLENBQWpCO0FBQ0EsSUFBTSxtQkFBbUIsUUFBUSxvQkFBUixDQUF6QjtBQUNBLElBQU0sYUFBYSxRQUFRLGNBQVIsQ0FBbkI7QUFDQSxJQUFNLGVBQWUsUUFBUSxnQkFBUixDQUFyQjtBQUNBLElBQU0sYUFBYSxRQUFRLGNBQVIsQ0FBbkI7O0FBRUE7QUFDQSxJQUFNLFlBQVksQ0FDZCxTQURjLEVBQ0gsV0FERyxFQUNVLFlBRFYsRUFDd0IsZUFEeEIsRUFDeUMsTUFEekMsRUFDaUQsV0FEakQsRUFFZCxhQUZjLEVBRUMsaUJBRkQsRUFFb0IsWUFGcEIsRUFFa0MsaUJBRmxDLEVBRXFELFdBRnJELEVBRWtFLFlBRmxFLEVBR2QsV0FIYyxFQUdELGlCQUhDLEVBR2tCLGtCQUhsQixFQUdzQyxZQUh0QyxFQUdvRCxZQUhwRCxFQUlkLHVCQUpjLEVBSVcsaUJBSlgsRUFJOEIsWUFKOUIsRUFJNEMsY0FKNUMsRUFLZCxhQUxjLEVBS0MsV0FMRCxFQUtjLGNBTGQsRUFLOEIsV0FMOUIsRUFLMkMsV0FMM0MsRUFNZCxrQkFOYyxFQU1NLGFBTk4sRUFNcUIsZUFOckIsRUFNc0MsV0FOdEMsRUFNbUQsU0FObkQsRUFPZCxXQVBjLEVBT0QsZUFQQyxFQU9nQixpQkFQaEIsRUFPbUMsU0FQbkMsRUFPOEMsWUFQOUMsRUFPNEQsVUFQNUQsRUFPd0UsaUJBUHhFLEVBTzJGLFlBUDNGLEVBUWQsUUFSYyxDQUFsQjs7QUFXQTs7OztJQUdNLEs7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFZLFFBQVosRUFBc0IsTUFBdEIsRUFBOEIsSUFBOUIsRUFBb0MsaUJBQXBDLEVBQXVEO0FBQUE7O0FBQ25ELGFBQUssS0FBTCxDQUFXLFFBQVgsRUFBcUIsTUFBckIsRUFBNkIsSUFBN0IsRUFBbUMsaUJBQW5DO0FBQ0g7O0FBRUQ7O0FBRUE7OztRQUdHOzs7Ozs7Ozs7aUNBS007QUFBQTs7QUFDTCxtQkFBTyxJQUFJLFVBQUosQ0FBZSxjQUFmLEVBQ0YsSUFERSxDQUNHLFlBQU07QUFDUix1QkFBTyxNQUFLLFFBQUwsR0FBZ0IsV0FBaEIsT0FBa0MsS0FBekM7QUFDSCxhQUhFLEVBSUYsSUFKRSxDQUlHLFNBSkgsRUFJYyxrQkFBVTtBQUN2QixvQkFBSSxDQUFDLE1BQUwsRUFBYSxNQUFNLElBQUksS0FBSixDQUFVLGdGQUFWLENBQU47QUFDYixzQkFBSyxRQUFMLEdBQWdCLFdBQWhCLENBQTRCLEtBQTVCO0FBQ0EsdUJBQU8sS0FBUDtBQUNILGFBUkUsRUFTRixNQVRFLENBU0ssU0FUTCxDQUFQO0FBVUg7O0FBRUQ7OztZQUdHOzs7O2VBSUE7Ozs7Ozs7OztxQ0FNVTtBQUFBOztBQUNULGdCQUFNLGdCQUFnQixLQUFLLHlCQUFMLEVBQXRCO0FBQ0EsZ0JBQUksZ0JBQWdCLEtBQUssU0FBTCxDQUFlLGFBQWYsRUFBOEIsV0FBOUIsQ0FBcEI7QUFDQSxtQkFBTyxJQUFJLFVBQUosQ0FBZSxrQkFBZixFQUNGLElBREUsQ0FDRyxZQUFNO0FBQ1Isb0JBQU0sY0FBYyxnQkFBZ0IsY0FBYyxVQUFkLENBQXlCLFVBQXpDLEdBQXNELElBQTFFO0FBQ0EsdUJBQU8sT0FBSyxJQUFMLENBQVUsV0FBVixDQUFQO0FBQ0gsYUFKRSxFQUtGLElBTEUsQ0FLRyxDQUFDLFFBQUQsRUFBVyxHQUFYLENBTEgsRUFLb0IsVUFBQyxTQUFELEVBQVksa0JBQVosRUFBbUM7QUFDdEQsb0JBQU0sT0FBTyxPQUFLLElBQUwsQ0FBVSxTQUFWLEVBQXFCLGtCQUFyQixDQUFiO0FBQ0EsdUJBQU8sT0FBSyxVQUFMLENBQWdCLElBQWhCLENBQVA7QUFDSCxhQVJFLEVBU0YsSUFURSxDQVNHLEdBVEgsRUFTUSxnQkFBUTtBQUNmLG9CQUFJLENBQUMsYUFBTCxFQUFvQjtBQUNoQixvQ0FBZ0I7QUFDWiw4QkFBTSxXQURNO0FBRVosb0NBQVksRUFGQTtBQUdaLGtDQUFVO0FBSEUscUJBQWhCOztBQU1BLHlCQUFLLFdBQUwsQ0FBaUIsYUFBakIsRUFBZ0MsYUFBaEM7QUFDSDs7QUFFRCxvQkFBSSxFQUFFLGdCQUFnQixJQUFsQixDQUFKLEVBQTZCLE9BQU8sT0FBSyxJQUFMLENBQVUsSUFBVixDQUFQO0FBQzdCLDhCQUFjLFVBQWQsQ0FBeUIsVUFBekIsR0FBc0MsY0FBYyxVQUFkLENBQXlCLEtBQXpCLEdBQWlDLEtBQUssT0FBTCxFQUF2RTtBQUNBLHVCQUFPLE1BQVA7QUFDSCxhQXZCRSxFQXdCRixNQXhCRSxDQXdCSyxTQXhCTCxDQUFQO0FBeUJIOztBQUVEOzs7O1lBSUc7Ozs7Ozs7OzsrQkFNSTtBQUFBOztBQUNILG1CQUFPLElBQUksVUFBSixDQUFlLFlBQWYsRUFDRixJQURFLENBQ0csUUFESCxFQUNhLG1CQUFXO0FBQ3ZCLG9CQUFNLE1BQU0saUJBQWlCLFdBQWpCLENBQTZCLE9BQTdCLENBQVo7QUFDQSxvQkFBSSxJQUFJLElBQUosS0FBYSxNQUFqQixFQUF5QixNQUFNLElBQUksS0FBSixDQUFVLDhCQUFWLENBQU47QUFDekIsdUJBQU8sT0FBSyxHQUFMLENBQVMsSUFBSSxTQUFiLEVBQXdCLElBQXhCLENBQTZCLElBQUksWUFBakMsQ0FBUDtBQUNILGFBTEUsRUFNRixJQU5FLENBTUcsQ0FBQyxRQUFELEVBQVcsR0FBWCxDQU5ILEVBTW9CLFVBQUMsU0FBRCxFQUFZLGtCQUFaLEVBQW1DO0FBQ3RELHVCQUFPLE9BQUssR0FBTCxDQUFTLFNBQVQsRUFBb0IsSUFBcEIsQ0FBeUIsa0JBQXpCLENBQVA7QUFDSCxhQVJFLEVBU0YsTUFURSxDQVNLLFNBVEwsQ0FBUDtBQVVIOztBQUVEOzs7Ozs7OzsrQkFLTyxrQixFQUFvQjtBQUN2QixnQkFBTSxlQUFlLE9BQU8sa0JBQVAsS0FBOEIsUUFBOUIsR0FBeUMsaUJBQWlCLGtCQUFqQixDQUFvQyxrQkFBcEMsQ0FBekMsR0FBbUcsa0JBQXhIOztBQUVBO0FBQ0EsZ0JBQUksS0FBSyxRQUFMLENBQWMsWUFBZCxDQUFKLEVBQWlDLE9BQU8sS0FBSyxRQUFMLENBQWMsWUFBZCxDQUFQOztBQUVqQztBQUNBO0FBQ0EsZ0JBQU0sa0JBQWtCLEtBQUssU0FBTCxDQUFlLFlBQWYsQ0FBeEI7O0FBRUEsZ0JBQUksZ0JBQUo7QUFDQSxnQkFBSSxlQUFKLEVBQXFCO0FBQ2pCO0FBQ0Esb0JBQUksZ0JBQWdCLFVBQWhCLENBQTJCLEdBQTNCLEdBQWlDLFlBQXJDLEVBQW1EO0FBQy9DO0FBQ0Esd0JBQU0sZ0JBQWdCLEVBQUUsU0FBRixDQUFZLGVBQVosQ0FBdEI7QUFDQSxrQ0FBYyxVQUFkLENBQXlCLEdBQXpCLEdBQStCLGVBQWUsQ0FBOUM7O0FBRUE7QUFDQSx5QkFBSyxJQUFJLElBQUksY0FBYyxVQUFkLENBQXlCLEdBQXRDLEVBQTJDLEtBQUssY0FBYyxVQUFkLENBQXlCLEdBQXpFLEVBQThFLEdBQTlFLEVBQW1GO0FBQy9FLDZCQUFLLFNBQUwsQ0FBZSxDQUFmLElBQW9CLGFBQXBCO0FBQ0g7QUFDSjs7QUFFRDtBQUNBLDBCQUFVLEVBQUUsU0FBRixDQUFZLGVBQVosQ0FBVjtBQUNBLHdCQUFRLFVBQVIsQ0FBbUIsR0FBbkIsR0FBeUIsWUFBekI7QUFDQSx3QkFBUSxVQUFSLENBQW1CLEdBQW5CLEdBQXlCLFlBQXpCO0FBQ0EscUJBQUssU0FBTCxDQUFlLFlBQWYsSUFBK0IsT0FBL0I7O0FBRUE7QUFDQSxvQkFBSSxnQkFBZ0IsVUFBaEIsQ0FBMkIsR0FBM0IsR0FBaUMsWUFBckMsRUFBbUQ7QUFDL0Msd0JBQU0sZUFBZSxFQUFFLFNBQUYsQ0FBWSxlQUFaLENBQXJCO0FBQ0EsaUNBQWEsVUFBYixDQUF3QixHQUF4QixHQUE4QixlQUFlLENBQTdDO0FBQ0EseUJBQUssSUFBSSxLQUFJLGFBQWEsVUFBYixDQUF3QixHQUFyQyxFQUEwQyxNQUFLLGFBQWEsVUFBYixDQUF3QixHQUF2RSxFQUE0RSxJQUE1RSxFQUFpRjtBQUM3RSw2QkFBSyxTQUFMLENBQWUsRUFBZixJQUFvQixZQUFwQjtBQUNIO0FBQ0o7QUFDSixhQTNCRCxNQTJCTztBQUNIO0FBQ0EsMEJBQVU7QUFDTiwwQkFBTSxLQURBO0FBRU4sZ0NBQVk7QUFDUiw2QkFBSyxZQURHO0FBRVIsNkJBQUs7QUFGRyxxQkFGTjtBQU1OLDhCQUFVO0FBTkosaUJBQVY7O0FBU0EscUJBQUssU0FBTCxDQUFlLFlBQWYsSUFBK0IsT0FBL0I7QUFDSDs7QUFFRDtBQUNBLGdCQUFNLFNBQVMsSUFBSSxNQUFKLENBQVcsSUFBWCxFQUFpQixPQUFqQixDQUFmO0FBQ0EsaUJBQUssUUFBTCxDQUFjLFlBQWQsSUFBOEIsTUFBOUI7QUFDQSxtQkFBTyxNQUFQO0FBQ0g7O0FBRUQ7Ozs7WUFJRzs7Ozs7Ozs7O3NDQU1XO0FBQUE7O0FBQ1YsbUJBQU8sSUFBSSxVQUFKLENBQWUsc0JBQWYsRUFDRixJQURFLENBQ0csUUFESCxFQUNhLGdCQUFRO0FBQ3BCLHVCQUFPLE9BQUssUUFBTCxHQUFnQixpQkFBaEIsQ0FBa0MsTUFBbEMsRUFBd0MsSUFBeEMsQ0FBUDtBQUNILGFBSEUsRUFJRixJQUpFLENBSUcsQ0FBQyxRQUFELEVBQVcsR0FBWCxDQUpILEVBSW9CLFVBQUMsSUFBRCxFQUFPLFFBQVAsRUFBb0I7QUFDdkMsdUJBQUssUUFBTCxHQUFnQixpQkFBaEIsQ0FBa0MsTUFBbEMsRUFBd0MsSUFBeEMsRUFBOEMsUUFBOUM7QUFDQSx1QkFBTyxNQUFQO0FBQ0gsYUFQRSxFQVFGLE1BUkUsQ0FRSyxTQVJMLENBQVA7QUFTSDs7QUFFRDs7Ozs7OztrQ0FJUztBQUNMLGlCQUFLLFFBQUwsR0FBZ0IsV0FBaEIsQ0FBNEIsSUFBNUI7QUFDQSxtQkFBTyxLQUFLLFFBQUwsRUFBUDtBQUNIOztBQUVEOzs7Ozs7Ozs7NkJBTUssTyxFQUFTLFcsRUFBYTtBQUN2QixzQkFBVSxTQUFTLE9BQVQsQ0FBVjs7QUFFQSxnQkFBSSxVQUFVLEVBQWQ7QUFDQSxpQkFBSyxLQUFMLENBQVcsT0FBWCxDQUFtQixlQUFPO0FBQ3RCLG9CQUFJLENBQUMsR0FBTCxFQUFVO0FBQ1YsMEJBQVUsUUFBUSxNQUFSLENBQWUsSUFBSSxJQUFKLENBQVMsT0FBVCxFQUFrQixXQUFsQixDQUFmLENBQVY7QUFDSCxhQUhEOztBQUtBLG1CQUFPLE9BQVA7QUFDSDs7QUFFRDs7O1lBR0c7Ozs7Ozs7OzJDQUtnQjtBQUFBOztBQUNmLGdCQUFNLGdCQUFnQixLQUFLLHlCQUFMLEVBQXRCO0FBQ0EsbUJBQU8sSUFBSSxVQUFKLENBQWUsd0JBQWYsRUFDRixJQURFLENBQ0csWUFBTTtBQUNSLHVCQUFPLGNBQWMsVUFBZCxDQUF5QixhQUF6QixLQUEyQyxDQUEzQyxJQUFnRCxjQUFjLFVBQWQsQ0FBeUIsYUFBekIsS0FBMkMsU0FBbEc7QUFDSCxhQUhFLEVBSUYsSUFKRSxDQUlHLFNBSkgsRUFJYyxtQkFBVztBQUN4Qiw4QkFBYyxVQUFkLENBQXlCLGFBQXpCLEdBQXlDLFVBQVUsQ0FBVixHQUFjLENBQXZEO0FBQ0EsdUJBQU8sTUFBUDtBQUNILGFBUEUsRUFRRixNQVJFLENBUUssU0FSTCxDQUFQO0FBU0g7O0FBRUQ7OztZQUdHOzs7Ozs7OztpQ0FLTTtBQUFBOztBQUNMLG1CQUFPLElBQUksVUFBSixDQUFlLGNBQWYsRUFDRixJQURFLENBQ0csWUFBTTtBQUNSLG9CQUFJLE9BQUssT0FBTCxDQUFhLFVBQWIsQ0FBd0IsS0FBeEIsS0FBa0MsUUFBdEMsRUFBZ0QsT0FBTyxJQUFQO0FBQ2hELG9CQUFJLE9BQUssT0FBTCxDQUFhLFVBQWIsQ0FBd0IsS0FBeEIsS0FBa0MsWUFBdEMsRUFBb0QsT0FBTyxNQUFQO0FBQ3BELHVCQUFPLEtBQVA7QUFDSCxhQUxFLEVBTUYsSUFORSxDQU1HLEdBTkgsRUFNUSxrQkFBVTtBQUNqQixvQkFBSSxNQUFKLEVBQVk7QUFDUix3QkFBTSxnQkFBZ0IsRUFBRSxNQUFGLENBQVMsT0FBSyxRQUFMLEdBQWdCLE1BQWhCLEVBQVQsRUFBbUM7QUFBQSwrQkFBUyxDQUFDLE1BQU0sTUFBTixFQUFWO0FBQUEscUJBQW5DLENBQXRCO0FBQ0Esd0JBQUksY0FBYyxNQUFkLEtBQXlCLENBQXpCLElBQThCLGNBQWMsQ0FBZCxNQUFxQixNQUF2RCxFQUE2RDtBQUN6RCw4QkFBTSxJQUFJLEtBQUosQ0FBVSxxRkFBVixDQUFOO0FBQ0g7O0FBRUQ7QUFDQSx3QkFBSSxPQUFLLE1BQUwsRUFBSixFQUFtQjtBQUNmLDRCQUFNLGNBQWMsY0FBYyxDQUFkLE1BQXFCLE1BQXJCLEdBQTRCLENBQTVCLEdBQWdDLENBQXBEO0FBQ0Esc0NBQWMsV0FBZCxFQUEyQixNQUEzQixDQUFrQyxJQUFsQztBQUNIO0FBQ0o7O0FBRUQsb0JBQUksV0FBVyxNQUFmLEVBQXVCLE9BQUssT0FBTCxDQUFhLFVBQWIsQ0FBd0IsS0FBeEIsR0FBZ0MsWUFBaEMsQ0FBdkIsS0FDSyxJQUFJLE1BQUosRUFBWSxPQUFLLE9BQUwsQ0FBYSxVQUFiLENBQXdCLEtBQXhCLEdBQWdDLFFBQWhDLENBQVosS0FDQSxPQUFPLE9BQUssT0FBTCxDQUFhLFVBQWIsQ0FBd0IsS0FBL0I7QUFDTCx1QkFBTyxNQUFQO0FBQ0gsYUF4QkUsRUF5QkYsTUF6QkUsQ0F5QkssU0F6QkwsQ0FBUDtBQTBCSDs7QUFFRDs7Ozs7Ozs7NkJBS0ssa0IsRUFBb0I7QUFDckIsaUJBQUssUUFBTCxHQUFnQixTQUFoQixDQUEwQixJQUExQixFQUFnQyxrQkFBaEM7QUFDQSxtQkFBTyxJQUFQO0FBQ0g7O0FBRUQ7OztZQUdHOzs7Ozs7OzsrQkFLSTtBQUFBOztBQUNILG1CQUFPLElBQUksVUFBSixDQUFlLFlBQWYsRUFDRixJQURFLENBQ0csWUFBTTtBQUNSLDRCQUFVLE9BQUssT0FBTCxDQUFhLFVBQWIsQ0FBd0IsSUFBbEM7QUFDSCxhQUhFLEVBSUYsSUFKRSxDQUlHLFFBSkgsRUFJYSxnQkFBUTtBQUNwQix1QkFBSyxPQUFMLENBQWEsVUFBYixDQUF3QixJQUF4QixHQUErQixJQUEvQjtBQUNBLHVCQUFPLE1BQVA7QUFDSCxhQVBFLEVBUUYsTUFSRSxDQVFLLFNBUkwsQ0FBUDtBQVNIOztBQUVEOzs7O1lBSUc7Ozs7O2VBS0E7Ozs7Ozs7Ozs7O2dDQVFLO0FBQUE7O0FBQ0osbUJBQU8sSUFBSSxVQUFKLENBQWUsYUFBZixFQUNGLElBREUsQ0FDRyxRQURILEVBQ2EsbUJBQVc7QUFDdkIsb0JBQU0sTUFBTSxpQkFBaUIsV0FBakIsQ0FBNkIsT0FBN0IsQ0FBWjtBQUNBLG9CQUFJLElBQUksSUFBSixLQUFhLE9BQWpCLEVBQTBCLE1BQU0sSUFBSSxLQUFKLENBQVUsOEJBQVYsQ0FBTjtBQUMxQix1QkFBTyxPQUFLLEtBQUwsQ0FBVyxJQUFJLGNBQWYsRUFBK0IsSUFBSSxpQkFBbkMsRUFBc0QsSUFBSSxZQUExRCxFQUF3RSxJQUFJLGVBQTVFLENBQVA7QUFDSCxhQUxFLEVBTUYsSUFORSxDQU1HLENBQUMsR0FBRCxFQUFNLEdBQU4sQ0FOSCxFQU1lLFVBQUMsU0FBRCxFQUFZLE9BQVosRUFBd0I7QUFDdEMsb0JBQUksT0FBTyxTQUFQLEtBQXFCLFFBQXpCLEVBQW1DLFlBQVksT0FBSyxJQUFMLENBQVUsU0FBVixDQUFaO0FBQ25DLG9CQUFJLE9BQU8sT0FBUCxLQUFtQixRQUF2QixFQUFpQyxVQUFVLE9BQUssSUFBTCxDQUFVLE9BQVYsQ0FBVjtBQUNqQyx1QkFBTyxJQUFJLEtBQUosQ0FBVSxTQUFWLEVBQXFCLE9BQXJCLENBQVA7QUFDSCxhQVZFLEVBV0YsSUFYRSxDQVdHLENBQUMsUUFBRCxFQUFXLEdBQVgsRUFBZ0IsUUFBaEIsRUFBMEIsR0FBMUIsQ0FYSCxFQVdtQyxVQUFDLGNBQUQsRUFBaUIsdUJBQWpCLEVBQTBDLFlBQTFDLEVBQXdELHFCQUF4RCxFQUFrRjtBQUNwSCx1QkFBTyxPQUFLLEtBQUwsQ0FBVyxPQUFLLElBQUwsQ0FBVSxjQUFWLEVBQTBCLHVCQUExQixDQUFYLEVBQStELE9BQUssSUFBTCxDQUFVLFlBQVYsRUFBd0IscUJBQXhCLENBQS9ELENBQVA7QUFDSCxhQWJFLEVBY0YsTUFkRSxDQWNLLFNBZEwsQ0FBUDtBQWVIOztBQUVEOzs7WUFHRzs7Ozs7Ozs7bUNBS1EsSyxFQUFPO0FBQ2QsaUJBQUssV0FBTCxHQUFtQixLQUFuQjs7QUFFQSxtQkFBTyxJQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7OzRCQUtJLFMsRUFBVztBQUNYLGdCQUFJLFlBQVksQ0FBaEIsRUFBbUIsTUFBTSxJQUFJLFVBQUoseUJBQXFDLFNBQXJDLHdEQUFOOztBQUVuQixnQkFBSSxLQUFLLEtBQUwsQ0FBVyxTQUFYLENBQUosRUFBMkIsT0FBTyxLQUFLLEtBQUwsQ0FBVyxTQUFYLENBQVA7O0FBRTNCLGdCQUFNLFVBQVU7QUFDWixzQkFBTSxLQURNO0FBRVosNEJBQVk7QUFDUix1QkFBRztBQURLLGlCQUZBO0FBS1osMEJBQVU7QUFMRSxhQUFoQjs7QUFRQSxnQkFBTSxNQUFNLElBQUksR0FBSixDQUFRLElBQVIsRUFBYyxPQUFkLENBQVo7QUFDQSxpQkFBSyxLQUFMLENBQVcsU0FBWCxJQUF3QixHQUF4QjtBQUNBLG1CQUFPLEdBQVA7QUFDSDs7QUFFRDs7O1lBR0c7Ozs7Ozs7bUNBSVE7QUFBQTs7QUFDUCxtQkFBTyxJQUFJLFVBQUosQ0FBZSxnQkFBZixFQUNGLElBREUsQ0FDRyxZQUFNO0FBQ1Isb0JBQU0sZUFBZSxLQUFLLFNBQUwsQ0FBZSxPQUFLLFlBQXBCLEVBQWtDLFVBQWxDLENBQXJCO0FBQ0Esb0JBQUksQ0FBQyxZQUFMLEVBQW1COztBQUVuQixvQkFBTSxRQUFRLEVBQWQ7QUFDQSxvQkFBSSxhQUFhLFVBQWIsQ0FBd0IsY0FBeEIsQ0FBdUMsS0FBdkMsQ0FBSixFQUFtRCxNQUFNLEdBQU4sR0FBWSxhQUFhLFVBQWIsQ0FBd0IsR0FBcEMsQ0FBbkQsS0FDSyxJQUFJLGFBQWEsVUFBYixDQUF3QixjQUF4QixDQUF1QyxPQUF2QyxDQUFKLEVBQXFELE1BQU0sS0FBTixHQUFjLGFBQWEsVUFBYixDQUF3QixLQUF0QyxDQUFyRCxLQUNBLElBQUksYUFBYSxVQUFiLENBQXdCLGNBQXhCLENBQXVDLFNBQXZDLENBQUosRUFBdUQsTUFBTSxHQUFOLEdBQVksYUFBYSxhQUFhLFVBQWIsQ0FBd0IsT0FBckMsQ0FBWjs7QUFFNUQsb0JBQUksYUFBYSxVQUFiLENBQXdCLGNBQXhCLENBQXVDLE1BQXZDLENBQUosRUFBb0QsTUFBTSxJQUFOLEdBQWEsYUFBYSxVQUFiLENBQXdCLElBQXJDOztBQUVwRCx1QkFBTyxLQUFQO0FBQ0gsYUFiRSxFQWNGLElBZEUsQ0FjRyxRQWRILEVBY2E7QUFBQSx1QkFBTyxPQUFLLFFBQUwsQ0FBYyxFQUFFLFFBQUYsRUFBZCxDQUFQO0FBQUEsYUFkYixFQWVGLElBZkUsQ0FlRyxTQWZILEVBZWM7QUFBQSx1QkFBUyxPQUFLLFFBQUwsQ0FBYyxFQUFFLFlBQUYsRUFBZCxDQUFUO0FBQUEsYUFmZCxFQWdCRixJQWhCRSxDQWdCRyxLQWhCSCxFQWdCVSxZQUFNO0FBQ2YscUJBQUssV0FBTCxDQUFpQixPQUFLLFlBQXRCLEVBQW9DLFVBQXBDO0FBQ0EsdUJBQU8sTUFBUDtBQUNILGFBbkJFLEVBb0JGLElBcEJFLENBb0JHLFFBcEJILEVBb0JhLGlCQUFTO0FBQ3JCLG9CQUFNLGVBQWUsS0FBSyxxQkFBTCxDQUEyQixPQUFLLFlBQWhDLEVBQThDLFVBQTlDLENBQXJCO0FBQ0EscUJBQUssYUFBTCxDQUFtQixZQUFuQixFQUFpQztBQUM3Qix5QkFBSyxNQUFNLEdBQU4sSUFBYSxNQUFNLEdBQU4sQ0FBVSxXQUFWLEVBRFc7QUFFN0IsNkJBQVMsSUFGb0I7QUFHN0IsMkJBQU8sTUFBTSxLQUhnQjtBQUk3QiwwQkFBTSxNQUFNO0FBSmlCLGlCQUFqQzs7QUFPQSx1QkFBTyxNQUFQO0FBQ0gsYUE5QkUsRUErQkYsTUEvQkUsQ0ErQkssU0EvQkwsQ0FBUDtBQWdDSDs7QUFFRDs7O1lBR0c7Ozs7Ozs7O3NDQUtXO0FBQUE7O0FBQ1YsZ0JBQU0sZ0JBQWdCLEtBQUsseUJBQUwsRUFBdEI7QUFDQSxtQkFBTyxJQUFJLFVBQUosQ0FBZSxtQkFBZixFQUNGLElBREUsQ0FDRyxZQUFNO0FBQ1IsdUJBQU8sY0FBYyxVQUFkLENBQXlCLFdBQXpCLEtBQXlDLENBQWhEO0FBQ0gsYUFIRSxFQUlGLElBSkUsQ0FJRyxTQUpILEVBSWMsb0JBQVk7QUFDekIsb0JBQUksUUFBSixFQUFjLGNBQWMsVUFBZCxDQUF5QixXQUF6QixHQUF1QyxDQUF2QyxDQUFkLEtBQ0ssT0FBTyxjQUFjLFVBQWQsQ0FBeUIsV0FBaEM7QUFDTCx1QkFBTyxPQUFQO0FBQ0gsYUFSRSxFQVNGLE1BVEUsQ0FTSyxTQVRMLENBQVA7QUFVSDs7QUFFRDs7Ozs7OztvQ0FJWTtBQUNSLGdCQUFNLGVBQWUsRUFBRSxTQUFGLENBQVksS0FBSyxLQUFqQixDQUFyQjtBQUNBLGdCQUFNLGVBQWUsS0FBSyxLQUFMLENBQVcsTUFBWCxHQUFvQixDQUF6Qzs7QUFFQSxnQkFBSSxrQkFBa0IsQ0FBdEI7QUFDQSxnQkFBSSxrQkFBa0IsQ0FBdEI7QUFDQSxpQkFBSyxJQUFJLElBQUksQ0FBYixFQUFnQixJQUFJLEtBQUssS0FBTCxDQUFXLE1BQS9CLEVBQXVDLEdBQXZDLEVBQTRDO0FBQ3hDLG9CQUFNLE1BQU0sS0FBSyxLQUFMLENBQVcsQ0FBWCxDQUFaO0FBQ0Esb0JBQUksQ0FBQyxHQUFMLEVBQVU7O0FBRVYsb0JBQU0sc0JBQXNCLElBQUksbUJBQUosRUFBNUI7QUFDQSxvQkFBTSxzQkFBc0IsSUFBSSxtQkFBSixFQUE1QjtBQUNBLG9CQUFJLHNCQUFzQixDQUF0QixLQUE0QixDQUFDLGVBQUQsSUFBb0Isc0JBQXNCLGVBQXRFLENBQUosRUFBNEYsa0JBQWtCLG1CQUFsQjtBQUM1RixvQkFBSSxzQkFBc0IsQ0FBdEIsS0FBNEIsQ0FBQyxlQUFELElBQW9CLHNCQUFzQixlQUF0RSxDQUFKLEVBQTRGLGtCQUFrQixtQkFBbEI7QUFDL0Y7O0FBRUQ7QUFDQSxnQkFBSSxnQkFBZ0IsQ0FBaEIsSUFBcUIsbUJBQW1CLENBQXhDLElBQTZDLGdCQUFnQixDQUE3RCxJQUFrRSxtQkFBbUIsQ0FBekYsRUFBNEY7O0FBRTVGLG1CQUFPLEtBQUssS0FBTCxDQUFXLFlBQVgsRUFBeUIsZUFBekIsRUFBMEMsWUFBMUMsRUFBd0QsZUFBeEQsQ0FBUDtBQUNIOztBQUVEOzs7Ozs7O21DQUlXO0FBQ1AsbUJBQU8sS0FBSyxTQUFaO0FBQ0g7O0FBRUQ7Ozs7Ozs7cUNBSWE7QUFDVCxtQkFBTyxLQUFLLFdBQVo7QUFDSDs7QUFFRDs7Ozs7Ozs2Q0FJcUI7QUFDakIsbUJBQU8sS0FBSyxXQUFMLENBQWlCLFNBQXhCO0FBQ0g7O0FBRUQ7Ozs7Ozs7K0NBSXVCO0FBQ25CLG1CQUFPLEtBQUssV0FBTCxDQUFpQixTQUF4QjtBQUNIOztBQUVEOztBQUVBOzs7Ozs7Ozs7cURBTTZCLGUsRUFBaUI7QUFDMUMsaUJBQUssS0FBTCxDQUFXLE9BQVgsQ0FBbUIsZUFBTztBQUN0QixvQkFBSSxDQUFDLEdBQUwsRUFBVTtBQUNWLG9CQUFJLDRCQUFKLENBQWlDLGVBQWpDO0FBQ0gsYUFIRDtBQUlIOztBQUVEOzs7Ozs7Ozs7OENBTXNCLFksRUFBYztBQUNoQztBQUNBLGdCQUFNLFVBQVUsS0FBSyxTQUFMLENBQWUsWUFBZixDQUFoQjtBQUNBLG1CQUFPLFdBQVcsUUFBUSxVQUFSLENBQW1CLEtBQXJDO0FBQ0g7O0FBRUQ7Ozs7Ozs7OztvREFNNEIsUSxFQUFVO0FBQ2xDLGNBQUUsT0FBRixDQUFVLEtBQUssU0FBZixFQUEwQixVQUFDLElBQUQsRUFBTyxZQUFQLEVBQXdCO0FBQzlDLG9CQUFJLENBQUMsSUFBTCxFQUFXO0FBQ1gseUJBQVMsWUFBVDtBQUNILGFBSEQ7QUFJSDs7QUFFRDs7Ozs7Ozs7OzJDQU1tQixRLEVBQVU7QUFDekIsY0FBRSxPQUFGLENBQVUsS0FBSyxLQUFmLEVBQXNCLFVBQUMsR0FBRCxFQUFNLFNBQU4sRUFBb0I7QUFDdEMsb0JBQUksR0FBSixFQUFTLFNBQVMsR0FBVCxFQUFjLFNBQWQ7QUFDWixhQUZEOztBQUlBLG1CQUFPLElBQVA7QUFDSDs7QUFFRDs7OztZQUlHOzs7Ozs7ZUFNQTs7Ozs7O2tCQU1BOzs7Ozs7Ozs7Ozs7O29DQVVTO0FBQUE7O0FBQ1IsbUJBQU8sSUFBSSxVQUFKLENBQWUsaUJBQWYsRUFDRixJQURFLENBQ0csUUFESCxFQUNhLG1CQUFXO0FBQ3ZCLG9CQUFNLGdCQUFnQixRQUFLLFdBQUwsQ0FBaUIsT0FBakIsQ0FBdEI7QUFDQSxvQkFBSSxDQUFDLGFBQUwsRUFBb0I7QUFDcEIsb0JBQU0sZUFBZSxRQUFLLGNBQUwsQ0FBb0IsUUFBcEIsQ0FBNkIsY0FBYyxVQUFkLENBQXlCLE1BQXpCLENBQTdCLENBQXJCO0FBQ0EsdUJBQU8sZ0JBQWdCLGFBQWEsVUFBYixDQUF3QixNQUEvQztBQUNILGFBTkUsRUFPRixJQVBFLENBT0csQ0FBQyxRQUFELEVBQVcsS0FBWCxDQVBILEVBT3NCLG1CQUFXO0FBQ2hDO0FBQ0EsdUJBQU8sUUFBSyxXQUFMLENBQWlCLE9BQWpCLENBQVA7QUFDQSx1QkFBTyxPQUFQO0FBQ0gsYUFYRSxFQVlGLElBWkUsQ0FZRyxDQUFDLFFBQUQsRUFBVyxRQUFYLENBWkgsRUFZeUIsVUFBQyxPQUFELEVBQVUsU0FBVixFQUF3QjtBQUNoRCx1QkFBTyxRQUFLLFNBQUwsQ0FBZSxPQUFmLEVBQXdCLFNBQXhCLEVBQW1DLEtBQW5DLENBQVA7QUFDSCxhQWRFLEVBZUYsSUFmRSxDQWVHLENBQUMsUUFBRCxFQUFXLFFBQVgsRUFBcUIsU0FBckIsQ0FmSCxFQWVvQyxVQUFDLE9BQUQsRUFBVSxTQUFWLEVBQXFCLFFBQXJCLEVBQWtDO0FBQ3JFLG9CQUFNLDZCQUE2QixZQUFZLGlCQUFpQixXQUFqQixDQUE2QixTQUE3QixDQUEvQztBQUNBLG9CQUFJLHVCQUFKO0FBQ0Esb0JBQUksMEJBQUosRUFBZ0M7QUFDNUIscUNBQWlCO0FBQ2IsNkJBQUssT0FEUTtBQUViLGtDQUFVLFNBRkc7QUFHYixpQ0FBUztBQUhJLHFCQUFqQjtBQUtILGlCQU5ELE1BTU87QUFDSCx3QkFBTSxlQUFlLFFBQUssY0FBTCxDQUFvQixHQUFwQixDQUF3QixXQUF4QixFQUFxQyxTQUFyQyxFQUFnRCxVQUFoRCxDQUFyQjtBQUNBLHFDQUFpQjtBQUNiLDZCQUFLLE9BRFE7QUFFYixnQ0FBUSxhQUFhLFVBQWIsQ0FBd0I7QUFGbkIscUJBQWpCO0FBSUg7QUFDRCx3QkFBSyxXQUFMLENBQWlCLE9BQWpCLElBQTRCO0FBQ3hCLDBCQUFNLFdBRGtCO0FBRXhCLGdDQUFZLGNBRlk7QUFHeEIsOEJBQVU7QUFIYyxpQkFBNUI7QUFLQSx1QkFBTyxPQUFQO0FBQ0gsYUFyQ0UsRUFzQ0YsSUF0Q0UsQ0FzQ0csQ0FBQyxRQUFELEVBQVcsUUFBWCxDQXRDSCxFQXNDeUIsVUFBQyxPQUFELEVBQVUsSUFBVixFQUFtQjtBQUMzQyxvQkFBSSxnQkFBZ0IsSUFBcEIsRUFBMEI7QUFDdEIsd0JBQU0sT0FBTyxJQUFiO0FBQ0Esd0JBQU0sWUFBWSxLQUFLLE9BQUwsQ0FBYSxFQUFFLGtCQUFrQixJQUFwQixFQUFiLENBQWxCO0FBQ0EsNEJBQUssU0FBTCxDQUFlLE9BQWYsRUFBd0IsU0FBeEIsRUFBbUMsSUFBbkM7QUFDSCxpQkFKRCxNQUlPLElBQUksS0FBSyxTQUFULEVBQW9CO0FBQ3ZCLDRCQUFLLFNBQUwsQ0FBZSxPQUFmLEVBQXdCLEtBQUssU0FBN0I7QUFDSCxpQkFGTSxNQUVBLElBQUksS0FBSyxLQUFULEVBQWdCO0FBQ25CLHdCQUFNLFFBQVEsS0FBSyxLQUFuQjtBQUNBLHdCQUFNLFVBQVUsS0FBSyxZQUFMLElBQXFCLEVBQXJDO0FBQ0EsNEJBQUssU0FBTCxDQUFlLE9BQWYsRUFBd0Isc0JBQW9CLEtBQXBCLGlCQUFxQyxPQUFyQyxDQUF4QjtBQUNIO0FBQ0Qsb0JBQU0sZ0JBQWdCLFFBQUssV0FBTCxDQUFpQixPQUFqQixDQUF0QjtBQUNBLG9CQUFJLGFBQUosRUFBbUI7QUFDZix3QkFBSSxLQUFLLE9BQVQsRUFBa0I7QUFDZCxzQ0FBYyxVQUFkLENBQXlCLE9BQXpCLEdBQW1DLEtBQUssT0FBeEM7QUFDSDtBQUNKO0FBQ0QsdUJBQU8sT0FBUDtBQUNILGFBekRFLEVBMERGLE1BMURFLENBMERLLFNBMURMLENBQVA7QUEyREg7O0FBRUQ7Ozs7Ozs7O3NEQUs4QjtBQUMxQixtQkFBTyxFQUFFLEtBQUssbUJBQWQ7QUFDSDs7QUFFRDs7Ozs7WUFLRzs7Ozs7Ozs7OztpQ0FPTTtBQUFBOztBQUNMLG1CQUFPLElBQUksVUFBSixDQUFlLGFBQWYsRUFDRixJQURFLENBQ0csUUFESCxFQUNhLG1CQUFXO0FBQ3ZCLHVCQUFPLFFBQUssV0FBTCxDQUFpQixjQUFqQixDQUFnQyxPQUFoQyxDQUFQO0FBQ0gsYUFIRSxFQUlGLElBSkUsQ0FJRyxDQUFDLFFBQUQsRUFBVyxHQUFYLENBSkgsRUFJb0IsVUFBQyxPQUFELEVBQVUsS0FBVixFQUFvQjtBQUN2QyxvQkFBSSxLQUFKLEVBQVc7QUFDUCw0QkFBSyxXQUFMLENBQWlCLE9BQWpCLElBQTRCO0FBQ3hCLDhCQUFNLFdBRGtCO0FBRXhCLG9DQUFZLEVBQUUsS0FBSyxPQUFQLEVBRlk7QUFHeEIsa0NBQVU7QUFIYyxxQkFBNUI7QUFLSCxpQkFORCxNQU1PO0FBQ0gsMkJBQU8sUUFBSyxXQUFMLENBQWlCLE9BQWpCLENBQVA7QUFDSDs7QUFFRCx1QkFBTyxPQUFQO0FBQ0gsYUFoQkUsRUFpQkYsTUFqQkUsQ0FpQkssU0FqQkwsQ0FBUDtBQWtCSDs7QUFHRDs7Ozs7WUFLRzs7Ozs7O2VBTUE7Ozs7Ozs7Ozs7eUNBT2M7QUFBQTs7QUFDYixtQkFBTyxJQUFJLFVBQUosQ0FBZSxzQkFBZixFQUNGLElBREUsQ0FDRyxRQURILEVBQ2EsbUJBQVc7QUFDdkIsb0JBQUksUUFBSyxnQkFBTCxDQUFzQixPQUF0QixDQUFKLEVBQW9DO0FBQ2hDLDJCQUFPO0FBQ0gsOEJBQU0sUUFBSyxnQkFBTCxDQUFzQixPQUF0QixFQUErQixVQUEvQixDQUEwQyxJQUQ3QztBQUVILG9DQUFZLFFBQUssZ0JBQUwsQ0FBc0IsT0FBdEIsRUFBK0IsVUFBL0IsQ0FBMEMsVUFGbkQ7QUFHSCwwQ0FBa0IsUUFBSyxnQkFBTCxDQUFzQixPQUF0QixFQUErQixVQUEvQixDQUEwQyxnQkFIekQ7QUFJSCxnQ0FBUSxRQUFLLGdCQUFMLENBQXNCLE9BQXRCLEVBQStCLFVBQS9CLENBQTBDLE1BSi9DO0FBS0gscUNBQWEsUUFBSyxnQkFBTCxDQUFzQixPQUF0QixFQUErQixVQUEvQixDQUEwQyxXQUxwRDtBQU1ILDBDQUFrQixRQUFLLGdCQUFMLENBQXNCLE9BQXRCLEVBQStCLFVBQS9CLENBQTBDLGdCQU56RDtBQU9ILCtCQUFPLFFBQUssZ0JBQUwsQ0FBc0IsT0FBdEIsRUFBK0IsVUFBL0IsQ0FBMEMsS0FQOUM7QUFRSCxvQ0FBWSxRQUFLLGdCQUFMLENBQXNCLE9BQXRCLEVBQStCLFVBQS9CLENBQTBDLFVBUm5EO0FBU0gsa0NBQVUsUUFBSyxnQkFBTCxDQUFzQixPQUF0QixFQUErQixVQUEvQixDQUEwQyxRQVRqRDtBQVVILGtDQUFVLFFBQUssZ0JBQUwsQ0FBc0IsT0FBdEIsRUFBK0IsUUFBL0IsQ0FBd0MsQ0FBeEMsRUFBMkMsUUFBM0MsQ0FBb0QsQ0FBcEQsQ0FWUDtBQVdILGtDQUFVLFFBQUssZ0JBQUwsQ0FBc0IsT0FBdEIsRUFBK0IsUUFBL0IsQ0FBd0MsQ0FBeEMsSUFBNkMsUUFBSyxnQkFBTCxDQUFzQixPQUF0QixFQUErQixRQUEvQixDQUF3QyxDQUF4QyxFQUEyQyxRQUEzQyxDQUFvRCxDQUFwRCxDQUE3QyxHQUFzRztBQVg3RyxxQkFBUDtBQWFILGlCQWRELE1BY087QUFDSCwyQkFBTyxLQUFQO0FBQ0g7QUFDSixhQW5CRSxFQW9CRixJQXBCRSxDQW9CRyxDQUFDLFFBQUQsRUFBVyxTQUFYLENBcEJILEVBb0IwQixVQUFDLE9BQUQsRUFBVSxHQUFWLEVBQWtCO0FBQzNDLG9CQUFJLFFBQUssZ0JBQUwsQ0FBc0IsT0FBdEIsQ0FBSixFQUFvQztBQUNoQyx3QkFBSSxRQUFRLEtBQVosRUFBbUIsT0FBTyxPQUFPLFFBQUssZ0JBQUwsQ0FBc0IsT0FBdEIsQ0FBZDtBQUN0QixpQkFGRCxNQUVPO0FBQ0gsMkJBQU8sS0FBUDtBQUNIO0FBQ0osYUExQkUsRUEyQkYsSUEzQkUsQ0EyQkcsQ0FBQyxRQUFELEVBQVcsR0FBWCxDQTNCSCxFQTJCb0IsVUFBQyxPQUFELEVBQVUsR0FBVixFQUFrQjtBQUNyQyxvQkFBSSxPQUFPLEdBQVAsS0FBZSxRQUFuQixFQUE2QjtBQUN6Qiw0QkFBSyxnQkFBTCxDQUFzQixPQUF0QixJQUFpQztBQUM3Qiw4QkFBTSxnQkFEdUI7QUFFN0Isb0NBQVk7QUFDUixrQ0FBTSxNQURFO0FBRVIsd0NBQVksS0FGSjtBQUdSLDhDQUFrQixLQUhWO0FBSVIsb0NBQVEsRUFKQTtBQUtSLHlDQUFhLEVBTEw7QUFNUiw4Q0FBa0IsS0FOVjtBQU9SLG1DQUFPLEVBUEM7QUFRUix3Q0FBWSxFQVJKO0FBU1Isc0NBQVUsRUFURjtBQVVSLG1DQUFPO0FBVkMseUJBRmlCO0FBYzdCLGtDQUFVLENBQ047QUFDSSxrQ0FBTSxVQURWO0FBRUksd0NBQVksRUFGaEI7QUFHSSxzQ0FBVSxDQUFDLEdBQUQ7QUFIZCx5QkFETSxFQU1OO0FBQ0ksa0NBQU0sVUFEVjtBQUVJLHdDQUFZLEVBRmhCO0FBR0ksc0NBQVUsQ0FBQyxFQUFEO0FBSGQseUJBTk07QUFkbUIscUJBQWpDO0FBMkJILGlCQTVCRCxNQTRCTyxJQUFJLFFBQU8sR0FBUCx5Q0FBTyxHQUFQLE9BQWUsUUFBbkIsRUFBNkI7QUFDaEMsNEJBQUssZ0JBQUwsQ0FBc0IsT0FBdEIsSUFBaUM7QUFDN0IsOEJBQU0sZ0JBRHVCO0FBRTdCLG9DQUFZO0FBQ1Isa0NBQU0sSUFBSSxJQUFKLEdBQVcsSUFBSSxJQUFmLEdBQXNCLE1BRHBCO0FBRVIsd0NBQVksSUFBSSxVQUZSO0FBR1IsOENBQWtCLElBQUksZ0JBSGQ7QUFJUixvQ0FBUSxJQUFJLE1BSko7QUFLUix5Q0FBYSxJQUFJLFdBTFQ7QUFNUiw4Q0FBa0IsSUFBSSxnQkFOZDtBQU9SLG1DQUFPLElBQUksS0FQSDtBQVFSLHdDQUFZLElBQUksVUFSUjtBQVNSLHNDQUFVLElBQUksUUFUTjtBQVVSLG1DQUFPO0FBVkMseUJBRmlCO0FBYzdCLGtDQUFVLENBQ047QUFDSSxrQ0FBTSxVQURWO0FBRUksd0NBQVksRUFGaEI7QUFHSSxzQ0FBVSxDQUNOLElBQUksUUFERTtBQUhkLHlCQURNLEVBUU47QUFDSSxrQ0FBTSxVQURWO0FBRUksd0NBQVksRUFGaEI7QUFHSSxzQ0FBVSxDQUNOLElBQUksUUFERTtBQUhkLHlCQVJNO0FBZG1CLHFCQUFqQztBQStCSDtBQUNELHVCQUFPLE9BQVA7QUFDSCxhQTFGRSxFQTJGRixNQTNGRSxDQTJGSyxTQTNGTCxDQUFQO0FBNEZIOztBQUVEOzs7Ozs7OztpQ0FLUztBQUFBOztBQUNMO0FBQ0EsZ0JBQU0sT0FBTyxFQUFFLEtBQUYsQ0FBUSxLQUFLLEtBQWIsQ0FBYjtBQUNBLGlCQUFLLFFBQUwsR0FBZ0IsS0FBSyxRQUFMLENBQWMsS0FBZCxFQUFoQjs7QUFFQTtBQUNBLGlCQUFLLFNBQUwsQ0FBZSxRQUFmLEdBQTBCLEVBQUUsTUFBRixDQUFTLEtBQUssU0FBZCxFQUF5QixVQUFDLE9BQUQsRUFBVSxDQUFWLEVBQWdCO0FBQy9EO0FBQ0EsdUJBQU8sV0FBVyxNQUFNLFFBQVEsVUFBUixDQUFtQixHQUFwQyxJQUEyQyxPQUFPLElBQVAsQ0FBWSxRQUFRLFVBQXBCLEVBQWdDLE1BQWhDLEdBQXlDLENBQTNGO0FBQ0gsYUFIeUIsQ0FBMUI7QUFJQSxnQkFBSSxLQUFLLFNBQUwsQ0FBZSxRQUFmLENBQXdCLE1BQTVCLEVBQW9DO0FBQ2hDLHFCQUFLLGFBQUwsQ0FBbUIsSUFBbkIsRUFBeUIsS0FBSyxTQUE5QixFQUF5QyxTQUF6QztBQUNIOztBQUVEO0FBQ0EsaUJBQUssZUFBTCxDQUFxQixRQUFyQixHQUFnQyxFQUFFLE1BQUYsQ0FBUyxLQUFLLFdBQWQsQ0FBaEM7QUFDQSxnQkFBSSxLQUFLLGVBQUwsQ0FBcUIsUUFBckIsQ0FBOEIsTUFBbEMsRUFBMEM7QUFDdEMscUJBQUssYUFBTCxDQUFtQixJQUFuQixFQUF5QixLQUFLLGVBQTlCLEVBQStDLFNBQS9DO0FBQ0g7O0FBRUQ7QUFDQSxnQkFBSSxLQUFLLGlCQUFULEVBQTRCO0FBQ3hCLG9CQUFJLE9BQU8sSUFBUCxDQUFZLEtBQUssaUJBQUwsQ0FBdUIsVUFBbkMsRUFBK0MsTUFBbkQsRUFBMkQ7QUFDdkQseUJBQUssYUFBTCxDQUFtQixJQUFuQixFQUF5QixLQUFLLGlCQUE5QixFQUFpRCxTQUFqRDtBQUNIO0FBQ0o7O0FBRUQ7QUFDQSxnQkFBSSxLQUFLLGdCQUFMLElBQXlCLEtBQUssc0JBQWxDLEVBQTBEO0FBQ3REO0FBQ0Esb0JBQU0sWUFBWSxFQUFFLEtBQUYsQ0FBUSxLQUFLLGdCQUFiLENBQWxCO0FBQ0Esb0JBQUksT0FBTyxJQUFQLENBQVksS0FBSyxnQkFBTCxDQUFzQixVQUFsQyxFQUE4QyxNQUFsRCxFQUEwRDtBQUN0RDtBQUNBLDhCQUFVLFVBQVYsR0FBdUIsRUFBRSxNQUFGLENBQ25CLEtBQUssbUJBQUwsQ0FBeUIsS0FBSyxzQkFBOUIsQ0FEbUIsRUFFbkIsS0FBSyxnQkFBTCxDQUFzQixVQUZILENBQXZCO0FBR0gsaUJBTEQsTUFLTztBQUNIO0FBQ0EsOEJBQVUsVUFBVixHQUF1QixLQUFLLG1CQUFMLENBQXlCLEtBQUssc0JBQTlCLENBQXZCO0FBQ0g7QUFDRCxxQkFBSyxhQUFMLENBQW1CLElBQW5CLEVBQXlCLFNBQXpCLEVBQW9DLFNBQXBDO0FBQ0g7O0FBRUQ7QUFDQSxpQkFBSyxlQUFMLENBQXFCLFFBQXJCLEdBQWdDLEVBQUUsTUFBRixDQUFTLEtBQUssV0FBZCxDQUFoQztBQUNBLGdCQUFJLEtBQUssZUFBTCxDQUFxQixRQUFyQixDQUE4QixNQUFsQyxFQUEwQztBQUN0QyxxQkFBSyxhQUFMLENBQW1CLElBQW5CLEVBQXlCLEtBQUssZUFBOUIsRUFBK0MsU0FBL0M7QUFDSDs7QUFFRDtBQUNBLGlCQUFLLG9CQUFMLENBQTBCLFFBQTFCLEdBQXFDLEVBQUUsTUFBRixDQUFTLEtBQUssZ0JBQWQsQ0FBckM7QUFDQSxnQkFBSSxLQUFLLG9CQUFMLENBQTBCLFFBQTFCLENBQW1DLE1BQXZDLEVBQStDO0FBQzNDLHFCQUFLLGFBQUwsQ0FBbUIsSUFBbkIsRUFBeUIsS0FBSyxvQkFBOUIsRUFBb0QsU0FBcEQ7QUFDSDs7QUFFRCxnQkFBSSxLQUFLLFdBQVQsRUFBc0I7QUFDbEIscUJBQUssYUFBTCxDQUFtQixJQUFuQixFQUF5QjtBQUNyQiwwQkFBTSxZQURlO0FBRXJCLDhCQUFVLEVBRlc7QUFHckIsZ0NBQVk7QUFDUiw2QkFBSyxLQUFLLFdBQUwsQ0FBaUIsT0FBakI7QUFERztBQUhTLGlCQUF6QixFQU1HLFNBTkg7QUFPSDs7QUFFRDtBQUNBLGFBQUMsV0FBRCxFQUFjLFdBQWQsRUFBMkIsT0FBM0IsQ0FBbUMsZ0JBQVE7QUFDdkMsb0JBQU0sU0FBUyxjQUFTLElBQVQsVUFBZjtBQUNBLG9CQUFJLE9BQU8sVUFBUCxDQUFrQixLQUF0QixFQUE2QjtBQUN6Qix5QkFBSyxhQUFMLENBQW1CLElBQW5CLEVBQXlCLE1BQXpCLEVBQWlDLFNBQWpDO0FBQ0g7QUFDSixhQUxEOztBQU9BLG1CQUFPO0FBQ0gsb0JBQUksS0FBSyxPQUROO0FBRUgsdUJBQU8sSUFGSjtBQUdILCtCQUFlLEtBQUs7QUFIakIsYUFBUDtBQUtIOztBQUVEOzs7Ozs7Ozs7aURBTXlCLGUsRUFBaUI7QUFDdEMsZ0JBQUksa0JBQWtCLEtBQUssbUJBQTNCLEVBQWdEO0FBQzVDLHFCQUFLLG1CQUFMLEdBQTJCLGVBQTNCO0FBQ0g7QUFDSjs7QUFFRDs7Ozs7Ozs7O1lBU0c7Ozs7Ozs7Ozt1Q0FNWTtBQUFBOztBQUNYLGdCQUFNLDBCQUEwQixDQUM1QixXQUQ0QixFQUNmLGNBRGUsRUFDQyxVQURELEVBQ2Esb0JBRGIsRUFDbUMsa0JBRG5DLENBQWhDO0FBRUEsZ0JBQU0scUJBQXFCLEtBQUssNEJBQUwsQ0FBa0MsY0FBbEMsRUFBa0QsdUJBQWxELENBQTNCO0FBQ0EsbUJBQU8sSUFBSSxVQUFKLENBQWUsb0JBQWYsRUFDRixJQURFLENBQ0csQ0FBQyxRQUFELENBREgsRUFDZSx5QkFBaUI7QUFDL0IsbUNBQW1CLGFBQW5CO0FBQ0EsdUJBQU8sUUFBSyxpQkFBTCxDQUF1QixVQUF2QixDQUFrQyxhQUFsQyxNQUFxRCxDQUE1RDtBQUNILGFBSkUsRUFLRixJQUxFLENBS0csQ0FBQyxRQUFELEVBQVcsS0FBWCxDQUxILEVBS3NCLHlCQUFpQjtBQUN0QyxtQ0FBbUIsYUFBbkI7QUFDQSx1QkFBTyxRQUFLLGlCQUFMLENBQXVCLFVBQXZCLENBQWtDLGFBQWxDLENBQVA7QUFDQSx1QkFBTyxPQUFQO0FBQ0gsYUFURSxFQVVGLElBVkUsQ0FVRyxDQUFDLFFBQUQsRUFBVyxTQUFYLENBVkgsRUFVMEIsVUFBQyxhQUFELEVBQWdCLGdCQUFoQixFQUFxQztBQUM5RCxtQ0FBbUIsYUFBbkI7QUFDQSxvQkFBSSxnQkFBSixFQUFzQjtBQUNsQiw0QkFBSyxpQkFBTCxDQUF1QixVQUF2QixDQUFrQyxhQUFsQyxJQUFtRCxDQUFuRDtBQUNBLDJCQUFPLE9BQVA7QUFDSCxpQkFIRCxNQUdPO0FBQ0gsMkJBQU8sUUFBSyxZQUFMLENBQWtCLGFBQWxCLEVBQWlDLFNBQWpDLENBQVA7QUFDSDtBQUNKLGFBbEJFLEVBbUJGLE1BbkJFLENBbUJLLFNBbkJMLENBQVA7QUFvQkg7O0FBRUQ7OztZQUdHOzs7Ozs7Ozt5Q0FLYztBQUFBOztBQUNiLG1CQUFPLElBQUksVUFBSixDQUFlLGlCQUFmLEVBQ0YsSUFERSxDQUNHLFlBQU07QUFDUix1QkFBTyxRQUFLLFlBQUwsQ0FBa0IsV0FBbEIsS0FBa0MsUUFBSyxZQUFMLENBQWtCLGNBQWxCLENBQXpDO0FBQ0gsYUFIRSxFQUlGLElBSkUsQ0FJRyxDQUFDLEtBQUQsQ0FKSCxFQUlZLFlBQU07QUFDakIsd0JBQUssWUFBTCxDQUFrQixXQUFsQixFQUErQixTQUEvQjtBQUNBLHdCQUFLLFlBQUwsQ0FBa0IsY0FBbEIsRUFBa0MsU0FBbEM7QUFDQSx1QkFBTyxPQUFQO0FBQ0gsYUFSRSxFQVNGLElBVEUsQ0FTRyxDQUFDLFNBQUQsQ0FUSCxFQVNnQixtQkFBVztBQUMxQix3QkFBSyxZQUFMLENBQWtCLFdBQWxCLEVBQStCLE9BQS9CO0FBQ0Esd0JBQUssWUFBTCxDQUFrQixjQUFsQixFQUFrQyxPQUFsQztBQUNBLHVCQUFPLE9BQVA7QUFDSCxhQWJFLEVBY0YsTUFkRSxDQWNLLFNBZEwsQ0FBUDtBQWVIOztBQUVEOzs7Ozs7Ozs7OztZQVdHOzs7Ozs7Ozs7c0NBTVc7QUFBQTs7QUFDVixnQkFBSSxLQUFLLGlCQUFMLE9BQTZCLFNBQWpDLEVBQTRDO0FBQ3hDLHNCQUFNLElBQUksS0FBSixDQUFVLHlDQUFWLENBQU47QUFDSDtBQUNELGdCQUFNLDBCQUEwQixDQUM1QixNQUQ0QixFQUNwQixPQURvQixFQUNYLEtBRFcsRUFDSixRQURJLEVBQ00sUUFETixFQUNnQixRQURoQixDQUFoQztBQUVBLGdCQUFNLHFCQUFxQixLQUFLLDRCQUFMLENBQWtDLGFBQWxDLEVBQWlELHVCQUFqRCxDQUEzQjtBQUNBLGdCQUFNLGFBQWEsS0FBSyxvQkFBTCxDQUEwQixhQUExQixFQUF5QyxDQUF6QyxFQUE0QyxTQUE1QyxDQUFuQjtBQUNBLG1CQUFPLElBQUksVUFBSixDQUFlLG1CQUFmLEVBQ0YsSUFERSxDQUNHLENBQUMsUUFBRCxDQURILEVBQ2UseUJBQWlCO0FBQy9CLG1DQUFtQixhQUFuQjtBQUNBLG9CQUFNLGlCQUFpQixRQUFLLGdCQUFMLENBQXNCLFVBQXRCLENBQWlDLGFBQWpDLENBQXZCO0FBQ0Esb0JBQUksbUJBQW1CLFNBQXZCLEVBQWtDO0FBQzlCLDJCQUFPLFdBQVcsY0FBWCxDQUFQO0FBQ0gsaUJBRkQsTUFFTyxJQUFJLFFBQUssc0JBQVQsRUFBaUM7QUFDcEMsMkJBQU8sV0FBVyxRQUFLLG1CQUFMLENBQXlCLFFBQUssc0JBQTlCLEVBQXNELGFBQXRELENBQVgsQ0FBUDtBQUNILGlCQUZNLE1BRUE7QUFDSCwyQkFBTyxTQUFQO0FBQ0g7QUFDSixhQVhFLEVBWUYsSUFaRSxDQVlHLENBQUMsUUFBRCxFQUFXLEtBQVgsQ0FaSCxFQVlzQix5QkFBaUI7QUFDdEMsbUNBQW1CLGFBQW5CO0FBQ0EsdUJBQU8sUUFBSyxnQkFBTCxDQUFzQixVQUF0QixDQUFpQyxhQUFqQyxDQUFQO0FBQ0EsdUJBQU8sT0FBUDtBQUNILGFBaEJFLEVBaUJGLElBakJFLENBaUJHLENBQUMsUUFBRCxFQUFXLFFBQVgsQ0FqQkgsRUFpQnlCLFVBQUMsYUFBRCxFQUFnQixvQkFBaEIsRUFBeUM7QUFDakUsbUNBQW1CLGFBQW5CO0FBQ0EsMkJBQVcsb0JBQVg7QUFDQSx3QkFBSyxnQkFBTCxDQUFzQixVQUF0QixDQUFpQyxhQUFqQyxJQUFrRCxvQkFBbEQ7QUFDQSx1QkFBTyxPQUFQO0FBQ0gsYUF0QkUsRUF1QkYsSUF2QkUsQ0F1QkcsQ0FBQyxRQUFELEVBQVcsUUFBWCxDQXZCSCxFQXVCeUIsVUFBQyxhQUFELEVBQWdCLG9CQUFoQixFQUF5QztBQUNqRSx1QkFBTyxRQUFLLFdBQUwsQ0FBaUIsYUFBakIsRUFBZ0MsV0FBVyxvQkFBWCxDQUFoQyxDQUFQO0FBQ0gsYUF6QkUsRUEwQkYsTUExQkUsQ0EwQkssU0ExQkwsQ0FBUDtBQTJCSDs7QUFFRDs7Ozs7Ozs7O1lBU0c7Ozs7ZUFJQTs7Ozs7Ozs7OzRDQU1pQjtBQUFBOztBQUNoQixtQkFBTyxJQUFJLFVBQUosQ0FBZSx5QkFBZixFQUNGLElBREUsQ0FDRyxZQUFNO0FBQ1IsdUJBQU8sUUFBSyxzQkFBWjtBQUNILGFBSEUsRUFJRixJQUpFLENBSUcsQ0FBQyxLQUFELENBSkgsRUFJWSxZQUFNO0FBQ2pCO0FBQ0Esd0JBQUssc0JBQUwsR0FBOEIsU0FBOUI7O0FBRUE7QUFDQSx3QkFBSyxnQkFBTCxDQUFzQixVQUF0QixHQUFtQyxFQUFuQztBQUNBLHVCQUFPLE9BQVA7QUFDSCxhQVhFLEVBWUYsSUFaRSxDQVlHLENBQUMsUUFBRCxDQVpILEVBWWUsc0JBQWM7QUFDNUIsb0JBQU0sa0JBQWtCLFFBQUssNEJBQUwsQ0FDcEIsbUJBRG9CLEVBQ0MsT0FBTyxJQUFQLENBQVksUUFBSyxtQkFBakIsQ0FERCxDQUF4QjtBQUVBLGdDQUFnQixVQUFoQjs7QUFFQTtBQUNBLHdCQUFLLHNCQUFMLEdBQThCLFVBQTlCOztBQUVBO0FBQ0Esd0JBQUssZ0JBQUwsQ0FBc0IsVUFBdEIsR0FBbUMsRUFBbkM7QUFDQSx1QkFBTyxPQUFQO0FBQ0gsYUF2QkUsRUF3QkYsSUF4QkUsQ0F3QkcsQ0FBQyxRQUFELEVBQVcsUUFBWCxDQXhCSCxFQXdCeUIsVUFBQyxVQUFELEVBQWEsZ0JBQWIsRUFBa0M7QUFDMUQsb0JBQUksUUFBSyxtQkFBTCxDQUF5QixjQUF6QixDQUF3QyxVQUF4QyxDQUFKLEVBQXlEO0FBQ3JELDBCQUFNLElBQUksS0FBSiwwQ0FBaUQsVUFBakQsc0JBQU47QUFDSDs7QUFFRDtBQUNBLG9CQUFNLDRCQUE0QixDQUM5QixNQUQ4QixFQUN0QixPQURzQixFQUNiLEtBRGEsRUFDTixRQURNLEVBQ0ksUUFESixFQUNjLFFBRGQsQ0FBbEM7QUFFQSxvQkFBTSw2QkFBNkIsRUFBRSxPQUFGLENBQy9CLEVBQUUsTUFBRixDQUFTLHlCQUFULENBRCtCLEVBRS9CLEVBQUUsTUFBRixDQUFTLE9BQU8sSUFBUCxDQUFZLGdCQUFaLENBQVQsQ0FGK0IsQ0FBbkM7QUFHQSxvQkFBSSwrQkFBK0IsS0FBbkMsRUFBMEM7QUFDdEMsMEJBQU0sSUFBSSxLQUFKLGdGQUFzRixPQUFPLElBQVAsQ0FBWSxnQkFBWixDQUF0RixRQUFOO0FBQ0g7O0FBRUQ7QUFDQSxrQkFBRSxPQUFGLENBQVUsVUFBQyxjQUFELEVBQWlCLGFBQWpCLEVBQW1DO0FBQ3pDLHdCQUFNLHVCQUF1QixXQUFXLGNBQVgsQ0FBN0I7QUFDQSx3QkFBSSxFQUFFLEtBQUYsQ0FBUSxvQkFBUixLQUFpQyxFQUFFLFFBQUYsQ0FBVyxvQkFBWCxNQUFxQyxLQUExRSxFQUFpRjtBQUM3RSw4QkFBTSxJQUFJLEtBQUosbUVBQXlFLGNBQXpFLFFBQU47QUFDSDtBQUNKLGlCQUxEOztBQU9BO0FBQ0Esd0JBQUssc0JBQUwsR0FBOEIsVUFBOUI7O0FBRUE7QUFDQSx3QkFBSyxnQkFBTCxDQUFzQixVQUF0QixHQUFtQyxFQUFuQzs7QUFFQTtBQUNBLHdCQUFLLG1CQUFMLENBQXlCLFVBQXpCLElBQXVDLGdCQUF2QztBQUNBLHVCQUFPLE9BQVA7QUFDSCxhQXhERSxFQXlERixNQXpERSxDQXlESyxTQXpETCxDQUFQO0FBMERIOztBQUVEOzs7Ozs7Ozs7Ozs7WUFZRzs7O2VBR0E7Ozs7Ozs7O2dDQUtLO0FBQUE7O0FBQ0osZ0JBQU0sa0JBQWtCLENBQUMsT0FBRCxFQUFVLFFBQVYsRUFBb0IsYUFBcEIsQ0FBeEI7QUFDQSxnQkFBTSx1QkFBdUIsQ0FBQyxZQUFELEVBQWUsYUFBZixFQUE4QixTQUE5QixFQUF5QyxVQUF6QyxDQUE3QjtBQUNBLGdCQUFNLGlCQUFpQixLQUFLLDRCQUFMLENBQWtDLFlBQWxDLEVBQWdELGVBQWhELENBQXZCO0FBQ0EsZ0JBQU0sa0JBQWtCLEtBQUssNEJBQUwsQ0FBa0MsaUJBQWxDLEVBQXFELG9CQUFyRCxDQUF4QjtBQUNBLGdCQUFNLGdCQUFnQixLQUFLLHlCQUFMLEVBQXRCO0FBQ0EsZ0JBQUksV0FBVyxLQUFLLFNBQUwsQ0FBZSxhQUFmLEVBQThCLE1BQTlCLENBQWY7QUFDQSxtQkFBTyxJQUFJLFVBQUosQ0FBZSxZQUFmLEVBQ0YsSUFERSxDQUNHLFlBQU07QUFDUixvQkFBSSxRQUFKLEVBQWM7QUFDVix3QkFBTSxTQUFTLEVBQUUsU0FBRixDQUFZLFNBQVMsVUFBckIsQ0FBZjtBQUNBLHdCQUFJLENBQUMsT0FBTyxLQUFaLEVBQW1CLE9BQU8sS0FBUCxHQUFlLE9BQWY7QUFDbkIsMkJBQU8sTUFBUDtBQUNIO0FBQ0osYUFQRSxFQVFGLElBUkUsQ0FRRyxDQUFDLEtBQUQsQ0FSSCxFQVFZLFlBQU07QUFDakIscUJBQUssV0FBTCxDQUFpQixhQUFqQixFQUFnQyxNQUFoQztBQUNBLHVCQUFPLE9BQVA7QUFDSCxhQVhFLEVBWUYsSUFaRSxDQVlHLENBQUMsUUFBRCxDQVpILEVBWWUsMEJBQWtCO0FBQ2hDLG9CQUFNLGFBQWEsRUFBRSxNQUFGLENBQVMsRUFBRSxZQUFZLGFBQWQsRUFBVCxFQUF3QyxjQUF4QyxDQUFuQjtBQUNBLCtCQUFlLFdBQVcsS0FBMUI7QUFDQSxnQ0FBZ0IsV0FBVyxVQUEzQjtBQUNBLG9CQUFJLFFBQUosRUFBYztBQUNWLDZCQUFTLFVBQVQsR0FBc0IsVUFBdEI7QUFDSCxpQkFGRCxNQUVPO0FBQ0gsK0JBQVc7QUFDUCw4QkFBTSxNQURDO0FBRVAsOENBRk87QUFHUCxrQ0FBVTtBQUhILHFCQUFYO0FBS0EseUJBQUssV0FBTCxDQUFpQixhQUFqQixFQUFnQyxRQUFoQztBQUNIO0FBQ0QsdUJBQU8sT0FBUDtBQUNILGFBM0JFLEVBNEJGLE1BNUJFLENBNEJLLFNBNUJMLENBQVA7QUE2Qkg7O0FBRUQ7Ozs7O1lBS0c7Ozs7Ozs7OztzQ0FNVztBQUFBOztBQUNWLG1CQUFPLElBQUksVUFBSixDQUFlLGtCQUFmLEVBQ0YsSUFERSxDQUNHLENBQUMsU0FBRCxFQUFZLFNBQVosQ0FESCxFQUMyQixVQUFDLE1BQUQsRUFBUyxNQUFULEVBQW9CO0FBQzlDLG9CQUFNLGNBQWMsaUJBQWlCLGtCQUFqQixDQUFvQyxTQUFTLENBQTdDLEtBQW1ELFNBQVMsQ0FBNUQsQ0FBcEI7QUFDQSxvQkFBSSxhQUFhLFdBQVcsQ0FBWCxHQUFlLFlBQWYsR0FBOEIsYUFBL0M7QUFDQSw2QkFBYSxXQUFXLENBQVgsR0FBZSxVQUFmLEdBQTRCLFVBQXpDO0FBQ0EsdUJBQU8sUUFBSyxLQUFMLENBQVcsRUFBRSxPQUFPLFFBQVQsRUFBbUIsd0JBQW5CLEVBQWdDLGNBQWhDLEVBQXdDLGNBQXhDLEVBQWdELHNCQUFoRCxFQUFYLENBQVA7QUFDSCxhQU5FLEVBT0YsSUFQRSxDQU9HLENBQUMsUUFBRCxDQVBILEVBT2UsdUJBQWU7QUFDN0Isb0JBQU0sTUFBTSxpQkFBaUIsV0FBakIsQ0FBNkIsV0FBN0IsQ0FBWjtBQUNBLG9CQUFNLFNBQVMsSUFBSSxZQUFKLEdBQW1CLENBQWxDO0FBQUEsb0JBQXFDLFNBQVMsSUFBSSxTQUFKLEdBQWdCLENBQTlEO0FBQ0Esb0JBQUksYUFBYSxXQUFXLENBQVgsR0FBZSxZQUFmLEdBQThCLGFBQS9DO0FBQ0EsNkJBQWEsV0FBVyxDQUFYLEdBQWUsVUFBZixHQUE0QixVQUF6QztBQUNBLHVCQUFPLFFBQUssS0FBTCxDQUFXLEVBQUUsT0FBTyxRQUFULEVBQW1CLHdCQUFuQixFQUFnQyxjQUFoQyxFQUF3QyxjQUF4QyxFQUFnRCxzQkFBaEQsRUFBWCxDQUFQO0FBQ0gsYUFiRSxFQWNGLE1BZEUsQ0FjSyxTQWRMLENBQVA7QUFlSDs7QUFFRDs7Ozs7Ozs7Ozs7bUNBUVcsTSxFQUFRLE0sRUFBUTtBQUN2QixtQkFBTyxLQUFLLEtBQUwsQ0FBVyxFQUFFLE9BQU8sT0FBVCxFQUFrQixjQUFsQixFQUEwQixjQUExQixFQUFYLENBQVA7QUFDSDs7QUFFRDs7Ozs7OztxQ0FJYTtBQUNULG1CQUFPLEtBQUssS0FBTCxDQUFXLElBQVgsQ0FBUDtBQUNIOztBQUVEOztBQUVBOzs7Ozs7Ozs7O3FEQU82QixZLEVBQWMsdUIsRUFBeUI7QUFDaEUsbUJBQU8seUJBQWlCO0FBQ3BCLG9CQUFJLENBQUMsRUFBRSxRQUFGLENBQVcsdUJBQVgsRUFBb0MsYUFBcEMsQ0FBTCxFQUF5RDtBQUNyRCwwQkFBTSxJQUFJLEtBQUosWUFBbUIsWUFBbkIsWUFBcUMsYUFBckMsMEJBQU47QUFDSDtBQUNKLGFBSkQ7QUFLSDs7QUFFRDs7Ozs7Ozs7Ozs0Q0FPb0IsWSxFQUFjLFMsRUFBVztBQUN6QyxtQkFBTyxpQkFBUztBQUNaLG9CQUFJLFFBQU8sS0FBUCx5Q0FBTyxLQUFQLE9BQWlCLFNBQXJCLEVBQWdDO0FBQzVCLDBCQUFNLElBQUksU0FBSixZQUF1QixZQUF2QiwrQ0FBNkUsU0FBN0UsT0FBTjtBQUNIO0FBQ0osYUFKRDtBQUtIOztBQUVEOzs7Ozs7Ozs7Ozs2Q0FRcUIsWSxFQUFjLFEsRUFBVSxRLEVBQVU7QUFDbkQsZ0JBQU0sWUFBWSxLQUFLLG1CQUFMLENBQXlCLFlBQXpCLEVBQXVDLFFBQXZDLENBQWxCO0FBQ0EsbUJBQU8saUJBQVM7QUFDWiwwQkFBVSxLQUFWO0FBQ0Esb0JBQUksYUFBYSxTQUFqQixFQUE0QjtBQUN4Qix3QkFBSSxRQUFRLFFBQVosRUFBc0I7QUFDbEIsOEJBQU0sSUFBSSxVQUFKLFlBQXdCLFlBQXhCLG1FQUFrRyxRQUFsRyxPQUFOO0FBQ0g7QUFDSjtBQUNELG9CQUFJLGFBQWEsU0FBakIsRUFBNEI7QUFDeEIsd0JBQUksWUFBWSxLQUFoQixFQUF1QjtBQUNuQiw4QkFBTSxJQUFJLFVBQUosWUFBd0IsWUFBeEIsb0RBQW1GLFFBQW5GLE9BQU47QUFDSDtBQUNKO0FBQ0osYUFaRDtBQWFIOztBQUVEOzs7Ozs7OztvREFLNEI7QUFDeEIsZ0JBQUksaUJBQWlCLEtBQUssU0FBTCxDQUFlLEtBQUssS0FBcEIsRUFBMkIsWUFBM0IsQ0FBckI7QUFDQSxnQkFBSSxDQUFDLGNBQUwsRUFBcUI7QUFDakIsaUNBQWlCO0FBQ2IsMEJBQU0sWUFETztBQUViLGdDQUFZLEVBRkM7QUFHYiw4QkFBVSxDQUFDO0FBQ1AsOEJBQU0sV0FEQztBQUVQLG9DQUFZO0FBQ1IsNENBQWdCO0FBRFIseUJBRkw7QUFLUCxrQ0FBVTtBQUxILHFCQUFEO0FBSEcsaUJBQWpCOztBQVlBLHFCQUFLLGFBQUwsQ0FBbUIsS0FBSyxLQUF4QixFQUErQixjQUEvQixFQUErQyxTQUEvQztBQUNIOztBQUVELG1CQUFPLEtBQUssU0FBTCxDQUFlLGNBQWYsRUFBK0IsV0FBL0IsQ0FBUDtBQUNIOztBQUVEOzs7Ozs7Ozs7Ozs7OEJBU00sUSxFQUFVLE0sRUFBUSxJLEVBQU0saUIsRUFBbUI7QUFBQTs7QUFDN0MsZ0JBQUksQ0FBQyxJQUFMLEVBQVc7QUFDUCx1QkFBTztBQUNILDBCQUFNLFdBREg7QUFFSCxnQ0FBWTtBQUNSLCtCQUFPLDJEQURDO0FBRVIsbUNBQVcscUVBRkg7QUFHUixvQ0FBWSw2REFISjtBQUlSLHdDQUFnQixPQUpSO0FBS1IsdUNBQWU7QUFMUCxxQkFGVDtBQVNILDhCQUFVLENBQUM7QUFDUCw4QkFBTSxXQURDO0FBRVAsb0NBQVksRUFGTDtBQUdQLGtDQUFVO0FBSEgscUJBQUQ7QUFUUCxpQkFBUDtBQWVIOztBQUVELGlCQUFLLFNBQUwsR0FBaUIsUUFBakI7QUFDQSxpQkFBSyxPQUFMLEdBQWUsTUFBZjtBQUNBLGlCQUFLLEtBQUwsR0FBYSxJQUFiO0FBQ0EsaUJBQUssbUJBQUwsR0FBMkIsQ0FBQyxDQUE1QjtBQUNBLGlCQUFLLFdBQUwsR0FBbUIsRUFBbkI7QUFDQSxpQkFBSyxnQkFBTCxHQUF3QixFQUF4QjtBQUNBLGlCQUFLLFdBQUwsR0FBbUIsRUFBbkI7QUFDQSxpQkFBSyxXQUFMLEdBQW1CLElBQW5COztBQUVBO0FBQ0EsaUJBQUssY0FBTCxHQUFzQixJQUFJLGFBQUosQ0FBa0IsaUJBQWxCLENBQXRCOztBQUVBO0FBQ0EsaUJBQUssV0FBTCxDQUFpQixLQUFLLEtBQXRCLEVBQTZCLFdBQTdCOztBQUVBO0FBQ0EsaUJBQUssS0FBTCxHQUFhLEVBQWI7QUFDQSxpQkFBSyxjQUFMLEdBQXNCLEtBQUssU0FBTCxDQUFlLEtBQUssS0FBcEIsRUFBMkIsV0FBM0IsQ0FBdEI7QUFDQSxpQkFBSyxjQUFMLENBQW9CLFFBQXBCLENBQTZCLE9BQTdCLENBQXFDLG1CQUFXO0FBQzVDLG9CQUFNLE1BQU0sSUFBSSxHQUFKLENBQVEsT0FBUixFQUFjLE9BQWQsQ0FBWjtBQUNBLHdCQUFLLEtBQUwsQ0FBVyxJQUFJLFNBQUosRUFBWCxJQUE4QixHQUE5QjtBQUNILGFBSEQ7QUFJQSxpQkFBSyxjQUFMLENBQW9CLFFBQXBCLEdBQStCLEtBQUssS0FBcEM7O0FBRUE7QUFDQSxpQkFBSyxRQUFMLEdBQWdCLEVBQWhCO0FBQ0EsaUJBQUssU0FBTCxHQUFpQixLQUFLLFNBQUwsQ0FBZSxLQUFLLEtBQXBCLEVBQTJCLE1BQTNCLENBQWpCO0FBQ0EsZ0JBQUksS0FBSyxTQUFULEVBQW9CO0FBQ2hCLHFCQUFLLFdBQUwsQ0FBaUIsS0FBSyxLQUF0QixFQUE2QixLQUFLLFNBQWxDO0FBQ0gsYUFGRCxNQUVPO0FBQ0gscUJBQUssU0FBTCxHQUFpQixFQUFFLE1BQU0sTUFBUixFQUFnQixZQUFZLEVBQTVCLEVBQWdDLFVBQVUsRUFBMUMsRUFBakI7QUFDSDs7QUFFRDtBQUNBLGlCQUFLLFNBQUwsR0FBaUIsRUFBakI7QUFDQSxjQUFFLE9BQUYsQ0FBVSxLQUFLLFNBQUwsQ0FBZSxRQUF6QixFQUFtQyxtQkFBVztBQUMxQyxvQkFBTSxNQUFNLFFBQVEsVUFBUixDQUFtQixHQUEvQjtBQUNBLG9CQUFNLE1BQU0sUUFBUSxVQUFSLENBQW1CLEdBQS9CO0FBQ0EscUJBQUssSUFBSSxJQUFJLEdBQWIsRUFBa0IsS0FBSyxHQUF2QixFQUE0QixHQUE1QixFQUFpQztBQUM3Qiw0QkFBSyxTQUFMLENBQWUsQ0FBZixJQUFvQixPQUFwQjtBQUNIO0FBQ0osYUFORDs7QUFRQTtBQUNBLGlCQUFLLFlBQUwsR0FBb0IsS0FBSyxTQUFMLENBQWUsS0FBSyxLQUFwQixFQUEyQixTQUEzQixDQUFwQjtBQUNBLGdCQUFJLENBQUMsS0FBSyxZQUFWLEVBQXdCO0FBQ3BCLHFCQUFLLFlBQUwsR0FBb0IsRUFBRSxNQUFNLFNBQVIsRUFBbUIsWUFBWSxFQUEvQixFQUFtQyxVQUFVLEVBQTdDLEVBQXBCO0FBQ0EscUJBQUssYUFBTCxDQUFtQixLQUFLLEtBQXhCLEVBQStCLEtBQUssWUFBcEMsRUFBa0QsU0FBbEQ7QUFDSDs7QUFFRDtBQUNBLGlCQUFLLGVBQUwsR0FBdUIsS0FBSyxTQUFMLENBQWUsS0FBSyxLQUFwQixFQUEyQixZQUEzQixDQUF2QjtBQUNBLGdCQUFJLEtBQUssZUFBVCxFQUEwQjtBQUN0QixxQkFBSyxXQUFMLENBQWlCLEtBQUssS0FBdEIsRUFBNkIsS0FBSyxlQUFsQztBQUNILGFBRkQsTUFFTztBQUNILHFCQUFLLGVBQUwsR0FBdUIsRUFBRSxNQUFNLFlBQVIsRUFBc0IsWUFBWSxFQUFsQyxFQUFzQyxVQUFVLEVBQWhELEVBQXZCO0FBQ0g7O0FBRUQsZ0JBQU0saUJBQWlCLEtBQUssZUFBTCxDQUFxQixRQUE1QztBQUNBLGlCQUFLLGVBQUwsQ0FBcUIsUUFBckIsR0FBZ0MsRUFBaEM7QUFDQSwyQkFBZSxPQUFmLENBQXVCLHlCQUFpQjtBQUNwQyx3QkFBSyxXQUFMLENBQWlCLGNBQWMsVUFBZCxDQUF5QixHQUExQyxJQUFpRCxhQUFqRDtBQUNILGFBRkQ7O0FBS0E7QUFDQSxpQkFBSyxvQkFBTCxHQUE0QixLQUFLLFNBQUwsQ0FBZSxLQUFLLEtBQXBCLEVBQTJCLGlCQUEzQixDQUE1QjtBQUNBLGdCQUFJLEtBQUssb0JBQVQsRUFBK0I7QUFDM0IscUJBQUssV0FBTCxDQUFpQixLQUFLLEtBQXRCLEVBQTZCLEtBQUssb0JBQWxDO0FBQ0gsYUFGRCxNQUVPO0FBQ0gscUJBQUssb0JBQUwsR0FBNEIsRUFBRSxNQUFNLGlCQUFSLEVBQTJCLFlBQVksRUFBdkMsRUFBMkMsVUFBVSxFQUFyRCxFQUE1QjtBQUNIOztBQUVELGdCQUFNLHNCQUFzQixLQUFLLG9CQUFMLENBQTBCLFFBQXREO0FBQ0EsaUJBQUssb0JBQUwsQ0FBMEIsUUFBMUIsR0FBcUMsRUFBckM7QUFDQSxnQ0FBb0IsT0FBcEIsQ0FBNEIsOEJBQXNCO0FBQzlDLHdCQUFLLGdCQUFMLENBQXNCLG1CQUFtQixVQUFuQixDQUE4QixLQUFwRCxJQUE2RCxrQkFBN0Q7QUFDSCxhQUZEOztBQUtBO0FBQ0EsaUJBQUssZUFBTCxHQUF1QixLQUFLLFNBQUwsQ0FBZSxLQUFLLEtBQXBCLEVBQTJCLFlBQTNCLENBQXZCO0FBQ0EsZ0JBQUksS0FBSyxlQUFULEVBQTBCO0FBQ3RCLHFCQUFLLFdBQUwsQ0FBaUIsS0FBSyxLQUF0QixFQUE2QixLQUFLLGVBQWxDO0FBQ0gsYUFGRCxNQUVPO0FBQ0gscUJBQUssZUFBTCxHQUF1QixFQUFFLE1BQU0sWUFBUixFQUFzQixZQUFZLEVBQWxDLEVBQXNDLFVBQVUsRUFBaEQsRUFBdkI7QUFDSDs7QUFFRCxnQkFBTSxpQkFBaUIsS0FBSyxlQUFMLENBQXFCLFFBQTVDO0FBQ0EsaUJBQUssZUFBTCxDQUFxQixRQUFyQixHQUFnQyxFQUFoQztBQUNBLDJCQUFlLE9BQWYsQ0FBdUIseUJBQWlCO0FBQ3BDLHdCQUFLLFdBQUwsQ0FBaUIsY0FBYyxVQUFkLENBQXlCLEdBQTFDLElBQWlELGFBQWpEO0FBQ0gsYUFGRDs7QUFLQTtBQUNBLGlCQUFLLGlCQUFMLEdBQXlCLEtBQUssU0FBTCxDQUFlLEtBQUssS0FBcEIsRUFBMkIsY0FBM0IsQ0FBekI7QUFDQSxnQkFBSSxLQUFLLGlCQUFULEVBQTRCO0FBQ3hCLHFCQUFLLFdBQUwsQ0FBaUIsS0FBSyxLQUF0QixFQUE2QixLQUFLLGlCQUFsQztBQUNILGFBRkQsTUFFTztBQUNILHFCQUFLLGlCQUFMLEdBQXlCLEVBQUUsTUFBTSxjQUFSLEVBQXdCLFlBQVksRUFBcEMsRUFBd0MsVUFBVSxFQUFsRCxFQUF6QjtBQUNIOztBQUdEO0FBQ0EsaUJBQUssbUJBQUwsR0FBMkI7QUFDdkIsd0JBQVE7QUFDSiwwQkFBTSxHQURGO0FBRUosMkJBQU8sR0FGSDtBQUdKLHlCQUFLLElBSEQ7QUFJSiw0QkFBUSxJQUpKO0FBS0osNEJBQVEsR0FMSjtBQU1KLDRCQUFRO0FBTkosaUJBRGU7QUFTdkIsc0JBQU07QUFDRiwwQkFBTSxDQURKO0FBRUYsMkJBQU8sQ0FGTDtBQUdGLHlCQUFLLENBSEg7QUFJRiw0QkFBUSxDQUpOO0FBS0YsNEJBQVEsR0FMTjtBQU1GLDRCQUFRO0FBTk4saUJBVGlCO0FBaUJ2Qix3QkFBUTtBQUNKLDBCQUFNLElBREY7QUFFSiwyQkFBTyxJQUZIO0FBR0oseUJBQUssSUFIRDtBQUlKLDRCQUFRLElBSko7QUFLSiw0QkFBUSxHQUxKO0FBTUosNEJBQVE7QUFOSjtBQWpCZSxhQUEzQjtBQTBCQSxpQkFBSyxnQkFBTCxHQUF3QixLQUFLLFNBQUwsQ0FBZSxLQUFLLEtBQXBCLEVBQTJCLGFBQTNCLENBQXhCO0FBQ0EsZ0JBQUksS0FBSyxnQkFBVCxFQUEyQjtBQUN2QjtBQUNBLHFCQUFLLHNCQUFMLEdBQThCLFVBQTlCOztBQUVBO0FBQ0EscUJBQUssSUFBTSxVQUFYLElBQXlCLEtBQUssbUJBQTlCLEVBQW1EO0FBQy9DLHdCQUFJLEVBQUUsT0FBRixDQUFVLEtBQUssZ0JBQUwsQ0FBc0IsVUFBaEMsRUFBNEMsS0FBSyxtQkFBTCxDQUF5QixVQUF6QixDQUE1QyxDQUFKLEVBQXVGO0FBQ25GLDZCQUFLLHNCQUFMLEdBQThCLFVBQTlCO0FBQ0E7QUFDSDtBQUNKOztBQUVEO0FBQ0Esb0JBQUksS0FBSyxzQkFBTCxLQUFnQyxVQUFwQyxFQUFnRDtBQUM1Qyx5QkFBSyxtQkFBTCxDQUF5QixRQUF6QixHQUFvQyxLQUFLLGdCQUFMLENBQXNCLFVBQTFEO0FBQ0EseUJBQUssZ0JBQUwsQ0FBc0IsVUFBdEIsR0FBbUMsRUFBbkM7QUFDSDs7QUFFRCxxQkFBSyxXQUFMLENBQWlCLEtBQUssS0FBdEIsRUFBNkIsS0FBSyxnQkFBbEM7QUFDSCxhQW5CRCxNQW1CTztBQUNIO0FBQ0EscUJBQUssc0JBQUwsR0FBOEIsU0FBOUI7QUFDQSxxQkFBSyxnQkFBTCxHQUF3QixFQUFFLE1BQU0sYUFBUixFQUF1QixZQUFZLEVBQW5DLEVBQXVDLFVBQVUsRUFBakQsRUFBeEI7QUFDSDs7QUFFRDtBQUNBLGFBQUMsV0FBRCxFQUFjLFdBQWQsRUFBMkIsT0FBM0IsQ0FBbUMsZ0JBQVE7QUFDdkMsOEJBQVMsSUFBVCxhQUF1QixLQUFLLFNBQUwsQ0FBZSxRQUFLLEtBQXBCLEVBQTJCLElBQTNCLENBQXZCO0FBQ0Esb0JBQUksY0FBUyxJQUFULFVBQUosRUFBMEI7QUFDdEIseUJBQUssV0FBTCxDQUFpQixRQUFLLEtBQXRCLEVBQTZCLGNBQVMsSUFBVCxVQUE3QjtBQUNILGlCQUZELE1BRU87QUFDSCxrQ0FBUyxJQUFULGFBQXVCO0FBQ25CLGtDQURtQjtBQUVuQixrQ0FBVSxFQUZTO0FBR25CLG9DQUFZO0FBQ1IsbUNBQU8sQ0FEQztBQUVSLDhDQUFrQjtBQUZWO0FBSE8scUJBQXZCO0FBUUg7QUFDSixhQWREO0FBZUEsaUJBQUssV0FBTCxHQUFtQjtBQUNmLDJCQUFXLElBQUksVUFBSixDQUFlLEtBQUssY0FBcEIsQ0FESTtBQUVmLDJCQUFXLElBQUksVUFBSixDQUFlLEtBQUssY0FBcEI7QUFGSSxhQUFuQjtBQUlIOzs7Ozs7QUFHTCxPQUFPLE9BQVAsR0FBaUIsS0FBakI7O0FBRUE7Ozs7Ozs7Ozs7Ozs7O0FDai9DQTs7QUFFQTs7Ozs7Ozs7QUFFQSxJQUFNLGFBQWEsUUFBUSxjQUFSLENBQW5CO0FBQ0EsSUFBTSxJQUFJLFFBQVEsUUFBUixDQUFWO0FBQ0EsSUFBTSxPQUFPLFFBQVEsUUFBUixDQUFiO0FBQ0EsSUFBTSxlQUFlLFFBQVEsZ0JBQVIsQ0FBckI7O0FBRUE7Ozs7O0lBSU0sSztBQUNGOzs7Ozs7Ozs7O0FBVUEsbUJBQVksVUFBWixFQUF3QixFQUF4QixFQUE0QixNQUE1QixFQUFvQyxRQUFwQyxFQUE4QyxRQUE5QyxFQUF3RCxVQUF4RCxFQUFvRTtBQUFBOztBQUNoRSxhQUFLLFdBQUwsR0FBbUIsVUFBbkI7QUFDQSxhQUFLLEdBQUwsR0FBVyxFQUFYO0FBQ0EsYUFBSyxPQUFMLEdBQWUsTUFBZjtBQUNBLGFBQUssU0FBTCxHQUFpQixRQUFqQjtBQUNBLGFBQUssU0FBTCxHQUFpQixRQUFqQjtBQUNBLGFBQUssV0FBTCxHQUFtQixVQUFuQjtBQUNIOztBQUVEOzs7Ozs7Ozs2QkFJSztBQUNELG1CQUFPLEtBQUssR0FBWjtBQUNIOztBQUVEOzs7Ozs7Ozs7Z0NBTVE7QUFBQTs7QUFDSixtQkFBTyxJQUFJLFVBQUosQ0FBZSxjQUFmLEVBQ0YsSUFERSxDQUNHLFFBREgsRUFDYSxnQkFBUTtBQUNwQixvQkFBTSx1QkFBcUIsSUFBM0I7QUFDQSxvQkFBSSxDQUFDLE1BQUssVUFBTCxDQUFMLEVBQXVCLE1BQU0sSUFBSSxLQUFKLHFCQUE0QixJQUE1Qiw0QkFBTjtBQUN2Qix1QkFBTyxNQUFLLFVBQUwsR0FBUDtBQUNILGFBTEUsRUFNRixJQU5FLENBTUcsQ0FBQyxRQUFELEVBQVcsR0FBWCxDQU5ILEVBTW9CLFVBQUMsSUFBRCxFQUFPLEtBQVAsRUFBaUI7QUFDcEMsb0JBQU0sdUJBQXFCLElBQTNCO0FBQ0Esb0JBQUksQ0FBQyxNQUFLLFVBQUwsQ0FBTCxFQUF1QixNQUFNLElBQUksS0FBSixxQkFBNEIsSUFBNUIsNEJBQU47QUFDdkIsc0JBQUssVUFBTCxFQUFpQixLQUFqQjtBQUNBLHVCQUFPLEtBQVA7QUFDSCxhQVhFLEVBWUYsTUFaRSxDQVlLLFNBWkwsQ0FBUDtBQWFIOzs7a0NBRVMsSSxFQUFNLEksRUFBTTtBQUNsQixnQkFBTSxRQUFRLEtBQUssU0FBTCxDQUFlLElBQWYsRUFBcUIsSUFBckIsQ0FBZDtBQUNBLGdCQUFJLENBQUMsS0FBRCxJQUFVLENBQUMsTUFBTSxVQUFyQixFQUFpQzs7QUFFakMsZ0JBQU0sUUFBUSxFQUFkO0FBQ0EsZ0JBQUksTUFBTSxVQUFOLENBQWlCLGNBQWpCLENBQWdDLEtBQWhDLENBQUosRUFBNEMsTUFBTSxHQUFOLEdBQVksTUFBTSxVQUFOLENBQWlCLEdBQTdCLENBQTVDLEtBQ0ssSUFBSSxNQUFNLFVBQU4sQ0FBaUIsY0FBakIsQ0FBZ0MsT0FBaEMsQ0FBSixFQUE4QyxNQUFNLEtBQU4sR0FBYyxNQUFNLFVBQU4sQ0FBaUIsS0FBL0IsQ0FBOUMsS0FDQSxJQUFJLE1BQU0sVUFBTixDQUFpQixjQUFqQixDQUFnQyxTQUFoQyxDQUFKLEVBQWdELE1BQU0sR0FBTixHQUFZLGFBQWEsTUFBTSxVQUFOLENBQWlCLE9BQTlCLENBQVo7O0FBRXJELGdCQUFJLE1BQU0sVUFBTixDQUFpQixjQUFqQixDQUFnQyxNQUFoQyxDQUFKLEVBQTZDLE1BQU0sSUFBTixHQUFhLE1BQU0sVUFBTixDQUFpQixJQUE5Qjs7QUFFN0MsZ0JBQUksRUFBRSxPQUFGLENBQVUsS0FBVixDQUFKLEVBQXNCOztBQUV0QixtQkFBTyxLQUFQO0FBQ0g7OztrQ0FFUyxJLEVBQU0sSSxFQUFNLEssRUFBTztBQUN6QixnQkFBSSxPQUFPLEtBQVAsS0FBaUIsUUFBckIsRUFBK0IsUUFBUSxFQUFFLEtBQUssS0FBUCxFQUFSLENBQS9CLEtBQ0ssSUFBSSxPQUFPLEtBQVAsS0FBaUIsUUFBckIsRUFBK0IsUUFBUSxFQUFFLE9BQU8sS0FBVCxFQUFSOztBQUVwQyxpQkFBSyxrQkFBTCxDQUF3QixJQUF4QixFQUE4QixJQUE5QixFQUFvQztBQUNoQyxxQkFBSyxTQUFTLE1BQU0sR0FBZixJQUFzQixNQUFNLEdBQU4sQ0FBVSxXQUFWLEVBREs7QUFFaEMseUJBQVMsSUFGdUI7QUFHaEMsdUJBQU8sU0FBUyxNQUFNLEtBSFU7QUFJaEMsc0JBQU0sU0FBUyxNQUFNO0FBSlcsYUFBcEM7O0FBT0EsaUJBQUssa0JBQUwsQ0FBd0IsSUFBeEIsRUFBOEIsT0FBOUI7QUFDSDs7O29DQUVXO0FBQ1IsbUJBQU8sS0FBSyxRQUFMLENBQWMsS0FBSyxTQUFuQixFQUE4QixHQUE5QixDQUFQO0FBQ0g7OztrQ0FFUyxJLEVBQU07QUFDWixnQkFBSSxJQUFKLEVBQVUsS0FBSyxxQkFBTCxDQUEyQixLQUFLLFNBQWhDLEVBQTJDLEdBQTNDLEVBQVYsS0FDSyxLQUFLLFdBQUwsQ0FBaUIsS0FBSyxTQUF0QixFQUFpQyxHQUFqQztBQUNSOzs7c0NBRWE7QUFDVixtQkFBTyxLQUFLLFFBQUwsQ0FBYyxLQUFLLFNBQW5CLEVBQThCLEdBQTlCLENBQVA7QUFDSDs7O29DQUVXLE0sRUFBUTtBQUNoQixnQkFBSSxNQUFKLEVBQVksS0FBSyxxQkFBTCxDQUEyQixLQUFLLFNBQWhDLEVBQTJDLEdBQTNDLEVBQVosS0FDSyxLQUFLLFdBQUwsQ0FBaUIsS0FBSyxTQUF0QixFQUFpQyxHQUFqQztBQUNSOzs7eUNBRWdCO0FBQ2IsZ0JBQU0sUUFBUSxLQUFLLFNBQUwsQ0FBZSxLQUFLLFNBQXBCLEVBQStCLEdBQS9CLENBQWQ7QUFDQSxtQkFBTyxRQUFRLE1BQU0sVUFBTixDQUFpQixHQUFqQixJQUF3QixJQUFoQyxHQUF1QyxLQUE5QztBQUNIOzs7dUNBRWMsUyxFQUFXO0FBQ3RCLGdCQUFJLFNBQUosRUFBZTtBQUNYLG9CQUFNLFFBQVEsS0FBSyxxQkFBTCxDQUEyQixLQUFLLFNBQWhDLEVBQTJDLEdBQTNDLENBQWQ7QUFDQSxvQkFBTSxNQUFNLE9BQU8sU0FBUCxLQUFxQixRQUFyQixHQUFnQyxTQUFoQyxHQUE0QyxJQUF4RDtBQUNBLHFCQUFLLGFBQUwsQ0FBbUIsS0FBbkIsRUFBMEIsRUFBRSxRQUFGLEVBQTFCO0FBQ0gsYUFKRCxNQUlPO0FBQ0gscUJBQUssV0FBTCxDQUFpQixLQUFLLFNBQXRCLEVBQWlDLEdBQWpDO0FBQ0g7QUFDSjs7OzZDQUVvQjtBQUNqQixtQkFBTyxLQUFLLFFBQUwsQ0FBYyxLQUFLLFNBQW5CLEVBQThCLFFBQTlCLENBQVA7QUFDSDs7OzJDQUVrQixhLEVBQWU7QUFDOUIsZ0JBQUksYUFBSixFQUFtQixLQUFLLHFCQUFMLENBQTJCLEtBQUssU0FBaEMsRUFBMkMsUUFBM0MsRUFBbkIsS0FDSyxLQUFLLFdBQUwsQ0FBaUIsS0FBSyxTQUF0QixFQUFpQyxRQUFqQztBQUNSOzs7b0RBRTJCO0FBQ3hCLG1CQUFPLEtBQUssaUJBQUwsQ0FBdUIsS0FBSyxTQUE1QixFQUF1QyxXQUF2QyxFQUFvRCxLQUFwRCxDQUFQO0FBQ0g7OztrREFFeUIsUyxFQUFXO0FBQ2pDLGlCQUFLLGtCQUFMLENBQXdCLEtBQUssU0FBN0IsRUFBd0MsV0FBeEMsRUFBcUQsRUFBRSxLQUFLLFNBQVAsRUFBckQ7QUFDQSxpQkFBSyxrQkFBTCxDQUF3QixLQUFLLFNBQTdCLEVBQXdDLFdBQXhDO0FBQ0g7Ozt5Q0FFZ0I7QUFDYixtQkFBTyxLQUFLLHlCQUFMLE9BQXFDLFdBQTVDO0FBQ0g7Ozt1Q0FFYyxTLEVBQVc7QUFDdEIsaUJBQUsseUJBQUwsQ0FBK0IsWUFBWSxXQUFaLEdBQTBCLElBQXpEO0FBQ0g7OzsyQ0FFa0I7QUFDZixtQkFBTyxLQUFLLHlCQUFMLE9BQXFDLGFBQTVDO0FBQ0g7Ozt5Q0FFZ0IsVyxFQUFhO0FBQzFCLGlCQUFLLHlCQUFMLENBQStCLGNBQWMsYUFBZCxHQUE4QixJQUE3RDtBQUNIOzs7d0NBRWU7QUFDWixtQkFBTyxLQUFLLGlCQUFMLENBQXVCLEtBQUssU0FBNUIsRUFBdUMsSUFBdkMsRUFBNkMsS0FBN0MsQ0FBUDtBQUNIOzs7c0NBRWEsSSxFQUFNO0FBQ2hCLGlCQUFLLGtCQUFMLENBQXdCLEtBQUssU0FBN0IsRUFBd0MsSUFBeEMsRUFBOEMsRUFBRSxLQUFLLElBQVAsRUFBOUM7QUFDQSxpQkFBSyxrQkFBTCxDQUF3QixLQUFLLFNBQTdCLEVBQXdDLElBQXhDO0FBQ0g7OzswQ0FFaUI7QUFDZCxtQkFBTyxLQUFLLGlCQUFMLENBQXVCLEtBQUssU0FBNUIsRUFBdUMsTUFBdkMsRUFBK0MsS0FBL0MsQ0FBUDtBQUNIOzs7d0NBRWUsTSxFQUFRO0FBQ3BCLGlCQUFLLGtCQUFMLENBQXdCLEtBQUssU0FBN0IsRUFBd0MsTUFBeEMsRUFBZ0QsRUFBRSxLQUFLLE1BQVAsRUFBaEQ7QUFDQSxpQkFBSyxrQkFBTCxDQUF3QixLQUFLLFNBQTdCLEVBQXdDLE1BQXhDO0FBQ0g7OztpREFFd0I7QUFDckIsbUJBQU8sS0FBSyxpQkFBTCxDQUF1QixLQUFLLFNBQTVCLEVBQXVDLFFBQXZDLEVBQWlELEtBQWpELENBQVA7QUFDSDs7OytDQUVzQixhLEVBQWU7QUFDbEMsaUJBQUssa0JBQUwsQ0FBd0IsS0FBSyxTQUE3QixFQUF3QyxRQUF4QyxFQUFrRCxFQUFFLEtBQUssYUFBUCxFQUFsRDtBQUNBLGlCQUFLLGtCQUFMLENBQXdCLEtBQUssU0FBN0IsRUFBd0MsUUFBeEM7QUFDSDs7O3lDQUVnQjtBQUNiLG1CQUFPLEtBQUssU0FBTCxDQUFlLEtBQUssU0FBcEIsRUFBK0IsT0FBL0IsQ0FBUDtBQUNIOzs7dUNBRWMsSyxFQUFPO0FBQ2xCLGlCQUFLLFNBQUwsQ0FBZSxLQUFLLFNBQXBCLEVBQStCLE9BQS9CLEVBQXdDLEtBQXhDO0FBQ0g7OzswQ0FFaUI7QUFDZDtBQUNBLG1CQUFPLEtBQUssaUJBQUwsQ0FBdUIsS0FBSyxTQUE1QixFQUF1QyxRQUF2QyxFQUFpRCxLQUFqRCxDQUFQO0FBQ0g7Ozt3Q0FFZSxNLEVBQVE7QUFDcEIsaUJBQUssa0JBQUwsQ0FBd0IsS0FBSyxTQUE3QixFQUF3QyxRQUF4QyxFQUFrRCxFQUFFLEtBQUssTUFBUCxFQUFsRDtBQUNBLGlCQUFLLGtCQUFMLENBQXdCLEtBQUssU0FBN0IsRUFBd0MsUUFBeEM7QUFDSDs7O21EQUUwQjtBQUN2QixtQkFBTyxLQUFLLGlCQUFMLENBQXVCLEtBQUssT0FBNUIsRUFBcUMsV0FBckMsRUFBa0QsWUFBbEQsQ0FBUDtBQUNIOzs7aURBRXdCLFMsRUFBVztBQUNoQyxpQkFBSyxrQkFBTCxDQUF3QixLQUFLLE9BQTdCLEVBQXNDLFdBQXRDLEVBQW1ELEVBQUUsWUFBWSxTQUFkLEVBQW5EO0FBQ0EsaUJBQUssa0JBQUwsQ0FBd0IsS0FBSyxPQUE3QixFQUFzQyxXQUF0QztBQUNIOzs7K0NBRXNCO0FBQ25CLG1CQUFPLEtBQUssaUJBQUwsQ0FBdUIsS0FBSyxPQUE1QixFQUFxQyxXQUFyQyxFQUFrRCxpQkFBbEQsTUFBeUUsQ0FBaEY7QUFDSDs7OzZDQUVvQixlLEVBQWlCO0FBQ2xDLGlCQUFLLGtCQUFMLENBQXdCLEtBQUssT0FBN0IsRUFBc0MsV0FBdEMsRUFBbUQsRUFBRSxpQkFBaUIsa0JBQWtCLENBQWxCLEdBQXNCLElBQXpDLEVBQW5EO0FBQ0EsaUJBQUssa0JBQUwsQ0FBd0IsS0FBSyxPQUE3QixFQUFzQyxXQUF0QztBQUNIOzs7c0NBRWE7QUFDVixtQkFBTyxLQUFLLGlCQUFMLENBQXVCLEtBQUssT0FBNUIsRUFBcUMsV0FBckMsRUFBa0QsUUFBbEQsQ0FBUDtBQUNIOzs7b0NBRVcsTSxFQUFRO0FBQ2hCLGlCQUFLLGtCQUFMLENBQXdCLEtBQUssT0FBN0IsRUFBc0MsV0FBdEMsRUFBbUQsRUFBRSxjQUFGLEVBQW5EO0FBQ0EsaUJBQUssa0JBQUwsQ0FBd0IsS0FBSyxPQUE3QixFQUFzQyxXQUF0QztBQUNIOzs7aURBRXdCO0FBQ3JCLG1CQUFPLEtBQUssaUJBQUwsQ0FBdUIsS0FBSyxPQUE1QixFQUFxQyxXQUFyQyxFQUFrRCxVQUFsRCxDQUFQO0FBQ0g7OzsrQ0FFc0IsUyxFQUFXO0FBQzlCLGlCQUFLLGtCQUFMLENBQXdCLEtBQUssT0FBN0IsRUFBc0MsV0FBdEMsRUFBbUQsRUFBRSxVQUFVLFNBQVosRUFBbkQ7QUFDQSxpQkFBSyxrQkFBTCxDQUF3QixLQUFLLE9BQTdCLEVBQXNDLFdBQXRDO0FBQ0g7Ozt3Q0FFZTtBQUNaLG1CQUFPLEtBQUssaUJBQUwsQ0FBdUIsS0FBSyxPQUE1QixFQUFxQyxXQUFyQyxFQUFrRCxVQUFsRCxNQUFrRSxDQUF6RTtBQUNIOzs7c0NBRWEsUSxFQUFVO0FBQ3BCLGlCQUFLLGtCQUFMLENBQXdCLEtBQUssT0FBN0IsRUFBc0MsV0FBdEMsRUFBbUQsRUFBRSxVQUFVLFdBQVcsQ0FBWCxHQUFlLElBQTNCLEVBQW5EO0FBQ0EsaUJBQUssa0JBQUwsQ0FBd0IsS0FBSyxPQUE3QixFQUFzQyxXQUF0QztBQUNIOzs7MkNBRWtCO0FBQ2YsbUJBQU8sS0FBSyxpQkFBTCxDQUF1QixLQUFLLE9BQTVCLEVBQXFDLFdBQXJDLEVBQWtELGFBQWxELE1BQXFFLENBQTVFO0FBQ0g7Ozt5Q0FFZ0IsVyxFQUFhO0FBQzFCLGlCQUFLLGtCQUFMLENBQXdCLEtBQUssT0FBN0IsRUFBc0MsV0FBdEMsRUFBbUQsRUFBRSxhQUFhLGNBQWMsQ0FBZCxHQUFrQixJQUFqQyxFQUFuRDtBQUNBLGlCQUFLLGtCQUFMLENBQXdCLEtBQUssT0FBN0IsRUFBc0MsV0FBdEM7QUFDSDs7OzZDQUVvQjtBQUNqQixnQkFBTSxlQUFlLEtBQUssaUJBQUwsQ0FBdUIsS0FBSyxPQUE1QixFQUFxQyxXQUFyQyxFQUFrRCxjQUFsRCxDQUFyQjtBQUNBLGdCQUFJLGlCQUFpQixDQUFyQixFQUF3QixPQUFPLGVBQVA7QUFDeEIsZ0JBQUksaUJBQWlCLENBQXJCLEVBQXdCLE9BQU8sZUFBUDtBQUN4QixtQkFBTyxZQUFQO0FBQ0g7OzsyQ0FFa0IsYSxFQUFlO0FBQzlCLGdCQUFJLHFCQUFKO0FBQ0EsZ0JBQUksa0JBQWtCLGVBQXRCLEVBQXVDLGVBQWUsQ0FBZixDQUF2QyxLQUNLLElBQUksa0JBQWtCLGVBQXRCLEVBQXVDLGVBQWUsQ0FBZjtBQUM1QyxpQkFBSyxrQkFBTCxDQUF3QixLQUFLLE9BQTdCLEVBQXNDLFdBQXRDLEVBQW1ELEVBQUUsMEJBQUYsRUFBbkQ7QUFDQSxpQkFBSyxrQkFBTCxDQUF3QixLQUFLLE9BQTdCLEVBQXNDLFdBQXRDO0FBQ0g7OzsyQ0FFa0I7QUFDZixtQkFBTyxLQUFLLGlCQUFMLENBQXVCLEtBQUssT0FBNUIsRUFBcUMsV0FBckMsRUFBa0QsY0FBbEQsQ0FBUDtBQUNIOzs7eUNBRWdCLFksRUFBYztBQUMzQixpQkFBSyxrQkFBTCxDQUF3QixLQUFLLE9BQTdCLEVBQXNDLFdBQXRDLEVBQW1ELEVBQUUsMEJBQUYsRUFBbkQ7QUFDQSxpQkFBSyxrQkFBTCxDQUF3QixLQUFLLE9BQTdCLEVBQXNDLFdBQXRDO0FBQ0g7Ozs0Q0FFbUI7QUFDaEIsZ0JBQUksZUFBZSxLQUFLLGdCQUFMLEVBQW5COztBQUVBO0FBQ0EsZ0JBQUksZUFBZSxFQUFuQixFQUF1QixlQUFlLEtBQUssWUFBcEI7QUFDdkIsbUJBQU8sWUFBUDtBQUNIOzs7MENBRWlCLFksRUFBYztBQUM1QjtBQUNBLGdCQUFJLGVBQWUsQ0FBbkIsRUFBc0IsZUFBZSxLQUFLLFlBQXBCO0FBQ3RCLGlCQUFLLGdCQUFMLENBQXNCLFlBQXRCO0FBQ0g7Ozt5REFFZ0M7QUFDN0IsbUJBQU8sS0FBSyxnQkFBTCxPQUE0QixFQUFuQztBQUNIOzs7dURBRThCLEssRUFBTztBQUNsQyxpQkFBSyxnQkFBTCxDQUFzQixRQUFRLEVBQVIsR0FBYSxJQUFuQztBQUNIOzs7a0RBRXlCO0FBQ3RCLG1CQUFPLEtBQUssZ0JBQUwsT0FBNEIsR0FBbkM7QUFDSDs7O2dEQUV1QixLLEVBQU87QUFDM0IsaUJBQUssZ0JBQUwsQ0FBc0IsUUFBUSxHQUFSLEdBQWMsSUFBcEM7QUFDSDs7OzRDQUVtQjtBQUNoQixtQkFBTyxLQUFLLGdCQUFMLE9BQTRCLEVBQW5DO0FBQ0g7OzswQ0FFaUIsSyxFQUFPO0FBQ3JCLGlCQUFLLGdCQUFMLENBQXNCLFFBQVEsRUFBUixHQUFhLElBQW5DO0FBQ0g7Ozs4Q0FFcUI7QUFDbEIsbUJBQU8sS0FBSyxnQkFBTCxPQUE0QixHQUFuQztBQUNIOzs7NENBRW1CLEssRUFBTztBQUN2QixpQkFBSyxnQkFBTCxDQUFzQixRQUFRLEdBQVIsR0FBYyxJQUFwQztBQUNIOzs7NENBRW1CO0FBQ2hCLG1CQUFPLEtBQUssZ0JBQUwsT0FBNEIsR0FBbkM7QUFDSDs7OzBDQUVpQixLLEVBQU87QUFDckIsaUJBQUssZ0JBQUwsQ0FBc0IsUUFBUSxHQUFSLEdBQWMsSUFBcEM7QUFDSDs7O29DQUVXO0FBQUE7O0FBQ1IsZ0JBQU0sa0JBQWtCLEtBQUssU0FBTCxDQUFlLEtBQUssU0FBcEIsRUFBK0IsYUFBL0IsQ0FBeEIsQ0FEUSxDQUM4RDtBQUN0RSxnQkFBTSxtQkFBbUIsS0FBSyxTQUFMLENBQWUsS0FBSyxTQUFwQixFQUErQixjQUEvQixDQUF6QixDQUZRLENBRWdFO0FBQ3hFLGdCQUFNLGNBQWMsbUJBQW1CLGdCQUFnQixVQUFoQixDQUEyQixXQUFsRSxDQUhRLENBR3NFOztBQUU5RSxnQkFBSSxnQkFBZ0IsT0FBcEIsRUFBNkI7QUFDekIsdUJBQU87QUFDSCwwQkFBTSxPQURIO0FBRUgsMkJBQU8sS0FBSyxTQUFMLENBQWUsZUFBZixFQUFnQyxTQUFoQztBQUZKLGlCQUFQO0FBSUg7O0FBRUQsZ0JBQUksV0FBSixFQUFpQjtBQUNiLHVCQUFPO0FBQ0gsMEJBQU0sU0FESDtBQUVILDZCQUFTLFdBRk47QUFHSCxnQ0FBWSxLQUFLLFNBQUwsQ0FBZSxlQUFmLEVBQWdDLFNBQWhDLENBSFQ7QUFJSCxnQ0FBWSxLQUFLLFNBQUwsQ0FBZSxlQUFmLEVBQWdDLFNBQWhDO0FBSlQsaUJBQVA7QUFNSDs7QUFFRCxnQkFBSSxnQkFBSixFQUFzQjtBQUNsQixvQkFBTSxlQUFlLGlCQUFpQixVQUFqQixDQUE0QixJQUE1QixJQUFvQyxRQUF6RDtBQUNBLG9CQUFNLE9BQU87QUFDVCwwQkFBTSxVQURHO0FBRVQsOENBRlM7QUFHVCwyQkFBTyxFQUFFLEdBQUYsQ0FBTSxpQkFBaUIsUUFBdkIsRUFBaUM7QUFBQSwrQkFBUztBQUM3QyxzQ0FBVSxLQUFLLFVBQUwsQ0FBZ0IsUUFEbUI7QUFFN0MsbUNBQU8sT0FBSyxTQUFMLENBQWUsSUFBZixFQUFxQixPQUFyQjtBQUZzQyx5QkFBVDtBQUFBLHFCQUFqQztBQUhFLGlCQUFiOztBQVNBLG9CQUFJLGlCQUFpQixRQUFyQixFQUErQjtBQUMzQix5QkFBSyxLQUFMLEdBQWEsaUJBQWlCLFVBQWpCLENBQTRCLE1BQXpDO0FBQ0gsaUJBRkQsTUFFTztBQUNILHlCQUFLLElBQUwsR0FBWSxpQkFBaUIsVUFBakIsQ0FBNEIsSUFBeEM7QUFDQSx5QkFBSyxLQUFMLEdBQWEsaUJBQWlCLFVBQWpCLENBQTRCLEtBQXpDO0FBQ0EseUJBQUssR0FBTCxHQUFXLGlCQUFpQixVQUFqQixDQUE0QixHQUF2QztBQUNBLHlCQUFLLE1BQUwsR0FBYyxpQkFBaUIsVUFBakIsQ0FBNEIsTUFBMUM7QUFDSDs7QUFFRCx1QkFBTyxJQUFQO0FBQ0g7QUFDSjs7O2tDQUVTLEksRUFBTTtBQUFBOztBQUNaLGlCQUFLLFNBQUwsQ0FBZSxRQUFmLEdBQTBCLEVBQTFCOztBQUVBO0FBQ0EsZ0JBQUksRUFBRSxLQUFGLENBQVEsSUFBUixDQUFKLEVBQW1COztBQUVuQjtBQUNBLGdCQUFJLEtBQUssSUFBTCxLQUFjLFNBQWxCLEVBQTZCO0FBQ3pCLG9CQUFNLGVBQWM7QUFDaEIsMEJBQU0sYUFEVTtBQUVoQixnQ0FBWSxFQUFFLGFBQWEsS0FBSyxPQUFwQixFQUZJO0FBR2hCLDhCQUFVO0FBSE0saUJBQXBCO0FBS0EscUJBQUssU0FBTCxDQUFlLFFBQWYsQ0FBd0IsSUFBeEIsQ0FBNkIsWUFBN0I7QUFDQSxxQkFBSyxTQUFMLENBQWUsWUFBZixFQUE0QixTQUE1QixFQUF1QyxLQUFLLFVBQTVDO0FBQ0EscUJBQUssU0FBTCxDQUFlLFlBQWYsRUFBNEIsU0FBNUIsRUFBdUMsS0FBSyxVQUE1QztBQUNBO0FBQ0g7O0FBRUQ7QUFDQSxnQkFBSSxLQUFLLElBQUwsS0FBYyxVQUFsQixFQUE4QjtBQUMxQixvQkFBTSxlQUFlLEVBQUUsTUFBTSxjQUFSLEVBQXdCLFlBQVksRUFBcEMsRUFBd0MsVUFBVSxFQUFsRCxFQUFyQjtBQUNBLHFCQUFLLFNBQUwsQ0FBZSxRQUFmLENBQXdCLElBQXhCLENBQTZCLFlBQTdCO0FBQ0EscUJBQUssYUFBTCxDQUFtQixZQUFuQixFQUFpQztBQUM3QiwwQkFBTSxLQUFLLFlBQUwsS0FBc0IsTUFBdEIsR0FBK0IsTUFBL0IsR0FBd0MsU0FEakI7QUFFN0IsMEJBQU0sS0FBSyxJQUZrQjtBQUc3QiwyQkFBTyxLQUFLLEtBSGlCO0FBSTdCLHlCQUFLLEtBQUssR0FKbUI7QUFLN0IsNEJBQVEsS0FBSyxNQUxnQjtBQU03Qiw0QkFBUSxLQUFLO0FBTmdCLGlCQUFqQzs7QUFTQSxrQkFBRSxPQUFGLENBQVUsS0FBSyxLQUFmLEVBQXNCLFVBQUMsUUFBRCxFQUFXLENBQVgsRUFBaUI7QUFDbkMsd0JBQU0sT0FBTztBQUNULDhCQUFNLE1BREc7QUFFVCxvQ0FBWSxFQUFFLFVBQVUsU0FBUyxRQUFyQixFQUZIO0FBR1Qsa0NBQVU7QUFIRCxxQkFBYjtBQUtBLGlDQUFhLFFBQWIsQ0FBc0IsSUFBdEIsQ0FBMkIsSUFBM0I7QUFDQSwyQkFBSyxTQUFMLENBQWUsSUFBZixFQUFxQixPQUFyQixFQUE4QixTQUFTLEtBQXZDO0FBQ0gsaUJBUkQ7O0FBVUE7QUFDSDs7QUFFRDtBQUNBLGdCQUFJLENBQUMsRUFBRSxRQUFGLENBQVcsSUFBWCxDQUFMLEVBQXVCLE9BQU8sRUFBRSxNQUFNLE9BQVIsRUFBaUIsT0FBTyxJQUF4QixFQUFQLENBQXZCLEtBQ0ssSUFBSSxLQUFLLGNBQUwsQ0FBb0IsS0FBcEIsS0FBOEIsS0FBSyxjQUFMLENBQW9CLE9BQXBCLENBQWxDLEVBQWdFLE9BQU8sRUFBRSxPQUFPLElBQVQsRUFBUDs7QUFFckUsZ0JBQU0sY0FBYztBQUNoQixzQkFBTSxhQURVO0FBRWhCLDRCQUFZLEVBQUUsYUFBYSxPQUFmO0FBRkksYUFBcEI7QUFJQSxpQkFBSyxTQUFMLENBQWUsUUFBZixDQUF3QixJQUF4QixDQUE2QixXQUE3QjtBQUNBLGlCQUFLLFNBQUwsQ0FBZSxXQUFmLEVBQTRCLFNBQTVCLEVBQXVDLEtBQUssS0FBNUM7QUFDSDs7O3FDQUVZO0FBQUE7O0FBQ1QsZ0JBQU0sU0FBUyxFQUFmO0FBQ0EsYUFBQyxNQUFELEVBQVMsT0FBVCxFQUFrQixLQUFsQixFQUF5QixRQUF6QixFQUFtQyxVQUFuQyxFQUErQyxPQUEvQyxDQUF1RCxnQkFBUTtBQUMzRCxvQkFBTSxXQUFXLEtBQUssU0FBTCxDQUFlLE9BQUssV0FBcEIsRUFBaUMsSUFBakMsQ0FBakI7QUFDQSxvQkFBTSxhQUFhLEVBQW5COztBQUVBLG9CQUFNLFFBQVEsS0FBSyxpQkFBTCxDQUF1QixPQUFLLFdBQTVCLEVBQXlDLElBQXpDLEVBQStDLE9BQS9DLENBQWQ7QUFDQSxvQkFBSSxLQUFKLEVBQVcsV0FBVyxLQUFYLEdBQW1CLEtBQW5CO0FBQ1gsb0JBQU0sUUFBUSxPQUFLLFNBQUwsQ0FBZSxRQUFmLEVBQXlCLE9BQXpCLENBQWQ7QUFDQSxvQkFBSSxLQUFKLEVBQVcsV0FBVyxLQUFYLEdBQW1CLEtBQW5COztBQUVYLG9CQUFJLFNBQVMsVUFBYixFQUF5QjtBQUNyQix3QkFBTSxLQUFLLE9BQUssV0FBTCxDQUFpQixVQUFqQixDQUE0QixVQUF2QztBQUNBLHdCQUFNLE9BQU8sT0FBSyxXQUFMLENBQWlCLFVBQWpCLENBQTRCLFlBQXpDO0FBQ0Esd0JBQUksa0JBQUo7QUFDQSx3QkFBSSxNQUFNLElBQVYsRUFBZ0IsWUFBWSxNQUFaLENBQWhCLEtBQ0ssSUFBSSxFQUFKLEVBQVEsWUFBWSxJQUFaLENBQVIsS0FDQSxJQUFJLElBQUosRUFBVSxZQUFZLE1BQVo7QUFDZix3QkFBSSxTQUFKLEVBQWUsV0FBVyxTQUFYLEdBQXVCLFNBQXZCO0FBQ2xCOztBQUVELG9CQUFJLENBQUMsRUFBRSxPQUFGLENBQVUsVUFBVixDQUFMLEVBQTRCLE9BQU8sSUFBUCxJQUFlLFVBQWY7QUFDL0IsYUFwQkQ7O0FBc0JBLG1CQUFPLE1BQVA7QUFDSDs7O21DQUVVLFEsRUFBVTtBQUFBOztBQUNqQixjQUFFLE1BQUYsQ0FBUyxRQUFULEVBQW1CLFVBQUMsT0FBRCxFQUFVLElBQVYsRUFBbUI7QUFDbEMsb0JBQUksT0FBTyxPQUFQLEtBQW1CLFNBQXZCLEVBQWtDO0FBQzlCLDhCQUFVLEVBQUUsT0FBTyxVQUFVLE1BQVYsR0FBbUIsSUFBNUIsRUFBVjtBQUNILGlCQUZELE1BRU8sSUFBSSxPQUFPLE9BQVAsS0FBbUIsUUFBdkIsRUFBaUM7QUFDcEMsOEJBQVUsRUFBRSxPQUFPLE9BQVQsRUFBVjtBQUNILGlCQUZNLE1BRUEsSUFBSSxZQUFZLElBQVosSUFBb0IsWUFBWSxTQUFwQyxFQUErQztBQUNsRCw4QkFBVSxFQUFFLE9BQU8sSUFBVCxFQUFlLE9BQU8sSUFBdEIsRUFBNEIsV0FBVyxJQUF2QyxFQUFWO0FBQ0g7O0FBRUQsb0JBQUksUUFBUSxjQUFSLENBQXVCLE9BQXZCLENBQUosRUFBcUM7QUFDakMseUJBQUssa0JBQUwsQ0FBd0IsT0FBSyxXQUE3QixFQUEwQyxJQUExQyxFQUFnRCxFQUFFLE9BQU8sUUFBUSxLQUFqQixFQUFoRDtBQUNIOztBQUVELG9CQUFJLFFBQVEsY0FBUixDQUF1QixPQUF2QixDQUFKLEVBQXFDO0FBQ2pDLHdCQUFNLFdBQVcsS0FBSyxTQUFMLENBQWUsT0FBSyxXQUFwQixFQUFpQyxJQUFqQyxDQUFqQjtBQUNBLDJCQUFLLFNBQUwsQ0FBZSxRQUFmLEVBQXlCLE9BQXpCLEVBQWtDLFFBQVEsS0FBMUM7QUFDSDs7QUFFRCxvQkFBSSxTQUFTLFVBQWIsRUFBeUI7QUFDckIseUJBQUssYUFBTCxDQUFtQixPQUFLLFdBQXhCLEVBQXFDO0FBQ2pDLG9DQUFZLFFBQVEsU0FBUixLQUFzQixJQUF0QixJQUE4QixRQUFRLFNBQVIsS0FBc0IsTUFBcEQsR0FBNkQsQ0FBN0QsR0FBaUUsSUFENUM7QUFFakMsc0NBQWMsUUFBUSxTQUFSLEtBQXNCLE1BQXRCLElBQWdDLFFBQVEsU0FBUixLQUFzQixNQUF0RCxHQUErRCxDQUEvRCxHQUFtRTtBQUZoRCxxQkFBckM7QUFJSDtBQUNKLGFBeEJEO0FBeUJIOzs7c0NBRWE7QUFDVixtQkFBTyxLQUFLLFVBQUwsRUFBUDtBQUNIOzs7b0NBRVcsUSxFQUFVO0FBQ2xCLGdCQUFJLEVBQUUsUUFBRixDQUFXLFFBQVgsS0FBd0IsQ0FBQyxTQUFTLGNBQVQsQ0FBd0IsT0FBeEIsQ0FBekIsSUFBNkQsQ0FBQyxTQUFTLGNBQVQsQ0FBd0IsT0FBeEIsQ0FBbEUsRUFBb0c7QUFDaEcsMkJBQVcsRUFBRSxRQUFGLENBQVcsUUFBWCxFQUFxQjtBQUM1QiwwQkFBTSxJQURzQjtBQUU1QiwyQkFBTyxJQUZxQjtBQUc1Qix5QkFBSyxJQUh1QjtBQUk1Qiw0QkFBUSxJQUpvQjtBQUs1Qiw4QkFBVTtBQUxrQixpQkFBckIsQ0FBWDtBQU9BLHFCQUFLLFVBQUwsQ0FBZ0IsUUFBaEI7QUFDSCxhQVRELE1BU087QUFDSCxxQkFBSyxVQUFMLENBQWdCO0FBQ1osMEJBQU0sUUFETTtBQUVaLDJCQUFPLFFBRks7QUFHWix5QkFBSyxRQUhPO0FBSVosNEJBQVE7QUFKSSxpQkFBaEI7QUFNSDtBQUNKOzs7MkNBRWtCO0FBQ2YsbUJBQU8sRUFBRSxTQUFGLENBQVksS0FBSyxVQUFMLEVBQVosRUFBK0I7QUFBQSx1QkFBUyxNQUFNLEtBQWY7QUFBQSxhQUEvQixDQUFQO0FBQ0g7Ozt5Q0FFZ0IsSyxFQUFPO0FBQ3BCLGdCQUFJLEVBQUUsUUFBRixDQUFXLEtBQVgsQ0FBSixFQUF1QjtBQUNuQixxQkFBSyxVQUFMLENBQWdCLEVBQUUsU0FBRixDQUFZLEtBQVosRUFBbUI7QUFBQSwyQkFBVSxFQUFFLFlBQUYsRUFBVjtBQUFBLGlCQUFuQixDQUFoQjtBQUNILGFBRkQsTUFFTztBQUNILHFCQUFLLFVBQUwsQ0FBZ0I7QUFDWiwwQkFBTSxFQUFFLFlBQUYsRUFETTtBQUVaLDJCQUFPLEVBQUUsWUFBRixFQUZLO0FBR1oseUJBQUssRUFBRSxZQUFGLEVBSE87QUFJWiw0QkFBUSxFQUFFLFlBQUYsRUFKSTtBQUtaLDhCQUFVLEVBQUUsWUFBRjtBQUxFLGlCQUFoQjtBQU9IO0FBQ0o7OzsyQ0FFa0I7QUFDZixtQkFBTyxFQUFFLFNBQUYsQ0FBWSxLQUFLLFVBQUwsRUFBWixFQUErQjtBQUFBLHVCQUFTLE1BQU0sS0FBZjtBQUFBLGFBQS9CLENBQVA7QUFDSDs7O3lDQUVnQixLLEVBQU87QUFDcEIsZ0JBQUksRUFBRSxRQUFGLENBQVcsS0FBWCxDQUFKLEVBQXVCO0FBQ25CLHFCQUFLLFVBQUwsQ0FBZ0IsRUFBRSxTQUFGLENBQVksS0FBWixFQUFtQjtBQUFBLDJCQUFVLEVBQUUsWUFBRixFQUFWO0FBQUEsaUJBQW5CLENBQWhCO0FBQ0gsYUFGRCxNQUVPO0FBQ0gscUJBQUssVUFBTCxDQUFnQjtBQUNaLDBCQUFNLEVBQUUsWUFBRixFQURNO0FBRVosMkJBQU8sRUFBRSxZQUFGLEVBRks7QUFHWix5QkFBSyxFQUFFLFlBQUYsRUFITztBQUlaLDRCQUFRLEVBQUUsWUFBRjtBQUpJLGlCQUFoQjtBQU1IO0FBQ0o7Ozt1REFFOEI7QUFDM0IsZ0JBQU0sU0FBUyxLQUFLLFVBQUwsR0FBa0IsUUFBakM7QUFDQSxtQkFBTyxVQUFVLE9BQU8sU0FBeEI7QUFDSDs7O3FEQUU0QixTLEVBQVc7QUFDcEMsaUJBQUssVUFBTCxDQUFnQixFQUFFLFVBQVUsRUFBRSxvQkFBRixFQUFaLEVBQWhCO0FBQ0g7Ozs0Q0FFbUI7QUFDaEIsZ0JBQU0sV0FBVyxLQUFLLE9BQUwsQ0FBYSxVQUFiLENBQXdCLFFBQXhCLElBQW9DLENBQXJEO0FBQ0EsbUJBQU8sS0FBSyxXQUFMLENBQWlCLG1CQUFqQixDQUFxQyxRQUFyQyxDQUFQO0FBQ0g7OzswQ0FFaUIsVSxFQUFZO0FBQzFCLGlCQUFLLE9BQUwsQ0FBYSxVQUFiLENBQXdCLFFBQXhCLEdBQW1DLEtBQUssV0FBTCxDQUFpQixpQkFBakIsQ0FBbUMsVUFBbkMsQ0FBbkM7QUFDSDs7Ozs7O0FBR0wsQ0FBQyxNQUFELEVBQVMsT0FBVCxFQUFrQixLQUFsQixFQUF5QixRQUF6QixFQUFtQyxVQUFuQyxFQUErQyxPQUEvQyxDQUF1RCxnQkFBUTtBQUMzRCxVQUFNLFNBQU4sV0FBd0IsSUFBeEIsZUFBd0MsWUFBWTtBQUNoRCxlQUFPLEtBQUssVUFBTCxHQUFrQixJQUFsQixDQUFQO0FBQ0gsS0FGRDs7QUFJQSxVQUFNLFNBQU4sV0FBd0IsSUFBeEIsZUFBd0MsVUFBVSxRQUFWLEVBQW9CO0FBQ3hELGFBQUssVUFBTCxxQkFBbUIsSUFBbkIsRUFBMEIsUUFBMUI7QUFDSCxLQUZEOztBQUlBLFVBQU0sU0FBTixXQUF3QixJQUF4QixvQkFBNkMsWUFBWTtBQUNyRCxZQUFNLFNBQVMsS0FBSyxVQUFMLEdBQWtCLElBQWxCLENBQWY7QUFDQSxlQUFPLFVBQVUsT0FBTyxLQUF4QjtBQUNILEtBSEQ7O0FBS0EsVUFBTSxTQUFOLFdBQXdCLElBQXhCLG9CQUE2QyxVQUFVLEtBQVYsRUFBaUI7QUFDMUQsYUFBSyxVQUFMLHFCQUFtQixJQUFuQixFQUEwQixFQUFFLFlBQUYsRUFBMUI7QUFDSCxLQUZEOztBQUlBLFVBQU0sU0FBTixXQUF3QixJQUF4QixvQkFBNkMsWUFBWTtBQUNyRCxZQUFNLFNBQVMsS0FBSyxVQUFMLEdBQWtCLElBQWxCLENBQWY7QUFDQSxlQUFPLFVBQVUsT0FBTyxLQUF4QjtBQUNILEtBSEQ7O0FBS0EsVUFBTSxTQUFOLFdBQXdCLElBQXhCLG9CQUE2QyxVQUFVLEtBQVYsRUFBaUI7QUFDMUQsYUFBSyxVQUFMLHFCQUFtQixJQUFuQixFQUEwQixFQUFFLFlBQUYsRUFBMUI7QUFDSCxLQUZEO0FBR0gsQ0ExQkQ7O0FBNEJBO0FBQ0EsSUFBSSxDQUFDLE1BQU0sSUFBWCxFQUFpQixNQUFNLElBQU4sR0FBYSxPQUFiOztBQUVqQixPQUFPLE9BQVAsR0FBaUIsS0FBakI7OztBQzNsQkE7Ozs7OztBQUVBLElBQU0sSUFBSSxRQUFRLFFBQVIsQ0FBVjtBQUNBLElBQU0sT0FBTyxRQUFRLFFBQVIsQ0FBYjtBQUNBLElBQU0sUUFBUSxRQUFRLFNBQVIsQ0FBZDs7QUFFQTs7Ozs7QUFLQSxJQUFNLGlCQUFpQjtBQUNuQixPQUFHLFNBRGdCO0FBRW5CLE9BQUcsR0FGZ0I7QUFHbkIsT0FBRyxNQUhnQjtBQUluQixPQUFHLE9BSmdCO0FBS25CLE9BQUcsVUFMZ0I7QUFNbkIsT0FBRyxJQU5nQjtBQU9uQixRQUFJLE9BUGU7QUFRbkIsUUFBSSxVQVJlO0FBU25CLFFBQUksT0FUZTtBQVVuQixRQUFJLFNBVmU7QUFXbkIsUUFBSSxVQVhlO0FBWW5CLFFBQUksVUFaZTtBQWFuQixRQUFJLE9BYmU7QUFjbkIsUUFBSSxRQWRlO0FBZW5CLFFBQUksWUFmZTtBQWdCbkIsUUFBSSxlQWhCZTtBQWlCbkIsUUFBSSxNQWpCZTtBQWtCbkIsUUFBSSxTQWxCZTtBQW1CbkIsUUFBSSxhQW5CZTtBQW9CbkIsUUFBSSxnQkFwQmU7QUFxQm5CLFFBQUkscUJBckJlO0FBc0JuQixRQUFJLHFCQXRCZTtBQXVCbkIsUUFBSSwwQkF2QmU7QUF3Qm5CLFFBQUksT0F4QmU7QUF5Qm5CLFFBQUksV0F6QmU7QUEwQm5CLFFBQUksUUExQmU7QUEyQm5CLFFBQUksVUEzQmU7QUE0Qm5CLFFBQUk7QUE1QmUsQ0FBdkI7O0FBK0JBOzs7O0FBSUEsSUFBTSxtQ0FBbUMsR0FBekM7O0FBRUE7Ozs7O0lBSU0sVTtBQUNGOzs7O0FBSUEsd0JBQVksSUFBWixFQUFrQjtBQUFBOztBQUNkLGFBQUssS0FBTCxDQUFXLElBQVg7QUFDQSxhQUFLLG1CQUFMO0FBQ0g7O0FBRUQ7Ozs7Ozs7OztvQ0FLWSxRLEVBQVU7QUFDbEIsZ0JBQUksaUJBQUo7QUFBQSxnQkFBYyxpQkFBZDtBQUFBLGdCQUF3QixtQkFBeEI7QUFBQSxnQkFBb0MsZUFBcEM7QUFDQSxnQkFBSSxZQUFZLENBQWhCLEVBQW1CO0FBQ2Ysb0JBQU0sZUFBZSxLQUFLLFlBQUwsQ0FBa0IsUUFBbEIsQ0FBMkIsUUFBM0IsQ0FBckI7QUFDQSx5QkFBUyxFQUFFLFNBQUYsQ0FBWSxZQUFaLENBQVQ7O0FBRUEsb0JBQUksYUFBYSxVQUFiLENBQXdCLFNBQTVCLEVBQXVDO0FBQ25DLHdCQUFNLFNBQVMsYUFBYSxVQUFiLENBQXdCLE1BQXZDO0FBQ0EsK0JBQVcsRUFBRSxTQUFGLENBQVksS0FBSyxVQUFMLENBQWdCLFFBQWhCLENBQXlCLE1BQXpCLENBQVosQ0FBWDtBQUNIOztBQUVELG9CQUFJLGFBQWEsVUFBYixDQUF3QixTQUE1QixFQUF1QztBQUNuQyx3QkFBTSxTQUFTLGFBQWEsVUFBYixDQUF3QixNQUF2QztBQUNBLCtCQUFXLEVBQUUsU0FBRixDQUFZLEtBQUssVUFBTCxDQUFnQixRQUFoQixDQUF5QixNQUF6QixDQUFaLENBQVg7QUFDSDs7QUFFRCxvQkFBSSxhQUFhLFVBQWIsQ0FBd0IsV0FBNUIsRUFBeUM7QUFDckMsd0JBQU0sV0FBVyxhQUFhLFVBQWIsQ0FBd0IsUUFBekM7QUFDQSxpQ0FBYSxFQUFFLFNBQUYsQ0FBWSxLQUFLLFlBQUwsQ0FBa0IsUUFBbEIsQ0FBMkIsUUFBM0IsQ0FBWixDQUFiO0FBQ0g7QUFDSjs7QUFFRCxnQkFBSSxDQUFDLFFBQUwsRUFBZSxXQUFXLEVBQUUsTUFBTSxNQUFSLEVBQWdCLFlBQVksRUFBNUIsRUFBZ0MsVUFBVSxFQUExQyxFQUFYO0FBQ2YsaUJBQUssVUFBTCxDQUFnQixRQUFoQixDQUF5QixJQUF6QixDQUE4QixRQUE5Qjs7QUFFQSxnQkFBSSxDQUFDLFFBQUwsRUFBZSxXQUFXLEVBQUUsTUFBTSxNQUFSLEVBQWdCLFlBQVksRUFBNUIsRUFBZ0MsVUFBVSxFQUExQyxFQUFYO0FBQ2YsaUJBQUssVUFBTCxDQUFnQixRQUFoQixDQUF5QixJQUF6QixDQUE4QixRQUE5Qjs7QUFFQTtBQUNBLGdCQUFJLENBQUMsVUFBTCxFQUFpQixhQUFhLEVBQUUsTUFBTSxRQUFSLEVBQWtCLFlBQVksRUFBOUIsRUFBa0MsVUFBVSxFQUE1QyxFQUFiO0FBQ2pCLHVCQUFXLFFBQVgsR0FBc0IsQ0FDbEIsS0FBSyxTQUFMLENBQWUsVUFBZixFQUEyQixNQUEzQixLQUFzQyxFQUFFLE1BQU0sTUFBUixFQUFnQixZQUFZLEVBQTVCLEVBQWdDLFVBQVUsRUFBMUMsRUFEcEIsRUFFbEIsS0FBSyxTQUFMLENBQWUsVUFBZixFQUEyQixPQUEzQixLQUF1QyxFQUFFLE1BQU0sT0FBUixFQUFpQixZQUFZLEVBQTdCLEVBQWlDLFVBQVUsRUFBM0MsRUFGckIsRUFHbEIsS0FBSyxTQUFMLENBQWUsVUFBZixFQUEyQixLQUEzQixLQUFxQyxFQUFFLE1BQU0sS0FBUixFQUFlLFlBQVksRUFBM0IsRUFBK0IsVUFBVSxFQUF6QyxFQUhuQixFQUlsQixLQUFLLFNBQUwsQ0FBZSxVQUFmLEVBQTJCLFFBQTNCLEtBQXdDLEVBQUUsTUFBTSxRQUFSLEVBQWtCLFlBQVksRUFBOUIsRUFBa0MsVUFBVSxFQUE1QyxFQUp0QixFQUtsQixLQUFLLFNBQUwsQ0FBZSxVQUFmLEVBQTJCLFVBQTNCLEtBQTBDLEVBQUUsTUFBTSxVQUFSLEVBQW9CLFlBQVksRUFBaEMsRUFBb0MsVUFBVSxFQUE5QyxFQUx4QixDQUF0QjtBQU9BLGlCQUFLLFlBQUwsQ0FBa0IsUUFBbEIsQ0FBMkIsSUFBM0IsQ0FBZ0MsVUFBaEM7O0FBRUEsZ0JBQUksQ0FBQyxNQUFMLEVBQWEsU0FBUyxFQUFFLE1BQU0sSUFBUixFQUFjLFlBQVksRUFBMUIsRUFBOEIsVUFBVSxFQUF4QyxFQUFUO0FBQ2IsY0FBRSxNQUFGLENBQVMsT0FBTyxVQUFoQixFQUE0QjtBQUN4Qix3QkFBUSxLQUFLLFVBQUwsQ0FBZ0IsUUFBaEIsQ0FBeUIsTUFBekIsR0FBa0MsQ0FEbEI7QUFFeEIsd0JBQVEsS0FBSyxVQUFMLENBQWdCLFFBQWhCLENBQXlCLE1BQXpCLEdBQWtDLENBRmxCO0FBR3hCLDBCQUFVLEtBQUssWUFBTCxDQUFrQixRQUFsQixDQUEyQixNQUEzQixHQUFvQyxDQUh0QjtBQUl4QiwyQkFBVyxDQUphO0FBS3hCLDJCQUFXLENBTGE7QUFNeEIsNkJBQWE7QUFOVyxhQUE1Qjs7QUFTQSxpQkFBSyxZQUFMLENBQWtCLFFBQWxCLENBQTJCLElBQTNCLENBQWdDLE1BQWhDOztBQUVBLG1CQUFPLElBQUksS0FBSixDQUFVLElBQVYsRUFBZ0IsS0FBSyxZQUFMLENBQWtCLFFBQWxCLENBQTJCLE1BQTNCLEdBQW9DLENBQXBELEVBQXVELE1BQXZELEVBQStELFFBQS9ELEVBQXlFLFFBQXpFLEVBQW1GLFVBQW5GLENBQVA7QUFDSDs7QUFFRDs7Ozs7Ozs7NENBS29CLEUsRUFBSTtBQUNwQixtQkFBTyxLQUFLLHNCQUFMLENBQTRCLEVBQTVCLENBQVA7QUFDSDs7QUFFRDs7Ozs7Ozs7MENBS2tCLEksRUFBTTtBQUNwQixnQkFBSSxLQUFLLEtBQUssc0JBQUwsQ0FBNEIsSUFBNUIsQ0FBVDtBQUNBLGdCQUFJLE9BQU8sU0FBWCxFQUFzQjtBQUNsQixxQkFBSyxLQUFLLGdCQUFMLEVBQUw7QUFDQSxxQkFBSyxzQkFBTCxDQUE0QixFQUE1QixJQUFrQyxJQUFsQztBQUNBLHFCQUFLLHNCQUFMLENBQTRCLElBQTVCLElBQW9DLEVBQXBDOztBQUVBLHFCQUFLLFlBQUwsQ0FBa0IsUUFBbEIsQ0FBMkIsSUFBM0IsQ0FBZ0M7QUFDNUIsMEJBQU0sUUFEc0I7QUFFNUIsZ0NBQVk7QUFDUixrQ0FBVSxFQURGO0FBRVIsb0NBQVk7QUFGSjtBQUZnQixpQkFBaEM7QUFPSDs7QUFFRCxtQkFBTyxFQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7O2dDQUtRO0FBQ0osbUJBQU8sS0FBSyxLQUFaO0FBQ0g7O0FBRUQ7Ozs7Ozs7OzhDQUtzQjtBQUFBOztBQUNsQjtBQUNBLGlCQUFLLHNCQUFMLEdBQThCLEVBQTlCO0FBQ0EsaUJBQUssc0JBQUwsR0FBOEIsRUFBOUI7QUFDQSxpQkFBSyxJQUFNLEVBQVgsSUFBaUIsY0FBakIsRUFBaUM7QUFDN0Isb0JBQUksQ0FBQyxlQUFlLGNBQWYsQ0FBOEIsRUFBOUIsQ0FBTCxFQUF3QztBQUN4QyxvQkFBTSxPQUFPLGVBQWUsRUFBZixDQUFiO0FBQ0EscUJBQUssc0JBQUwsQ0FBNEIsRUFBNUIsSUFBa0MsSUFBbEM7QUFDQSxxQkFBSyxzQkFBTCxDQUE0QixJQUE1QixJQUFvQyxTQUFTLEVBQVQsQ0FBcEM7QUFDSDs7QUFFRDtBQUNBLGlCQUFLLGdCQUFMLEdBQXdCLGdDQUF4Qjs7QUFFQTtBQUNBLGlCQUFLLFlBQUwsQ0FBa0IsUUFBbEIsQ0FBMkIsT0FBM0IsQ0FBbUMsZ0JBQVE7QUFDdkMsb0JBQU0sS0FBSyxLQUFLLFVBQUwsQ0FBZ0IsUUFBM0I7QUFDQSxvQkFBTSxPQUFPLEtBQUssVUFBTCxDQUFnQixVQUE3QjtBQUNBLHNCQUFLLHNCQUFMLENBQTRCLEVBQTVCLElBQWtDLElBQWxDO0FBQ0Esc0JBQUssc0JBQUwsQ0FBNEIsSUFBNUIsSUFBb0MsRUFBcEM7QUFDQSxvQkFBSSxNQUFNLE1BQUssZ0JBQWYsRUFBaUMsTUFBSyxnQkFBTCxHQUF3QixLQUFLLENBQTdCO0FBQ3BDLGFBTkQ7QUFPSDs7QUFFRDs7Ozs7Ozs7OzhCQU1NLEksRUFBTTtBQUNSLGlCQUFLLEtBQUwsR0FBYSxJQUFiOztBQUVBO0FBQ0EsaUJBQUssWUFBTCxHQUFvQixLQUFLLFNBQUwsQ0FBZSxLQUFLLEtBQXBCLEVBQTJCLFNBQTNCLENBQXBCO0FBQ0EsaUJBQUssVUFBTCxHQUFrQixLQUFLLFNBQUwsQ0FBZSxLQUFLLEtBQXBCLEVBQTJCLE9BQTNCLENBQWxCO0FBQ0EsaUJBQUssVUFBTCxHQUFrQixLQUFLLFNBQUwsQ0FBZSxLQUFLLEtBQXBCLEVBQTJCLE9BQTNCLENBQWxCO0FBQ0EsaUJBQUssWUFBTCxHQUFvQixLQUFLLFNBQUwsQ0FBZSxLQUFLLEtBQXBCLEVBQTJCLFNBQTNCLENBQXBCO0FBQ0EsaUJBQUssWUFBTCxHQUFvQixLQUFLLFNBQUwsQ0FBZSxLQUFLLEtBQXBCLEVBQTJCLFNBQTNCLENBQXBCOztBQUVBLGdCQUFJLENBQUMsS0FBSyxZQUFWLEVBQXdCO0FBQ3BCLHFCQUFLLFlBQUwsR0FBb0I7QUFDaEIsMEJBQU0sU0FEVTtBQUVoQixnQ0FBWSxFQUZJO0FBR2hCLDhCQUFVO0FBSE0saUJBQXBCOztBQU1BO0FBQ0EscUJBQUssWUFBTCxDQUFrQixLQUFLLEtBQXZCLEVBQThCLEtBQUssWUFBbkMsRUFBaUQsS0FBSyxVQUF0RDtBQUNIOztBQUVEO0FBQ0EsbUJBQU8sS0FBSyxZQUFMLENBQWtCLFVBQWxCLENBQTZCLEtBQXBDO0FBQ0EsbUJBQU8sS0FBSyxVQUFMLENBQWdCLFVBQWhCLENBQTJCLEtBQWxDO0FBQ0EsbUJBQU8sS0FBSyxVQUFMLENBQWdCLFVBQWhCLENBQTJCLEtBQWxDO0FBQ0EsbUJBQU8sS0FBSyxZQUFMLENBQWtCLFVBQWxCLENBQTZCLEtBQXBDO0FBQ0EsbUJBQU8sS0FBSyxZQUFMLENBQWtCLFVBQWxCLENBQTZCLEtBQXBDO0FBQ0g7Ozs7OztBQUdMLE9BQU8sT0FBUCxHQUFpQixVQUFqQjs7QUFFQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUN0T0E7Ozs7Ozs7O0FBRUEsSUFBTSxJQUFJLFFBQVEsUUFBUixDQUFWO0FBQ0EsSUFBTSxLQUFLLFFBQVEsSUFBUixDQUFYO0FBQ0EsSUFBTSxRQUFRLFFBQVEsT0FBUixDQUFkOztBQUVBLElBQU0sWUFBWSxRQUFRLGFBQVIsQ0FBbEI7QUFDQSxJQUFNLFdBQVcsUUFBUSxZQUFSLENBQWpCO0FBQ0EsSUFBTSxRQUFRLFFBQVEsU0FBUixHQUFkO0FBQ0EsSUFBTSxPQUFPLFFBQVEsUUFBUixDQUFiO0FBQ0EsSUFBTSxRQUFRLFFBQVEsU0FBUixDQUFkO0FBQ0EsSUFBTSxlQUFlLFFBQVEsZ0JBQVIsQ0FBckI7QUFDQSxJQUFNLGdCQUFnQixRQUFRLGlCQUFSLENBQXRCO0FBQ0EsSUFBTSxpQkFBaUIsUUFBUSxrQkFBUixDQUF2QjtBQUNBLElBQU0sZ0JBQWdCLFFBQVEsaUJBQVIsQ0FBdEI7QUFDQSxJQUFNLGdCQUFnQixRQUFRLGlCQUFSLENBQXRCO0FBQ0EsSUFBTSxhQUFhLFFBQVEsY0FBUixDQUFuQjtBQUNBLElBQU0sWUFBWSxRQUFRLGFBQVIsQ0FBbEI7QUFDQSxJQUFNLFlBQVksUUFBUSxhQUFSLENBQWxCO0FBQ0EsSUFBTSxhQUFhLFFBQVEsY0FBUixDQUFuQjtBQUNBLElBQU0sYUFBYSxRQUFRLGNBQVIsQ0FBbkI7QUFDQSxJQUFNLG1CQUFtQixRQUFRLG9CQUFSLENBQXpCOztBQUVBO0FBQ0E7QUFDQSxJQUFNLGNBQWM7QUFDaEIsVUFBTSxJQUFJLElBQUosQ0FBUyxDQUFULENBRFU7QUFFaEIsbUJBQWU7QUFGQyxDQUFwQjs7QUFLQTtBQUNBLElBQU0sWUFBWSxJQUFJLFNBQUosRUFBbEI7QUFDQSxJQUFNLGFBQWEsSUFBSSxVQUFKLEVBQW5COztBQUVBO0FBQ0EsSUFBTSxZQUFZLE9BQU8sU0FBUCxLQUFxQixVQUFyQixJQUFtQyxJQUFJLFNBQUosRUFBckQ7O0FBRUE7QUFDQSxJQUFNLG9CQUFvQixDQUFDLElBQUQsRUFBTyxHQUFQLEVBQVksR0FBWixFQUFpQixHQUFqQixFQUFzQixHQUF0QixFQUEyQixHQUEzQixFQUFnQyxHQUFoQyxDQUExQjs7QUFFQTtBQUNBLElBQU0scUJBQXFCLEVBQTNCOztBQUVBO0FBQ0EsSUFBTSxZQUFZLENBQ2QsYUFEYyxFQUNDLGFBREQsRUFDZ0IsWUFEaEIsRUFDOEIsb0JBRDlCLEVBQ29ELFdBRHBELEVBQ2lFLFFBRGpFLEVBQzJFLGdCQUQzRSxFQUVkLG9CQUZjLEVBRVEsY0FGUixFQUV3QixRQUZ4QixFQUVrQyxTQUZsQyxFQUU2QyxxQkFGN0MsRUFFb0UsYUFGcEUsRUFFbUYsWUFGbkYsRUFHZCxlQUhjLEVBR0csZUFISCxFQUdvQixnQkFIcEIsRUFHc0MsbUJBSHRDLEVBRzJELFFBSDNELENBQWxCOztBQU1BOzs7O0lBR00sUTs7Ozs7Ozs7O0FBc0NGOzs7WUFHRzs7Ozs7c0NBS1c7QUFBQTs7QUFDVixtQkFBTyxJQUFJLFVBQUosQ0FBZSxzQkFBZixFQUNGLElBREUsQ0FDRyxZQUFNO0FBQ1IsdUJBQU8sTUFBSyxZQUFaO0FBQ0gsYUFIRSxFQUlGLElBSkUsQ0FJRyxHQUpILEVBSVEsaUJBQVM7QUFDaEI7QUFDQSxvQkFBSSxFQUFFLGlCQUFpQixLQUFuQixDQUFKLEVBQStCLFFBQVEsTUFBSyxLQUFMLENBQVcsS0FBWCxDQUFSOztBQUUvQjtBQUNBLG9CQUFJLE1BQU0sTUFBTixFQUFKLEVBQW9CLE1BQU0sSUFBSSxLQUFKLENBQVUsc0NBQVYsQ0FBTjs7QUFFcEI7QUFDQSxrQkFBRSxPQUFGLENBQVUsTUFBSyxPQUFmLEVBQXdCLG1CQUFXO0FBQy9CLDRCQUFRLFdBQVIsQ0FBb0IsWUFBWSxLQUFoQztBQUNILGlCQUZEOztBQUlBLHNCQUFLLFlBQUwsR0FBb0IsS0FBcEI7O0FBRUEsdUJBQU8sS0FBUDtBQUNILGFBbkJFLEVBb0JGLE1BcEJFLENBb0JLLFNBcEJMLENBQVA7QUFxQkg7O0FBRUQ7Ozs7Ozs7OztpQ0FNUyxJLEVBQU0sa0IsRUFBb0I7QUFDL0IsbUJBQU8sS0FBSyxTQUFMLENBQWUsSUFBZixFQUFxQixrQkFBckIsQ0FBUDtBQUNIOztBQUVEOzs7O1lBSUc7Ozs7Ozs7OztzQ0FNVztBQUFBOztBQUNWLG1CQUFPLElBQUksVUFBSixDQUFlLHNCQUFmLEVBQ0YsSUFERSxDQUNHLFFBREgsRUFDYSxnQkFBUTtBQUNwQix1QkFBTyxPQUFLLGlCQUFMLENBQXVCLFNBQXZCLEVBQWtDLElBQWxDLENBQVA7QUFDSCxhQUhFLEVBSUYsSUFKRSxDQUlHLENBQUMsUUFBRCxFQUFXLEdBQVgsQ0FKSCxFQUlvQixVQUFDLElBQUQsRUFBTyxRQUFQLEVBQW9CO0FBQ3ZDLHVCQUFLLGlCQUFMLENBQXVCLFNBQXZCLEVBQWtDLElBQWxDLEVBQXdDLFFBQXhDO0FBQ0EsdUJBQU8sTUFBUDtBQUNILGFBUEUsRUFRRixNQVJFLENBUUssU0FSTCxDQUFQO0FBU0g7O0FBRUQ7Ozs7Ozs7O29DQUtZLEssRUFBTztBQUNmO0FBQ0EsZ0JBQUksRUFBRSxpQkFBaUIsS0FBbkIsQ0FBSixFQUErQjtBQUMzQix3QkFBUSxLQUFLLEtBQUwsQ0FBVyxLQUFYLENBQVI7QUFDQSxvQkFBSSxDQUFDLEtBQUwsRUFBWSxNQUFNLElBQUksS0FBSixDQUFVLCtCQUFWLENBQU47QUFDZjs7QUFFRDtBQUNBLGdCQUFNLGdCQUFnQixFQUFFLE1BQUYsQ0FBUyxLQUFLLE9BQWQsRUFBdUI7QUFBQSx1QkFBUyxDQUFDLE1BQU0sTUFBTixFQUFWO0FBQUEsYUFBdkIsQ0FBdEI7QUFDQSxnQkFBSSxjQUFjLE1BQWQsS0FBeUIsQ0FBekIsSUFBOEIsY0FBYyxDQUFkLE1BQXFCLEtBQXZELEVBQThEO0FBQzFELHNCQUFNLElBQUksS0FBSixDQUFVLHNGQUFWLENBQU47QUFDSDs7QUFFRDtBQUNBLGdCQUFJLFFBQVEsS0FBSyxPQUFMLENBQWEsT0FBYixDQUFxQixLQUFyQixDQUFaO0FBQ0EsaUJBQUssT0FBTCxDQUFhLE1BQWIsQ0FBb0IsS0FBcEIsRUFBMkIsQ0FBM0I7O0FBRUE7QUFDQSxnQkFBSSxVQUFVLEtBQUssV0FBTCxFQUFkLEVBQWtDO0FBQzlCLG9CQUFJLFNBQVMsS0FBSyxPQUFMLENBQWEsTUFBMUIsRUFBa0M7QUFDbEMscUJBQUssV0FBTCxDQUFpQixLQUFqQjtBQUNIOztBQUVELG1CQUFPLElBQVA7QUFDSDs7QUFFRDs7Ozs7Ozs7OzZCQU1LLE8sRUFBUyxXLEVBQWE7QUFDdkIsc0JBQVUsU0FBUyxPQUFULENBQVY7O0FBRUEsZ0JBQUksVUFBVSxFQUFkO0FBQ0EsaUJBQUssT0FBTCxDQUFhLE9BQWIsQ0FBcUIsaUJBQVM7QUFDMUIsMEJBQVUsUUFBUSxNQUFSLENBQWUsTUFBTSxJQUFOLENBQVcsT0FBWCxFQUFvQixXQUFwQixDQUFmLENBQVY7QUFDSCxhQUZEOztBQUlBLG1CQUFPLE9BQVA7QUFDSDs7QUFFRDs7Ozs7Ozs7O2tDQU1VLEssRUFBTyxrQixFQUFvQjtBQUNqQztBQUNBLGdCQUFJLEVBQUUsaUJBQWlCLEtBQW5CLENBQUosRUFBK0I7QUFDM0Isd0JBQVEsS0FBSyxLQUFMLENBQVcsS0FBWCxDQUFSO0FBQ0Esb0JBQUksQ0FBQyxLQUFMLEVBQVksTUFBTSxJQUFJLEtBQUosQ0FBVSwrQkFBVixDQUFOO0FBQ2Y7O0FBRUQ7QUFDQSxnQkFBTSxPQUFPLEtBQUssT0FBTCxDQUFhLE9BQWIsQ0FBcUIsS0FBckIsQ0FBYjtBQUNBLGdCQUFJLFdBQUo7QUFDQSxnQkFBSSxFQUFFLEtBQUYsQ0FBUSxrQkFBUixDQUFKLEVBQWlDO0FBQzdCLHFCQUFLLEtBQUssT0FBTCxDQUFhLE1BQWIsR0FBc0IsQ0FBM0I7QUFDSCxhQUZELE1BRU8sSUFBSSxFQUFFLFNBQUYsQ0FBWSxrQkFBWixDQUFKLEVBQXFDO0FBQ3hDLHFCQUFLLGtCQUFMO0FBQ0gsYUFGTSxNQUVBO0FBQ0gsb0JBQUksRUFBRSw4QkFBOEIsS0FBaEMsQ0FBSixFQUE0QztBQUN4Qyx5Q0FBcUIsS0FBSyxLQUFMLENBQVcsa0JBQVgsQ0FBckI7QUFDQSx3QkFBSSxDQUFDLGtCQUFMLEVBQXlCLE1BQU0sSUFBSSxLQUFKLENBQVUsaUNBQVYsQ0FBTjtBQUM1Qjs7QUFFRCxxQkFBSyxLQUFLLE9BQUwsQ0FBYSxPQUFiLENBQXFCLGtCQUFyQixDQUFMO0FBQ0g7O0FBRUQ7QUFDQSxpQkFBSyxPQUFMLENBQWEsTUFBYixDQUFvQixFQUFwQixFQUF3QixDQUF4QixFQUEyQixLQUFLLE9BQUwsQ0FBYSxNQUFiLENBQW9CLElBQXBCLEVBQTBCLENBQTFCLEVBQTZCLENBQTdCLENBQTNCOztBQUVBLG1CQUFPLElBQVA7QUFDSDs7QUFFRDs7OztZQUlHOzs7Ozs7Ozs7O29DQU9TLEksRUFBTTtBQUFBOztBQUNkLG1CQUFPLFFBQVEsRUFBZjtBQUNBLGdCQUFJLE9BQU8sSUFBUCxLQUFnQixRQUFwQixFQUE4QixPQUFPLEVBQUUsTUFBTSxJQUFSLEVBQVA7O0FBRTlCLGlCQUFLLGFBQUw7O0FBRUEsZ0JBQUksbUJBQW1CLEtBQUssU0FBTCxDQUFlLEtBQUssS0FBcEIsRUFBMkIsY0FBM0IsQ0FBdkI7O0FBRUEsaUJBQUssT0FBTCxDQUFhLE9BQWIsQ0FBcUIsVUFBQyxLQUFELEVBQVEsQ0FBUixFQUFjO0FBQy9CLG9CQUFJLENBQUMsTUFBTSxXQUFYLEVBQXdCOztBQUV4QixvQkFBSSxDQUFDLGdCQUFMLEVBQXVCO0FBQ25CLHVDQUFtQjtBQUNmLDhCQUFNLGNBRFM7QUFFZixvQ0FBWSxFQUZHO0FBR2Ysa0NBQVU7QUFISyxxQkFBbkI7O0FBTUEseUJBQUssYUFBTCxDQUFtQixPQUFLLEtBQXhCLEVBQStCLGdCQUEvQixFQUFpRCxTQUFqRDtBQUNIOztBQUVELHFCQUFLLFdBQUwsQ0FBaUIsZ0JBQWpCLEVBQW1DO0FBQy9CLDBCQUFNLGFBRHlCO0FBRS9CLGdDQUFZO0FBQ1IsOEJBQU0sdUJBREU7QUFFUixzQ0FBYyxDQUZOO0FBR1IsZ0NBQVE7QUFIQSxxQkFGbUI7QUFPL0IsOEJBQVUsQ0FBQyxNQUFNLFdBQU4sQ0FBa0IsT0FBbEIsQ0FBMEIsRUFBRSxrQkFBa0IsSUFBcEIsRUFBMEIsVUFBVSxJQUFwQyxFQUExQixDQUFEO0FBUHFCLGlCQUFuQztBQVNILGFBdEJEOztBQXdCQSxpQkFBSyxXQUFMLENBQWlCLFFBQWpCLEdBQTRCLEVBQTVCO0FBQ0EsaUJBQUssT0FBTCxDQUFhLE9BQWIsQ0FBcUIsVUFBQyxLQUFELEVBQVEsQ0FBUixFQUFjO0FBQy9CLG9CQUFNLHFDQUFrQyxJQUFJLENBQXRDLFVBQU47QUFDQSxvQkFBTSwrQ0FBNEMsSUFBSSxDQUFoRCxlQUFOO0FBQ0Esb0JBQU0sWUFBWSxNQUFNLE1BQU4sRUFBbEI7QUFDQSxvQkFBTSxlQUFlLE9BQUssY0FBTCxDQUFvQixRQUFwQixDQUE2QixVQUFVLEVBQVYsQ0FBYSxVQUFiLENBQXdCLE1BQXhCLENBQTdCLENBQXJCO0FBQ0EsNkJBQWEsVUFBYixDQUF3QixNQUF4Qix5QkFBb0QsSUFBSSxDQUF4RDtBQUNBLHVCQUFLLFdBQUwsQ0FBaUIsUUFBakIsQ0FBMEIsSUFBMUIsQ0FBK0IsVUFBVSxFQUF6QztBQUNBLHVCQUFLLElBQUwsQ0FBVSxJQUFWLENBQWUsU0FBZixFQUEwQixXQUFXLEtBQVgsQ0FBaUIsVUFBVSxLQUEzQixDQUExQixFQUE2RCxXQUE3RDs7QUFFQSxvQkFBTSxtQkFBbUIsV0FBVyxLQUFYLENBQWlCLFVBQVUsYUFBM0IsQ0FBekI7QUFDQSxvQkFBSSxnQkFBSixFQUFzQjtBQUNsQiwyQkFBSyxJQUFMLENBQVUsSUFBVixDQUFlLGFBQWYsRUFBOEIsZ0JBQTlCLEVBQWdELFdBQWhEO0FBQ0gsaUJBRkQsTUFFTztBQUNILDJCQUFLLElBQUwsQ0FBVSxNQUFWLENBQWlCLGFBQWpCO0FBQ0g7QUFDSixhQWZEOztBQWlCQTtBQUNBOztBQUVBO0FBQ0EsaUJBQUssSUFBTCxDQUFVLElBQVYsQ0FBZSxxQkFBZixFQUFzQyxXQUFXLEtBQVgsQ0FBaUIsS0FBSyxhQUF0QixDQUF0QyxFQUE0RSxXQUE1RTtBQUNBLGlCQUFLLElBQUwsQ0FBVSxJQUFWLENBQWUsa0JBQWYsRUFBbUMsV0FBVyxLQUFYLENBQWlCLEtBQUssY0FBdEIsQ0FBbkMsRUFBMEUsV0FBMUU7QUFDQSxpQkFBSyxJQUFMLENBQVUsSUFBVixDQUFlLG1CQUFmLEVBQW9DLFdBQVcsS0FBWCxDQUFpQixLQUFLLGVBQXRCLENBQXBDLEVBQTRFLFdBQTVFO0FBQ0EsaUJBQUssSUFBTCxDQUFVLElBQVYsQ0FBZSw0QkFBZixFQUE2QyxXQUFXLEtBQVgsQ0FBaUIsS0FBSyxjQUF0QixDQUE3QyxFQUFvRixXQUFwRjtBQUNBLGlCQUFLLElBQUwsQ0FBVSxJQUFWLENBQWUsc0JBQWYsRUFBdUMsV0FBVyxLQUFYLENBQWlCLEtBQUssY0FBdEIsQ0FBdkMsRUFBOEUsV0FBOUU7QUFDQSxpQkFBSyxJQUFMLENBQVUsSUFBVixDQUFlLGVBQWYsRUFBZ0MsV0FBVyxLQUFYLENBQWlCLEtBQUssV0FBdEIsQ0FBaEMsRUFBb0UsV0FBcEU7QUFDQSxpQkFBSyxJQUFMLENBQVUsSUFBVixDQUFlLGlCQUFmLEVBQWtDLFdBQVcsS0FBWCxDQUFpQixLQUFLLEtBQXRCLENBQWxDLEVBQWdFLFdBQWhFOztBQUVBO0FBQ0EsbUJBQU8sS0FBSyxJQUFMLENBQVUsYUFBVixDQUF3QjtBQUMzQixzQkFBTSxZQURxQjtBQUUzQiw2QkFBYTtBQUZjLGFBQXhCLEVBR0osSUFISSxDQUdDLGtCQUFVO0FBQ2Q7QUFDQSxvQkFBSSxLQUFLLFFBQVQsRUFBbUIsU0FBUyxVQUFVLE9BQVYsQ0FBa0IsTUFBbEIsRUFBMEIsS0FBSyxRQUEvQixDQUFUOztBQUVuQjtBQUNBLHVCQUFPLE9BQUssc0JBQUwsQ0FBNEIsTUFBNUIsRUFBb0MsS0FBSyxJQUF6QyxDQUFQO0FBQ0gsYUFUTSxDQUFQO0FBVUg7O0FBRUQ7Ozs7Ozs7OzhCQUtNLGdCLEVBQWtCO0FBQ3BCLGdCQUFJLEVBQUUsU0FBRixDQUFZLGdCQUFaLENBQUosRUFBbUMsT0FBTyxLQUFLLE9BQUwsQ0FBYSxnQkFBYixDQUFQO0FBQ25DLG1CQUFPLEVBQUUsSUFBRixDQUFPLEtBQUssT0FBWixFQUFxQjtBQUFBLHVCQUFTLE1BQU0sSUFBTixPQUFpQixnQkFBMUI7QUFBQSxhQUFyQixDQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7aUNBSVM7QUFDTCxtQkFBTyxLQUFLLE9BQUwsQ0FBYSxLQUFiLEVBQVA7QUFDSDs7QUFFRDs7OztZQUlHOzs7O2VBSUE7Ozs7O2tCQUtBOzs7Ozs7OzttQ0FLUTtBQUFBOztBQUNQLG1CQUFPLElBQUksVUFBSixDQUFlLG1CQUFmLEVBQ0YsSUFERSxDQUNHLFFBREgsRUFDYSxnQkFBUTtBQUNwQjtBQUNBLHVCQUFPLE9BQUssZUFBTCxDQUFxQixHQUFyQixDQUF5QixJQUF6QixDQUFQO0FBQ0gsYUFKRSxFQUtGLElBTEUsQ0FLRyxPQUxILEVBS1ksaUJBQVM7QUFDcEI7QUFDQSxvQkFBTSxTQUFTLEVBQWY7QUFDQSxzQkFBTSxPQUFOLENBQWMsZ0JBQVE7QUFDbEIsMkJBQU8sSUFBUCxJQUFlLE9BQUssZUFBTCxDQUFxQixHQUFyQixDQUF5QixJQUF6QixDQUFmO0FBQ0gsaUJBRkQ7O0FBSUEsdUJBQU8sTUFBUDtBQUNILGFBYkUsRUFjRixJQWRFLENBY0csQ0FBQyxRQUFELEVBQVcsR0FBWCxDQWRILEVBY29CLFVBQUMsSUFBRCxFQUFPLEtBQVAsRUFBaUI7QUFDcEM7QUFDQSx1QkFBSyxlQUFMLENBQXFCLEdBQXJCLENBQXlCLElBQXpCLEVBQStCLEtBQS9CO0FBQ0EsdUJBQU8sTUFBUDtBQUNILGFBbEJFLEVBbUJGLElBbkJFLENBbUJHLFFBbkJILEVBbUJhLHNCQUFjO0FBQzFCO0FBQ0EscUJBQUssSUFBTSxJQUFYLElBQW1CLFVBQW5CLEVBQStCO0FBQzNCLHdCQUFJLENBQUMsV0FBVyxjQUFYLENBQTBCLElBQTFCLENBQUwsRUFBc0M7QUFDdEMsd0JBQU0sUUFBUSxXQUFXLElBQVgsQ0FBZDtBQUNBLDJCQUFLLGVBQUwsQ0FBcUIsR0FBckIsQ0FBeUIsSUFBekIsRUFBK0IsS0FBL0I7QUFDSDs7QUFFRCx1QkFBTyxNQUFQO0FBQ0gsYUE1QkUsRUE2QkYsTUE3QkUsQ0E2QkssU0E3QkwsQ0FBUDtBQThCSDs7QUFFRDs7Ozs7OztxQ0FJYTtBQUNULG1CQUFPLEtBQUssZUFBWjtBQUNIOztBQUVEOzs7Ozs7Ozs7O29DQU9ZLEksRUFBTSxJLEVBQU07QUFDcEIsZ0JBQUksUUFBUSxPQUFaLEVBQXFCLE1BQU0sSUFBSSxLQUFKLENBQVUsdURBQVYsQ0FBTjtBQUNyQixtQkFBTyxLQUFLLFdBQUwsQ0FBaUIsSUFBakIsRUFDRixJQURFLENBQ0c7QUFBQSx1QkFBUSxJQUFJLFVBQVUsT0FBZCxDQUFzQixVQUFDLE9BQUQsRUFBVSxNQUFWLEVBQXFCO0FBQ3JELHVCQUFHLFNBQUgsQ0FBYSxJQUFiLEVBQW1CLElBQW5CLEVBQXlCLGVBQU87QUFDNUIsNEJBQUksR0FBSixFQUFTLE9BQU8sT0FBTyxHQUFQLENBQVA7QUFDVDtBQUNILHFCQUhEO0FBSUgsaUJBTGEsQ0FBUjtBQUFBLGFBREgsQ0FBUDtBQU9IOztBQUVEOzs7Ozs7WUFNRzs7Ozs7Ozs7Ozs7MENBUWUsVSxFQUFZLEksRUFBTSxRLEVBQVU7QUFBQTs7QUFDMUMsZ0JBQUksbUJBQW1CLEtBQUssU0FBTCxDQUFlLEtBQUssS0FBcEIsRUFBMkIsY0FBM0IsQ0FBdkI7QUFDQSxnQkFBSSxrQkFBa0Isb0JBQW9CLEVBQUUsSUFBRixDQUFPLGlCQUFpQixRQUF4QixFQUFrQztBQUFBLHVCQUFRLEtBQUssVUFBTCxDQUFnQixJQUFoQixLQUF5QixJQUF6QixJQUFpQyxLQUFLLFVBQUwsS0FBb0IsVUFBN0Q7QUFBQSxhQUFsQyxDQUExQzs7QUFFQSxtQkFBTyxJQUFJLFVBQUosQ0FBZSw0QkFBZixFQUNGLElBREUsQ0FDRyxDQUFDLEdBQUQsRUFBTSxRQUFOLENBREgsRUFDb0IsWUFBTTtBQUN6QjtBQUNBLG9CQUFNLFdBQVcsbUJBQW1CLGdCQUFnQixRQUFoQixDQUF5QixDQUF6QixDQUFwQztBQUNBLG9CQUFJLENBQUMsUUFBTCxFQUFlLE9BQU8sU0FBUDs7QUFFZjtBQUNBLG9CQUFNLE1BQU0saUJBQWlCLFdBQWpCLENBQTZCLFFBQTdCLENBQVo7QUFDQSxvQkFBSSxDQUFDLEdBQUwsRUFBVSxPQUFPLFFBQVA7O0FBRVY7QUFDQSxvQkFBTSxRQUFRLE9BQUssS0FBTCxDQUFXLElBQUksU0FBZixDQUFkO0FBQ0Esb0JBQUksSUFBSSxJQUFKLEtBQWEsTUFBakIsRUFBeUIsT0FBTyxNQUFNLElBQU4sQ0FBVyxJQUFJLFNBQWYsRUFBMEIsSUFBSSxZQUE5QixDQUFQO0FBQ3pCLG9CQUFJLElBQUksSUFBSixLQUFhLE9BQWpCLEVBQTBCLE9BQU8sTUFBTSxLQUFOLENBQVksSUFBSSxjQUFoQixFQUFnQyxJQUFJLGlCQUFwQyxFQUF1RCxJQUFJLFlBQTNELEVBQXlFLElBQUksZUFBN0UsQ0FBUDtBQUMxQixvQkFBSSxJQUFJLElBQUosS0FBYSxLQUFqQixFQUF3QixPQUFPLE1BQU0sR0FBTixDQUFVLElBQUksU0FBZCxDQUFQO0FBQ3hCLG9CQUFJLElBQUksSUFBSixLQUFhLFFBQWpCLEVBQTJCLE9BQU8sTUFBTSxNQUFOLENBQWEsSUFBSSxZQUFqQixDQUFQO0FBQzNCLHVCQUFPLFFBQVA7QUFDSCxhQWpCRSxFQWtCRixJQWxCRSxDQWtCRyxDQUFDLEdBQUQsRUFBTSxRQUFOLEVBQWdCLEtBQWhCLENBbEJILEVBa0IyQixZQUFNO0FBQ2hDLG9CQUFJLGVBQUosRUFBcUIsS0FBSyxXQUFMLENBQWlCLGdCQUFqQixFQUFtQyxlQUFuQztBQUNyQixvQkFBSSxvQkFBb0IsQ0FBQyxpQkFBaUIsUUFBakIsQ0FBMEIsTUFBbkQsRUFBMkQsS0FBSyxXQUFMLENBQWlCLE9BQUssS0FBdEIsRUFBNkIsZ0JBQTdCO0FBQzNELHVCQUFPLE1BQVA7QUFDSCxhQXRCRSxFQXVCRixJQXZCRSxDQXVCRyxDQUFDLEdBQUQsRUFBTSxRQUFOLEVBQWdCLEdBQWhCLENBdkJILEVBdUJ5QixZQUFNO0FBQzlCLG9CQUFJLE9BQU8sUUFBUCxLQUFvQixRQUF4QixFQUFrQztBQUM5QiwrQkFBVyxTQUFTLE9BQVQsQ0FBaUI7QUFDeEIsMENBQWtCLElBRE07QUFFeEIsa0NBQVU7QUFGYyxxQkFBakIsQ0FBWDtBQUlIOztBQUVELG9CQUFJLENBQUMsZ0JBQUwsRUFBdUI7QUFDbkIsdUNBQW1CO0FBQ2YsOEJBQU0sY0FEUztBQUVmLG9DQUFZLEVBRkc7QUFHZixrQ0FBVTtBQUhLLHFCQUFuQjs7QUFNQSx5QkFBSyxhQUFMLENBQW1CLE9BQUssS0FBeEIsRUFBK0IsZ0JBQS9CLEVBQWlELFNBQWpEO0FBQ0g7O0FBRUQsb0JBQUksQ0FBQyxlQUFMLEVBQXNCO0FBQ2xCLHNDQUFrQjtBQUNkLDhCQUFNLGFBRFE7QUFFZCxvQ0FBWSxFQUFFLFVBQUYsRUFGRTtBQUdkLGtDQUFVLENBQUMsUUFBRDtBQUhJLHFCQUFsQjs7QUFNQSx3QkFBSSxVQUFKLEVBQWdCLGdCQUFnQixVQUFoQixHQUE2QixVQUE3Qjs7QUFFaEIseUJBQUssV0FBTCxDQUFpQixnQkFBakIsRUFBbUMsZUFBbkM7QUFDSDs7QUFFRCxnQ0FBZ0IsUUFBaEIsR0FBMkIsQ0FBQyxRQUFELENBQTNCOztBQUVBLHVCQUFPLE1BQVA7QUFDSCxhQXhERSxFQXlERixNQXpERSxDQXlESyxTQXpETCxDQUFQO0FBMERIOztBQUVEOzs7Ozs7Ozt3Q0FLZ0I7QUFDWixtQkFBTyxLQUFLLGNBQVo7QUFDSDs7QUFFRDs7Ozs7Ozs7cUNBS2E7QUFDVCxtQkFBTyxLQUFLLFdBQVo7QUFDSDs7QUFFRDs7Ozs7Ozs7Ozs7O21DQVNXLEksRUFBTSxJLEVBQU0sa0IsRUFBb0I7QUFDdkMsZ0JBQUksQ0FBQyxJQUFELElBQVMsRUFBRSxnQkFBZ0IsS0FBbEIsQ0FBYixFQUF1QyxNQUFNLElBQUksS0FBSixDQUFVLHFCQUFWLENBQU47O0FBRXZDLG1CQUFPLEtBQUssU0FBTCxDQUFlLElBQWYsRUFBcUIsa0JBQXJCLEVBQXlDLFlBQU07QUFDbEQsb0JBQU0sV0FBVyxTQUFYLFFBQVcsT0FBUTtBQUNyQjtBQUNBLHdCQUFJLFFBQVEsRUFBRSxVQUFGLENBQWEsS0FBSyxLQUFsQixDQUFaLEVBQXNDLE9BQU8sS0FBSyxLQUFMLEVBQVA7O0FBRXRDLHdCQUFJLFFBQU8sSUFBUCx5Q0FBTyxJQUFQLE9BQWdCLFFBQXBCLEVBQThCO0FBQzFCLDRCQUFJLEtBQUssSUFBVCxFQUFlO0FBQ1gsZ0NBQU0sU0FBUztBQUNYLHNDQUFNLEtBQUssSUFEQTtBQUVYLDRDQUFZLEVBRkQ7QUFHWCwwQ0FBVTtBQUhDLDZCQUFmOztBQU1BLDhCQUFFLE1BQUYsQ0FBUyxLQUFLLFVBQWQsRUFBMEIsVUFBQyxLQUFELEVBQVEsSUFBUixFQUFpQjtBQUN2Qyx1Q0FBTyxVQUFQLENBQWtCLElBQWxCLElBQTBCLEtBQTFCO0FBQ0gsNkJBRkQ7O0FBSUEsZ0NBQUksYUFBSjtBQUNBLGdDQUFJLEtBQUssUUFBVCxFQUFtQjtBQUNmLHFDQUFLLFFBQUwsQ0FBYyxPQUFkLENBQXNCLGlCQUFTO0FBQzNCLDJDQUFPLFNBQVMsS0FBVCxDQUFQO0FBQ0Esd0NBQUksVUFBVSxJQUFkLEVBQW9CO0FBQ2hCLCtDQUFPLFFBQVAsQ0FBZ0IsSUFBaEIsQ0FBcUIsSUFBckI7QUFDSDtBQUNKLGlDQUxEO0FBTUg7QUFDRCxtQ0FBTyxNQUFQO0FBQ0g7QUFDSixxQkF2QkQsTUF1Qk8sSUFBSSxTQUFTLElBQWIsRUFBbUI7QUFDdEIsK0JBQU8sSUFBUDtBQUNIO0FBQ0QsMkJBQU8sSUFBUDtBQUNILGlCQS9CRDs7QUFpQ0E7QUFDQSxvQkFBTSxVQUFVLEtBQUssTUFBTCxFQUFoQjtBQUNBLG9CQUFNLFlBQVksU0FBUyxRQUFRLEtBQWpCLENBQWxCO0FBQ0Esb0JBQU0sbUJBQW1CLFNBQVMsUUFBUSxhQUFqQixDQUF6QjtBQUNBLHVCQUFPLEVBQUUsb0JBQUYsRUFBYSxrQ0FBYixFQUFQO0FBQ0gsYUF2Q00sQ0FBUDtBQXdDSDs7QUFFRDs7Ozs7Ozs7Ozs7a0NBUVUsSSxFQUFNLGtCLEVBQW9CLGdCLEVBQWtCO0FBQ2xEO0FBQ0EsZ0JBQUksQ0FBQyxJQUFELElBQVMsT0FBTyxJQUFQLEtBQWdCLFFBQTdCLEVBQXVDLE1BQU0sSUFBSSxLQUFKLENBQVUscUJBQVYsQ0FBTjtBQUN2QyxnQkFBSSxFQUFFLElBQUYsQ0FBTyxpQkFBUCxFQUEwQjtBQUFBLHVCQUFRLEtBQUssT0FBTCxDQUFhLElBQWIsS0FBc0IsQ0FBOUI7QUFBQSxhQUExQixDQUFKLEVBQWdFLE1BQU0sSUFBSSxLQUFKLGtFQUF5RSxrQkFBa0IsSUFBbEIsQ0FBdUIsR0FBdkIsQ0FBekUsQ0FBTjtBQUNoRSxnQkFBSSxLQUFLLE1BQUwsR0FBYyxrQkFBbEIsRUFBc0MsTUFBTSxJQUFJLEtBQUoseUNBQWdELGtCQUFoRCxrQkFBTjtBQUN0QyxnQkFBSSxLQUFLLEtBQUwsQ0FBVyxJQUFYLENBQUosRUFBc0IsTUFBTSxJQUFJLEtBQUosd0JBQThCLElBQTlCLHdCQUFOOztBQUV0QjtBQUNBLGdCQUFJLGNBQUo7QUFDQSxnQkFBSSxFQUFFLEtBQUYsQ0FBUSxrQkFBUixDQUFKLEVBQWlDO0FBQzdCLHdCQUFRLEtBQUssT0FBTCxDQUFhLE1BQXJCO0FBQ0gsYUFGRCxNQUVPLElBQUksRUFBRSxTQUFGLENBQVksa0JBQVosQ0FBSixFQUFxQztBQUN4Qyx3QkFBUSxrQkFBUjtBQUNILGFBRk0sTUFFQTtBQUNILG9CQUFJLEVBQUUsOEJBQThCLEtBQWhDLENBQUosRUFBNEM7QUFDeEMseUNBQXFCLEtBQUssS0FBTCxDQUFXLGtCQUFYLENBQXJCO0FBQ0Esd0JBQUksQ0FBQyxrQkFBTCxFQUF5QixNQUFNLElBQUksS0FBSixDQUFVLGlDQUFWLENBQU47QUFDNUI7O0FBRUQsd0JBQVEsS0FBSyxPQUFMLENBQWEsT0FBYixDQUFxQixrQkFBckIsQ0FBUjtBQUNIOztBQUVEO0FBQ0EsZ0JBQU0sZUFBZSxLQUFLLGNBQUwsQ0FBb0IsR0FBcEIsQ0FBd0IsV0FBeEIsQ0FBckIsQ0F2QmtELENBdUJTO0FBQzNELGdCQUFNLGNBQWM7QUFDaEIsc0JBQU0sT0FEVTtBQUVoQiw0QkFBWTtBQUNSLDhCQURRO0FBRVIsNkJBQVMsRUFBRSxLQUFLLFdBRlI7QUFHUiw0QkFBUSxhQUFhLFVBQWIsQ0FBd0I7QUFIeEIsaUJBRkk7QUFPaEIsMEJBQVU7QUFQTSxhQUFwQjs7QUFVQTtBQUNBLGdCQUFJLGNBQUo7QUFDQSxnQkFBSSxnQkFBSixFQUFzQjtBQUFBLHdDQUNzQixrQkFEdEI7QUFBQSxvQkFDVixTQURVLHFCQUNWLFNBRFU7QUFBQSxvQkFDQyxnQkFERCxxQkFDQyxnQkFERDs7QUFFbEIsd0JBQVEsSUFBSSxLQUFKLENBQVUsSUFBVixFQUFnQixXQUFoQixFQUE2QixTQUE3QixFQUF3QyxnQkFBeEMsQ0FBUjtBQUNILGFBSEQsTUFHTztBQUNILHdCQUFRLElBQUksS0FBSixDQUFVLElBQVYsRUFBZ0IsV0FBaEIsQ0FBUjtBQUNIOztBQUVEO0FBQ0EsaUJBQUssT0FBTCxDQUFhLE1BQWIsQ0FBb0IsS0FBcEIsRUFBMkIsQ0FBM0IsRUFBOEIsS0FBOUI7O0FBRUEsbUJBQU8sS0FBUDtBQUNIOztBQUVEOzs7Ozs7Ozs7OzttQ0FRVyxJLEVBQU0sSSxFQUFNO0FBQUE7O0FBQ25CLG1CQUFPLFFBQVEsRUFBZjs7QUFFQSxpQkFBSyxXQUFMLEdBQW1CLENBQW5CO0FBQ0EsaUJBQUssT0FBTCxHQUFlLEVBQWY7O0FBRUEsbUJBQU8sVUFBVSxPQUFWLENBQWtCLE9BQWxCLEdBQ0YsSUFERSxDQUNHLFlBQU07QUFDUjtBQUNBLHVCQUFPLE9BQUssMEJBQUwsQ0FBZ0MsSUFBaEMsRUFBc0MsS0FBSyxNQUEzQyxFQUNGLElBREUsQ0FDRyxrQkFBVTtBQUNaLDJCQUFPLE1BQVA7QUFDSCxpQkFIRSxDQUFQO0FBSUgsYUFQRSxFQVFGLElBUkUsQ0FRRyxZQUFNO0FBQ1Isb0JBQUksQ0FBQyxLQUFLLFFBQVYsRUFBb0I7QUFDcEIsdUJBQU8sVUFBVSxZQUFWLENBQXVCLElBQXZCLEVBQTZCLEtBQUssUUFBbEMsRUFDRixJQURFLENBQ0cscUJBQWE7QUFDZiwyQkFBTyxTQUFQO0FBQ0gsaUJBSEUsQ0FBUDtBQUlILGFBZEUsRUFlRixJQWZFLENBZUc7QUFBQSx1QkFBTSxNQUFNLFNBQU4sQ0FBZ0IsSUFBaEIsQ0FBTjtBQUFBLGFBZkgsRUFnQkYsSUFoQkUsQ0FnQkcsZUFBTztBQUNULHVCQUFLLElBQUwsR0FBWSxHQUFaO0FBQ0EsdUJBQU8sT0FBSyxnQkFBTCxDQUFzQixDQUN6QixxQkFEeUIsRUFFekIsa0JBRnlCLEVBR3pCLG1CQUh5QixFQUl6Qiw0QkFKeUIsRUFLekIsc0JBTHlCLEVBTXpCLGVBTnlCLEVBT3pCLGlCQVB5QixDQUF0QixDQUFQO0FBU0gsYUEzQkUsRUE0QkYsSUE1QkUsQ0E0QkcsaUJBQVM7QUFDWCxvQkFBTSxtQkFBbUIsTUFBTSxDQUFOLENBQXpCO0FBQ0Esb0JBQU0sb0JBQW9CLE1BQU0sQ0FBTixDQUExQjtBQUNBLG9CQUFNLHFCQUFxQixNQUFNLENBQU4sQ0FBM0I7QUFDQSxvQkFBTSxvQkFBb0IsTUFBTSxDQUFOLENBQTFCO0FBQ0Esb0JBQU0sb0JBQW9CLE1BQU0sQ0FBTixDQUExQjtBQUNBLG9CQUFNLGlCQUFpQixNQUFNLENBQU4sQ0FBdkI7QUFDQSxvQkFBTSxlQUFlLE1BQU0sQ0FBTixDQUFyQjs7QUFFQTtBQUNBLHVCQUFLLGFBQUwsR0FBcUIsSUFBSSxZQUFKLENBQWlCLGdCQUFqQixDQUFyQjtBQUNBLHVCQUFLLGNBQUwsR0FBc0IsSUFBSSxhQUFKLENBQWtCLGlCQUFsQixDQUF0QjtBQUNBLHVCQUFLLGVBQUwsR0FBdUIsSUFBSSxjQUFKLENBQW1CLGtCQUFuQixDQUF2QjtBQUNBLHVCQUFLLGNBQUwsR0FBc0IsSUFBSSxhQUFKLENBQWtCLGlCQUFsQixDQUF0QjtBQUNBLHVCQUFLLGNBQUwsR0FBc0IsSUFBSSxhQUFKLENBQWtCLGlCQUFsQixDQUF0QjtBQUNBLHVCQUFLLFdBQUwsR0FBbUIsSUFBSSxVQUFKLENBQWUsY0FBZixDQUFuQjtBQUNBLHVCQUFLLEtBQUwsR0FBYSxZQUFiOztBQUVBO0FBQ0Esb0JBQUksQ0FBQyxPQUFLLGNBQUwsQ0FBb0IsVUFBcEIsQ0FBK0IsZUFBL0IsQ0FBTCxFQUFzRDtBQUNsRCwyQkFBSyxjQUFMLENBQW9CLEdBQXBCLENBQXdCLGVBQXhCLEVBQXlDLG1CQUF6QztBQUNIOztBQUVEO0FBQ0Esb0JBQUksQ0FBQyxPQUFLLGFBQUwsQ0FBbUIsY0FBbkIsQ0FBa0MsdUJBQWxDLENBQUwsRUFBaUU7QUFDN0QsMkJBQUssYUFBTCxDQUFtQixHQUFuQixDQUF1Qix1QkFBdkIsRUFBZ0QsK0VBQWhEO0FBQ0g7O0FBRUQ7QUFDQSx1QkFBSyxJQUFMLENBQVUsTUFBVixDQUFpQixrQkFBakI7O0FBRUE7QUFDQSx1QkFBSyxXQUFMLEdBQW1CLEtBQUssU0FBTCxDQUFlLE9BQUssS0FBcEIsRUFBMkIsUUFBM0IsQ0FBbkI7QUFDQSx1QkFBTyxVQUFVLE9BQVYsQ0FBa0IsR0FBbEIsQ0FBc0IsRUFBRSxHQUFGLENBQU0sT0FBSyxXQUFMLENBQWlCLFFBQXZCLEVBQWlDLFVBQUMsV0FBRCxFQUFjLENBQWQsRUFBb0I7QUFDOUUsd0JBQUksWUFBWSxVQUFaLENBQXVCLE9BQXZCLEdBQWlDLE9BQUssV0FBMUMsRUFBdUQsT0FBSyxXQUFMLEdBQW1CLFlBQVksVUFBWixDQUF1QixPQUExQzs7QUFFdkQsMkJBQU8sT0FBSyxnQkFBTCxDQUFzQiwwQkFBdUIsSUFBSSxDQUEzQiwyQ0FBZ0UsSUFBSSxDQUFwRSxnQkFBdEIsRUFDRixJQURFLENBQ0csaUJBQVM7QUFDWCw0QkFBTSxZQUFZLE1BQU0sQ0FBTixDQUFsQjtBQUNBLDRCQUFNLHlCQUF5QixNQUFNLENBQU4sQ0FBL0I7O0FBRUE7QUFDQSwrQkFBSyxPQUFMLENBQWEsQ0FBYixJQUFrQixJQUFJLEtBQUosQ0FBVSxNQUFWLEVBQWdCLFdBQWhCLEVBQTZCLFNBQTdCLEVBQXdDLHNCQUF4QyxDQUFsQjtBQUNILHFCQVBFLENBQVA7QUFRSCxpQkFYNEIsQ0FBdEIsQ0FBUDtBQVlILGFBekVFLEVBMEVGLElBMUVFLENBMEVHO0FBQUEsdUJBQU0sT0FBSyxlQUFMLEVBQU47QUFBQSxhQTFFSCxFQTJFRixJQTNFRSxDQTJFRztBQUFBLHVCQUFNLE1BQU47QUFBQSxhQTNFSCxDQUFQO0FBNEVIOztBQUVEOzs7Ozs7Ozs7eUNBTWlCLEssRUFBTztBQUFBOztBQUNwQixtQkFBTyxVQUFVLE9BQVYsQ0FBa0IsR0FBbEIsQ0FBc0IsRUFBRSxHQUFGLENBQU0sS0FBTixFQUFhO0FBQUEsdUJBQVEsT0FBSyxJQUFMLENBQVUsSUFBVixDQUFlLElBQWYsQ0FBUjtBQUFBLGFBQWIsQ0FBdEIsRUFDRixJQURFLENBQ0c7QUFBQSx1QkFBUyxVQUFVLE9BQVYsQ0FBa0IsR0FBbEIsQ0FBc0IsRUFBRSxHQUFGLENBQU0sS0FBTixFQUFhO0FBQUEsMkJBQVEsUUFBUSxLQUFLLEtBQUwsQ0FBVyxRQUFYLENBQWhCO0FBQUEsaUJBQWIsQ0FBdEIsQ0FBVDtBQUFBLGFBREgsRUFFRixJQUZFLENBRUc7QUFBQSx1QkFBUyxVQUFVLE9BQVYsQ0FBa0IsR0FBbEIsQ0FBc0IsRUFBRSxHQUFGLENBQU0sS0FBTixFQUFhO0FBQUEsMkJBQVEsUUFBUSxVQUFVLFVBQVYsQ0FBcUIsSUFBckIsQ0FBaEI7QUFBQSxpQkFBYixDQUF0QixDQUFUO0FBQUEsYUFGSCxDQUFQO0FBR0g7O0FBRUQ7Ozs7Ozs7OzBDQUtrQjtBQUFBOztBQUNkO0FBQ0EsZ0JBQU0sZ0JBQWdCLEtBQUssU0FBTCxDQUFlLEtBQUssS0FBcEIsRUFBMkIsV0FBM0IsQ0FBdEI7QUFDQSxnQkFBTSxtQkFBbUIsaUJBQWlCLEtBQUssU0FBTCxDQUFlLGFBQWYsRUFBOEIsY0FBOUIsQ0FBMUM7QUFDQSxnQkFBTSxjQUFjLG9CQUFvQixpQkFBaUIsVUFBakIsQ0FBNEIsU0FBaEQsSUFBNkQsQ0FBakY7QUFDQSxpQkFBSyxZQUFMLEdBQW9CLEtBQUssT0FBTCxDQUFhLFdBQWIsQ0FBcEI7O0FBRUE7QUFDQTtBQUNBLGdCQUFNLG1CQUFtQixLQUFLLFNBQUwsQ0FBZSxLQUFLLEtBQXBCLEVBQTJCLGNBQTNCLENBQXpCO0FBQ0EsZ0JBQUksZ0JBQUosRUFBc0I7QUFDbEIsa0JBQUUsT0FBRixDQUFVLGlCQUFpQixRQUEzQixFQUFxQywyQkFBbUI7QUFDcEQsd0JBQUksZ0JBQWdCLFVBQWhCLENBQTJCLGNBQTNCLENBQTBDLGNBQTFDLENBQUosRUFBK0Q7QUFDM0Qsd0NBQWdCLFVBQWhCLEdBQTZCLE9BQUssT0FBTCxDQUFhLGdCQUFnQixVQUFoQixDQUEyQixZQUF4QyxDQUE3QjtBQUNIO0FBQ0osaUJBSkQ7QUFLSDtBQUNKOztBQUVEOzs7Ozs7Ozt3Q0FLZ0I7QUFBQTs7QUFDWjtBQUNBLGdCQUFJLGdCQUFnQixLQUFLLFNBQUwsQ0FBZSxLQUFLLEtBQXBCLEVBQTJCLFdBQTNCLENBQXBCO0FBQ0EsZ0JBQUksQ0FBQyxhQUFMLEVBQW9CO0FBQ2hCLGdDQUFnQixFQUFFLE1BQU0sV0FBUixFQUFxQixZQUFZLEVBQWpDLEVBQXFDLFVBQVUsRUFBL0MsRUFBaEI7QUFDQSxxQkFBSyxhQUFMLENBQW1CLEtBQUssS0FBeEIsRUFBK0IsYUFBL0IsRUFBOEMsU0FBOUM7QUFDSDs7QUFFRCxnQkFBSSxtQkFBbUIsS0FBSyxTQUFMLENBQWUsYUFBZixFQUE4QixjQUE5QixDQUF2QjtBQUNBLGdCQUFJLENBQUMsZ0JBQUwsRUFBdUI7QUFDbkIsbUNBQW1CLEVBQUUsTUFBTSxjQUFSLEVBQXdCLFlBQVksRUFBcEMsRUFBd0MsVUFBVSxFQUFsRCxFQUFuQjtBQUNBLHFCQUFLLFdBQUwsQ0FBaUIsYUFBakIsRUFBZ0MsZ0JBQWhDO0FBQ0g7O0FBRUQsNkJBQWlCLFVBQWpCLENBQTRCLFNBQTVCLEdBQXdDLEtBQUssT0FBTCxDQUFhLE9BQWIsQ0FBcUIsS0FBSyxZQUExQixDQUF4Qzs7QUFFQTtBQUNBLGdCQUFNLG1CQUFtQixLQUFLLFNBQUwsQ0FBZSxLQUFLLEtBQXBCLEVBQTJCLGNBQTNCLENBQXpCO0FBQ0EsZ0JBQUksZ0JBQUosRUFBc0I7QUFDbEIsa0JBQUUsT0FBRixDQUFVLGlCQUFpQixRQUEzQixFQUFxQywyQkFBbUI7QUFDcEQsd0JBQUksZ0JBQWdCLFVBQXBCLEVBQWdDO0FBQzVCLHdDQUFnQixVQUFoQixDQUEyQixZQUEzQixHQUEwQyxPQUFLLE9BQUwsQ0FBYSxPQUFiLENBQXFCLGdCQUFnQixVQUFyQyxDQUExQztBQUNIO0FBQ0osaUJBSkQ7QUFLSDtBQUNKOztBQUVEOzs7Ozs7Ozs7OytDQU91QixNLEVBQVEsSSxFQUFNO0FBQ2pDLGdCQUFJLENBQUMsSUFBTCxFQUFXLE9BQU8sUUFBUSxPQUFSLEdBQWtCLE1BQWxCLEdBQTJCLFlBQWxDOztBQUVYLGdCQUFJLFNBQVMsUUFBVCxJQUFxQixTQUFTLFlBQWxDLEVBQWdELE9BQU8sTUFBUDtBQUNoRCxnQkFBSSxRQUFRLE9BQVIsSUFBbUIsU0FBUyxNQUFoQyxFQUF3QyxPQUFPLElBQUksSUFBSixDQUFTLENBQUMsTUFBRCxDQUFULEVBQW1CLEVBQUUsTUFBTSxTQUFTLFNBQWpCLEVBQW5CLENBQVA7QUFDeEMsZ0JBQUksU0FBUyxRQUFiLEVBQXVCLE9BQU8sT0FBTyxRQUFQLENBQWdCLFFBQWhCLENBQVA7QUFDdkIsZ0JBQUksU0FBUyxjQUFiLEVBQTZCLE9BQU8sT0FBTyxRQUFQLENBQWdCLE1BQWhCLENBQVA7QUFDN0IsZ0JBQUksU0FBUyxZQUFiLEVBQTJCLE9BQU8sSUFBSSxVQUFKLENBQWUsTUFBZixDQUFQO0FBQzNCLGdCQUFJLFNBQVMsYUFBYixFQUE0QixPQUFPLElBQUksVUFBSixDQUFlLE1BQWYsRUFBdUIsTUFBOUI7O0FBRTVCLGtCQUFNLElBQUksS0FBSixtQkFBMEIsSUFBMUIsc0JBQU47QUFDSDs7QUFFRDs7Ozs7Ozs7OzttREFPMkIsSyxFQUFPLE0sRUFBUTtBQUN0QyxtQkFBTyxVQUFVLE9BQVYsQ0FBa0IsT0FBbEIsR0FDRixJQURFLENBQ0csWUFBTTtBQUNSLG9CQUFJLE9BQU8sUUFBUCxDQUFnQixLQUFoQixDQUFKLEVBQTRCLE9BQU8sS0FBUDs7QUFFNUIsb0JBQUksUUFBUSxPQUFSLElBQW1CLGlCQUFpQixJQUF4QyxFQUE4QztBQUMxQywyQkFBTyxJQUFJLFVBQVUsT0FBZCxDQUFzQixtQkFBVztBQUNwQyw0QkFBTSxhQUFhLElBQUksVUFBSixFQUFuQjtBQUNBLG1DQUFXLE1BQVgsR0FBb0IsaUJBQVM7QUFDekIsb0NBQVEsT0FBTyxJQUFQLENBQVksTUFBTSxNQUFOLENBQWEsTUFBekIsQ0FBUjtBQUNILHlCQUZEO0FBR0EsbUNBQVcsaUJBQVgsQ0FBNkIsS0FBN0I7QUFDSCxxQkFOTSxDQUFQO0FBT0g7O0FBRUQsb0JBQUksT0FBTyxLQUFQLEtBQWlCLFFBQWpCLElBQTZCLE1BQWpDLEVBQXlDLE9BQU8sT0FBTyxJQUFQLENBQVksS0FBWixFQUFtQixRQUFuQixDQUFQO0FBQ3pDLG9CQUFJLE9BQU8sS0FBUCxLQUFpQixRQUFqQixJQUE2QixDQUFDLE1BQWxDLEVBQTBDLE9BQU8sT0FBTyxJQUFQLENBQVksS0FBWixFQUFtQixNQUFuQixDQUFQO0FBQzFDLG9CQUFJLGlCQUFpQixVQUFqQixJQUErQixpQkFBaUIsV0FBcEQsRUFBaUUsT0FBTyxPQUFPLElBQVAsQ0FBWSxLQUFaLENBQVA7O0FBRWpFLHNCQUFNLElBQUksS0FBSix1QkFBTjtBQUNILGFBbkJFLENBQVA7QUFvQkg7Ozs7QUE1d0JEOzs7Ozt5Q0FLd0I7QUFDcEIsbUJBQU8sU0FBUyxhQUFULENBQXVCLEtBQXZCLENBQVA7QUFDSDs7QUFFRDs7Ozs7Ozs7OztzQ0FPcUIsSSxFQUFNLEksRUFBTTtBQUM3QixtQkFBTyxJQUFJLFFBQUosR0FBZSxVQUFmLENBQTBCLElBQTFCLEVBQWdDLElBQWhDLENBQVA7QUFDSDs7QUFFRDs7Ozs7Ozs7OztzQ0FPcUIsSSxFQUFNLEksRUFBTTtBQUM3QixnQkFBSSxRQUFRLE9BQVosRUFBcUIsTUFBTSxJQUFJLEtBQUosQ0FBVSx3REFBVixDQUFOO0FBQ3JCLG1CQUFPLElBQUksVUFBVSxPQUFkLENBQXNCLFVBQUMsT0FBRCxFQUFVLE1BQVYsRUFBcUI7QUFDOUMsbUJBQUcsUUFBSCxDQUFZLElBQVosRUFBa0IsVUFBQyxHQUFELEVBQU0sSUFBTixFQUFlO0FBQzdCLHdCQUFJLEdBQUosRUFBUyxPQUFPLE9BQU8sR0FBUCxDQUFQO0FBQ1QsNEJBQVEsSUFBUjtBQUNILGlCQUhEO0FBSUgsYUFMTSxFQUtKLElBTEksQ0FLQztBQUFBLHVCQUFRLFNBQVMsYUFBVCxDQUF1QixJQUF2QixFQUE2QixJQUE3QixDQUFSO0FBQUEsYUFMRCxDQUFQO0FBTUg7Ozs7OztBQTR1Qkw7Ozs7Ozs7QUFLQSxTQUFTLFNBQVQsR0FBcUIsbUVBQXJCOztBQUVBLE9BQU8sT0FBUCxHQUFpQixRQUFqQjs7QUFFQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDOTBCQTs7Ozs7O0FBRUEsSUFBTSxZQUFZLFFBQVEsYUFBUixDQUFsQjtBQUNBLElBQU0sV0FBVyxRQUFRLFlBQVIsQ0FBakI7QUFDQSxJQUFNLGVBQWUsUUFBUSxnQkFBUixDQUFyQjtBQUNBLElBQU0sZ0JBQWdCLFFBQVEsaUJBQVIsQ0FBdEI7QUFDQSxJQUFNLFdBQVcsUUFBUSxZQUFSLENBQWpCOztBQUVBOzs7OztJQUlNLFk7Ozs7Ozs7O0FBQ0Y7Ozs7O3FDQUtvQixJLEVBQU07QUFDdEIsbUJBQU8sY0FBYyxZQUFkLENBQTJCLElBQTNCLENBQVA7QUFDSDs7QUFFRDs7Ozs7Ozt5Q0FJd0I7QUFDcEIsbUJBQU8sU0FBUyxjQUFULEVBQVA7QUFDSDs7QUFFRDs7Ozs7Ozs7OztzQ0FPcUIsSSxFQUFNLEksRUFBTTtBQUM3QixtQkFBTyxTQUFTLGFBQVQsQ0FBdUIsSUFBdkIsRUFBNkIsSUFBN0IsQ0FBUDtBQUNIOztBQUVEOzs7Ozs7Ozs7O3NDQU9xQixJLEVBQU0sSSxFQUFNO0FBQzdCLG1CQUFPLFNBQVMsYUFBVCxDQUF1QixJQUF2QixFQUE2QixJQUE3QixDQUFQO0FBQ0g7O0FBRUQ7Ozs7Ozs7O3FDQUtvQixNLEVBQVE7QUFDeEIsbUJBQU8sY0FBYyxZQUFkLENBQTJCLE1BQTNCLENBQVA7QUFDSDs7QUFFRDs7Ozs7Ozs0QkFJcUI7QUFDakIsbUJBQU8sVUFBVSxPQUFqQjtBQUNILFM7MEJBQ2tCLE8sRUFBUztBQUN4QixzQkFBVSxPQUFWLEdBQW9CLE9BQXBCO0FBQ0g7Ozs7OztBQUdMOzs7Ozs7QUFJQSxhQUFhLFNBQWIsR0FBeUIsU0FBUyxTQUFsQzs7QUFFQTs7OztBQUlBLGFBQWEsWUFBYixHQUE0QixZQUE1Qjs7QUFFQTs7OztBQUlBLGFBQWEsUUFBYixHQUF3QixRQUF4Qjs7QUFFQSxPQUFPLE9BQVAsR0FBaUIsWUFBakI7OztBQzNGQTs7Ozs7O0FBRUEsSUFBTSxJQUFJLFFBQVEsUUFBUixDQUFWOztBQUVBLElBQU0saUZBQU47O0FBRUE7Ozs7O0lBSU0sVTs7Ozs7Ozs7QUFDRjs7Ozs7OEJBS00sSSxFQUFNO0FBQ1IsaUJBQUssRUFBTCxHQUFVLENBQVY7QUFDQSxnQkFBTSxNQUFNLEtBQUssTUFBTCxDQUFZLElBQVosRUFBa0IsRUFBbEIsQ0FBWjtBQUNBLGdCQUFJLFFBQVEsRUFBWixFQUFnQjtBQUNoQixtQkFBTyxrQkFBa0IsR0FBekI7QUFDSDs7QUFFRDs7Ozs7Ozs7OzsrQkFPTyxJLEVBQU0sRyxFQUFLO0FBQUE7O0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFJLEtBQUssRUFBTCxLQUFZLE9BQVosS0FBd0IsQ0FBNUIsRUFBK0I7QUFDM0IscUJBQUssRUFBTCxHQUFVLElBQUksQ0FBSixDQUFWO0FBQ0g7O0FBRUQ7QUFDQSxnQkFBSSxRQUFRLEVBQUUsVUFBRixDQUFhLEtBQUssS0FBbEIsQ0FBWixFQUFzQyxPQUFPLEtBQUssS0FBTCxFQUFQOztBQUV0QyxnQkFBSSxFQUFFLFFBQUYsQ0FBVyxJQUFYLENBQUosRUFBc0I7QUFDbEI7QUFDQSxvQkFBSSxDQUFDLEtBQUssSUFBVixFQUFnQixNQUFNLElBQUksS0FBSixtQ0FBMEMsS0FBSyxTQUFMLENBQWUsSUFBZixDQUExQyxDQUFOOztBQUVoQjtBQUNBLDZCQUFXLEtBQUssSUFBaEI7O0FBRUE7QUFDQSxrQkFBRSxNQUFGLENBQVMsS0FBSyxVQUFkLEVBQTBCLFVBQUMsS0FBRCxFQUFRLElBQVIsRUFBaUI7QUFDdkMsaUNBQVcsSUFBWCxXQUFvQixNQUFLLGFBQUwsQ0FBbUIsS0FBbkIsRUFBMEIsSUFBMUIsQ0FBcEI7QUFDSCxpQkFGRDs7QUFJQSxvQkFBSSxFQUFFLE9BQUYsQ0FBVSxLQUFLLFFBQWYsQ0FBSixFQUE4QjtBQUMxQjtBQUNBLDJCQUFPLElBQVA7QUFDSCxpQkFIRCxNQUdPO0FBQ0gsMkJBQU8sR0FBUDs7QUFFQTtBQUNBLHNCQUFFLE9BQUYsQ0FBVSxLQUFLLFFBQWYsRUFBeUIsaUJBQVM7QUFDOUI7QUFDQSw4QkFBTSxNQUFLLE1BQUwsQ0FBWSxLQUFaLEVBQW1CLEdBQW5CLENBQU47QUFDSCxxQkFIRDs7QUFLQTtBQUNBLGtDQUFZLEtBQUssSUFBakI7QUFDSDtBQUNKLGFBM0JELE1BMkJPLElBQUksQ0FBQyxFQUFFLEtBQUYsQ0FBUSxJQUFSLENBQUwsRUFBb0I7QUFDdkI7QUFDQSx1QkFBTyxLQUFLLGFBQUwsQ0FBbUIsSUFBbkIsQ0FBUDtBQUNIOztBQUVEO0FBQ0EsbUJBQU8sR0FBUDtBQUNIOztBQUVEOzs7Ozs7Ozs7O3NDQU9jLEssRUFBTyxXLEVBQWE7QUFDOUIsZ0JBQUksRUFBRSxLQUFGLENBQVEsS0FBUixDQUFKLEVBQW9CLE9BQU8sS0FBUDtBQUNwQixvQkFBUSxNQUFNLFFBQU4sR0FDSCxPQURHLENBQ0ssSUFETCxFQUNXLE9BRFgsRUFDb0I7QUFEcEIsYUFFSCxPQUZHLENBRUssSUFGTCxFQUVXLE1BRlgsRUFHSCxPQUhHLENBR0ssSUFITCxFQUdXLE1BSFgsQ0FBUjs7QUFLQSxnQkFBSSxXQUFKLEVBQWlCO0FBQ2Isd0JBQVEsTUFBTSxPQUFOLENBQWMsSUFBZCxFQUFvQixRQUFwQixDQUFSO0FBQ0g7O0FBRUQsbUJBQU8sS0FBUDtBQUNIOzs7Ozs7QUFHTCxPQUFPLE9BQVAsR0FBaUIsVUFBakI7OztBQ3JHQTs7Ozs7O0FBRUEsSUFBTSxNQUFNLFFBQVEsS0FBUixDQUFaO0FBQ0EsSUFBTSxZQUFZLFFBQVEsYUFBUixDQUFsQjs7QUFFQTtBQUNBLElBQU0scUJBQXFCLE9BQTNCOztBQUVBOzs7OztJQUlNLFM7Ozs7Ozs7O0FBQ0Y7Ozs7O21DQUtXLE8sRUFBUztBQUFBOztBQUNoQixtQkFBTyxJQUFJLFVBQVUsT0FBZCxDQUFzQixVQUFDLE9BQUQsRUFBVSxNQUFWLEVBQXFCO0FBQzlDO0FBQ0Esb0JBQU0sU0FBUyxJQUFJLE1BQUosQ0FBVyxJQUFYLENBQWY7O0FBRUE7QUFDQTtBQUNBLG9CQUFJLGVBQUo7QUFBQSxvQkFBWSxnQkFBWjtBQUNBLG9CQUFNLFFBQVEsRUFBZDs7QUFFQTtBQUNBLHVCQUFPLE9BQVAsR0FBaUIsTUFBakI7O0FBRUE7QUFDQSx1QkFBTyxNQUFQLEdBQWdCLGdCQUFRO0FBQ3BCLHdCQUFJLG1CQUFtQixJQUFuQixDQUF3QixJQUF4QixDQUFKLEVBQW1DO0FBQy9CLDRCQUFJLFdBQVcsUUFBUSxVQUFSLENBQW1CLFdBQW5CLE1BQW9DLFVBQW5ELEVBQStEO0FBQzNELG9DQUFRLFFBQVIsQ0FBaUIsSUFBakIsQ0FBc0IsSUFBdEI7QUFDSDtBQUNKLHFCQUpELE1BSU87QUFDSCxnQ0FBUSxRQUFSLENBQWlCLElBQWpCLENBQXNCLE1BQUssdUJBQUwsQ0FBNkIsSUFBN0IsQ0FBdEI7QUFDSDtBQUNKLGlCQVJEOztBQVVBO0FBQ0E7QUFDQSx1QkFBTyxjQUFQLEdBQXdCLGdCQUFRO0FBQzVCLHdCQUFNLFFBQVEsRUFBRSxNQUFNLEtBQUssSUFBYixFQUFtQixZQUFZLEVBQS9CLEVBQW1DLFVBQVUsRUFBN0MsRUFBZDtBQUNBLHdCQUFJLE9BQUosRUFBYTtBQUNULGdDQUFRLFFBQVIsQ0FBaUIsSUFBakIsQ0FBc0IsS0FBdEI7QUFDSCxxQkFGRCxNQUVPO0FBQ0gsaUNBQVMsS0FBVDtBQUNIOztBQUVELDBCQUFNLElBQU4sQ0FBVyxLQUFYO0FBQ0EsOEJBQVUsS0FBVjtBQUNILGlCQVZEOztBQVlBO0FBQ0EsdUJBQU8sVUFBUCxHQUFvQixnQkFBUTtBQUN4QiwwQkFBTSxHQUFOO0FBQ0EsOEJBQVUsTUFBTSxNQUFNLE1BQU4sR0FBZSxDQUFyQixDQUFWO0FBQ0gsaUJBSEQ7O0FBS0E7QUFDQSx1QkFBTyxXQUFQLEdBQXFCLHFCQUFhO0FBQzlCLDRCQUFRLFVBQVIsQ0FBbUIsVUFBVSxJQUE3QixJQUFxQyxNQUFLLHVCQUFMLENBQTZCLFVBQVUsS0FBdkMsQ0FBckM7QUFDSCxpQkFGRDs7QUFJQTtBQUNBLHVCQUFPLEtBQVAsR0FBZTtBQUFBLDJCQUFNLFFBQVEsTUFBUixDQUFOO0FBQUEsaUJBQWY7O0FBRUE7QUFDQSx1QkFBTyxLQUFQLENBQWEsT0FBYixFQUFzQixLQUF0QjtBQUNILGFBckRNLENBQVA7QUFzREg7O0FBRUQ7Ozs7Ozs7OztnREFNd0IsRyxFQUFLO0FBQ3pCLGdCQUFNLE1BQU0sT0FBTyxHQUFQLENBQVo7QUFDQSxtQkFBTyxJQUFJLFFBQUosT0FBbUIsR0FBbkIsR0FBeUIsR0FBekIsR0FBK0IsR0FBdEM7QUFDSDs7Ozs7O0FBR0wsT0FBTyxPQUFQLEdBQWlCLFNBQWpCOzs7QUN2RkE7O0FBRUE7QUFDQTtBQUNBOztBQUVBLElBQU0sSUFBSSxRQUFRLFFBQVIsQ0FBVjtBQUNBLElBQU0sZ0JBQWdCLDZIQUF0Qjs7QUFFQTs7OztBQUlBLE9BQU8sT0FBUCxHQUFpQjtBQUNiOzs7OztBQUtBLHNCQU5hLDhCQU1NLElBTk4sRUFNWTtBQUNyQixZQUFJLENBQUMsSUFBRCxJQUFTLE9BQU8sSUFBUCxLQUFnQixRQUE3QixFQUF1Qzs7QUFFdkMsZUFBTyxLQUFLLFdBQUwsRUFBUDtBQUNBLFlBQUksTUFBTSxDQUFWO0FBQ0EsYUFBSyxJQUFJLElBQUksQ0FBYixFQUFnQixJQUFJLEtBQUssTUFBekIsRUFBaUMsR0FBakMsRUFBc0M7QUFDbEMsa0JBQU0sTUFBTSxFQUFaO0FBQ0Esa0JBQU0sT0FBTyxLQUFLLENBQUwsRUFBUSxVQUFSLENBQW1CLENBQW5CLElBQXdCLElBQUksVUFBSixDQUFlLENBQWYsQ0FBeEIsR0FBNEMsQ0FBbkQsQ0FBTjtBQUNIOztBQUVELGVBQU8sR0FBUDtBQUNILEtBakJZOzs7QUFtQmI7Ozs7O0FBS0Esc0JBeEJhLDhCQXdCTSxNQXhCTixFQXdCYztBQUN2QixZQUFJLFdBQVcsTUFBZjtBQUNBLFlBQUksT0FBTyxFQUFYO0FBQ0EsWUFBSSxTQUFTLENBQWI7O0FBRUEsZUFBTyxXQUFXLENBQWxCLEVBQXFCO0FBQ2pCLHFCQUFTLENBQUMsV0FBVyxDQUFaLElBQWlCLEVBQTFCO0FBQ0EsbUJBQU8sT0FBTyxZQUFQLENBQW9CLElBQUksVUFBSixDQUFlLENBQWYsSUFBb0IsTUFBeEMsSUFBa0QsSUFBekQ7QUFDQSx1QkFBVyxLQUFLLEtBQUwsQ0FBVyxDQUFDLFdBQVcsTUFBWixJQUFzQixFQUFqQyxDQUFYO0FBQ0g7O0FBRUQsZUFBTyxJQUFQO0FBQ0gsS0FwQ1k7OztBQXNDYjs7Ozs7QUFLQSxlQTNDYSx1QkEyQ0QsT0EzQ0MsRUEyQ1E7QUFDakIsWUFBTSxRQUFRLFFBQVEsS0FBUixDQUFjLGFBQWQsQ0FBZDtBQUNBLFlBQUksQ0FBQyxLQUFMLEVBQVk7QUFDWixZQUFNLE1BQU0sRUFBWjs7QUFFQSxZQUFJLE1BQU0sQ0FBTixDQUFKLEVBQWMsSUFBSSxTQUFKLEdBQWdCLE1BQU0sQ0FBTixFQUFTLE9BQVQsQ0FBaUIsS0FBakIsRUFBd0IsR0FBeEIsQ0FBaEI7QUFDZCxZQUFJLE1BQU0sQ0FBTixLQUFZLE1BQU0sQ0FBTixDQUFoQixFQUEwQjtBQUN0QixnQkFBSSxJQUFKLEdBQVcsT0FBWDtBQUNBLGdCQUFJLG1CQUFKLEdBQTBCLENBQUMsQ0FBQyxNQUFNLENBQU4sQ0FBNUI7QUFDQSxnQkFBSSxlQUFKLEdBQXNCLE1BQU0sQ0FBTixDQUF0QjtBQUNBLGdCQUFJLGlCQUFKLEdBQXdCLEtBQUssa0JBQUwsQ0FBd0IsSUFBSSxlQUE1QixDQUF4QjtBQUNBLGdCQUFJLGdCQUFKLEdBQXVCLENBQUMsQ0FBQyxNQUFNLENBQU4sQ0FBekI7QUFDQSxnQkFBSSxjQUFKLEdBQXFCLFNBQVMsTUFBTSxDQUFOLENBQVQsQ0FBckI7QUFDQSxnQkFBSSxpQkFBSixHQUF3QixDQUFDLENBQUMsTUFBTSxDQUFOLENBQTFCO0FBQ0EsZ0JBQUksYUFBSixHQUFvQixNQUFNLENBQU4sQ0FBcEI7QUFDQSxnQkFBSSxlQUFKLEdBQXNCLEtBQUssa0JBQUwsQ0FBd0IsSUFBSSxhQUE1QixDQUF0QjtBQUNBLGdCQUFJLGNBQUosR0FBcUIsQ0FBQyxDQUFDLE1BQU0sQ0FBTixDQUF2QjtBQUNBLGdCQUFJLFlBQUosR0FBbUIsU0FBUyxNQUFNLENBQU4sQ0FBVCxDQUFuQjtBQUNILFNBWkQsTUFZTyxJQUFJLE1BQU0sQ0FBTixDQUFKLEVBQWM7QUFDakIsZ0JBQUksSUFBSixHQUFXLE1BQVg7QUFDQSxnQkFBSSxjQUFKLEdBQXFCLENBQUMsQ0FBQyxNQUFNLENBQU4sQ0FBdkI7QUFDQSxnQkFBSSxVQUFKLEdBQWlCLE1BQU0sQ0FBTixDQUFqQjtBQUNBLGdCQUFJLFlBQUosR0FBbUIsS0FBSyxrQkFBTCxDQUF3QixJQUFJLFVBQTVCLENBQW5CO0FBQ0EsZ0JBQUksV0FBSixHQUFrQixDQUFDLENBQUMsTUFBTSxDQUFOLENBQXBCO0FBQ0EsZ0JBQUksU0FBSixHQUFnQixTQUFTLE1BQU0sQ0FBTixDQUFULENBQWhCO0FBQ0gsU0FQTSxNQU9BLElBQUksTUFBTSxFQUFOLEtBQWEsTUFBTSxFQUFOLE1BQWMsTUFBTSxFQUFOLENBQS9CLEVBQTBDO0FBQzdDLGdCQUFJLElBQUosR0FBVyxhQUFYO0FBQ0EsZ0JBQUksbUJBQUosR0FBMEIsQ0FBQyxDQUFDLE1BQU0sRUFBTixDQUE1QjtBQUNBLGdCQUFJLGVBQUosR0FBc0IsTUFBTSxFQUFOLENBQXRCO0FBQ0EsZ0JBQUksaUJBQUosR0FBd0IsS0FBSyxrQkFBTCxDQUF3QixJQUFJLGVBQTVCLENBQXhCO0FBQ0EsZ0JBQUksaUJBQUosR0FBd0IsQ0FBQyxDQUFDLE1BQU0sRUFBTixDQUExQjtBQUNBLGdCQUFJLGFBQUosR0FBb0IsTUFBTSxFQUFOLENBQXBCO0FBQ0EsZ0JBQUksZUFBSixHQUFzQixLQUFLLGtCQUFMLENBQXdCLElBQUksYUFBNUIsQ0FBdEI7QUFDSCxTQVJNLE1BUUEsSUFBSSxNQUFNLEVBQU4sQ0FBSixFQUFlO0FBQ2xCLGdCQUFJLElBQUosR0FBVyxRQUFYO0FBQ0EsZ0JBQUksY0FBSixHQUFxQixDQUFDLENBQUMsTUFBTSxFQUFOLENBQXZCO0FBQ0EsZ0JBQUksVUFBSixHQUFpQixNQUFNLEVBQU4sQ0FBakI7QUFDQSxnQkFBSSxZQUFKLEdBQW1CLEtBQUssa0JBQUwsQ0FBd0IsSUFBSSxVQUE1QixDQUFuQjtBQUNILFNBTE0sTUFLQSxJQUFJLE1BQU0sRUFBTixLQUFhLE1BQU0sRUFBTixNQUFjLE1BQU0sRUFBTixDQUEvQixFQUEwQztBQUM3QyxnQkFBSSxJQUFKLEdBQVcsVUFBWDtBQUNBLGdCQUFJLGdCQUFKLEdBQXVCLENBQUMsQ0FBQyxNQUFNLEVBQU4sQ0FBekI7QUFDQSxnQkFBSSxjQUFKLEdBQXFCLFNBQVMsTUFBTSxFQUFOLENBQVQsQ0FBckI7QUFDQSxnQkFBSSxjQUFKLEdBQXFCLENBQUMsQ0FBQyxNQUFNLEVBQU4sQ0FBdkI7QUFDQSxnQkFBSSxZQUFKLEdBQW1CLFNBQVMsTUFBTSxFQUFOLENBQVQsQ0FBbkI7QUFDSCxTQU5NLE1BTUEsSUFBSSxNQUFNLEVBQU4sQ0FBSixFQUFlO0FBQ2xCLGdCQUFJLElBQUosR0FBVyxLQUFYO0FBQ0EsZ0JBQUksV0FBSixHQUFrQixDQUFDLENBQUMsTUFBTSxFQUFOLENBQXBCO0FBQ0EsZ0JBQUksU0FBSixHQUFnQixTQUFTLE1BQU0sRUFBTixDQUFULENBQWhCO0FBQ0g7O0FBRUQsZUFBTyxHQUFQO0FBQ0gsS0E5Rlk7OztBQWdHYjs7Ozs7QUFLQSxhQXJHYSxxQkFxR0gsR0FyR0csRUFxR0U7QUFDWCxZQUFJLFVBQUo7QUFBQSxZQUFPLFVBQVA7QUFDQSxZQUFNLFlBQVksSUFBSSxTQUF0Qjs7QUFFQSxZQUFJLElBQUksSUFBSixLQUFhLE1BQWpCLEVBQXlCO0FBQ3JCLGdCQUFJO0FBQ0EsNEJBQVksSUFBSSxVQURoQjtBQUVBLDhCQUFjLElBQUksWUFGbEI7QUFHQSxnQ0FBZ0IsSUFBSSxjQUhwQjtBQUlBLDJCQUFXLElBQUksU0FKZjtBQUtBLDZCQUFhLElBQUk7QUFMakIsYUFBSjtBQU9ILFNBUkQsTUFRTyxJQUFJLElBQUksSUFBSixLQUFhLE9BQWpCLEVBQTBCO0FBQzdCLGdCQUFJO0FBQ0EsNEJBQVksSUFBSSxlQURoQjtBQUVBLDhCQUFjLElBQUksaUJBRmxCO0FBR0EsZ0NBQWdCLElBQUksbUJBSHBCO0FBSUEsMkJBQVcsSUFBSSxjQUpmO0FBS0EsNkJBQWEsSUFBSTtBQUxqQixhQUFKO0FBT0EsZ0JBQUk7QUFDQSw0QkFBWSxJQUFJLGFBRGhCO0FBRUEsOEJBQWMsSUFBSSxlQUZsQjtBQUdBLGdDQUFnQixJQUFJLGlCQUhwQjtBQUlBLDJCQUFXLElBQUksWUFKZjtBQUtBLDZCQUFhLElBQUk7QUFMakIsYUFBSjtBQU9ILFNBZk0sTUFlQSxJQUFJLElBQUksSUFBSixLQUFhLFFBQWpCLEVBQTJCO0FBQzlCLGdCQUFJLElBQUk7QUFDSiw0QkFBWSxJQUFJLFVBRFo7QUFFSiw4QkFBYyxJQUFJLFlBRmQ7QUFHSixnQ0FBZ0IsSUFBSTtBQUhoQixhQUFSO0FBS0gsU0FOTSxNQU1BLElBQUksSUFBSSxJQUFKLEtBQWEsS0FBakIsRUFBd0I7QUFDM0IsZ0JBQUksSUFBSTtBQUNKLDJCQUFXLElBQUksU0FEWDtBQUVKLDZCQUFhLElBQUk7QUFGYixhQUFSO0FBSUgsU0FMTSxNQUtBLElBQUksSUFBSSxJQUFKLEtBQWEsYUFBakIsRUFBZ0M7QUFDbkMsZ0JBQUk7QUFDQSw0QkFBWSxJQUFJLGVBRGhCO0FBRUEsOEJBQWMsSUFBSSxpQkFGbEI7QUFHQSxnQ0FBZ0IsSUFBSTtBQUhwQixhQUFKO0FBS0EsZ0JBQUk7QUFDQSw0QkFBWSxJQUFJLGFBRGhCO0FBRUEsOEJBQWMsSUFBSSxlQUZsQjtBQUdBLGdDQUFnQixJQUFJO0FBSHBCLGFBQUo7QUFLSCxTQVhNLE1BV0EsSUFBSSxJQUFJLElBQUosS0FBYSxVQUFqQixFQUE2QjtBQUNoQyxnQkFBSTtBQUNBLDJCQUFXLElBQUksY0FEZjtBQUVBLDZCQUFhLElBQUk7QUFGakIsYUFBSjtBQUlBLGdCQUFJO0FBQ0EsMkJBQVcsSUFBSSxZQURmO0FBRUEsNkJBQWEsSUFBSTtBQUZqQixhQUFKO0FBSUg7O0FBRUQsWUFBSSxVQUFVLEVBQWQ7QUFDQSxZQUFJLFNBQUosRUFBZSxVQUFhLE9BQWIsU0FBd0IsVUFBVSxPQUFWLENBQWtCLElBQWxCLEVBQXdCLElBQXhCLENBQXhCO0FBQ2YsWUFBSSxFQUFFLGNBQU4sRUFBc0IsVUFBYSxPQUFiO0FBQ3RCLFlBQUksRUFBRSxVQUFOLEVBQWtCLFVBQVUsVUFBVSxFQUFFLFVBQXRCLENBQWxCLEtBQ0ssSUFBSSxFQUFFLFlBQU4sRUFBb0IsVUFBVSxVQUFVLEtBQUssa0JBQUwsQ0FBd0IsRUFBRSxZQUExQixDQUFwQjtBQUN6QixZQUFJLEVBQUUsV0FBTixFQUFtQixVQUFhLE9BQWI7QUFDbkIsWUFBSSxFQUFFLFNBQU4sRUFBaUIsVUFBVSxVQUFVLEVBQUUsU0FBdEI7O0FBRWpCLFlBQUksQ0FBSixFQUFPO0FBQ0gsc0JBQWEsT0FBYjtBQUNBLGdCQUFJLEVBQUUsY0FBTixFQUFzQixVQUFhLE9BQWI7QUFDdEIsZ0JBQUksRUFBRSxVQUFOLEVBQWtCLFVBQVUsVUFBVSxFQUFFLFVBQXRCLENBQWxCLEtBQ0ssSUFBSSxFQUFFLFlBQU4sRUFBb0IsVUFBVSxVQUFVLEtBQUssa0JBQUwsQ0FBd0IsRUFBRSxZQUExQixDQUFwQjtBQUN6QixnQkFBSSxFQUFFLFdBQU4sRUFBbUIsVUFBYSxPQUFiO0FBQ25CLGdCQUFJLEVBQUUsU0FBTixFQUFpQixVQUFVLFVBQVUsRUFBRSxTQUF0QjtBQUNwQjs7QUFFRCxlQUFPLE9BQVA7QUFDSDtBQW5MWSxDQUFqQjs7OztBQ2JBOztBQUVBOztBQUNBLE9BQU8sT0FBUCxHQUFpQjtBQUFBLFNBQU0sT0FBTyxJQUFQLENBQVkscytPQUFaLEVBQW8vTyxRQUFwL08sQ0FBTjtBQUFBLENBQWpCOzs7OztBQ0hBOztBQUVBOzs7OztBQUlBLE9BQU8sT0FBUCxHQUFpQixDQUNiLFFBRGEsRUFFYixRQUZhLEVBR2IsUUFIYSxFQUliLFFBSmEsRUFLYixRQUxhLEVBTWIsUUFOYSxFQU9iLFFBUGEsRUFRYixRQVJhLEVBU2IsUUFUYSxFQVViLFFBVmEsRUFXYixRQVhhLEVBWWIsUUFaYSxFQWFiLFFBYmEsRUFjYixRQWRhLEVBZWIsUUFmYSxFQWdCYixRQWhCYSxFQWlCYixRQWpCYSxFQWtCYixRQWxCYSxFQW1CYixRQW5CYSxFQW9CYixRQXBCYSxFQXFCYixRQXJCYSxFQXNCYixRQXRCYSxFQXVCYixRQXZCYSxFQXdCYixRQXhCYSxFQXlCYixRQXpCYSxFQTBCYixRQTFCYSxFQTJCYixRQTNCYSxFQTRCYixRQTVCYSxFQTZCYixRQTdCYSxFQThCYixRQTlCYSxFQStCYixRQS9CYSxFQWdDYixRQWhDYSxFQWlDYixRQWpDYSxFQWtDYixRQWxDYSxFQW1DYixRQW5DYSxFQW9DYixRQXBDYSxFQXFDYixRQXJDYSxFQXNDYixRQXRDYSxFQXVDYixRQXZDYSxFQXdDYixRQXhDYSxFQXlDYixRQXpDYSxFQTBDYixRQTFDYSxFQTJDYixRQTNDYSxFQTRDYixRQTVDYSxFQTZDYixRQTdDYSxFQThDYixRQTlDYSxFQStDYixRQS9DYSxFQWdEYixRQWhEYSxFQWlEYixRQWpEYSxFQWtEYixRQWxEYSxFQW1EYixRQW5EYSxFQW9EYixRQXBEYSxFQXFEYixRQXJEYSxFQXNEYixRQXREYSxFQXVEYixRQXZEYSxFQXdEYixRQXhEYSxFQXlEYixRQXpEYSxFQTBEYixRQTFEYSxFQTJEYixRQTNEYSxFQTREYixRQTVEYSxFQTZEYixRQTdEYSxFQThEYixRQTlEYSxFQStEYixRQS9EYSxFQWdFYixRQWhFYSxFQWlFYixtQkFqRWEsRUFrRWIsbUJBbEVhLENBQWpCOzs7QUNOQTs7QUFFQTs7QUFDQSxJQUFNLFdBQVcsSUFBSSxJQUFKLENBQVMsSUFBVCxFQUFlLENBQWYsRUFBa0IsQ0FBbEIsQ0FBakI7O0FBRUE7QUFDQSxJQUFNLG9CQUFvQixJQUFJLElBQUosQ0FBUyxJQUFULEVBQWUsQ0FBZixFQUFrQixFQUFsQixDQUExQjs7QUFFQTtBQUNBLElBQU0sb0JBQW9CLE9BQU8sRUFBUCxHQUFZLEVBQVosR0FBaUIsRUFBM0M7O0FBRUE7Ozs7QUFJQSxPQUFPLE9BQVAsR0FBaUI7QUFDYjs7Ozs7QUFLQSxvQkFOYSx3QkFNQSxJQU5BLEVBTU07QUFDZjtBQUNBLG9CQUFNLFdBQVcsSUFBSSxJQUFKLENBQVMsS0FBSyxPQUFMLEVBQVQsQ0FBakI7QUFDQSx5QkFBUyxRQUFULENBQWtCLENBQWxCLEVBQXFCLENBQXJCLEVBQXdCLENBQXhCLEVBQTJCLENBQTNCOztBQUVBO0FBQ0E7QUFDQSxvQkFBSSxTQUFTLEtBQUssS0FBTCxDQUFXLENBQUMsV0FBVyxRQUFaLElBQXdCLGlCQUFuQyxDQUFiOztBQUVBO0FBQ0EsMEJBQVUsQ0FBQyxPQUFPLFFBQVIsSUFBb0IsaUJBQTlCOztBQUVBO0FBQ0Esb0JBQUksT0FBTyxpQkFBWCxFQUE4QixVQUFVLENBQVY7O0FBRTlCLHVCQUFPLE1BQVA7QUFDSCxTQXRCWTs7O0FBd0JiOzs7OztBQUtBLG9CQTdCYSx3QkE2QkEsTUE3QkEsRUE2QlE7QUFDakI7QUFDQSxvQkFBSSxTQUFTLEtBQUssWUFBTCxDQUFrQixpQkFBbEIsQ0FBYixFQUFtRDs7QUFFbkQ7QUFDQSxvQkFBTSxXQUFXLEtBQUssS0FBTCxDQUFXLE1BQVgsQ0FBakI7QUFDQSxvQkFBTSxzQkFBc0IsS0FBSyxLQUFMLENBQVcsQ0FBQyxTQUFTLFFBQVYsSUFBc0IsaUJBQWpDLENBQTVCOztBQUVBO0FBQ0Esb0JBQU0sT0FBTyxJQUFJLElBQUosQ0FBUyxTQUFTLE9BQVQsS0FBcUIsbUJBQTlCLENBQWI7O0FBRUE7QUFDQSxxQkFBSyxPQUFMLENBQWEsS0FBSyxPQUFMLEtBQWlCLFFBQTlCOztBQUVBLHVCQUFPLElBQVA7QUFDSDtBQTVDWSxDQUFqQjs7O0FDZkE7O0FBRUEsSUFBTSxRQUFRLFFBQVEsT0FBUixDQUFkOztBQUVBOzs7O0FBSUEsT0FBTyxPQUFQLEdBQWlCO0FBQ2I7Ozs7QUFJQSxRQUFJLE9BQUosR0FBYztBQUNWLGVBQU8sTUFBTSxRQUFOLENBQWUsT0FBdEI7QUFDSCxLQVBZOztBQVNiLFFBQUksT0FBSixDQUFZLE9BQVosRUFBcUI7QUFDakIsY0FBTSxRQUFOLENBQWUsT0FBZixHQUF5QixPQUF6QjtBQUNIO0FBWFksQ0FBakI7OztBQ1JBOztBQUVBLElBQU0sSUFBSSxRQUFRLFFBQVIsQ0FBVjs7QUFFQTs7Ozs7O0FBTUEsT0FBTyxPQUFQLEdBQWlCLG1CQUFXO0FBQ3hCLFFBQUksT0FBTyxPQUFQLEtBQW1CLFFBQXZCLEVBQWlDO0FBQzdCLGtCQUFVLElBQUksTUFBSixDQUFXLEVBQUUsWUFBRixDQUFlLE9BQWYsQ0FBWCxFQUFvQyxLQUFwQyxDQUFWO0FBQ0g7O0FBRUQsWUFBUSxTQUFSLEdBQW9CLENBQXBCOztBQUVBLFdBQU8sT0FBUDtBQUNILENBUkQ7OztBQ1ZBOztBQUVBLElBQU0sSUFBSSxRQUFRLFFBQVIsQ0FBVjs7QUFFQTs7OztBQUlBLE9BQU8sT0FBUCxHQUFpQjtBQUNiOzs7Ozs7QUFNQSxlQVBhLHVCQU9ELElBUEMsRUFPSyxLQVBMLEVBT1k7QUFDckIsWUFBSSxDQUFDLEtBQUssUUFBVixFQUFvQixLQUFLLFFBQUwsR0FBZ0IsRUFBaEI7QUFDcEIsYUFBSyxRQUFMLENBQWMsSUFBZCxDQUFtQixLQUFuQjtBQUNILEtBVlk7OztBQVliOzs7Ozs7QUFNQSx5QkFsQmEsaUNBa0JTLElBbEJULEVBa0JlLElBbEJmLEVBa0JxQjtBQUM5QixZQUFJLFFBQVEsS0FBSyxTQUFMLENBQWUsSUFBZixFQUFxQixJQUFyQixDQUFaO0FBQ0EsWUFBSSxDQUFDLEtBQUwsRUFBWTtBQUNSLG9CQUFRLEVBQUUsVUFBRixFQUFRLFlBQVksRUFBcEIsRUFBd0IsVUFBVSxFQUFsQyxFQUFSO0FBQ0EsaUJBQUssV0FBTCxDQUFpQixJQUFqQixFQUF1QixLQUF2QjtBQUNIOztBQUVELGVBQU8sS0FBUDtBQUNILEtBMUJZOzs7QUE0QmI7Ozs7OztBQU1BLGFBbENhLHFCQWtDSCxJQWxDRyxFQWtDRyxJQWxDSCxFQWtDUztBQUNsQixlQUFPLEVBQUUsSUFBRixDQUFPLEtBQUssUUFBWixFQUFzQixFQUFFLFVBQUYsRUFBdEIsQ0FBUDtBQUNILEtBcENZOzs7QUFzQ2I7Ozs7Ozs7QUFPQSxxQkE3Q2EsNkJBNkNLLElBN0NMLEVBNkNXLElBN0NYLEVBNkNpQixTQTdDakIsRUE2QzRCO0FBQ3JDLFlBQU0sUUFBUSxLQUFLLFNBQUwsQ0FBZSxJQUFmLEVBQXFCLElBQXJCLENBQWQ7QUFDQSxZQUFJLEtBQUosRUFBVyxPQUFPLE1BQU0sVUFBTixJQUFvQixNQUFNLFVBQU4sQ0FBaUIsU0FBakIsQ0FBM0I7QUFDZCxLQWhEWTs7O0FBa0RiOzs7Ozs7QUFNQSxZQXhEYSxvQkF3REosSUF4REksRUF3REUsSUF4REYsRUF3RFE7QUFDakIsZUFBTyxFQUFFLElBQUYsQ0FBTyxLQUFLLFFBQVosRUFBc0IsRUFBRSxVQUFGLEVBQXRCLENBQVA7QUFDSCxLQTFEWTs7O0FBNERiOzs7Ozs7O0FBT0EsZUFuRWEsdUJBbUVELElBbkVDLEVBbUVLLEtBbkVMLEVBbUVZLEtBbkVaLEVBbUVtQjtBQUM1QixZQUFJLENBQUMsS0FBSyxRQUFWLEVBQW9CLEtBQUssUUFBTCxHQUFnQixFQUFoQjtBQUNwQixZQUFNLFFBQVEsS0FBSyxRQUFMLENBQWMsT0FBZCxDQUFzQixLQUF0QixDQUFkO0FBQ0EsYUFBSyxRQUFMLENBQWMsTUFBZCxDQUFxQixRQUFRLENBQTdCLEVBQWdDLENBQWhDLEVBQW1DLEtBQW5DO0FBQ0gsS0F2RVk7OztBQXlFYjs7Ozs7OztBQU9BLGdCQWhGYSx3QkFnRkEsSUFoRkEsRUFnRk0sS0FoRk4sRUFnRmEsTUFoRmIsRUFnRnFCO0FBQzlCLFlBQUksQ0FBQyxLQUFLLFFBQVYsRUFBb0IsS0FBSyxRQUFMLEdBQWdCLEVBQWhCO0FBQ3BCLFlBQU0sUUFBUSxLQUFLLFFBQUwsQ0FBYyxPQUFkLENBQXNCLE1BQXRCLENBQWQ7QUFDQSxhQUFLLFFBQUwsQ0FBYyxNQUFkLENBQXFCLEtBQXJCLEVBQTRCLENBQTVCLEVBQStCLEtBQS9CO0FBQ0gsS0FwRlk7OztBQXNGYjs7Ozs7OztBQU9BLGlCQTdGYSx5QkE2RkMsSUE3RkQsRUE2Rk8sS0E3RlAsRUE2RmMsU0E3RmQsRUE2RnlCO0FBQ2xDLFlBQU0sYUFBYSxVQUFVLE9BQVYsQ0FBa0IsTUFBTSxJQUF4QixDQUFuQjtBQUNBLFlBQUksS0FBSyxRQUFMLElBQWlCLGNBQWMsQ0FBbkMsRUFBc0M7QUFDbEMsaUJBQUssSUFBSSxJQUFJLGFBQWEsQ0FBMUIsRUFBNkIsSUFBSSxVQUFVLE1BQTNDLEVBQW1ELEdBQW5ELEVBQXdEO0FBQ3BELG9CQUFNLFVBQVUsS0FBSyxTQUFMLENBQWUsSUFBZixFQUFxQixVQUFVLENBQVYsQ0FBckIsQ0FBaEI7QUFDQSxvQkFBSSxPQUFKLEVBQWE7QUFDVCx5QkFBSyxZQUFMLENBQWtCLElBQWxCLEVBQXdCLEtBQXhCLEVBQStCLE9BQS9CO0FBQ0E7QUFDSDtBQUNKO0FBQ0o7O0FBRUQsYUFBSyxXQUFMLENBQWlCLElBQWpCLEVBQXVCLEtBQXZCO0FBQ0gsS0ExR1k7OztBQTRHYjs7Ozs7QUFLQSxXQWpIYSxtQkFpSEwsSUFqSEssRUFpSEM7QUFDVixlQUFPLEVBQUUsT0FBRixDQUFVLEtBQUssUUFBZixLQUE0QixFQUFFLE9BQUYsQ0FBVSxLQUFLLFVBQWYsQ0FBbkM7QUFDSCxLQW5IWTs7O0FBcUhiOzs7Ozs7QUFNQSxlQTNIYSx1QkEySEQsSUEzSEMsRUEySEssS0EzSEwsRUEySFk7QUFDckIsWUFBSSxDQUFDLEtBQUssUUFBVixFQUFvQjtBQUNwQixZQUFJLE9BQU8sS0FBUCxLQUFpQixRQUFyQixFQUErQjtBQUMzQixjQUFFLE1BQUYsQ0FBUyxLQUFLLFFBQWQsRUFBd0IsRUFBRSxNQUFNLEtBQVIsRUFBeEI7QUFDSCxTQUZELE1BRU87QUFDSCxnQkFBTSxRQUFRLEtBQUssUUFBTCxDQUFjLE9BQWQsQ0FBc0IsS0FBdEIsQ0FBZDtBQUNBLGdCQUFJLFNBQVMsQ0FBYixFQUFnQixLQUFLLFFBQUwsQ0FBYyxNQUFkLENBQXFCLEtBQXJCLEVBQTRCLENBQTVCO0FBQ25CO0FBQ0osS0FuSVk7OztBQXFJYjs7Ozs7O0FBTUEsaUJBM0lhLHlCQTJJQyxJQTNJRCxFQTJJTyxVQTNJUCxFQTJJbUI7QUFDNUIsVUFBRSxNQUFGLENBQVMsVUFBVCxFQUFxQixVQUFDLEtBQUQsRUFBUSxTQUFSLEVBQXNCO0FBQ3ZDLGdCQUFJLEVBQUUsS0FBRixDQUFRLEtBQVIsQ0FBSixFQUFvQjtBQUNoQixvQkFBSSxLQUFLLFVBQVQsRUFBcUIsT0FBTyxLQUFLLFVBQUwsQ0FBZ0IsU0FBaEIsQ0FBUDtBQUN4QixhQUZELE1BRU87QUFDSCxvQkFBSSxDQUFDLEtBQUssVUFBVixFQUFzQixLQUFLLFVBQUwsR0FBa0IsRUFBbEI7QUFDdEIscUJBQUssVUFBTCxDQUFnQixTQUFoQixJQUE2QixLQUE3QjtBQUNIO0FBQ0osU0FQRDtBQVFILEtBcEpZOzs7QUFzSmI7Ozs7Ozs7QUFPQSxzQkE3SmEsOEJBNkpNLElBN0pOLEVBNkpZLElBN0paLEVBNkprQixVQTdKbEIsRUE2SjhCO0FBQUE7O0FBQ3ZDLFlBQUksUUFBUSxLQUFLLFNBQUwsQ0FBZSxJQUFmLEVBQXFCLElBQXJCLENBQVo7QUFDQSxVQUFFLE1BQUYsQ0FBUyxVQUFULEVBQXFCLFVBQUMsS0FBRCxFQUFRLFNBQVIsRUFBc0I7QUFDdkMsZ0JBQUksRUFBRSxLQUFGLENBQVEsS0FBUixDQUFKLEVBQW9CO0FBQ2hCLG9CQUFJLFNBQVMsTUFBTSxVQUFuQixFQUErQixPQUFPLE1BQU0sVUFBTixDQUFpQixTQUFqQixDQUFQO0FBQ2xDLGFBRkQsTUFFTztBQUNILG9CQUFJLENBQUMsS0FBTCxFQUFZO0FBQ1IsNEJBQVEsRUFBRSxVQUFGLEVBQVEsWUFBWSxFQUFwQixFQUF3QixVQUFVLEVBQWxDLEVBQVI7QUFDQSwwQkFBSyxXQUFMLENBQWlCLElBQWpCLEVBQXVCLEtBQXZCO0FBQ0g7O0FBRUQsb0JBQUksQ0FBQyxNQUFNLFVBQVgsRUFBdUIsTUFBTSxVQUFOLEdBQW1CLEVBQW5CO0FBQ3ZCLHNCQUFNLFVBQU4sQ0FBaUIsU0FBakIsSUFBOEIsS0FBOUI7QUFDSDtBQUNKLFNBWkQ7O0FBY0EsZUFBTyxLQUFQO0FBQ0gsS0E5S1k7OztBQWdMYjs7Ozs7O0FBTUEsc0JBdExhLDhCQXNMTSxJQXRMTixFQXNMWSxLQXRMWixFQXNMbUI7QUFDNUIsWUFBSSxPQUFPLEtBQVAsS0FBaUIsUUFBckIsRUFBK0IsUUFBUSxLQUFLLFNBQUwsQ0FBZSxJQUFmLEVBQXFCLEtBQXJCLENBQVI7QUFDL0IsWUFBSSxTQUFTLEtBQUssT0FBTCxDQUFhLEtBQWIsQ0FBYixFQUFrQyxLQUFLLFdBQUwsQ0FBaUIsSUFBakIsRUFBdUIsS0FBdkI7QUFDckM7QUF6TFksQ0FBakI7OztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ24yR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pFQTs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQy9MQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzlEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDeENBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDM0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDakpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7O0FDbkZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3ZTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDanZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3hrREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkdBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7O0FDQUE7QUFDQTtBQUNBOztBQ0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTs7QUNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQzNHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDNUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0lBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDaFFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQzFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNwS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2piQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcExBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDejZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1d0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNnQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNyRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNWhCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDbEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JZQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDdlFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNwTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM3UEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ250aEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2xKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25IQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaFpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbGFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2wxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDelZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwaERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdlZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDekZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzR0E7QUFDQTtBQUNBOzs7QUNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3BHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN4R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzVHQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDLzJCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ25MQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNuZ0JBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTs7QUNEQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDbktBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzdoREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9IQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzdOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUMzRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ25FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG5jb25zdCBfID0gcmVxdWlyZShcImxvZGFzaFwiKTtcclxuY29uc3QgeG1scSA9IHJlcXVpcmUoXCIuL3htbHFcIik7XHJcbmNvbnN0IEFyZ0hhbmRsZXIgPSByZXF1aXJlKFwiLi9BcmdIYW5kbGVyXCIpO1xyXG5cclxuLyoqXHJcbiAqIEFwcCBwcm9wZXJ0aWVzXHJcbiAqIEBpZ25vcmVcclxuICovXHJcbmNsYXNzIEFwcFByb3BlcnRpZXMge1xyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIEFwcFByb3BlcnRpZXNcclxuICAgICAqIEBwYXJhbSB7e319IG5vZGUgLSBUaGUgbm9kZS5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3Iobm9kZSkge1xyXG4gICAgICAgIHRoaXMuX25vZGUgPSBub2RlO1xyXG4gICAgfVxyXG5cclxuICAgIGlzU2VjdXJlKHZhbHVlKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBcmdIYW5kbGVyKFwiUmFuZ2UuZm9ybXVsYVwiKVxyXG4gICAgICAgICAgICAuY2FzZSgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBkb2NTZWN1cml0eU5vZGUgPSB4bWxxLmZpbmRDaGlsZCh0aGlzLl9ub2RlLCBcIkRvY1NlY3VyaXR5XCIpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFkb2NTZWN1cml0eU5vZGUpIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBkb2NTZWN1cml0eU5vZGUuY2hpbGRyZW5bMF0gPT09IDE7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKCdib29sZWFuJywgdmFsdWUgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZG9jU2VjdXJpdHlOb2RlID0geG1scS5hcHBlbmRDaGlsZElmTm90Rm91bmQodGhpcy5fbm9kZSwgXCJEb2NTZWN1cml0eVwiKTtcclxuICAgICAgICAgICAgICAgIGRvY1NlY3VyaXR5Tm9kZS5jaGlsZHJlbiA9IFt2YWx1ZSA/IDEgOiAwXTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuaGFuZGxlKGFyZ3VtZW50cyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0IHRoZSBjb2xsZWN0aW9uIHRvIGFuIFhNTCBvYmplY3QuXHJcbiAgICAgKiBAcmV0dXJucyB7e319IFRoZSBYTUwuXHJcbiAgICAgKi9cclxuICAgIHRvWG1sKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9ub2RlO1xyXG4gICAgfVxyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IEFwcFByb3BlcnRpZXM7XHJcblxyXG4vKlxyXG5kb2NQcm9wcy9hcHAueG1sXHJcblxyXG48P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJVVEYtOFwiIHN0YW5kYWxvbmU9XCJ5ZXNcIj8+XHJcbjxQcm9wZXJ0aWVzIHhtbG5zPVwiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL29mZmljZURvY3VtZW50LzIwMDYvZXh0ZW5kZWQtcHJvcGVydGllc1wiIHhtbG5zOnZ0PVwiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL29mZmljZURvY3VtZW50LzIwMDYvZG9jUHJvcHNWVHlwZXNcIj5cclxuICAgIDxBcHBsaWNhdGlvbj5NaWNyb3NvZnQgRXhjZWw8L0FwcGxpY2F0aW9uPlxyXG48RG9jU2VjdXJpdHk+MTwvRG9jU2VjdXJpdHk+XHJcbjxTY2FsZUNyb3A+ZmFsc2U8L1NjYWxlQ3JvcD5cclxuPEhlYWRpbmdQYWlycz5cclxuPHZ0OnZlY3RvciBzaXplPVwiMlwiIGJhc2VUeXBlPVwidmFyaWFudFwiPlxyXG4gICAgPHZ0OnZhcmlhbnQ+XHJcbjx2dDpscHN0cj5Xb3Jrc2hlZXRzPC92dDpscHN0cj5cclxuPC92dDp2YXJpYW50PlxyXG48dnQ6dmFyaWFudD5cclxuPHZ0Omk0PjE8L3Z0Omk0PlxyXG48L3Z0OnZhcmlhbnQ+XHJcbjwvdnQ6dmVjdG9yPlxyXG48L0hlYWRpbmdQYWlycz5cclxuPFRpdGxlc09mUGFydHM+XHJcbjx2dDp2ZWN0b3Igc2l6ZT1cIjFcIiBiYXNlVHlwZT1cImxwc3RyXCI+XHJcbiAgICA8dnQ6bHBzdHI+U2hlZXQxPC92dDpscHN0cj5cclxuPC92dDp2ZWN0b3I+XHJcbjwvVGl0bGVzT2ZQYXJ0cz5cclxuPENvbXBhbnkvPlxyXG48TGlua3NVcFRvRGF0ZT5mYWxzZTwvTGlua3NVcFRvRGF0ZT5cclxuPFNoYXJlZERvYz5mYWxzZTwvU2hhcmVkRG9jPlxyXG48SHlwZXJsaW5rc0NoYW5nZWQ+ZmFsc2U8L0h5cGVybGlua3NDaGFuZ2VkPlxyXG48QXBwVmVyc2lvbj4xNi4wMzAwPC9BcHBWZXJzaW9uPlxyXG48L1Byb3BlcnRpZXM+XHJcbiAqL1xyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxuXHJcbmNvbnN0IF8gPSByZXF1aXJlKFwibG9kYXNoXCIpO1xyXG5cclxuLyoqXHJcbiAqIE1ldGhvZCBhcmd1bWVudCBoYW5kbGVyLiBVc2VkIGZvciBvdmVybG9hZGluZyBtZXRob2RzLlxyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuY2xhc3MgQXJnSGFuZGxlciB7XHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgQXJnSGFuZGxlci5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gVGhlIG1ldGhvZCBuYW1lIHRvIHVzZSBpbiBlcnJvciBtZXNzYWdlcy5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobmFtZSkge1xyXG4gICAgICAgIHRoaXMuX25hbWUgPSBuYW1lO1xyXG4gICAgICAgIHRoaXMuX2Nhc2VzID0gW107XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBZGQgYSBjYXNlLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd8QXJyYXkuPHN0cmluZz59IFt0eXBlc10gLSBUaGUgdHlwZSBvciB0eXBlcyBvZiBhcmd1bWVudHMgdG8gbWF0Y2ggdGhpcyBjYXNlLlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlciAtIFRoZSBmdW5jdGlvbiB0byBjYWxsIHdoZW4gdGhpcyBjYXNlIGlzIG1hdGNoZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7QXJnSGFuZGxlcn0gVGhlIGhhbmRsZXIgZm9yIGNoYWluaW5nLlxyXG4gICAgICovXHJcbiAgICBjYXNlKHR5cGVzLCBoYW5kbGVyKSB7XHJcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcclxuICAgICAgICAgICAgaGFuZGxlciA9IHR5cGVzO1xyXG4gICAgICAgICAgICB0eXBlcyA9IFtdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHR5cGVzKSkgdHlwZXMgPSBbdHlwZXNdO1xyXG4gICAgICAgIHRoaXMuX2Nhc2VzLnB1c2goeyB0eXBlcywgaGFuZGxlciB9KTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEhhbmRsZSB0aGUgbWV0aG9kIGFyZ3VtZW50cyBieSBjaGVja2luZyBlYWNoIGNhc2UgaW4gb3JkZXIgdW50aWwgb25lIG1hdGNoZXMgYW5kIHRoZW4gY2FsbCBpdHMgaGFuZGxlci5cclxuICAgICAqIEBwYXJhbSB7QXJndW1lbnRzfEFycmF5LjwqPn0gYXJncyAtIFRoZSBtZXRob2QgYXJndW1lbnRzLlxyXG4gICAgICogQHJldHVybnMgeyp9IFRoZSByZXN1bHQgb2YgdGhlIGhhbmRsZXIuXHJcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gVGhyb3dzIGlmIG5vIGNhc2UgbWF0Y2hlcy5cclxuICAgICAqL1xyXG4gICAgaGFuZGxlKGFyZ3MpIHtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2Nhc2VzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGMgPSB0aGlzLl9jYXNlc1tpXTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2FyZ3NNYXRjaFR5cGVzKGFyZ3MsIGMudHlwZXMpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYy5oYW5kbGVyLmFwcGx5KG51bGwsIGFyZ3MpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy5fbmFtZX06IEludmFsaWQgYXJndW1lbnRzLmApO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2hlY2sgaWYgdGhlIGFyZ3VtZW50cyBtYXRjaCB0aGUgZ2l2ZW4gdHlwZXMuXHJcbiAgICAgKiBAcGFyYW0ge0FyZ3VtZW50c30gYXJncyAtIFRoZSBhcmd1bWVudHMuXHJcbiAgICAgKiBAcGFyYW0ge0FycmF5LjxzdHJpbmc+fSB0eXBlcyAtIFRoZSB0eXBlcy5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIG1hdGNoZXMsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSBUaHJvd3MgaWYgdW5rbm93biB0eXBlLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgX2FyZ3NNYXRjaFR5cGVzKGFyZ3MsIHR5cGVzKSB7XHJcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoICE9PSB0eXBlcy5sZW5ndGgpIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICAgICAgcmV0dXJuIF8uZXZlcnkoYXJncywgKGFyZywgaSkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCB0eXBlID0gdHlwZXNbaV07XHJcblxyXG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gJyonKSByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgaWYgKHR5cGUgPT09ICduaWwnKSByZXR1cm4gXy5pc05pbChhcmcpO1xyXG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHJldHVybiB0eXBlb2YgYXJnID09PSBcInN0cmluZ1wiO1xyXG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gJ2Jvb2xlYW4nKSByZXR1cm4gdHlwZW9mIGFyZyA9PT0gXCJib29sZWFuXCI7XHJcbiAgICAgICAgICAgIGlmICh0eXBlID09PSAnbnVtYmVyJykgcmV0dXJuIHR5cGVvZiBhcmcgPT09IFwibnVtYmVyXCI7XHJcbiAgICAgICAgICAgIGlmICh0eXBlID09PSAnaW50ZWdlcicpIHJldHVybiB0eXBlb2YgYXJnID09PSBcIm51bWJlclwiICYmIF8uaXNJbnRlZ2VyKGFyZyk7XHJcbiAgICAgICAgICAgIGlmICh0eXBlID09PSAnZnVuY3Rpb24nKSByZXR1cm4gdHlwZW9mIGFyZyA9PT0gXCJmdW5jdGlvblwiO1xyXG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gJ2FycmF5JykgcmV0dXJuIEFycmF5LmlzQXJyYXkoYXJnKTtcclxuICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdkYXRlJykgcmV0dXJuIGFyZyAmJiBhcmcuY29uc3RydWN0b3IgPT09IERhdGU7XHJcbiAgICAgICAgICAgIGlmICh0eXBlID09PSAnb2JqZWN0JykgcmV0dXJuIGFyZyAmJiBhcmcuY29uc3RydWN0b3IgPT09IE9iamVjdDtcclxuICAgICAgICAgICAgaWYgKGFyZyAmJiBhcmcuY29uc3RydWN0b3IgJiYgYXJnLmNvbnN0cnVjdG9yLm5hbWUgPT09IHR5cGUpIHJldHVybiB0cnVlO1xyXG5cclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHR5cGU6ICR7dHlwZX1gKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBBcmdIYW5kbGVyO1xyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxuXHJcbmNvbnN0IF8gPSByZXF1aXJlKFwibG9kYXNoXCIpO1xyXG5jb25zdCBBcmdIYW5kbGVyID0gcmVxdWlyZShcIi4vQXJnSGFuZGxlclwiKTtcclxuY29uc3QgYWRkcmVzc0NvbnZlcnRlciA9IHJlcXVpcmUoXCIuL2FkZHJlc3NDb252ZXJ0ZXJcIik7XHJcbmNvbnN0IGRhdGVDb252ZXJ0ZXIgPSByZXF1aXJlKFwiLi9kYXRlQ29udmVydGVyXCIpO1xyXG5jb25zdCByZWdleGlmeSA9IHJlcXVpcmUoXCIuL3JlZ2V4aWZ5XCIpO1xyXG5jb25zdCB4bWxxID0gcmVxdWlyZShcIi4veG1scVwiKTtcclxuY29uc3QgRm9ybXVsYUVycm9yID0gcmVxdWlyZShcIi4vRm9ybXVsYUVycm9yXCIpO1xyXG5jb25zdCBTdHlsZSA9IHJlcXVpcmUoXCIuL1N0eWxlXCIpO1xyXG5jb25zdCBSaWNoVGV4dCA9IHJlcXVpcmUoXCIuL1JpY2hUZXh0XCIpO1xyXG5cclxuLyoqXHJcbiAqIEEgY2VsbFxyXG4gKi9cclxuY2xhc3MgQ2VsbCB7XHJcbiAgICAvLyAvKipcclxuICAgIC8vICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgY2VsbC5cclxuICAgIC8vICAqIEBwYXJhbSB7Um93fSByb3cgLSBUaGUgcGFyZW50IHJvdy5cclxuICAgIC8vICAqIEBwYXJhbSB7e319IG5vZGUgLSBUaGUgY2VsbCBub2RlLlxyXG4gICAgLy8gICovXHJcbiAgICBjb25zdHJ1Y3Rvcihyb3csIG5vZGUsIHN0eWxlSWQpIHtcclxuICAgICAgICB0aGlzLl9yb3cgPSByb3c7XHJcbiAgICAgICAgdGhpcy5faW5pdChub2RlLCBzdHlsZUlkKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiBQVUJMSUMgKi9cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgYSB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGNlbGwgaXMgdGhlIGFjdGl2ZSBjZWxsIGluIHRoZSBzaGVldC5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIGFjdGl2ZSwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBNYWtlIHRoZSBjZWxsIHRoZSBhY3RpdmUgY2VsbCBpbiB0aGUgc2hlZXQuXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGFjdGl2ZSAtIE11c3QgYmUgc2V0IHRvIGB0cnVlYC4gRGVhY3RpdmF0aW5nIGRpcmVjdGx5IGlzIG5vdCBzdXBwb3J0ZWQuIFRvIGRlYWN0aXZhdGUsIHlvdSBzaG91bGQgYWN0aXZhdGUgYSBkaWZmZXJlbnQgY2VsbCBpbnN0ZWFkLlxyXG4gICAgICogQHJldHVybnMge0NlbGx9IFRoZSBjZWxsLlxyXG4gICAgICovXHJcbiAgICBhY3RpdmUoKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBcmdIYW5kbGVyKCdDZWxsLmFjdGl2ZScpXHJcbiAgICAgICAgICAgIC5jYXNlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNoZWV0KCkuYWN0aXZlQ2VsbCgpID09PSB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnYm9vbGVhbicsIGFjdGl2ZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWFjdGl2ZSkgdGhyb3cgbmV3IEVycm9yKFwiRGVhY3RpdmF0aW5nIGNlbGwgZGlyZWN0bHkgbm90IHN1cHBvcnRlZC4gQWN0aXZhdGUgYSBkaWZmZXJlbnQgY2VsbCBpbnN0ZWFkLlwiKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuc2hlZXQoKS5hY3RpdmVDZWxsKHRoaXMpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5oYW5kbGUoYXJndW1lbnRzKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldCB0aGUgYWRkcmVzcyBvZiB0aGUgY29sdW1uLlxyXG4gICAgICogQHBhcmFtIHt7fX0gW29wdHNdIC0gT3B0aW9uc1xyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5pbmNsdWRlU2hlZXROYW1lXSAtIEluY2x1ZGUgdGhlIHNoZWV0IG5hbWUgaW4gdGhlIGFkZHJlc3MuXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLnJvd0FuY2hvcmVkXSAtIEFuY2hvciB0aGUgcm93LlxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5jb2x1bW5BbmNob3JlZF0gLSBBbmNob3IgdGhlIGNvbHVtbi5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuYW5jaG9yZWRdIC0gQW5jaG9yIGJvdGggdGhlIHJvdyBhbmQgdGhlIGNvbHVtbi5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBhZGRyZXNzXHJcbiAgICAgKi9cclxuICAgIGFkZHJlc3Mob3B0cykge1xyXG4gICAgICAgIHJldHVybiBhZGRyZXNzQ29udmVydGVyLnRvQWRkcmVzcyh7XHJcbiAgICAgICAgICAgIHR5cGU6ICdjZWxsJyxcclxuICAgICAgICAgICAgcm93TnVtYmVyOiB0aGlzLnJvd051bWJlcigpLFxyXG4gICAgICAgICAgICBjb2x1bW5OdW1iZXI6IHRoaXMuY29sdW1uTnVtYmVyKCksXHJcbiAgICAgICAgICAgIHNoZWV0TmFtZTogb3B0cyAmJiBvcHRzLmluY2x1ZGVTaGVldE5hbWUgJiYgdGhpcy5zaGVldCgpLm5hbWUoKSxcclxuICAgICAgICAgICAgcm93QW5jaG9yZWQ6IG9wdHMgJiYgKG9wdHMucm93QW5jaG9yZWQgfHwgb3B0cy5hbmNob3JlZCksXHJcbiAgICAgICAgICAgIGNvbHVtbkFuY2hvcmVkOiBvcHRzICYmIChvcHRzLmNvbHVtbkFuY2hvcmVkIHx8IG9wdHMuYW5jaG9yZWQpXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBwYXJlbnQgY29sdW1uIG9mIHRoZSBjZWxsLlxyXG4gICAgICogQHJldHVybnMge0NvbHVtbn0gVGhlIHBhcmVudCBjb2x1bW4uXHJcbiAgICAgKi9cclxuICAgIGNvbHVtbigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zaGVldCgpLmNvbHVtbih0aGlzLmNvbHVtbk51bWJlcigpKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENsZWFycyB0aGUgY29udGVudHMgZnJvbSB0aGUgY2VsbC5cclxuICAgICAqIEByZXR1cm5zIHtDZWxsfSBUaGUgY2VsbC5cclxuICAgICAqL1xyXG4gICAgY2xlYXIoKSB7XHJcbiAgICAgICAgY29uc3QgaG9zdFNoYXJlZEZvcm11bGFJZCA9IHRoaXMuX2Zvcm11bGFSZWYgJiYgdGhpcy5fc2hhcmVkRm9ybXVsYUlkO1xyXG5cclxuICAgICAgICBkZWxldGUgdGhpcy5fdmFsdWU7XHJcbiAgICAgICAgZGVsZXRlIHRoaXMuX2Zvcm11bGFUeXBlO1xyXG4gICAgICAgIGRlbGV0ZSB0aGlzLl9mb3JtdWxhO1xyXG4gICAgICAgIGRlbGV0ZSB0aGlzLl9zaGFyZWRGb3JtdWxhSWQ7XHJcbiAgICAgICAgZGVsZXRlIHRoaXMuX2Zvcm11bGFSZWY7XHJcblxyXG4gICAgICAgIC8vIFRPRE8gaW4gZnV0dXJlIHZlcnNpb246IE1vdmUgc2hhcmVkIGZvcm11bGEgdG8gc29tZSBvdGhlciBjZWxsLiBUaGlzIHdvdWxkIHJlcXVpcmUgcGFyc2luZyB0aGUgZm9ybXVsYS4uLlxyXG4gICAgICAgIGlmICghXy5pc05pbChob3N0U2hhcmVkRm9ybXVsYUlkKSkgdGhpcy5zaGVldCgpLmNsZWFyQ2VsbHNVc2luZ1NoYXJlZEZvcm11bGEoaG9zdFNoYXJlZEZvcm11bGFJZCk7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgY29sdW1uIG5hbWUgb2YgdGhlIGNlbGwuXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgY29sdW1uIG5hbWUuXHJcbiAgICAgKi9cclxuICAgIGNvbHVtbk5hbWUoKSB7XHJcbiAgICAgICAgcmV0dXJuIGFkZHJlc3NDb252ZXJ0ZXIuY29sdW1uTnVtYmVyVG9OYW1lKHRoaXMuY29sdW1uTnVtYmVyKCkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgY29sdW1uIG51bWJlciBvZiB0aGUgY2VsbCAoMS1iYXNlZCkuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgY29sdW1uIG51bWJlci5cclxuICAgICAqL1xyXG4gICAgY29sdW1uTnVtYmVyKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9jb2x1bW5OdW1iZXI7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaW5kIHRoZSBnaXZlbiBwYXR0ZXJuIGluIHRoZSBjZWxsIGFuZCBvcHRpb25hbGx5IHJlcGxhY2UgaXQuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xSZWdFeHB9IHBhdHRlcm4gLSBUaGUgcGF0dGVybiB0byBsb29rIGZvci4gUHJvdmlkaW5nIGEgc3RyaW5nIHdpbGwgcmVzdWx0IGluIGEgY2FzZS1pbnNlbnNpdGl2ZSBzdWJzdHJpbmcgc2VhcmNoLiBVc2UgYSBSZWdFeHAgZm9yIG1vcmUgc29waGlzdGljYXRlZCBzZWFyY2hlcy5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfGZ1bmN0aW9ufSBbcmVwbGFjZW1lbnRdIC0gVGhlIHRleHQgdG8gcmVwbGFjZSBvciBhIFN0cmluZy5yZXBsYWNlIGNhbGxiYWNrIGZ1bmN0aW9uLiBJZiBwYXR0ZXJuIGlzIGEgc3RyaW5nLCBhbGwgb2NjdXJyZW5jZXMgb2YgdGhlIHBhdHRlcm4gaW4gdGhlIGNlbGwgd2lsbCBiZSByZXBsYWNlZC5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBBIGZsYWcgaW5kaWNhdGluZyBpZiB0aGUgcGF0dGVybiB3YXMgZm91bmQuXHJcbiAgICAgKi9cclxuICAgIGZpbmQocGF0dGVybiwgcmVwbGFjZW1lbnQpIHtcclxuICAgICAgICBwYXR0ZXJuID0gcmVnZXhpZnkocGF0dGVybik7XHJcblxyXG4gICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy52YWx1ZSgpO1xyXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKSByZXR1cm4gZmFsc2U7XHJcblxyXG4gICAgICAgIGlmIChfLmlzTmlsKHJlcGxhY2VtZW50KSkge1xyXG4gICAgICAgICAgICByZXR1cm4gcGF0dGVybi50ZXN0KHZhbHVlKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCByZXBsYWNlZCA9IHZhbHVlLnJlcGxhY2UocGF0dGVybiwgcmVwbGFjZW1lbnQpO1xyXG4gICAgICAgICAgICBpZiAocmVwbGFjZWQgPT09IHZhbHVlKSByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIHRoaXMudmFsdWUocmVwbGFjZWQpO1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBmb3JtdWxhIGluIHRoZSBjZWxsLiBOb3RlIHRoYXQgaWYgYSBmb3JtdWxhIHdhcyBzZXQgYXMgcGFydCBvZiBhIHJhbmdlLCB0aGUgZ2V0dGVyIHdpbGwgcmV0dXJuICdTSEFSRUQnLiBUaGlzIGlzIGEgbGltaXRhdGlvbiB0aGF0IG1heSBiZSBhZGRyZXNzZWQgaW4gYSBmdXR1cmUgcmVsZWFzZS5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBmb3JtdWxhIGluIHRoZSBjZWxsLlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXRzIHRoZSBmb3JtdWxhIGluIHRoZSBjZWxsLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGZvcm11bGEgLSBUaGUgZm9ybXVsYSB0byBzZXQuXHJcbiAgICAgKiBAcmV0dXJucyB7Q2VsbH0gVGhlIGNlbGwuXHJcbiAgICAgKi9cclxuICAgIGZvcm11bGEoKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBcmdIYW5kbGVyKCdDZWxsLmZvcm11bGEnKVxyXG4gICAgICAgICAgICAuY2FzZSgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBUT0RPIGluIGZ1dHVyZTogUmV0dXJuIHRyYW5zbGF0ZWQgZm9ybXVsYS5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9mb3JtdWxhVHlwZSA9PT0gXCJzaGFyZWRcIiAmJiAhdGhpcy5fZm9ybXVsYVJlZikgcmV0dXJuIFwiU0hBUkVEXCI7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZm9ybXVsYTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoJ25pbCcsICgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2xlYXIoKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnc3RyaW5nJywgZm9ybXVsYSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFyKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9mb3JtdWxhVHlwZSA9IFwibm9ybWFsXCI7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9mb3JtdWxhID0gZm9ybXVsYTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuaGFuZGxlKGFyZ3VtZW50cyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBoeXBlcmxpbmsgYXR0YWNoZWQgdG8gdGhlIGNlbGwuXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfHVuZGVmaW5lZH0gVGhlIGh5cGVybGluayBvciB1bmRlZmluZWQgaWYgbm90IHNldC5cclxuICAgICAqLy8qKlxyXG4gICAgICogU2V0IG9yIGNsZWFyIHRoZSBoeXBlcmxpbmsgb24gdGhlIGNlbGwuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xDZWxsfHVuZGVmaW5lZH0gaHlwZXJsaW5rIC0gVGhlIGh5cGVybGluayB0byBzZXQgb3IgdW5kZWZpbmVkIHRvIGNsZWFyLlxyXG4gICAgICogQHJldHVybnMge0NlbGx9IFRoZSBjZWxsLlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXQgdGhlIGh5cGVybGluayBvcHRpb25zIG9uIHRoZSBjZWxsLlxyXG4gICAgICogQHBhcmFtIHt7fXxDZWxsfSBvcHRzIC0gT3B0aW9ucyBvciBDZWxsLiBJZiBvcHRzIGlzIGEgQ2VsbCB0aGVuIGFuIGludGVybmFsIGh5cGVybGluayBpcyBhZGRlZC5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfENlbGx9IFtvcHRzLmh5cGVybGlua10gLSBUaGUgaHlwZXJsaW5rIHRvIHNldCwgY2FuIGJlIGEgQ2VsbCBvciBhbiBpbnRlcm5hbC9leHRlcm5hbCBzdHJpbmcuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMudG9vbHRpcF0gLSBBZGRpdGlvbmFsIHRleHQgdG8gaGVscCB0aGUgdXNlciB1bmRlcnN0YW5kIG1vcmUgYWJvdXQgdGhlIGh5cGVybGluay5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5lbWFpbF0gLSBFbWFpbCBhZGRyZXNzLCBpZ25vcmVkIGlmIG9wdHMuaHlwZXJsaW5rIGlzIHNldC5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5lbWFpbFN1YmplY3RdIC0gRW1haWwgc3ViamVjdCwgaWdub3JlZCBpZiBvcHRzLmh5cGVybGluayBpcyBzZXQuXHJcbiAgICAgKiBAcmV0dXJucyB7Q2VsbH0gVGhlIGNlbGwuXHJcbiAgICAgKi9cclxuICAgIGh5cGVybGluaygpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEFyZ0hhbmRsZXIoJ0NlbGwuaHlwZXJsaW5rJylcclxuICAgICAgICAgICAgLmNhc2UoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2hlZXQoKS5oeXBlcmxpbmsodGhpcy5hZGRyZXNzKCkpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnc3RyaW5nJywgaHlwZXJsaW5rID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc2hlZXQoKS5oeXBlcmxpbmsodGhpcy5hZGRyZXNzKCksIGh5cGVybGluayk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoWydvYmplY3QnXSwgb3B0cyA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNoZWV0KCkuaHlwZXJsaW5rKHRoaXMuYWRkcmVzcygpLCBvcHRzKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuaGFuZGxlKGFyZ3VtZW50cyk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgZGF0YSB2YWxpZGF0aW9uIG9iamVjdCBhdHRhY2hlZCB0byB0aGUgY2VsbC5cclxuICAgICAqIEByZXR1cm5zIHtvYmplY3R8dW5kZWZpbmVkfSBUaGUgZGF0YSB2YWxpZGF0aW9uIG9yIHVuZGVmaW5lZCBpZiBub3Qgc2V0LlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXQgb3IgY2xlYXIgdGhlIGRhdGEgdmFsaWRhdGlvbiBvYmplY3Qgb2YgdGhlIGNlbGwuXHJcbiAgICAgKiBAcGFyYW0ge29iamVjdHx1bmRlZmluZWR9IGRhdGFWYWxpZGF0aW9uIC0gT2JqZWN0IG9yIG51bGwgdG8gY2xlYXIuXHJcbiAgICAgKiBAcmV0dXJucyB7Q2VsbH0gVGhlIGNlbGwuXHJcbiAgICAgKi9cclxuICAgIGRhdGFWYWxpZGF0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQXJnSGFuZGxlcignQ2VsbC5kYXRhVmFsaWRhdGlvbicpXHJcbiAgICAgICAgICAgIC5jYXNlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNoZWV0KCkuZGF0YVZhbGlkYXRpb24odGhpcy5hZGRyZXNzKCkpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnYm9vbGVhbicsIG9iaiA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zaGVldCgpLmRhdGFWYWxpZGF0aW9uKHRoaXMuYWRkcmVzcygpLCBvYmopO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnKicsIG9iaiA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNoZWV0KCkuZGF0YVZhbGlkYXRpb24odGhpcy5hZGRyZXNzKCksIG9iaik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmhhbmRsZShhcmd1bWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGJhY2sgdXNlZCBieSB0YXAuXHJcbiAgICAgKiBAY2FsbGJhY2sgQ2VsbH50YXBDYWxsYmFja1xyXG4gICAgICogQHBhcmFtIHtDZWxsfSBjZWxsIC0gVGhlIGNlbGxcclxuICAgICAqIEByZXR1cm5zIHt1bmRlZmluZWR9XHJcbiAgICAgKi8vKipcclxuICAgICAqIEludm9rZSBhIGNhbGxiYWNrIG9uIHRoZSBjZWxsIGFuZCByZXR1cm4gdGhlIGNlbGwuIFVzZWZ1bCBmb3IgbWV0aG9kIGNoYWluaW5nLlxyXG4gICAgICogQHBhcmFtIHtDZWxsfnRhcENhbGxiYWNrfSBjYWxsYmFjayAtIFRoZSBjYWxsYmFjayBmdW5jdGlvbi5cclxuICAgICAqIEByZXR1cm5zIHtDZWxsfSBUaGUgY2VsbC5cclxuICAgICAqL1xyXG4gICAgdGFwKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgY2FsbGJhY2sodGhpcyk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsYmFjayB1c2VkIGJ5IHRocnUuXHJcbiAgICAgKiBAY2FsbGJhY2sgQ2VsbH50aHJ1Q2FsbGJhY2tcclxuICAgICAqIEBwYXJhbSB7Q2VsbH0gY2VsbCAtIFRoZSBjZWxsXHJcbiAgICAgKiBAcmV0dXJucyB7Kn0gVGhlIHZhbHVlIHRvIHJldHVybiBmcm9tIHRocnUuXHJcbiAgICAgKi8vKipcclxuICAgICAqIEludm9rZSBhIGNhbGxiYWNrIG9uIHRoZSBjZWxsIGFuZCByZXR1cm4gdGhlIHZhbHVlIHByb3ZpZGVkIGJ5IHRoZSBjYWxsYmFjay4gVXNlZnVsIGZvciBtZXRob2QgY2hhaW5pbmcuXHJcbiAgICAgKiBAcGFyYW0ge0NlbGx+dGhydUNhbGxiYWNrfSBjYWxsYmFjayAtIFRoZSBjYWxsYmFjayBmdW5jdGlvbi5cclxuICAgICAqIEByZXR1cm5zIHsqfSBUaGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBjYWxsYmFjay5cclxuICAgICAqL1xyXG4gICAgdGhydShjYWxsYmFjaykge1xyXG4gICAgICAgIHJldHVybiBjYWxsYmFjayh0aGlzKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZSBhIHJhbmdlIGZyb20gdGhpcyBjZWxsIGFuZCBhbm90aGVyLlxyXG4gICAgICogQHBhcmFtIHtDZWxsfHN0cmluZ30gY2VsbCAtIFRoZSBvdGhlciBjZWxsIG9yIGNlbGwgYWRkcmVzcyB0byByYW5nZSB0by5cclxuICAgICAqIEByZXR1cm5zIHtSYW5nZX0gVGhlIHJhbmdlLlxyXG4gICAgICovXHJcbiAgICByYW5nZVRvKGNlbGwpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zaGVldCgpLnJhbmdlKHRoaXMsIGNlbGwpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhIGNlbGwgd2l0aCBhIHJlbGF0aXZlIHBvc2l0aW9uIGdpdmVuIHRoZSBvZmZzZXRzIHByb3ZpZGVkLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJvd09mZnNldCAtIFRoZSByb3cgb2Zmc2V0ICgwIGZvciB0aGUgY3VycmVudCByb3cpLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGNvbHVtbk9mZnNldCAtIFRoZSBjb2x1bW4gb2Zmc2V0ICgwIGZvciB0aGUgY3VycmVudCBjb2x1bW4pLlxyXG4gICAgICogQHJldHVybnMge0NlbGx9IFRoZSByZWxhdGl2ZSBjZWxsLlxyXG4gICAgICovXHJcbiAgICByZWxhdGl2ZUNlbGwocm93T2Zmc2V0LCBjb2x1bW5PZmZzZXQpIHtcclxuICAgICAgICBjb25zdCByb3cgPSByb3dPZmZzZXQgKyB0aGlzLnJvd051bWJlcigpO1xyXG4gICAgICAgIGNvbnN0IGNvbHVtbiA9IGNvbHVtbk9mZnNldCArIHRoaXMuY29sdW1uTnVtYmVyKCk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc2hlZXQoKS5jZWxsKHJvdywgY29sdW1uKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIHBhcmVudCByb3cgb2YgdGhlIGNlbGwuXHJcbiAgICAgKiBAcmV0dXJucyB7Um93fSBUaGUgcGFyZW50IHJvdy5cclxuICAgICAqL1xyXG4gICAgcm93KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9yb3c7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSByb3cgbnVtYmVyIG9mIHRoZSBjZWxsICgxLWJhc2VkKS5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFRoZSByb3cgbnVtYmVyLlxyXG4gICAgICovXHJcbiAgICByb3dOdW1iZXIoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucm93KCkucm93TnVtYmVyKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBwYXJlbnQgc2hlZXQuXHJcbiAgICAgKiBAcmV0dXJucyB7U2hlZXR9IFRoZSBwYXJlbnQgc2hlZXQuXHJcbiAgICAgKi9cclxuICAgIHNoZWV0KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJvdygpLnNoZWV0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIGFuIGluZGl2aWR1YWwgc3R5bGUuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBzdHlsZS5cclxuICAgICAqIEByZXR1cm5zIHsqfSBUaGUgc3R5bGUuXHJcbiAgICAgKi8vKipcclxuICAgICAqIEdldHMgbXVsdGlwbGUgc3R5bGVzLlxyXG4gICAgICogQHBhcmFtIHtBcnJheS48c3RyaW5nPn0gbmFtZXMgLSBUaGUgbmFtZXMgb2YgdGhlIHN0eWxlLlxyXG4gICAgICogQHJldHVybnMge29iamVjdC48c3RyaW5nLCAqPn0gT2JqZWN0IHdob3NlIGtleXMgYXJlIHRoZSBzdHlsZSBuYW1lcyBhbmQgdmFsdWVzIGFyZSB0aGUgc3R5bGVzLlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXRzIGFuIGluZGl2aWR1YWwgc3R5bGUuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBzdHlsZS5cclxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gc2V0LlxyXG4gICAgICogQHJldHVybnMge0NlbGx9IFRoZSBjZWxsLlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXRzIHRoZSBzdHlsZXMgaW4gdGhlIHJhbmdlIHN0YXJ0aW5nIHdpdGggdGhlIGNlbGwuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBzdHlsZS5cclxuICAgICAqIEBwYXJhbSB7QXJyYXkuPEFycmF5LjwqPj59IC0gMkQgYXJyYXkgb2YgdmFsdWVzIHRvIHNldC5cclxuICAgICAqIEByZXR1cm5zIHtSYW5nZX0gVGhlIHJhbmdlIHRoYXQgd2FzIHNldC5cclxuICAgICAqLy8qKlxyXG4gICAgICogU2V0cyBtdWx0aXBsZSBzdHlsZXMuXHJcbiAgICAgKiBAcGFyYW0ge29iamVjdC48c3RyaW5nLCAqPn0gc3R5bGVzIC0gT2JqZWN0IHdob3NlIGtleXMgYXJlIHRoZSBzdHlsZSBuYW1lcyBhbmQgdmFsdWVzIGFyZSB0aGUgc3R5bGVzIHRvIHNldC5cclxuICAgICAqIEByZXR1cm5zIHtDZWxsfSBUaGUgY2VsbC5cclxuICAgICAqLy8qKlxyXG4gICAgICogU2V0cyB0byBhIHNwZWNpZmljIHN0eWxlXHJcbiAgICAgKiBAcGFyYW0ge1N0eWxlfSBzdHlsZSAtIFN0eWxlIG9iamVjdCBnaXZlbiBmcm9tIHN0eWxlc2hlZXQuY3JlYXRlU3R5bGVcclxuICAgICAqIEByZXR1cm5zIHtDZWxsfSBUaGUgY2VsbC5cclxuICAgICAqL1xyXG4gICAgc3R5bGUoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLl9zdHlsZSAmJiAhKGFyZ3VtZW50c1swXSBpbnN0YW5jZW9mIFN0eWxlKSkge1xyXG4gICAgICAgICAgICB0aGlzLl9zdHlsZSA9IHRoaXMud29ya2Jvb2soKS5zdHlsZVNoZWV0KCkuY3JlYXRlU3R5bGUodGhpcy5fc3R5bGVJZCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gbmV3IEFyZ0hhbmRsZXIoXCJDZWxsLnN0eWxlXCIpXHJcbiAgICAgICAgICAgIC5jYXNlKCdzdHJpbmcnLCBuYW1lID0+IHtcclxuICAgICAgICAgICAgICAgIC8vIEdldCBzaW5nbGUgdmFsdWVcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9zdHlsZS5zdHlsZShuYW1lKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoJ2FycmF5JywgbmFtZXMgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gR2V0IGxpc3Qgb2YgdmFsdWVzXHJcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZXMgPSB7fTtcclxuICAgICAgICAgICAgICAgIG5hbWVzLmZvckVhY2gobmFtZSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVzW25hbWVdID0gdGhpcy5zdHlsZShuYW1lKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZXM7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKFtcInN0cmluZ1wiLCBcImFycmF5XCJdLCAobmFtZSwgdmFsdWVzKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBudW1Sb3dzID0gdmFsdWVzLmxlbmd0aDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG51bUNvbHMgPSB2YWx1ZXNbMF0ubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcmFuZ2UgPSB0aGlzLnJhbmdlVG8odGhpcy5yZWxhdGl2ZUNlbGwobnVtUm93cyAtIDEsIG51bUNvbHMgLSAxKSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmFuZ2Uuc3R5bGUobmFtZSwgdmFsdWVzKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoWydzdHJpbmcnLCAnKiddLCAobmFtZSwgdmFsdWUpID0+IHtcclxuICAgICAgICAgICAgICAgIC8vIFNldCBhIHNpbmdsZSB2YWx1ZSBmb3IgYWxsIGNlbGxzIHRvIGEgc2luZ2xlIHZhbHVlXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zdHlsZS5zdHlsZShuYW1lLCB2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoJ29iamVjdCcsIG5hbWVWYWx1ZXMgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gT2JqZWN0IG9mIGtleSB2YWx1ZSBwYWlycyB0byBzZXRcclxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgbmFtZSBpbiBuYW1lVmFsdWVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFuYW1lVmFsdWVzLmhhc093blByb3BlcnR5KG5hbWUpKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IG5hbWVWYWx1ZXNbbmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHlsZShuYW1lLCB2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKCdTdHlsZScsIHN0eWxlID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3N0eWxlID0gc3R5bGU7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zdHlsZUlkID0gc3R5bGUuaWQoKTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmhhbmRsZShhcmd1bWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgdmFsdWUgb2YgdGhlIGNlbGwuXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfGJvb2xlYW58bnVtYmVyfERhdGV8UmljaFRleHR8dW5kZWZpbmVkfSBUaGUgdmFsdWUgb2YgdGhlIGNlbGwuXHJcbiAgICAgKi8vKipcclxuICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBjZWxsLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd8Ym9vbGVhbnxudW1iZXJ8bnVsbHx1bmRlZmluZWR8UmljaFRleHR9IHZhbHVlIC0gVGhlIHZhbHVlIHRvIHNldC5cclxuICAgICAqIEByZXR1cm5zIHtDZWxsfSBUaGUgY2VsbC5cclxuICAgICAqLy8qKlxyXG4gICAgICogU2V0cyB0aGUgdmFsdWVzIGluIHRoZSByYW5nZSBzdGFydGluZyB3aXRoIHRoZSBjZWxsLlxyXG4gICAgICogQHBhcmFtIHtBcnJheS48QXJyYXkuPHN0cmluZ3xib29sZWFufG51bWJlcnxudWxsfHVuZGVmaW5lZD4+fSAtIDJEIGFycmF5IG9mIHZhbHVlcyB0byBzZXQuXHJcbiAgICAgKiBAcmV0dXJucyB7UmFuZ2V9IFRoZSByYW5nZSB0aGF0IHdhcyBzZXQuXHJcbiAgICAgKi9cclxuICAgIHZhbHVlKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQXJnSGFuZGxlcignQ2VsbC52YWx1ZScpXHJcbiAgICAgICAgICAgIC5jYXNlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl92YWx1ZSBpbnN0YW5jZW9mIFJpY2hUZXh0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlLmdldEluc3RhbmNlV2l0aENlbGxSZWYodGhpcyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fdmFsdWU7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKFwiYXJyYXlcIiwgdmFsdWVzID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG51bVJvd3MgPSB2YWx1ZXMubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbnVtQ29scyA9IHZhbHVlc1swXS5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByYW5nZSA9IHRoaXMucmFuZ2VUbyh0aGlzLnJlbGF0aXZlQ2VsbChudW1Sb3dzIC0gMSwgbnVtQ29scyAtIDEpKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiByYW5nZS52YWx1ZSh2YWx1ZXMpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnKicsIHZhbHVlID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2xlYXIoKTtcclxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFJpY2hUZXh0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdmFsdWUgPSB2YWx1ZS5jb3B5KHRoaXMpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZSA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5oYW5kbGUoYXJndW1lbnRzKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIHBhcmVudCB3b3JrYm9vay5cclxuICAgICAqIEByZXR1cm5zIHtXb3JrYm9va30gVGhlIHBhcmVudCB3b3JrYm9vay5cclxuICAgICAqL1xyXG4gICAgd29ya2Jvb2soKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucm93KCkud29ya2Jvb2soKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFwcGVuZCBob3Jpem9udGFsIHBhZ2UgYnJlYWsgYWZ0ZXIgdGhlIGNlbGwuXHJcbiAgICAgKiBAcmV0dXJucyB7Q2VsbH0gdGhlIGNlbGwuXHJcbiAgICAgKi9cclxuICAgIGFkZEhvcml6b250YWxQYWdlQnJlYWsoKSB7XHJcbiAgICAgICAgdGhpcy5yb3coKS5hZGRQYWdlQnJlYWsoKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICAvKiBJTlRFUk5BTCAqL1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgZm9ybXVsYSBpZiBhIHNoYXJlZCBmb3JtdWxhIHJlZiBjZWxsLlxyXG4gICAgICogQHJldHVybnMge3N0cmluZ3x1bmRlZmluZWR9IFRoZSBmb3JtdWxhLlxyXG4gICAgICogQGlnbm9yZVxyXG4gICAgICovXHJcbiAgICBnZXRTaGFyZWRSZWZGb3JtdWxhKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9mb3JtdWxhVHlwZSA9PT0gXCJzaGFyZWRcIiA/IHRoaXMuX2Zvcm11bGFSZWYgJiYgdGhpcy5fZm9ybXVsYSA6IHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENoZWNrIGlmIHRoaXMgY2VsbCB1c2VzIGEgZ2l2ZW4gc2hhcmVkIGEgZm9ybXVsYSBJRC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpZCAtIFRoZSBzaGFyZWQgZm9ybXVsYSBJRC5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBBIGZsYWcgaW5kaWNhdGluZyBpZiBzaGFyZWQuXHJcbiAgICAgKiBAaWdub3JlXHJcbiAgICAgKi9cclxuICAgIHNoYXJlc0Zvcm11bGEoaWQpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZm9ybXVsYVR5cGUgPT09IFwic2hhcmVkXCIgJiYgdGhpcy5fc2hhcmVkRm9ybXVsYUlkID09PSBpZDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldCBhIHNoYXJlZCBmb3JtdWxhIG9uIHRoZSBjZWxsLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGlkIC0gVGhlIHNoYXJlZCBmb3JtdWxhIGluZGV4LlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtmb3JtdWxhXSAtIFRoZSBmb3JtdWxhIChpZiB0aGUgcmVmZXJlbmNlIGNlbGwpLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzaGFyZWRSZWZdIC0gVGhlIGFkZHJlc3Mgb2YgdGhlIHNoYXJlZCByYW5nZSAoaWYgdGhlIHJlZmVyZW5jZSBjZWxsKS5cclxuICAgICAqIEByZXR1cm5zIHt1bmRlZmluZWR9XHJcbiAgICAgKiBAaWdub3JlXHJcbiAgICAgKi9cclxuICAgIHNldFNoYXJlZEZvcm11bGEoaWQsIGZvcm11bGEsIHNoYXJlZFJlZikge1xyXG4gICAgICAgIHRoaXMuY2xlYXIoKTtcclxuXHJcbiAgICAgICAgdGhpcy5fZm9ybXVsYVR5cGUgPSBcInNoYXJlZFwiO1xyXG4gICAgICAgIHRoaXMuX3NoYXJlZEZvcm11bGFJZCA9IGlkO1xyXG4gICAgICAgIHRoaXMuX2Zvcm11bGEgPSBmb3JtdWxhO1xyXG4gICAgICAgIHRoaXMuX2Zvcm11bGFSZWYgPSBzaGFyZWRSZWY7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0IHRoZSBjZWxsIHRvIGFuIFhNTCBvYmplY3QuXHJcbiAgICAgKiBAcmV0dXJucyB7e319IFRoZSBYTUwgZm9ybS5cclxuICAgICAqIEBpZ25vcmVcclxuICAgICAqL1xyXG4gICAgdG9YbWwoKSB7XHJcbiAgICAgICAgLy8gQ3JlYXRlIGEgbm9kZS5cclxuICAgICAgICBjb25zdCBub2RlID0ge1xyXG4gICAgICAgICAgICBuYW1lOiAnYycsXHJcbiAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHRoaXMuX3JlbWFpbmluZ0F0dHJpYnV0ZXMgfHwge30sIC8vIFN0YXJ0IHdpdGggYW55IHJlbWFpbmluZyBhdHRyaWJ1dGVzIHdlIGRvbid0IGN1cnJlbnQgaGFuZGxlLlxyXG4gICAgICAgICAgICBjaGlsZHJlbjogW11cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvLyBTZXQgdGhlIGFkZHJlc3MuXHJcbiAgICAgICAgbm9kZS5hdHRyaWJ1dGVzLnIgPSB0aGlzLmFkZHJlc3MoKTtcclxuXHJcbiAgICAgICAgaWYgKCFfLmlzTmlsKHRoaXMuX2Zvcm11bGFUeXBlKSkge1xyXG4gICAgICAgICAgICAvLyBBZGQgdGhlIGZvcm11bGEuXHJcbiAgICAgICAgICAgIGNvbnN0IGZOb2RlID0ge1xyXG4gICAgICAgICAgICAgICAgbmFtZTogJ2YnLFxyXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlczogdGhpcy5fcmVtYWluaW5nRm9ybXVsYUF0dHJpYnV0ZXMgfHwge31cclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9mb3JtdWxhVHlwZSAhPT0gXCJub3JtYWxcIikgZk5vZGUuYXR0cmlidXRlcy50ID0gdGhpcy5fZm9ybXVsYVR5cGU7XHJcbiAgICAgICAgICAgIGlmICghXy5pc05pbCh0aGlzLl9mb3JtdWxhUmVmKSkgZk5vZGUuYXR0cmlidXRlcy5yZWYgPSB0aGlzLl9mb3JtdWxhUmVmO1xyXG4gICAgICAgICAgICBpZiAoIV8uaXNOaWwodGhpcy5fc2hhcmVkRm9ybXVsYUlkKSkgZk5vZGUuYXR0cmlidXRlcy5zaSA9IHRoaXMuX3NoYXJlZEZvcm11bGFJZDtcclxuICAgICAgICAgICAgaWYgKCFfLmlzTmlsKHRoaXMuX2Zvcm11bGEpKSBmTm9kZS5jaGlsZHJlbiA9IFt0aGlzLl9mb3JtdWxhXTtcclxuXHJcbiAgICAgICAgICAgIG5vZGUuY2hpbGRyZW4ucHVzaChmTm9kZSk7XHJcbiAgICAgICAgfSBlbHNlIGlmICghXy5pc05pbCh0aGlzLl92YWx1ZSkpIHtcclxuICAgICAgICAgICAgLy8gQWRkIHRoZSB2YWx1ZS4gRG9uJ3QgZW1pdCB2YWx1ZSBpZiBhIGZvcm11bGEgaXMgc2V0IGFzIEV4Y2VsIHdpbGwgc2hvdyB0aGlzIHN0YWxlIHZhbHVlLlxyXG4gICAgICAgICAgICBsZXQgdHlwZSwgdGV4dDtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl92YWx1ZSA9PT0gXCJzdHJpbmdcIikge1xyXG4gICAgICAgICAgICAgICAgdHlwZSA9IFwic1wiO1xyXG4gICAgICAgICAgICAgICAgdGV4dCA9IHRoaXMud29ya2Jvb2soKS5zaGFyZWRTdHJpbmdzKCkuZ2V0SW5kZXhGb3JTdHJpbmcodGhpcy5fdmFsdWUpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLl92YWx1ZSA9PT0gXCJib29sZWFuXCIpIHtcclxuICAgICAgICAgICAgICAgIHR5cGUgPSBcImJcIjtcclxuICAgICAgICAgICAgICAgIHRleHQgPSB0aGlzLl92YWx1ZSA/IDEgOiAwO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLl92YWx1ZSA9PT0gXCJudW1iZXJcIikge1xyXG4gICAgICAgICAgICAgICAgdGV4dCA9IHRoaXMuX3ZhbHVlO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX3ZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgdGV4dCA9IGRhdGVDb252ZXJ0ZXIuZGF0ZVRvTnVtYmVyKHRoaXMuX3ZhbHVlKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLl92YWx1ZSBpbnN0YW5jZW9mIFJpY2hUZXh0IHx8IHR5cGVvZiB0aGlzLl92YWx1ZSA9PT0gXCJvYmplY3RcIiAmJiB0aGlzLl92YWx1ZS5jb25zdHJ1Y3Rvci5uYW1lID09PSBcIlJpY2hUZXh0XCIpIHsgLy8gSGFjayB0byBtYWtlIEphc21pbmUgdGVzdCB3b3JrXHJcbiAgICAgICAgICAgICAgICB0eXBlID0gXCJzXCI7XHJcbiAgICAgICAgICAgICAgICB0ZXh0ID0gdGhpcy53b3JrYm9vaygpLnNoYXJlZFN0cmluZ3MoKS5nZXRJbmRleEZvclN0cmluZyh0aGlzLl92YWx1ZS50b1htbCgpKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHR5cGUpIG5vZGUuYXR0cmlidXRlcy50ID0gdHlwZTtcclxuICAgICAgICAgICAgY29uc3Qgdk5vZGUgPSB7IG5hbWU6ICd2JywgY2hpbGRyZW46IFt0ZXh0XSB9O1xyXG4gICAgICAgICAgICBub2RlLmNoaWxkcmVuLnB1c2godk5vZGUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gSWYgdGhlIHN0eWxlIGlzIHNldCwgc2V0IHRoZSBzdHlsZSBJRC5cclxuICAgICAgICBpZiAoIV8uaXNOaWwodGhpcy5fc3R5bGUpKSB7XHJcbiAgICAgICAgICAgIG5vZGUuYXR0cmlidXRlcy5zID0gdGhpcy5fc3R5bGUuaWQoKTtcclxuICAgICAgICB9IGVsc2UgaWYgKCFfLmlzTmlsKHRoaXMuX3N0eWxlSWQpKSB7XHJcbiAgICAgICAgICAgIG5vZGUuYXR0cmlidXRlcy5zID0gdGhpcy5fc3R5bGVJZDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEFkZCBhbnkgcmVtYWluaW5nIGNoaWxkcmVuIHRoYXQgd2UgZG9uJ3QgY3VycmVudGx5IGhhbmRsZS5cclxuICAgICAgICBpZiAodGhpcy5fcmVtYWluaW5nQ2hpbGRyZW4pIHtcclxuICAgICAgICAgICAgbm9kZS5jaGlsZHJlbiA9IG5vZGUuY2hpbGRyZW4uY29uY2F0KHRoaXMuX3JlbWFpbmluZ0NoaWxkcmVuKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBub2RlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qIFBSSVZBVEUgKi9cclxuXHJcbiAgICAvKipcclxuICAgICAqIEluaXRpYWxpemUgdGhlIGNlbGwgbm9kZS5cclxuICAgICAqIEBwYXJhbSB7e318bnVtYmVyfSBub2RlT3JDb2x1bW5OdW1iZXIgLSBUaGUgZXhpc3Rpbmcgbm9kZSBvciB0aGUgY29sdW1uIG51bWJlciBvZiBhIG5ldyBjZWxsLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdHlsZUlkXSAtIFRoZSBzdHlsZSBJRCBmb3IgdGhlIG5ldyBjZWxsLlxyXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIF9pbml0KG5vZGVPckNvbHVtbk51bWJlciwgc3R5bGVJZCkge1xyXG4gICAgICAgIGlmIChfLmlzT2JqZWN0KG5vZGVPckNvbHVtbk51bWJlcikpIHtcclxuICAgICAgICAgICAgLy8gUGFyc2UgdGhlIGV4aXN0aW5nIG5vZGUuXHJcbiAgICAgICAgICAgIHRoaXMuX3BhcnNlTm9kZShub2RlT3JDb2x1bW5OdW1iZXIpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIFRoaXMgaXMgYSBuZXcgY2VsbC5cclxuICAgICAgICAgICAgdGhpcy5fY29sdW1uTnVtYmVyID0gbm9kZU9yQ29sdW1uTnVtYmVyO1xyXG4gICAgICAgICAgICBpZiAoIV8uaXNOaWwoc3R5bGVJZCkpIHRoaXMuX3N0eWxlSWQgPSBzdHlsZUlkO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFBhcnNlIHRoZSBleGlzdGluZyBub2RlLlxyXG4gICAgICogQHBhcmFtIHt7fX0gbm9kZSAtIFRoZSBleGlzdGluZyBub2RlLlxyXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIF9wYXJzZU5vZGUobm9kZSkge1xyXG4gICAgICAgIC8vIFBhcnNlIHRoZSBjb2x1bW4gbnVtYnIgb3V0IG9mIHRoZSBhZGRyZXNzLlxyXG4gICAgICAgIGNvbnN0IHJlZiA9IGFkZHJlc3NDb252ZXJ0ZXIuZnJvbUFkZHJlc3Mobm9kZS5hdHRyaWJ1dGVzLnIpO1xyXG4gICAgICAgIHRoaXMuX2NvbHVtbk51bWJlciA9IHJlZi5jb2x1bW5OdW1iZXI7XHJcblxyXG4gICAgICAgIC8vIFN0b3JlIHRoZSBzdHlsZSBJRCBpZiBwcmVzZW50LlxyXG4gICAgICAgIGlmICghXy5pc05pbChub2RlLmF0dHJpYnV0ZXMucykpIHRoaXMuX3N0eWxlSWQgPSBub2RlLmF0dHJpYnV0ZXMucztcclxuXHJcbiAgICAgICAgLy8gUGFyc2UgdGhlIGZvcm11bGEgaWYgcHJlc2VudC4uXHJcbiAgICAgICAgY29uc3QgZk5vZGUgPSB4bWxxLmZpbmRDaGlsZChub2RlLCAnZicpO1xyXG4gICAgICAgIGlmIChmTm9kZSkge1xyXG4gICAgICAgICAgICB0aGlzLl9mb3JtdWxhVHlwZSA9IGZOb2RlLmF0dHJpYnV0ZXMudCB8fCBcIm5vcm1hbFwiO1xyXG4gICAgICAgICAgICB0aGlzLl9mb3JtdWxhUmVmID0gZk5vZGUuYXR0cmlidXRlcy5yZWY7XHJcbiAgICAgICAgICAgIHRoaXMuX2Zvcm11bGEgPSBmTm9kZS5jaGlsZHJlblswXTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuX3NoYXJlZEZvcm11bGFJZCA9IGZOb2RlLmF0dHJpYnV0ZXMuc2k7XHJcbiAgICAgICAgICAgIGlmICghXy5pc05pbCh0aGlzLl9zaGFyZWRGb3JtdWxhSWQpKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgdGhlIHNoZWV0J3MgbWF4IHNoYXJlZCBmb3JtdWxhIElEIHNvIHdlIGNhbiBzZXQgZnV0dXJlIElEcyBhbiBpbmRleCBiZXlvbmQgdGhpcy5cclxuICAgICAgICAgICAgICAgIHRoaXMuc2hlZXQoKS51cGRhdGVNYXhTaGFyZWRGb3JtdWxhSWQodGhpcy5fc2hhcmVkRm9ybXVsYUlkKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gRGVsZXRlIHRoZSBrbm93biBhdHRyaWJ1dGVzLlxyXG4gICAgICAgICAgICBkZWxldGUgZk5vZGUuYXR0cmlidXRlcy50O1xyXG4gICAgICAgICAgICBkZWxldGUgZk5vZGUuYXR0cmlidXRlcy5yZWY7XHJcbiAgICAgICAgICAgIGRlbGV0ZSBmTm9kZS5hdHRyaWJ1dGVzLnNpO1xyXG5cclxuICAgICAgICAgICAgLy8gSWYgYW55IHVua25vd24gYXR0cmlidXRlcyBhcmUgc3RpbGwgcHJlc2VudCwgc3RvcmUgdGhlbSBmb3IgbGF0ZXIgb3V0cHV0LlxyXG4gICAgICAgICAgICBpZiAoIV8uaXNFbXB0eShmTm9kZS5hdHRyaWJ1dGVzKSkgdGhpcy5fcmVtYWluaW5nRm9ybXVsYUF0dHJpYnV0ZXMgPSBmTm9kZS5hdHRyaWJ1dGVzO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gUGFyc2UgdGhlIHZhbHVlLlxyXG4gICAgICAgIGNvbnN0IHR5cGUgPSBub2RlLmF0dHJpYnV0ZXMudDtcclxuICAgICAgICBpZiAodHlwZSA9PT0gXCJzXCIpIHtcclxuICAgICAgICAgICAgLy8gU3RyaW5nIHZhbHVlLlxyXG4gICAgICAgICAgICBjb25zdCB2Tm9kZSA9IHhtbHEuZmluZENoaWxkKG5vZGUsICd2Jyk7XHJcbiAgICAgICAgICAgIGlmICh2Tm9kZSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc2hhcmVkSW5kZXggPSB2Tm9kZS5jaGlsZHJlblswXTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3ZhbHVlID0gdGhpcy53b3JrYm9vaygpLnNoYXJlZFN0cmluZ3MoKS5nZXRTdHJpbmdCeUluZGV4KHNoYXJlZEluZGV4KTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyByaWNoIHRleHRcclxuICAgICAgICAgICAgICAgIGlmIChfLmlzQXJyYXkodGhpcy5fdmFsdWUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdmFsdWUgPSBuZXcgUmljaFRleHQodGhpcy5fdmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdmFsdWUgPSAnJztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gXCJzdHJcIikge1xyXG4gICAgICAgICAgICAvLyBTaW1wbGUgc3RyaW5nIHZhbHVlLlxyXG4gICAgICAgICAgICBjb25zdCB2Tm9kZSA9IHhtbHEuZmluZENoaWxkKG5vZGUsICd2Jyk7XHJcbiAgICAgICAgICAgIHRoaXMuX3ZhbHVlID0gdk5vZGUgJiYgdk5vZGUuY2hpbGRyZW5bMF07XHJcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSBcImlubGluZVN0clwiKSB7XHJcbiAgICAgICAgICAgIC8vIElubGluZSBzdHJpbmcgdmFsdWU6IGNhbiBiZSBzaW1wbGUgdGV4dCBvciByaWNoIHRleHQuXHJcbiAgICAgICAgICAgIGNvbnN0IGlzTm9kZSA9IHhtbHEuZmluZENoaWxkKG5vZGUsICdpcycpO1xyXG4gICAgICAgICAgICBpZiAoaXNOb2RlLmNoaWxkcmVuWzBdLm5hbWUgPT09IFwidFwiKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB0Tm9kZSA9IGlzTm9kZS5jaGlsZHJlblswXTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3ZhbHVlID0gdE5vZGUuY2hpbGRyZW5bMF07XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl92YWx1ZSA9IGlzTm9kZS5jaGlsZHJlbjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gXCJiXCIpIHtcclxuICAgICAgICAgICAgLy8gQm9vbGVhbiB2YWx1ZS5cclxuICAgICAgICAgICAgdGhpcy5fdmFsdWUgPSB4bWxxLmZpbmRDaGlsZChub2RlLCAndicpLmNoaWxkcmVuWzBdID09PSAxO1xyXG4gICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gXCJlXCIpIHtcclxuICAgICAgICAgICAgLy8gRXJyb3IgdmFsdWUuXHJcbiAgICAgICAgICAgIGNvbnN0IGVycm9yID0geG1scS5maW5kQ2hpbGQobm9kZSwgJ3YnKS5jaGlsZHJlblswXTtcclxuICAgICAgICAgICAgdGhpcy5fdmFsdWUgPSBGb3JtdWxhRXJyb3IuZ2V0RXJyb3IoZXJyb3IpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIE51bWJlciB2YWx1ZS5cclxuICAgICAgICAgICAgY29uc3Qgdk5vZGUgPSB4bWxxLmZpbmRDaGlsZChub2RlLCAndicpO1xyXG4gICAgICAgICAgICB0aGlzLl92YWx1ZSA9IHZOb2RlICYmIE51bWJlcih2Tm9kZS5jaGlsZHJlblswXSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBEZWxldGUga25vd24gYXR0cmlidXRlcy5cclxuICAgICAgICBkZWxldGUgbm9kZS5hdHRyaWJ1dGVzLnI7XHJcbiAgICAgICAgZGVsZXRlIG5vZGUuYXR0cmlidXRlcy5zO1xyXG4gICAgICAgIGRlbGV0ZSBub2RlLmF0dHJpYnV0ZXMudDtcclxuXHJcbiAgICAgICAgLy8gSWYgYW55IHVua25vd24gYXR0cmlidXRlcyBhcmUgc3RpbGwgcHJlc2VudCwgc3RvcmUgdGhlbSBmb3IgbGF0ZXIgb3V0cHV0LlxyXG4gICAgICAgIGlmICghXy5pc0VtcHR5KG5vZGUuYXR0cmlidXRlcykpIHRoaXMuX3JlbWFpbmluZ0F0dHJpYnV0ZXMgPSBub2RlLmF0dHJpYnV0ZXM7XHJcblxyXG4gICAgICAgIC8vIERlbGV0ZSBrbm93biBjaGlsZHJlbi5cclxuICAgICAgICB4bWxxLnJlbW92ZUNoaWxkKG5vZGUsICdmJyk7XHJcbiAgICAgICAgeG1scS5yZW1vdmVDaGlsZChub2RlLCAndicpO1xyXG4gICAgICAgIHhtbHEucmVtb3ZlQ2hpbGQobm9kZSwgJ2lzJyk7XHJcblxyXG4gICAgICAgIC8vIElmIGFueSB1bmtub3duIGNoaWxkcmVuIGFyZSBzdGlsbCBwcmVzZW50LCBzdG9yZSB0aGVtIGZvciBsYXRlciBvdXRwdXQuXHJcbiAgICAgICAgaWYgKCFfLmlzRW1wdHkobm9kZS5jaGlsZHJlbikpIHRoaXMuX3JlbWFpbmluZ0NoaWxkcmVuID0gbm9kZS5jaGlsZHJlbjtcclxuICAgIH1cclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBDZWxsO1xyXG5cclxuLypcclxuPGMgcj1cIkE2XCIgcz1cIjFcIiB0PVwic1wiPlxyXG4gICAgPHY+Mjwvdj5cclxuPC9jPlxyXG4qL1xyXG5cclxuIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG5jb25zdCBBcmdIYW5kbGVyID0gcmVxdWlyZShcIi4vQXJnSGFuZGxlclwiKTtcclxuY29uc3QgYWRkcmVzc0NvbnZlcnRlciA9IHJlcXVpcmUoJy4vYWRkcmVzc0NvbnZlcnRlcicpO1xyXG5cclxuLy8gRGVmYXVsdCBjb2x1bW4gd2lkdGguXHJcbmNvbnN0IGRlZmF1bHRDb2x1bW5XaWR0aCA9IDkuMTQwNjI1O1xyXG5cclxuLyoqXHJcbiAqIEEgY29sdW1uLlxyXG4gKi9cclxuY2xhc3MgQ29sdW1uIHtcclxuICAgIC8vIC8qKlxyXG4gICAgLy8gICogQ3JlYXRlcyBhIG5ldyBDb2x1bW4uXHJcbiAgICAvLyAgKiBAcGFyYW0ge1NoZWV0fSBzaGVldCAtIFRoZSBwYXJlbnQgc2hlZXQuXHJcbiAgICAvLyAgKiBAcGFyYW0ge3t9fSBub2RlIC0gVGhlIGNvbHVtbiBub2RlLlxyXG4gICAgLy8gICogQGNvbnN0cnVjdG9yXHJcbiAgICAvLyAgKiBAaWdub3JlXHJcbiAgICAvLyAgKiBAcHJpdmF0ZVxyXG4gICAgLy8gICovXHJcbiAgICBjb25zdHJ1Y3RvcihzaGVldCwgbm9kZSkge1xyXG4gICAgICAgIHRoaXMuX3NoZWV0ID0gc2hlZXQ7XHJcbiAgICAgICAgdGhpcy5fbm9kZSA9IG5vZGU7XHJcbiAgICB9XHJcblxyXG4gICAgLyogUFVCTElDICovXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXQgdGhlIGFkZHJlc3Mgb2YgdGhlIGNvbHVtbi5cclxuICAgICAqIEBwYXJhbSB7e319IFtvcHRzXSAtIE9wdGlvbnNcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuaW5jbHVkZVNoZWV0TmFtZV0gLSBJbmNsdWRlIHRoZSBzaGVldCBuYW1lIGluIHRoZSBhZGRyZXNzLlxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5hbmNob3JlZF0gLSBBbmNob3IgdGhlIGFkZHJlc3MuXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgYWRkcmVzc1xyXG4gICAgICovXHJcbiAgICBhZGRyZXNzKG9wdHMpIHtcclxuICAgICAgICByZXR1cm4gYWRkcmVzc0NvbnZlcnRlci50b0FkZHJlc3Moe1xyXG4gICAgICAgICAgICB0eXBlOiAnY29sdW1uJyxcclxuICAgICAgICAgICAgY29sdW1uTmFtZTogdGhpcy5jb2x1bW5OYW1lKCksXHJcbiAgICAgICAgICAgIHNoZWV0TmFtZTogb3B0cyAmJiBvcHRzLmluY2x1ZGVTaGVldE5hbWUgJiYgdGhpcy5zaGVldCgpLm5hbWUoKSxcclxuICAgICAgICAgICAgY29sdW1uQW5jaG9yZWQ6IG9wdHMgJiYgb3B0cy5hbmNob3JlZFxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0IGEgY2VsbCB3aXRoaW4gdGhlIGNvbHVtbi5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByb3dOdW1iZXIgLSBUaGUgcm93IG51bWJlci5cclxuICAgICAqIEByZXR1cm5zIHtDZWxsfSBUaGUgY2VsbCBpbiB0aGUgY29sdW1uIHdpdGggdGhlIGdpdmVuIHJvdyBudW1iZXIuXHJcbiAgICAgKi9cclxuICAgIGNlbGwocm93TnVtYmVyKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc2hlZXQoKS5jZWxsKHJvd051bWJlciwgdGhpcy5jb2x1bW5OdW1iZXIoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXQgdGhlIG5hbWUgb2YgdGhlIGNvbHVtbi5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjb2x1bW4gbmFtZS5cclxuICAgICAqL1xyXG4gICAgY29sdW1uTmFtZSgpIHtcclxuICAgICAgICByZXR1cm4gYWRkcmVzc0NvbnZlcnRlci5jb2x1bW5OdW1iZXJUb05hbWUodGhpcy5jb2x1bW5OdW1iZXIoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXQgdGhlIG51bWJlciBvZiB0aGUgY29sdW1uLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVGhlIGNvbHVtbiBudW1iZXIuXHJcbiAgICAgKi9cclxuICAgIGNvbHVtbk51bWJlcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbm9kZS5hdHRyaWJ1dGVzLm1pbjtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgYSB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGNvbHVtbiBpcyBoaWRkZW4uXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gQSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGUgY29sdW1uIGlzIGhpZGRlbi5cclxuICAgICAqLy8qKlxyXG4gICAgICogU2V0cyB3aGV0aGVyIHRoZSBjb2x1bW4gaXMgaGlkZGVuLlxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBoaWRkZW4gLSBBIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRvIGhpZGUgdGhlIGNvbHVtbi5cclxuICAgICAqIEByZXR1cm5zIHtDb2x1bW59IFRoZSBjb2x1bW4uXHJcbiAgICAgKi9cclxuICAgIGhpZGRlbigpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEFyZ0hhbmRsZXIoXCJDb2x1bW4uaGlkZGVuXCIpXHJcbiAgICAgICAgICAgIC5jYXNlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9ub2RlLmF0dHJpYnV0ZXMuaGlkZGVuID09PSAxO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnYm9vbGVhbicsIGhpZGRlbiA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaGlkZGVuKSB0aGlzLl9ub2RlLmF0dHJpYnV0ZXMuaGlkZGVuID0gMTtcclxuICAgICAgICAgICAgICAgIGVsc2UgZGVsZXRlIHRoaXMuX25vZGUuYXR0cmlidXRlcy5oaWRkZW47XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmhhbmRsZShhcmd1bWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0IHRoZSBwYXJlbnQgc2hlZXQuXHJcbiAgICAgKiBAcmV0dXJucyB7U2hlZXR9IFRoZSBwYXJlbnQgc2hlZXQuXHJcbiAgICAgKi9cclxuICAgIHNoZWV0KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaGVldDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgYW4gaW5kaXZpZHVhbCBzdHlsZS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHN0eWxlLlxyXG4gICAgICogQHJldHVybnMgeyp9IFRoZSBzdHlsZS5cclxuICAgICAqLy8qKlxyXG4gICAgICogR2V0cyBtdWx0aXBsZSBzdHlsZXMuXHJcbiAgICAgKiBAcGFyYW0ge0FycmF5LjxzdHJpbmc+fSBuYW1lcyAtIFRoZSBuYW1lcyBvZiB0aGUgc3R5bGUuXHJcbiAgICAgKiBAcmV0dXJucyB7b2JqZWN0LjxzdHJpbmcsICo+fSBPYmplY3Qgd2hvc2Uga2V5cyBhcmUgdGhlIHN0eWxlIG5hbWVzIGFuZCB2YWx1ZXMgYXJlIHRoZSBzdHlsZXMuXHJcbiAgICAgKi8vKipcclxuICAgICAqIFNldHMgYW4gaW5kaXZpZHVhbCBzdHlsZS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHN0eWxlLlxyXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBzZXQuXHJcbiAgICAgKiBAcmV0dXJucyB7Q2VsbH0gVGhlIGNlbGwuXHJcbiAgICAgKi8vKipcclxuICAgICAqIFNldHMgbXVsdGlwbGUgc3R5bGVzLlxyXG4gICAgICogQHBhcmFtIHtvYmplY3QuPHN0cmluZywgKj59IHN0eWxlcyAtIE9iamVjdCB3aG9zZSBrZXlzIGFyZSB0aGUgc3R5bGUgbmFtZXMgYW5kIHZhbHVlcyBhcmUgdGhlIHN0eWxlcyB0byBzZXQuXHJcbiAgICAgKiBAcmV0dXJucyB7Q2VsbH0gVGhlIGNlbGwuXHJcbiAgICAgKi8vKipcclxuXHQgKiBTZXRzIHRvIGEgc3BlY2lmaWMgc3R5bGVcclxuXHQgKiBAcGFyYW0ge1N0eWxlfSBzdHlsZSAtIFN0eWxlIG9iamVjdCBnaXZlbiBmcm9tIHN0eWxlc2hlZXQuY3JlYXRlU3R5bGVcclxuXHQgKiBAcmV0dXJucyB7Q2VsbH0gVGhlIGNlbGwuXHJcblx0ICovXHJcbiAgICBzdHlsZSgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEFyZ0hhbmRsZXIoXCJDb2x1bW4uc3R5bGVcIilcclxuICAgICAgICAgICAgLmNhc2UoJ3N0cmluZycsIG5hbWUgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gR2V0IHNpbmdsZSB2YWx1ZVxyXG4gICAgICAgICAgICAgICAgdGhpcy5fY3JlYXRlU3R5bGVJZk5lZWRlZCgpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3N0eWxlLnN0eWxlKG5hbWUpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnYXJyYXknLCBuYW1lcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBHZXQgbGlzdCBvZiB2YWx1ZXNcclxuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlcyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgbmFtZXMuZm9yRWFjaChuYW1lID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXNbbmFtZV0gPSB0aGlzLnN0eWxlKG5hbWUpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoWydzdHJpbmcnLCAnKiddLCAobmFtZSwgdmFsdWUpID0+IHtcclxuICAgICAgICAgICAgICAgIC8vIElmIGEgcm93IG5vZGUgaXMgYWxyZWFkeSBkZWZpbmVkIHRoYXQgaW50ZXJzZWN0cyB3aXRoIHRoaXMgY29sdW1uIGFuZCB0aGF0IHJvdyBoYXMgYSBzdHlsZSBzZXQsIHdlXHJcbiAgICAgICAgICAgICAgICAvLyBuZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IGEgY2VsbCBub2RlIGV4aXN0cyBhdCB0aGUgaW50ZXJzZWN0aW9uIHNvIHdlIGNhbiBzdHlsZSBpdCBhcHByb3ByaWF0ZWx5LlxyXG4gICAgICAgICAgICAgICAgLy8gRmV0Y2hpbmcgdGhlIGNlbGwgd2lsbCBmb3JjZSBhIG5ldyBjZWxsIG5vZGUgdG8gYmUgY3JlYXRlZCB3aXRoIGEgc3R5bGUgbWF0Y2hpbmcgdGhlIGNvbHVtbi4gU28gd2VcclxuICAgICAgICAgICAgICAgIC8vIHdpbGwgZmV0Y2ggYW5kIHN0eWxlIHRoZSBjZWxsIGF0IGVhY2ggcm93IHRoYXQgaW50ZXJzZWN0cyB0aGlzIGNvbHVtbiBpZiBpdCBpcyBhbHJlYWR5IHByZXNlbnQgb3IgaXRcclxuICAgICAgICAgICAgICAgIC8vIGhhcyBhIHN0eWxlIGRlZmluZWQuXHJcbiAgICAgICAgICAgICAgICB0aGlzLnNoZWV0KCkuZm9yRWFjaEV4aXN0aW5nUm93KHJvdyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJvdy5oYXNTdHlsZSgpIHx8IHJvdy5oYXNDZWxsKHRoaXMuY29sdW1uTnVtYmVyKCkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJvdy5jZWxsKHRoaXMuY29sdW1uTnVtYmVyKCkpLnN0eWxlKG5hbWUsIHZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBTZXQgYSBzaW5nbGUgdmFsdWUgZm9yIGFsbCBjZWxscyB0byBhIHNpbmdsZSB2YWx1ZVxyXG4gICAgICAgICAgICAgICAgdGhpcy5fY3JlYXRlU3R5bGVJZk5lZWRlZCgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fc3R5bGUuc3R5bGUobmFtZSwgdmFsdWUpO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnb2JqZWN0JywgbmFtZVZhbHVlcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBPYmplY3Qgb2Yga2V5IHZhbHVlIHBhaXJzIHRvIHNldFxyXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBuYW1lIGluIG5hbWVWYWx1ZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5hbWVWYWx1ZXMuaGFzT3duUHJvcGVydHkobmFtZSkpIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gbmFtZVZhbHVlc1tuYW1lXTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0eWxlKG5hbWUsIHZhbHVlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoJ1N0eWxlJywgc3R5bGUgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gU2VlIExhcmdlIENvbW1lbnQgQWJvdmVcclxuICAgICAgICAgICAgICAgIHRoaXMuc2hlZXQoKS5mb3JFYWNoRXhpc3RpbmdSb3cocm93ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocm93Lmhhc1N0eWxlKCkgfHwgcm93Lmhhc0NlbGwodGhpcy5jb2x1bW5OdW1iZXIoKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcm93LmNlbGwodGhpcy5jb2x1bW5OdW1iZXIoKSkuc3R5bGUoc3R5bGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuX3N0eWxlID0gc3R5bGU7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9ub2RlLmF0dHJpYnV0ZXMuc3R5bGUgPSBzdHlsZS5pZCgpO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuaGFuZGxlKGFyZ3VtZW50cyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSB3aWR0aC5cclxuICAgICAqIEByZXR1cm5zIHt1bmRlZmluZWR8bnVtYmVyfSBUaGUgd2lkdGggKG9yIHVuZGVmaW5lZCkuXHJcbiAgICAgKi8vKipcclxuICAgICAqIFNldHMgdGhlIHdpZHRoLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoIC0gVGhlIHdpZHRoIG9mIHRoZSBjb2x1bW4uXHJcbiAgICAgKiBAcmV0dXJucyB7Q29sdW1ufSBUaGUgY29sdW1uLlxyXG4gICAgICovXHJcbiAgICB3aWR0aCh3aWR0aCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQXJnSGFuZGxlcihcIkNvbHVtbi53aWR0aFwiKVxyXG4gICAgICAgICAgICAuY2FzZSgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbm9kZS5hdHRyaWJ1dGVzLmN1c3RvbVdpZHRoID8gdGhpcy5fbm9kZS5hdHRyaWJ1dGVzLndpZHRoIDogdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnbnVtYmVyJywgd2lkdGggPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fbm9kZS5hdHRyaWJ1dGVzLndpZHRoID0gd2lkdGg7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9ub2RlLmF0dHJpYnV0ZXMuY3VzdG9tV2lkdGggPSAxO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKCduaWwnLCAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5fbm9kZS5hdHRyaWJ1dGVzLndpZHRoO1xyXG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX25vZGUuYXR0cmlidXRlcy5jdXN0b21XaWR0aDtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuaGFuZGxlKGFyZ3VtZW50cyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXQgdGhlIHBhcmVudCB3b3JrYm9vay5cclxuICAgICAqIEByZXR1cm5zIHtXb3JrYm9va30gVGhlIHBhcmVudCB3b3JrYm9vay5cclxuICAgICAqL1xyXG4gICAgd29ya2Jvb2soKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc2hlZXQoKS53b3JrYm9vaygpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQXBwZW5kIHZlcnRpY2FsIHBhZ2UgYnJlYWsgYWZ0ZXIgdGhlIGNvbHVtbi5cclxuICAgICAqIEByZXR1cm5zIHtDb2x1bW59IHRoZSBjb2x1bW4uXHJcbiAgICAgKi9cclxuICAgIGFkZFBhZ2VCcmVhaygpIHtcclxuICAgICAgICB0aGlzLnNoZWV0KCkudmVydGljYWxQYWdlQnJlYWtzKCkuYWRkKHRoaXMuY29sdW1uTnVtYmVyKCkpO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qIElOVEVSTkFMICovXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0IHRoZSBjb2x1bW4gdG8gYW4gWE1MIG9iamVjdC5cclxuICAgICAqIEByZXR1cm5zIHt7fX0gVGhlIFhNTCBmb3JtLlxyXG4gICAgICogQGlnbm9yZVxyXG4gICAgICovXHJcbiAgICB0b1htbCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbm9kZTtcclxuICAgIH1cclxuXHJcbiAgICAvKiBQUklWQVRFICovXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGUgYSBzdHlsZSBmb3IgdGhpcyBjb2x1bW4gaWYgaXQgZG9lc24ndCBhbHJlYWR5IGV4aXN0LlxyXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIF9jcmVhdGVTdHlsZUlmTmVlZGVkKCkge1xyXG4gICAgICAgIGlmICghdGhpcy5fc3R5bGUpIHtcclxuICAgICAgICAgICAgY29uc3Qgc3R5bGVJZCA9IHRoaXMuX25vZGUuYXR0cmlidXRlcy5zdHlsZTtcclxuICAgICAgICAgICAgdGhpcy5fc3R5bGUgPSB0aGlzLndvcmtib29rKCkuc3R5bGVTaGVldCgpLmNyZWF0ZVN0eWxlKHN0eWxlSWQpO1xyXG4gICAgICAgICAgICB0aGlzLl9ub2RlLmF0dHJpYnV0ZXMuc3R5bGUgPSB0aGlzLl9zdHlsZS5pZCgpO1xyXG5cclxuICAgICAgICAgICAgaWYgKCF0aGlzLndpZHRoKCkpIHRoaXMud2lkdGgoZGVmYXVsdENvbHVtbldpZHRoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gQ29sdW1uO1xyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxuXHJcbmNvbnN0IF8gPSByZXF1aXJlKFwibG9kYXNoXCIpO1xyXG5cclxuLyoqXHJcbiAqIEEgY29udGVudCB0eXBlIGNvbGxlY3Rpb24uXHJcbiAqIEBpZ25vcmVcclxuICovXHJcbmNsYXNzIENvbnRlbnRUeXBlcyB7XHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgQ29udGVudFR5cGVzXHJcbiAgICAgKiBAcGFyYW0ge3t9fSBub2RlIC0gVGhlIG5vZGUuXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKG5vZGUpIHtcclxuICAgICAgICB0aGlzLl9ub2RlID0gbm9kZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFkZCBhIG5ldyBjb250ZW50IHR5cGUuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGFydE5hbWUgLSBUaGUgcGFydCBuYW1lLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNvbnRlbnRUeXBlIC0gVGhlIGNvbnRlbnQgdHlwZS5cclxuICAgICAqIEByZXR1cm5zIHt7fX0gVGhlIG5ldyBjb250ZW50IHR5cGUuXHJcbiAgICAgKi9cclxuICAgIGFkZChwYXJ0TmFtZSwgY29udGVudFR5cGUpIHtcclxuICAgICAgICBjb25zdCBub2RlID0ge1xyXG4gICAgICAgICAgICBuYW1lOiBcIk92ZXJyaWRlXCIsXHJcbiAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHtcclxuICAgICAgICAgICAgICAgIFBhcnROYW1lOiBwYXJ0TmFtZSxcclxuICAgICAgICAgICAgICAgIENvbnRlbnRUeXBlOiBjb250ZW50VHlwZVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgdGhpcy5fbm9kZS5jaGlsZHJlbi5wdXNoKG5vZGUpO1xyXG4gICAgICAgIHJldHVybiBub2RlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmluZCBhIGNvbnRlbnQgdHlwZSBieSBwYXJ0IG5hbWUuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGFydE5hbWUgLSBUaGUgcGFydCBuYW1lLlxyXG4gICAgICogQHJldHVybnMge3t9fHVuZGVmaW5lZH0gVGhlIG1hdGNoaW5nIGNvbnRlbnQgdHlwZSBvciB1bmRlZmluZWQgaWYgbm90IGZvdW5kLlxyXG4gICAgICovXHJcbiAgICBmaW5kQnlQYXJ0TmFtZShwYXJ0TmFtZSkge1xyXG4gICAgICAgIHJldHVybiBfLmZpbmQodGhpcy5fbm9kZS5jaGlsZHJlbiwgbm9kZSA9PiBub2RlLmF0dHJpYnV0ZXMuUGFydE5hbWUgPT09IHBhcnROYW1lKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnQgdGhlIGNvbGxlY3Rpb24gdG8gYW4gWE1MIG9iamVjdC5cclxuICAgICAqIEByZXR1cm5zIHt7fX0gVGhlIFhNTC5cclxuICAgICAqL1xyXG4gICAgdG9YbWwoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX25vZGU7XHJcbiAgICB9XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gQ29udGVudFR5cGVzO1xyXG5cclxuLypcclxuW0NvbnRlbnRfVHlwZXNdLnhtbFxyXG5cclxuPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVRGLThcIiBzdGFuZGFsb25lPVwieWVzXCI/PlxyXG48VHlwZXMgeG1sbnM9XCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvcGFja2FnZS8yMDA2L2NvbnRlbnQtdHlwZXNcIj5cclxuICAgIDxEZWZhdWx0IEV4dGVuc2lvbj1cImJpblwiIENvbnRlbnRUeXBlPVwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwucHJpbnRlclNldHRpbmdzXCIvPlxyXG4gICAgPERlZmF1bHQgRXh0ZW5zaW9uPVwicmVsc1wiIENvbnRlbnRUeXBlPVwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLXBhY2thZ2UucmVsYXRpb25zaGlwcyt4bWxcIi8+XHJcbiAgICA8RGVmYXVsdCBFeHRlbnNpb249XCJ4bWxcIiBDb250ZW50VHlwZT1cImFwcGxpY2F0aW9uL3htbFwiLz5cclxuICAgIDxPdmVycmlkZSBQYXJ0TmFtZT1cIi94bC93b3JrYm9vay54bWxcIiBDb250ZW50VHlwZT1cImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnNoZWV0Lm1haW4reG1sXCIvPlxyXG4gICAgPE92ZXJyaWRlIFBhcnROYW1lPVwiL3hsL3dvcmtzaGVldHMvc2hlZXQxLnhtbFwiIENvbnRlbnRUeXBlPVwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwud29ya3NoZWV0K3htbFwiLz5cclxuICAgIDxPdmVycmlkZSBQYXJ0TmFtZT1cIi94bC90aGVtZS90aGVtZTEueG1sXCIgQ29udGVudFR5cGU9XCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQudGhlbWUreG1sXCIvPlxyXG4gICAgPE92ZXJyaWRlIFBhcnROYW1lPVwiL3hsL3N0eWxlcy54bWxcIiBDb250ZW50VHlwZT1cImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnN0eWxlcyt4bWxcIi8+XHJcbiAgICA8T3ZlcnJpZGUgUGFydE5hbWU9XCIveGwvc2hhcmVkU3RyaW5ncy54bWxcIiBDb250ZW50VHlwZT1cImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnNoYXJlZFN0cmluZ3MreG1sXCIvPlxyXG4gICAgPE92ZXJyaWRlIFBhcnROYW1lPVwiL3hsL2NhbGNDaGFpbi54bWxcIiBDb250ZW50VHlwZT1cImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLmNhbGNDaGFpbit4bWxcIi8+XHJcbiAgICA8T3ZlcnJpZGUgUGFydE5hbWU9XCIvZG9jUHJvcHMvY29yZS54bWxcIiBDb250ZW50VHlwZT1cImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1wYWNrYWdlLmNvcmUtcHJvcGVydGllcyt4bWxcIi8+XHJcbiAgICA8T3ZlcnJpZGUgUGFydE5hbWU9XCIvZG9jUHJvcHMvYXBwLnhtbFwiIENvbnRlbnRUeXBlPVwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LmV4dGVuZGVkLXByb3BlcnRpZXMreG1sXCIvPlxyXG48L1R5cGVzPlxyXG4qL1xyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxuXHJcbmNvbnN0IGFsbG93ZWRQcm9wZXJ0aWVzID0ge1xyXG4gICAgdGl0bGU6IFwiZGM6dGl0bGVcIixcclxuICAgIHN1YmplY3Q6IFwiZGM6c3ViamVjdFwiLFxyXG4gICAgYXV0aG9yOiBcImRjOmNyZWF0b3JcIixcclxuICAgIGNyZWF0b3I6IFwiZGM6Y3JlYXRvclwiLFxyXG4gICAgZGVzY3JpcHRpb246IFwiZGM6ZGVzY3JpcHRpb25cIixcclxuICAgIGtleXdvcmRzOiBcImNwOmtleXdvcmRzXCIsXHJcbiAgICBjYXRlZ29yeTogXCJjcDpjYXRlZ29yeVwiXHJcbn07XHJcblxyXG4vKipcclxuICogQ29yZSBwcm9wZXJ0aWVzXHJcbiAqIEBpZ25vcmVcclxuICovXHJcbmNsYXNzIENvcmVQcm9wZXJ0aWVzIHtcclxuICAgIGNvbnN0cnVjdG9yKG5vZGUpIHtcclxuICAgICAgICB0aGlzLl9ub2RlID0gbm9kZTtcclxuICAgICAgICB0aGlzLl9wcm9wZXJ0aWVzID0ge307XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZXRzIGEgc3BlY2lmaWMgcHJvcGVydHkuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eS5cclxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgLSBUaGUgdmFsdWUgb2YgdGhlIHByb3BlcnR5LlxyXG4gICAgICogQHJldHVybnMge0NvcmVQcm9wZXJ0aWVzfSBDb3JlUHJvcGVydGllcy5cclxuICAgICAqL1xyXG4gICAgc2V0KG5hbWUsIHZhbHVlKSB7XHJcbiAgICAgICAgY29uc3Qga2V5ID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xyXG5cclxuICAgICAgICBpZiAodHlwZW9mIGFsbG93ZWRQcm9wZXJ0aWVzW2tleV0gPT09IFwidW5kZWZpbmVkXCIpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHByb3BlcnR5IG5hbWU6IFwiJHtuYW1lfVwiYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl9wcm9wZXJ0aWVzW2tleV0gPSB2YWx1ZTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXQgYSBzcGVjaWZpYyBwcm9wZXJ0eS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5LlxyXG4gICAgICogQHJldHVybnMgeyp9IFRoZSBwcm9wZXJ0eSB2YWx1ZS5cclxuICAgICAqL1xyXG4gICAgZ2V0KG5hbWUpIHtcclxuICAgICAgICBjb25zdCBrZXkgPSBuYW1lLnRvTG93ZXJDYXNlKCk7XHJcblxyXG4gICAgICAgIGlmICh0eXBlb2YgYWxsb3dlZFByb3BlcnRpZXNba2V5XSA9PT0gXCJ1bmRlZmluZWRcIikge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gcHJvcGVydHkgbmFtZTogXCIke25hbWV9XCJgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9wcm9wZXJ0aWVzW2tleV07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0IHRoZSBjb2xsZWN0aW9uIHRvIGFuIFhNTCBvYmplY3QuXHJcbiAgICAgKiBAcmV0dXJucyB7e319IFRoZSBYTUwuXHJcbiAgICAgKi9cclxuICAgIHRvWG1sKCkge1xyXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHRoaXMuX3Byb3BlcnRpZXMpIHtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLl9wcm9wZXJ0aWVzLmhhc093blByb3BlcnR5KGtleSkpIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB0aGlzLl9ub2RlLmNoaWxkcmVuLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgbmFtZTogYWxsb3dlZFByb3BlcnRpZXNba2V5XSxcclxuICAgICAgICAgICAgICAgIGNoaWxkcmVuOiBbdGhpcy5fcHJvcGVydGllc1trZXldXVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9ub2RlO1xyXG4gICAgfVxyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IENvcmVQcm9wZXJ0aWVzO1xyXG5cclxuLypcclxuZG9jUHJvcHMvY29yZS54bWxcclxuXHJcbjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIlVURi04XCIgc3RhbmRhbG9uZT1cInllc1wiPz5cclxuPGNwOmNvcmVQcm9wZXJ0aWVzIHhtbG5zOmNwPVwiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL3BhY2thZ2UvMjAwNi9tZXRhZGF0YS9jb3JlLXByb3BlcnRpZXNcIiB4bWxuczpkYz1cImh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvXCIgeG1sbnM6ZGN0ZXJtcz1cImh0dHA6Ly9wdXJsLm9yZy9kYy90ZXJtcy9cIiB4bWxuczpkY21pdHlwZT1cImh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9cIiB4bWxuczp4c2k9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZVwiPlxyXG48ZGM6dGl0bGU+VGl0bGU8L2RjOnRpdGxlPlxyXG48ZGM6c3ViamVjdD5TdWJqZWN0PC9kYzpzdWJqZWN0PlxyXG48ZGM6Y3JlYXRvcj5DcmVhdG9yPC9kYzpjcmVhdG9yPlxyXG48Y3A6a2V5d29yZHM+S2V5d29yZHM8L2NwOmtleXdvcmRzPlxyXG48ZGM6ZGVzY3JpcHRpb24+RGVzY3JpcHRpb248L2RjOmRlc2NyaXB0aW9uPlxyXG48Y3A6Y2F0ZWdvcnk+Q2F0ZWdvcnk8L2NwOmNhdGVnb3J5PlxyXG48L2NwOmNvcmVQcm9wZXJ0aWVzPlxyXG4gKi9cclxuIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4vKipcclxuICogT09YTUwgdXNlcyB0aGUgQ0ZCIGZpbGUgZm9ybWF0IHdpdGggQWdpbGUgRW5jcnlwdGlvbi4gVGhlIGRldGFpbHMgb2YgdGhlIGVuY3J5cHRpb24gYXJlIGhlcmU6XHJcbiAqIGh0dHBzOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvZGQ5NTAxNjUodj1vZmZpY2UuMTIpLmFzcHhcclxuICpcclxuICogSGVscGZ1bCBndWlkYW5jZSBhbHNvIHRha2UgZnJvbSB0aGlzIEdpdGh1YiBwcm9qZWN0OlxyXG4gKiBodHRwczovL2dpdGh1Yi5jb20vbm9semUvbXMtb2ZmY3J5cHRvLXRvb2xcclxuICovXHJcblxyXG5jb25zdCBfID0gcmVxdWlyZShcImxvZGFzaFwiKTtcclxuY29uc3QgY2ZiID0gcmVxdWlyZShcImNmYlwiKTtcclxuY29uc3QgY3J5cHRvID0gcmVxdWlyZShcImNyeXB0b1wiKTtcclxuY29uc3QgZXh0ZXJuYWxzID0gcmVxdWlyZShcIi4vZXh0ZXJuYWxzXCIpO1xyXG5jb25zdCBYbWxQYXJzZXIgPSByZXF1aXJlKFwiLi9YbWxQYXJzZXJcIik7XHJcbmNvbnN0IFhtbEJ1aWxkZXIgPSByZXF1aXJlKFwiLi9YbWxCdWlsZGVyXCIpO1xyXG5jb25zdCB4bWxxID0gcmVxdWlyZShcIi4veG1scVwiKTtcclxuXHJcbmNvbnN0IEVOQ1JZUFRJT05fSU5GT19QUkVGSVggPSBCdWZmZXIuZnJvbShbMHgwNCwgMHgwMCwgMHgwNCwgMHgwMCwgMHg0MCwgMHgwMCwgMHgwMCwgMHgwMF0pOyAvLyBGaXJzdCA0IGJ5dGVzIGFyZSB0aGUgdmVyc2lvbiBudW1iZXIsIHNlY29uZCA0IGJ5dGVzIGFyZSByZXNlcnZlZC5cclxuY29uc3QgUEFDS0FHRV9FTkNSWVBUSU9OX0NIVU5LX1NJWkUgPSA0MDk2O1xyXG5jb25zdCBQQUNLQUdFX09GRlNFVCA9IDg7IC8vIEZpcnN0IDggYnl0ZXMgYXJlIHRoZSBzaXplIG9mIHRoZSBzdHJlYW1cclxuXHJcbi8vIEJsb2NrIGtleXMgdXNlZCBmb3IgZW5jcnlwdGlvblxyXG5jb25zdCBCTE9DS19LRVlTID0ge1xyXG4gICAgZGF0YUludGVncml0eToge1xyXG4gICAgICAgIGhtYWNLZXk6IEJ1ZmZlci5mcm9tKFsweDVmLCAweGIyLCAweGFkLCAweDAxLCAweDBjLCAweGI5LCAweGUxLCAweGY2XSksXHJcbiAgICAgICAgaG1hY1ZhbHVlOiBCdWZmZXIuZnJvbShbMHhhMCwgMHg2NywgMHg3ZiwgMHgwMiwgMHhiMiwgMHgyYywgMHg4NCwgMHgzM10pXHJcbiAgICB9LFxyXG4gICAga2V5OiBCdWZmZXIuZnJvbShbMHgxNCwgMHg2ZSwgMHgwYiwgMHhlNywgMHhhYiwgMHhhYywgMHhkMCwgMHhkNl0pLFxyXG4gICAgdmVyaWZpZXJIYXNoOiB7XHJcbiAgICAgICAgaW5wdXQ6IEJ1ZmZlci5mcm9tKFsweGZlLCAweGE3LCAweGQyLCAweDc2LCAweDNiLCAweDRiLCAweDllLCAweDc5XSksXHJcbiAgICAgICAgdmFsdWU6IEJ1ZmZlci5mcm9tKFsweGQ3LCAweGFhLCAweDBmLCAweDZkLCAweDMwLCAweDYxLCAweDM0LCAweDRlXSlcclxuICAgIH1cclxufTtcclxuXHJcbi8qKlxyXG4gKiBFbmNyeXB0cy9kZWNyeXB0cyBYTFNYcy5cclxuICogQHByaXZhdGVcclxuICovXHJcbmNsYXNzIEVuY3J5cHRvciB7XHJcbiAgICAvKipcclxuICAgICAqIEVuY3J5cHQgdGhlIGRhdGEgd2l0aCB0aGUgcGFzc3dvcmQuXHJcbiAgICAgKiBAcGFyYW0ge0J1ZmZlcn0gZGF0YSAtIFRoZSBkYXRhIHRvIGVuY3J5cHRcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXNzd29yZCAtIFRoZSBwYXNzd29yZFxyXG4gICAgICogQHJldHVybnMge0J1ZmZlcn0gVGhlIGVuY3J5cHRlZCBkYXRhXHJcbiAgICAgKi9cclxuICAgIGVuY3J5cHQoZGF0YSwgcGFzc3dvcmQpIHtcclxuICAgICAgICAvLyBHZW5lcmF0ZSBhIHJhbmRvbSBrZXkgdG8gdXNlIHRvIGVuY3J5cHQgdGhlIGRvY3VtZW50LiBFeGNlbCB1c2VzIDMyIGJ5dGVzLiBXZSdsbCB1c2UgdGhlIHBhc3N3b3JkIHRvIGVuY3J5cHQgdGhpcyBrZXkuXHJcbiAgICAgICAgLy8gTi5CLiBUaGUgbnVtYmVyIG9mIGJpdHMgbmVlZHMgdG8gY29ycmVzcG9uZCB0byBhbiBhbGdvcml0aG0gYXZhaWxhYmxlIGluIGNyeXB0byAoZS5nLiBhZXMtMjU2LWNiYykuXHJcbiAgICAgICAgY29uc3QgcGFja2FnZUtleSA9IGNyeXB0by5yYW5kb21CeXRlcygzMik7XHJcblxyXG4gICAgICAgIC8vIENyZWF0ZSB0aGUgZW5jcnlwdGlvbiBpbmZvLiBXZSdsbCB1c2UgdGhpcyBmb3IgYWxsIG9mIHRoZSBlbmNyeXB0aW9uIG9wZXJhdGlvbnMgYW5kIGZvciBidWlsZGluZyB0aGUgZW5jcnlwdGlvbiBpbmZvIFhNTCBlbnRyeVxyXG4gICAgICAgIGNvbnN0IGVuY3J5cHRpb25JbmZvID0ge1xyXG4gICAgICAgICAgICBwYWNrYWdlOiB7IC8vIEluZm8gb24gdGhlIGVuY3J5cHRpb24gb2YgdGhlIHBhY2thZ2UuXHJcbiAgICAgICAgICAgICAgICBjaXBoZXJBbGdvcml0aG06ICdBRVMnLCAvLyBDaXBoZXIgYWxnb3JpdGhtIHRvIHVzZS4gRXhjZWwgdXNlcyBBRVMuXHJcbiAgICAgICAgICAgICAgICBjaXBoZXJDaGFpbmluZzogJ0NoYWluaW5nTW9kZUNCQycsIC8vIENpcGhlciBjaGFpbmluZyBtb2RlIHRvIHVzZS4gRXhjZWwgdXNlcyBDQkMuXHJcbiAgICAgICAgICAgICAgICBzYWx0VmFsdWU6IGNyeXB0by5yYW5kb21CeXRlcygxNiksIC8vIFJhbmRvbSB2YWx1ZSB0byB1c2UgYXMgZW5jcnlwdGlvbiBzYWx0LiBFeGNlbCB1c2VzIDE2IGJ5dGVzLlxyXG4gICAgICAgICAgICAgICAgaGFzaEFsZ29yaXRobTogJ1NIQTUxMicsIC8vIEhhc2ggYWxnb3JpdGhtIHRvIHVzZS4gRXhjZWwgdXNlcyBTSEE1MTIuXHJcbiAgICAgICAgICAgICAgICBoYXNoU2l6ZTogNjQsIC8vIFRoZSBzaXplIG9mIHRoZSBoYXNoIGluIGJ5dGVzLiBTSEE1MTIgcmVzdWx0cyBpbiA2NC1ieXRlIGhhc2hlc1xyXG4gICAgICAgICAgICAgICAgYmxvY2tTaXplOiAxNiwgLy8gVGhlIG51bWJlciBvZiBieXRlcyB1c2VkIHRvIGVuY3J5cHQgb25lIGJsb2NrIG9mIGRhdGEuIEl0IE1VU1QgYmUgYXQgbGVhc3QgMiwgbm8gZ3JlYXRlciB0aGFuIDQwOTYsIGFuZCBhIG11bHRpcGxlIG9mIDIuIEV4Y2VsIHVzZXMgMTZcclxuICAgICAgICAgICAgICAgIGtleUJpdHM6IHBhY2thZ2VLZXkubGVuZ3RoICogOCAvLyBUaGUgbnVtYmVyIG9mIGJpdHMgaW4gdGhlIHBhY2thZ2Uga2V5LlxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBrZXk6IHsgLy8gSW5mbyBvbiB0aGUgZW5jcnlwdGlvbiBvZiB0aGUgcGFja2FnZSBrZXkuXHJcbiAgICAgICAgICAgICAgICBjaXBoZXJBbGdvcml0aG06ICdBRVMnLCAvLyBDaXBoZXIgYWxnb3JpdGhtIHRvIHVzZS4gRXhjZWwgdXNlcyBBRVMuXHJcbiAgICAgICAgICAgICAgICBjaXBoZXJDaGFpbmluZzogJ0NoYWluaW5nTW9kZUNCQycsIC8vIENpcGhlciBjaGFpbmluZyBtb2RlIHRvIHVzZS4gRXhjZWwgdXNlcyBDQkMuXHJcbiAgICAgICAgICAgICAgICBzYWx0VmFsdWU6IGNyeXB0by5yYW5kb21CeXRlcygxNiksIC8vIFJhbmRvbSB2YWx1ZSB0byB1c2UgYXMgZW5jcnlwdGlvbiBzYWx0LiBFeGNlbCB1c2VzIDE2IGJ5dGVzLlxyXG4gICAgICAgICAgICAgICAgaGFzaEFsZ29yaXRobTogJ1NIQTUxMicsIC8vIEhhc2ggYWxnb3JpdGhtIHRvIHVzZS4gRXhjZWwgdXNlcyBTSEE1MTIuXHJcbiAgICAgICAgICAgICAgICBoYXNoU2l6ZTogNjQsIC8vIFRoZSBzaXplIG9mIHRoZSBoYXNoIGluIGJ5dGVzLiBTSEE1MTIgcmVzdWx0cyBpbiA2NC1ieXRlIGhhc2hlc1xyXG4gICAgICAgICAgICAgICAgYmxvY2tTaXplOiAxNiwgLy8gVGhlIG51bWJlciBvZiBieXRlcyB1c2VkIHRvIGVuY3J5cHQgb25lIGJsb2NrIG9mIGRhdGEuIEl0IE1VU1QgYmUgYXQgbGVhc3QgMiwgbm8gZ3JlYXRlciB0aGFuIDQwOTYsIGFuZCBhIG11bHRpcGxlIG9mIDIuIEV4Y2VsIHVzZXMgMTZcclxuICAgICAgICAgICAgICAgIHNwaW5Db3VudDogMTAwMDAwLCAvLyBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIGl0ZXJhdGUgb24gYSBoYXNoIG9mIGEgcGFzc3dvcmQuIEl0IE1VU1QgTk9UIGJlIGdyZWF0ZXIgdGhhbiAxMCwwMDAsMDAwLiBFeGNlbCB1c2VzIDEwMCwwMDAuXHJcbiAgICAgICAgICAgICAgICBrZXlCaXRzOiAyNTYgLy8gVGhlIGxlbmd0aCBvZiB0aGUga2V5IHRvIGdlbmVyYXRlIGZyb20gdGhlIHBhc3N3b3JkLiBNdXN0IGJlIGEgbXVsdGlwbGUgb2YgOC4gRXhjZWwgdXNlcyAyNTYuXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKiBQYWNrYWdlIEVuY3J5cHRpb24gKi9cclxuXHJcbiAgICAgICAgLy8gRW5jcnlwdCBwYWNrYWdlIHVzaW5nIHRoZSBwYWNrYWdlIGtleS5cclxuICAgICAgICBjb25zdCBlbmNyeXB0ZWRQYWNrYWdlID0gdGhpcy5fY3J5cHRQYWNrYWdlKFxyXG4gICAgICAgICAgICB0cnVlLFxyXG4gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5wYWNrYWdlLmNpcGhlckFsZ29yaXRobSxcclxuICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8ucGFja2FnZS5jaXBoZXJDaGFpbmluZyxcclxuICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8ucGFja2FnZS5oYXNoQWxnb3JpdGhtLFxyXG4gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5wYWNrYWdlLmJsb2NrU2l6ZSxcclxuICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8ucGFja2FnZS5zYWx0VmFsdWUsXHJcbiAgICAgICAgICAgIHBhY2thZ2VLZXksXHJcbiAgICAgICAgICAgIGRhdGFcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICAvKiBEYXRhIEludGVncml0eSAqL1xyXG5cclxuICAgICAgICAvLyBDcmVhdGUgdGhlIGRhdGEgaW50ZWdyaXR5IGZpZWxkcyB1c2VkIGJ5IGNsaWVudHMgZm9yIGludGVncml0eSBjaGVja3MuXHJcbiAgICAgICAgLy8gRmlyc3QgZ2VuZXJhdGUgYSByYW5kb20gYXJyYXkgb2YgYnl0ZXMgdG8gdXNlIGluIEhNQUMuIFRoZSBkb2NzIHNheSB0byB1c2UgdGhlIHNhbWUgbGVuZ3RoIGFzIHRoZSBrZXkgc2FsdCwgYnV0IEV4Y2VsIHNlZW1zIHRvIHVzZSA2NC5cclxuICAgICAgICBjb25zdCBobWFjS2V5ID0gY3J5cHRvLnJhbmRvbUJ5dGVzKDY0KTtcclxuXHJcbiAgICAgICAgLy8gVGhlbiBjcmVhdGUgYW4gaW5pdGlhbGl6YXRpb24gdmVjdG9yIHVzaW5nIHRoZSBwYWNrYWdlIGVuY3J5cHRpb24gaW5mbyBhbmQgdGhlIGFwcHJvcHJpYXRlIGJsb2NrIGtleS5cclxuICAgICAgICBjb25zdCBobWFjS2V5SVYgPSB0aGlzLl9jcmVhdGVJVihcclxuICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8ucGFja2FnZS5oYXNoQWxnb3JpdGhtLFxyXG4gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5wYWNrYWdlLnNhbHRWYWx1ZSxcclxuICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8ucGFja2FnZS5ibG9ja1NpemUsXHJcbiAgICAgICAgICAgIEJMT0NLX0tFWVMuZGF0YUludGVncml0eS5obWFjS2V5XHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgLy8gVXNlIHRoZSBwYWNrYWdlIGtleSBhbmQgdGhlIElWIHRvIGVuY3J5cHQgdGhlIEhNQUMga2V5XHJcbiAgICAgICAgY29uc3QgZW5jcnlwdGVkSG1hY0tleSA9IHRoaXMuX2NyeXB0KFxyXG4gICAgICAgICAgICB0cnVlLFxyXG4gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5wYWNrYWdlLmNpcGhlckFsZ29yaXRobSxcclxuICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8ucGFja2FnZS5jaXBoZXJDaGFpbmluZyxcclxuICAgICAgICAgICAgcGFja2FnZUtleSxcclxuICAgICAgICAgICAgaG1hY0tleUlWLFxyXG4gICAgICAgICAgICBobWFjS2V5KTtcclxuXHJcbiAgICAgICAgLy8gTm93IGNyZWF0ZSB0aGUgSE1BQ1xyXG4gICAgICAgIGNvbnN0IGhtYWNWYWx1ZSA9IHRoaXMuX2htYWMoZW5jcnlwdGlvbkluZm8ucGFja2FnZS5oYXNoQWxnb3JpdGhtLCBobWFjS2V5LCBlbmNyeXB0ZWRQYWNrYWdlKTtcclxuXHJcbiAgICAgICAgLy8gTmV4dCBnZW5lcmF0ZSBhbiBpbml0aWFsaXphdGlvbiB2ZWN0b3IgZm9yIGVuY3J5cHRpbmcgdGhlIHJlc3VsdGluZyBITUFDIHZhbHVlLlxyXG4gICAgICAgIGNvbnN0IGhtYWNWYWx1ZUlWID0gdGhpcy5fY3JlYXRlSVYoXHJcbiAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLnBhY2thZ2UuaGFzaEFsZ29yaXRobSxcclxuICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8ucGFja2FnZS5zYWx0VmFsdWUsXHJcbiAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLnBhY2thZ2UuYmxvY2tTaXplLFxyXG4gICAgICAgICAgICBCTE9DS19LRVlTLmRhdGFJbnRlZ3JpdHkuaG1hY1ZhbHVlXHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgLy8gTm93IGVuY3J5cHQgdGhlIHZhbHVlXHJcbiAgICAgICAgY29uc3QgZW5jcnlwdGVkSG1hY1ZhbHVlID0gdGhpcy5fY3J5cHQoXHJcbiAgICAgICAgICAgIHRydWUsXHJcbiAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLnBhY2thZ2UuY2lwaGVyQWxnb3JpdGhtLFxyXG4gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5wYWNrYWdlLmNpcGhlckNoYWluaW5nLFxyXG4gICAgICAgICAgICBwYWNrYWdlS2V5LFxyXG4gICAgICAgICAgICBobWFjVmFsdWVJVixcclxuICAgICAgICAgICAgaG1hY1ZhbHVlXHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgLy8gUHV0IHRoZSBlbmNyeXB0ZWQga2V5IGFuZCB2YWx1ZSBvbiB0aGUgZW5jcnlwdGlvbiBpbmZvXHJcbiAgICAgICAgZW5jcnlwdGlvbkluZm8uZGF0YUludGVncml0eSA9IHtcclxuICAgICAgICAgICAgZW5jcnlwdGVkSG1hY0tleSxcclxuICAgICAgICAgICAgZW5jcnlwdGVkSG1hY1ZhbHVlXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyogS2V5IEVuY3J5cHRpb24gKi9cclxuXHJcbiAgICAgICAgLy8gQ29udmVydCB0aGUgcGFzc3dvcmQgdG8gYW4gZW5jcnlwdGlvbiBrZXlcclxuICAgICAgICBjb25zdCBrZXkgPSB0aGlzLl9jb252ZXJ0UGFzc3dvcmRUb0tleShcclxuICAgICAgICAgICAgcGFzc3dvcmQsXHJcbiAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLmtleS5oYXNoQWxnb3JpdGhtLFxyXG4gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5rZXkuc2FsdFZhbHVlLFxyXG4gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5rZXkuc3BpbkNvdW50LFxyXG4gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5rZXkua2V5Qml0cyxcclxuICAgICAgICAgICAgQkxPQ0tfS0VZUy5rZXlcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICAvLyBFbmNyeXB0IHRoZSBwYWNrYWdlIGtleSB3aXRoIHRoZVxyXG4gICAgICAgIGVuY3J5cHRpb25JbmZvLmtleS5lbmNyeXB0ZWRLZXlWYWx1ZSA9IHRoaXMuX2NyeXB0KFxyXG4gICAgICAgICAgICB0cnVlLFxyXG4gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5rZXkuY2lwaGVyQWxnb3JpdGhtLFxyXG4gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5rZXkuY2lwaGVyQ2hhaW5pbmcsXHJcbiAgICAgICAgICAgIGtleSxcclxuICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8ua2V5LnNhbHRWYWx1ZSxcclxuICAgICAgICAgICAgcGFja2FnZUtleSk7XHJcblxyXG4gICAgICAgIC8qIFZlcmlmaWVyIGhhc2ggKi9cclxuXHJcbiAgICAgICAgLy8gQ3JlYXRlIGEgcmFuZG9tIGJ5dGUgYXJyYXkgZm9yIGhhc2hpbmdcclxuICAgICAgICBjb25zdCB2ZXJpZmllckhhc2hJbnB1dCA9IGNyeXB0by5yYW5kb21CeXRlcygxNik7XHJcblxyXG4gICAgICAgIC8vIENyZWF0ZSBhbiBlbmNyeXB0aW9uIGtleSBmcm9tIHRoZSBwYXNzd29yZCBmb3IgdGhlIGlucHV0XHJcbiAgICAgICAgY29uc3QgdmVyaWZpZXJIYXNoSW5wdXRLZXkgPSB0aGlzLl9jb252ZXJ0UGFzc3dvcmRUb0tleShcclxuICAgICAgICAgICAgcGFzc3dvcmQsXHJcbiAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLmtleS5oYXNoQWxnb3JpdGhtLFxyXG4gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5rZXkuc2FsdFZhbHVlLFxyXG4gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5rZXkuc3BpbkNvdW50LFxyXG4gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5rZXkua2V5Qml0cyxcclxuICAgICAgICAgICAgQkxPQ0tfS0VZUy52ZXJpZmllckhhc2guaW5wdXRcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICAvLyBVc2UgdGhlIGtleSB0byBlbmNyeXB0IHRoZSB2ZXJpZmllciBpbnB1dFxyXG4gICAgICAgIGVuY3J5cHRpb25JbmZvLmtleS5lbmNyeXB0ZWRWZXJpZmllckhhc2hJbnB1dCA9IHRoaXMuX2NyeXB0KFxyXG4gICAgICAgICAgICB0cnVlLFxyXG4gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5rZXkuY2lwaGVyQWxnb3JpdGhtLFxyXG4gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5rZXkuY2lwaGVyQ2hhaW5pbmcsXHJcbiAgICAgICAgICAgIHZlcmlmaWVySGFzaElucHV0S2V5LFxyXG4gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5rZXkuc2FsdFZhbHVlLFxyXG4gICAgICAgICAgICB2ZXJpZmllckhhc2hJbnB1dFxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICAgIC8vIENyZWF0ZSBhIGhhc2ggb2YgdGhlIGlucHV0XHJcbiAgICAgICAgY29uc3QgdmVyaWZpZXJIYXNoVmFsdWUgPSB0aGlzLl9oYXNoKGVuY3J5cHRpb25JbmZvLmtleS5oYXNoQWxnb3JpdGhtLCB2ZXJpZmllckhhc2hJbnB1dCk7XHJcblxyXG4gICAgICAgIC8vIENyZWF0ZSBhbiBlbmNyeXB0aW9uIGtleSBmcm9tIHRoZSBwYXNzd29yZCBmb3IgdGhlIGhhc2hcclxuICAgICAgICBjb25zdCB2ZXJpZmllckhhc2hWYWx1ZUtleSA9IHRoaXMuX2NvbnZlcnRQYXNzd29yZFRvS2V5KFxyXG4gICAgICAgICAgICBwYXNzd29yZCxcclxuICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8ua2V5Lmhhc2hBbGdvcml0aG0sXHJcbiAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLmtleS5zYWx0VmFsdWUsXHJcbiAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLmtleS5zcGluQ291bnQsXHJcbiAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLmtleS5rZXlCaXRzLFxyXG4gICAgICAgICAgICBCTE9DS19LRVlTLnZlcmlmaWVySGFzaC52YWx1ZVxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICAgIC8vIFVzZSB0aGUga2V5IHRvIGVuY3J5cHQgdGhlIGhhc2ggdmFsdWVcclxuICAgICAgICBlbmNyeXB0aW9uSW5mby5rZXkuZW5jcnlwdGVkVmVyaWZpZXJIYXNoVmFsdWUgPSB0aGlzLl9jcnlwdChcclxuICAgICAgICAgICAgdHJ1ZSxcclxuICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8ua2V5LmNpcGhlckFsZ29yaXRobSxcclxuICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8ua2V5LmNpcGhlckNoYWluaW5nLFxyXG4gICAgICAgICAgICB2ZXJpZmllckhhc2hWYWx1ZUtleSxcclxuICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8ua2V5LnNhbHRWYWx1ZSxcclxuICAgICAgICAgICAgdmVyaWZpZXJIYXNoVmFsdWVcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICAvLyBCdWlsZCB0aGUgZW5jcnlwdGlvbiBpbmZvIGJ1ZmZlclxyXG4gICAgICAgIGNvbnN0IGVuY3J5cHRpb25JbmZvQnVmZmVyID0gdGhpcy5fYnVpbGRFbmNyeXB0aW9uSW5mbyhlbmNyeXB0aW9uSW5mbyk7XHJcblxyXG4gICAgICAgIC8vIENyZWF0ZSBhIG5ldyBDRkJcclxuICAgICAgICBsZXQgb3V0cHV0ID0gY2ZiLnV0aWxzLmNmYl9uZXcoKTtcclxuXHJcbiAgICAgICAgLy8gQWRkIHRoZSBlbmNyeXB0aW9uIGluZm8gYW5kIGVuY3J5cHRlZCBwYWNrYWdlXHJcbiAgICAgICAgY2ZiLnV0aWxzLmNmYl9hZGQob3V0cHV0LCBcIkVuY3J5cHRpb25JbmZvXCIsIGVuY3J5cHRpb25JbmZvQnVmZmVyKTtcclxuICAgICAgICBjZmIudXRpbHMuY2ZiX2FkZChvdXRwdXQsIFwiRW5jcnlwdGVkUGFja2FnZVwiLCBlbmNyeXB0ZWRQYWNrYWdlKTtcclxuXHJcbiAgICAgICAgLy8gRGVsZXRlIHRoZSBTaGVldEpTIGVudHJ5IHRoYXQgaXMgYWRkZWQgYXQgaW5pdGlhbGl6YXRpb25cclxuICAgICAgICBjZmIudXRpbHMuY2ZiX2RlbChvdXRwdXQsIFwiXFx1MDAwMVNoMzN0SjVcIik7XHJcblxyXG4gICAgICAgIC8vIFdyaXRlIHRvIGEgYnVmZmVyIGFuZCByZXR1cm5cclxuICAgICAgICBvdXRwdXQgPSBjZmIud3JpdGUob3V0cHV0KTtcclxuXHJcbiAgICAgICAgLy8gVGhlIGNmYiBsaWJyYXJ5IHdyaXRlcyB0byBhIFVpbnQ4YXJyYXkgaW4gdGhlIGJyb3dzZXIuIENvbnZlcnQgdG8gYSBCdWZmZXIuXHJcbiAgICAgICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIob3V0cHV0KSkgb3V0cHV0ID0gQnVmZmVyLmZyb20ob3V0cHV0KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG91dHB1dDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERlY3J5cHQgdGhlIGRhdGEgd2l0aCB0aGUgZ2l2ZW4gcGFzc3dvcmRcclxuICAgICAqIEBwYXJhbSB7QnVmZmVyfSBkYXRhIC0gVGhlIGRhdGEgdG8gZGVjcnlwdFxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHBhc3N3b3JkIC0gVGhlIHBhc3N3b3JkXHJcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZS48QnVmZmVyPn0gVGhlIGRlY3J5cHRlZCBkYXRhXHJcbiAgICAgKi9cclxuICAgIGRlY3J5cHRBc3luYyhkYXRhLCBwYXNzd29yZCkge1xyXG4gICAgICAgIC8vIFBhcnNlIHRoZSBDRkIgaW5wdXQgYW5kIHB1bGwgb3V0IHRoZSBlbmNyeXB0aW9uIGluZm8gYW5kIGVuY3J5cHRlZCBwYWNrYWdlIGVudHJpZXMuXHJcbiAgICAgICAgY29uc3QgcGFyc2VkID0gY2ZiLnBhcnNlKGRhdGEpO1xyXG4gICAgICAgIGxldCBlbmNyeXB0aW9uSW5mb0J1ZmZlciA9IF8uZmluZChwYXJzZWQuRmlsZUluZGV4LCB7IG5hbWU6IFwiRW5jcnlwdGlvbkluZm9cIiB9KS5jb250ZW50O1xyXG4gICAgICAgIGxldCBlbmNyeXB0ZWRQYWNrYWdlQnVmZmVyID0gXy5maW5kKHBhcnNlZC5GaWxlSW5kZXgsIHsgbmFtZTogXCJFbmNyeXB0ZWRQYWNrYWdlXCIgfSkuY29udGVudDtcclxuXHJcbiAgICAgICAgLy8gSW4gdGhlIGJyb3dzZXIgdGhlIENGQiBjb250ZW50IGlzIGFuIGFycmF5LiBDb252ZXJ0IHRvIGEgQnVmZmVyLlxyXG4gICAgICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKGVuY3J5cHRpb25JbmZvQnVmZmVyKSkgZW5jcnlwdGlvbkluZm9CdWZmZXIgPSBCdWZmZXIuZnJvbShlbmNyeXB0aW9uSW5mb0J1ZmZlcik7XHJcbiAgICAgICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoZW5jcnlwdGVkUGFja2FnZUJ1ZmZlcikpIGVuY3J5cHRlZFBhY2thZ2VCdWZmZXIgPSBCdWZmZXIuZnJvbShlbmNyeXB0ZWRQYWNrYWdlQnVmZmVyKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGV4dGVybmFscy5Qcm9taXNlLnJlc29sdmUoKVxyXG4gICAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLl9wYXJzZUVuY3J5cHRpb25JbmZvQXN5bmMoZW5jcnlwdGlvbkluZm9CdWZmZXIpKSAvLyBQYXJzZSB0aGUgZW5jcnlwdGlvbiBpbmZvIFhNTCBpbnRvIGFuIG9iamVjdFxyXG4gICAgICAgICAgICAudGhlbihlbmNyeXB0aW9uSW5mbyA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBDb252ZXJ0IHRoZSBwYXNzd29yZCBpbnRvIGFuIGVuY3J5cHRpb24ga2V5XHJcbiAgICAgICAgICAgICAgICBjb25zdCBrZXkgPSB0aGlzLl9jb252ZXJ0UGFzc3dvcmRUb0tleShcclxuICAgICAgICAgICAgICAgICAgICBwYXNzd29yZCxcclxuICAgICAgICAgICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5rZXkuaGFzaEFsZ29yaXRobSxcclxuICAgICAgICAgICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5rZXkuc2FsdFZhbHVlLFxyXG4gICAgICAgICAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLmtleS5zcGluQ291bnQsXHJcbiAgICAgICAgICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8ua2V5LmtleUJpdHMsXHJcbiAgICAgICAgICAgICAgICAgICAgQkxPQ0tfS0VZUy5rZXlcclxuICAgICAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gVXNlIHRoZSBrZXkgdG8gZGVjcnlwdCB0aGUgcGFja2FnZSBrZXlcclxuICAgICAgICAgICAgICAgIGNvbnN0IHBhY2thZ2VLZXkgPSB0aGlzLl9jcnlwdChcclxuICAgICAgICAgICAgICAgICAgICBmYWxzZSxcclxuICAgICAgICAgICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5rZXkuY2lwaGVyQWxnb3JpdGhtLFxyXG4gICAgICAgICAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLmtleS5jaXBoZXJDaGFpbmluZyxcclxuICAgICAgICAgICAgICAgICAgICBrZXksXHJcbiAgICAgICAgICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8ua2V5LnNhbHRWYWx1ZSxcclxuICAgICAgICAgICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5rZXkuZW5jcnlwdGVkS2V5VmFsdWVcclxuICAgICAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gVXNlIHRoZSBwYWNrYWdlIGtleSB0byBkZWNyeXB0IHRoZSBwYWNrYWdlXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fY3J5cHRQYWNrYWdlKFxyXG4gICAgICAgICAgICAgICAgICAgIGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLnBhY2thZ2UuY2lwaGVyQWxnb3JpdGhtLFxyXG4gICAgICAgICAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLnBhY2thZ2UuY2lwaGVyQ2hhaW5pbmcsXHJcbiAgICAgICAgICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8ucGFja2FnZS5oYXNoQWxnb3JpdGhtLFxyXG4gICAgICAgICAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLnBhY2thZ2UuYmxvY2tTaXplLFxyXG4gICAgICAgICAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLnBhY2thZ2Uuc2FsdFZhbHVlLFxyXG4gICAgICAgICAgICAgICAgICAgIHBhY2thZ2VLZXksXHJcbiAgICAgICAgICAgICAgICAgICAgZW5jcnlwdGVkUGFja2FnZUJ1ZmZlcik7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQnVpbGQgdGhlIGVuY3J5cHRpb24gaW5mbyBYTUwvYnVmZmVyXHJcbiAgICAgKiBAcGFyYW0ge3t9fSBlbmNyeXB0aW9uSW5mbyAtIFRoZSBlbmNyeXB0aW9uIGluZm8gb2JqZWN0XHJcbiAgICAgKiBAcmV0dXJucyB7QnVmZmVyfSBUaGUgYnVmZmVyXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICBfYnVpbGRFbmNyeXB0aW9uSW5mbyhlbmNyeXB0aW9uSW5mbykge1xyXG4gICAgICAgIC8vIE1hcCB0aGUgb2JqZWN0IGludG8gdGhlIGFwcHJvcHJpYXRlIFhNTCBzdHJ1Y3R1cmUuIEJ1ZmZlcnMgYXJlIGVuY29kZWQgaW4gYmFzZSA2NC5cclxuICAgICAgICBjb25zdCBlbmNyeXB0aW9uSW5mb05vZGUgPSB7XHJcbiAgICAgICAgICAgIG5hbWU6IFwiZW5jcnlwdGlvblwiLFxyXG4gICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XHJcbiAgICAgICAgICAgICAgICB4bWxuczogXCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL29mZmljZS8yMDA2L2VuY3J5cHRpb25cIixcclxuICAgICAgICAgICAgICAgICd4bWxuczpwJzogXCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL29mZmljZS8yMDA2L2tleUVuY3J5cHRvci9wYXNzd29yZFwiLFxyXG4gICAgICAgICAgICAgICAgJ3htbG5zOmMnOiBcImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vb2ZmaWNlLzIwMDYva2V5RW5jcnlwdG9yL2NlcnRpZmljYXRlXCJcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgY2hpbGRyZW46IFtcclxuICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBcImtleURhdGFcIixcclxuICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNhbHRTaXplOiBlbmNyeXB0aW9uSW5mby5wYWNrYWdlLnNhbHRWYWx1ZS5sZW5ndGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrU2l6ZTogZW5jcnlwdGlvbkluZm8ucGFja2FnZS5ibG9ja1NpemUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleUJpdHM6IGVuY3J5cHRpb25JbmZvLnBhY2thZ2Uua2V5Qml0cyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGFzaFNpemU6IGVuY3J5cHRpb25JbmZvLnBhY2thZ2UuaGFzaFNpemUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNpcGhlckFsZ29yaXRobTogZW5jcnlwdGlvbkluZm8ucGFja2FnZS5jaXBoZXJBbGdvcml0aG0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNpcGhlckNoYWluaW5nOiBlbmNyeXB0aW9uSW5mby5wYWNrYWdlLmNpcGhlckNoYWluaW5nLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBoYXNoQWxnb3JpdGhtOiBlbmNyeXB0aW9uSW5mby5wYWNrYWdlLmhhc2hBbGdvcml0aG0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNhbHRWYWx1ZTogZW5jcnlwdGlvbkluZm8ucGFja2FnZS5zYWx0VmFsdWUudG9TdHJpbmcoXCJiYXNlNjRcIilcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IFwiZGF0YUludGVncml0eVwiLFxyXG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZW5jcnlwdGVkSG1hY0tleTogZW5jcnlwdGlvbkluZm8uZGF0YUludGVncml0eS5lbmNyeXB0ZWRIbWFjS2V5LnRvU3RyaW5nKFwiYmFzZTY0XCIpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbmNyeXB0ZWRIbWFjVmFsdWU6IGVuY3J5cHRpb25JbmZvLmRhdGFJbnRlZ3JpdHkuZW5jcnlwdGVkSG1hY1ZhbHVlLnRvU3RyaW5nKFwiYmFzZTY0XCIpXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBcImtleUVuY3J5cHRvcnNcIixcclxuICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbjogW1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBcImtleUVuY3J5cHRvclwiLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVyaTogXCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL29mZmljZS8yMDA2L2tleUVuY3J5cHRvci9wYXNzd29yZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW46IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IFwicDplbmNyeXB0ZWRLZXlcIixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BpbkNvdW50OiBlbmNyeXB0aW9uSW5mby5rZXkuc3BpbkNvdW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FsdFNpemU6IGVuY3J5cHRpb25JbmZvLmtleS5zYWx0VmFsdWUubGVuZ3RoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2tTaXplOiBlbmNyeXB0aW9uSW5mby5rZXkuYmxvY2tTaXplLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5Qml0czogZW5jcnlwdGlvbkluZm8ua2V5LmtleUJpdHMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYXNoU2l6ZTogZW5jcnlwdGlvbkluZm8ua2V5Lmhhc2hTaXplLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2lwaGVyQWxnb3JpdGhtOiBlbmNyeXB0aW9uSW5mby5rZXkuY2lwaGVyQWxnb3JpdGhtLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2lwaGVyQ2hhaW5pbmc6IGVuY3J5cHRpb25JbmZvLmtleS5jaXBoZXJDaGFpbmluZyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc2hBbGdvcml0aG06IGVuY3J5cHRpb25JbmZvLmtleS5oYXNoQWxnb3JpdGhtLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FsdFZhbHVlOiBlbmNyeXB0aW9uSW5mby5rZXkuc2FsdFZhbHVlLnRvU3RyaW5nKFwiYmFzZTY0XCIpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5jcnlwdGVkVmVyaWZpZXJIYXNoSW5wdXQ6IGVuY3J5cHRpb25JbmZvLmtleS5lbmNyeXB0ZWRWZXJpZmllckhhc2hJbnB1dC50b1N0cmluZyhcImJhc2U2NFwiKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuY3J5cHRlZFZlcmlmaWVySGFzaFZhbHVlOiBlbmNyeXB0aW9uSW5mby5rZXkuZW5jcnlwdGVkVmVyaWZpZXJIYXNoVmFsdWUudG9TdHJpbmcoXCJiYXNlNjRcIiksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmNyeXB0ZWRLZXlWYWx1ZTogZW5jcnlwdGlvbkluZm8ua2V5LmVuY3J5cHRlZEtleVZhbHVlLnRvU3RyaW5nKFwiYmFzZTY0XCIpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBdXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIF1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvLyBDb252ZXJ0IHRvIGFuIFhNTCBzdHJpbmdcclxuICAgICAgICBjb25zdCB4bWxCdWlsZGVyID0gbmV3IFhtbEJ1aWxkZXIoKTtcclxuICAgICAgICBjb25zdCBlbmNyeXB0aW9uSW5mb1htbCA9IHhtbEJ1aWxkZXIuYnVpbGQoZW5jcnlwdGlvbkluZm9Ob2RlKTtcclxuXHJcbiAgICAgICAgLy8gQ29udmVydCB0byBhIGJ1ZmZlciBhbmQgcHJlZml4IHdpdGggdGhlIGFwcHJvcHJpYXRlIGJ5dGVzXHJcbiAgICAgICAgcmV0dXJuIEJ1ZmZlci5jb25jYXQoW0VOQ1JZUFRJT05fSU5GT19QUkVGSVgsIEJ1ZmZlci5mcm9tKGVuY3J5cHRpb25JbmZvWG1sLCBcInV0ZjhcIildKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFBhcnNlIHRoZSBlbmNyeXB0aW9uIGluZm8gZnJvbSB0aGUgWE1ML2J1ZmZlclxyXG4gICAgICogQHBhcmFtIHtCdWZmZXJ9IGJ1ZmZlciAtIFRoZSBidWZmZXJcclxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlLjx7fT59IFRoZSBwYXJzZWQgZW5jcnlwdGlvbiBpbmZvIG9iamVjdFxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgX3BhcnNlRW5jcnlwdGlvbkluZm9Bc3luYyhidWZmZXIpIHtcclxuICAgICAgICAvLyBQdWxsIG9mZiB0aGUgcHJlZml4IGFuZCBjb252ZXJ0IHRvIHN0cmluZ1xyXG4gICAgICAgIGNvbnN0IHhtbCA9IGJ1ZmZlci5zbGljZShFTkNSWVBUSU9OX0lORk9fUFJFRklYLmxlbmd0aCkudG9TdHJpbmcoXCJ1dGY4XCIpO1xyXG5cclxuICAgICAgICAvLyBQYXJzZSB0aGUgWE1MXHJcbiAgICAgICAgY29uc3QgeG1sUGFyc2VyID0gbmV3IFhtbFBhcnNlcigpO1xyXG4gICAgICAgIHJldHVybiB4bWxQYXJzZXIucGFyc2VBc3luYyh4bWwpXHJcbiAgICAgICAgICAgIC50aGVuKGRvYyA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBQdWxsIG91dCB0aGUgcmVsZXZhbnQgdmFsdWVzIGZvciBkZWNyeXB0aW9uIGFuZCByZXR1cm5cclxuICAgICAgICAgICAgICAgIGNvbnN0IGtleURhdGFOb2RlID0geG1scS5maW5kQ2hpbGQoZG9jLCBcImtleURhdGFcIik7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBrZXlFbmNyeXB0b3JzTm9kZSA9IHhtbHEuZmluZENoaWxkKGRvYywgXCJrZXlFbmNyeXB0b3JzXCIpO1xyXG4gICAgICAgICAgICAgICAgY29uc3Qga2V5RW5jcnlwdG9yTm9kZSA9IHhtbHEuZmluZENoaWxkKGtleUVuY3J5cHRvcnNOb2RlLCBcImtleUVuY3J5cHRvclwiKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGVuY3J5cHRlZEtleU5vZGUgPSB4bWxxLmZpbmRDaGlsZChrZXlFbmNyeXB0b3JOb2RlLCBcInA6ZW5jcnlwdGVkS2V5XCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgcGFja2FnZToge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaXBoZXJBbGdvcml0aG06IGtleURhdGFOb2RlLmF0dHJpYnV0ZXMuY2lwaGVyQWxnb3JpdGhtLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaXBoZXJDaGFpbmluZzoga2V5RGF0YU5vZGUuYXR0cmlidXRlcy5jaXBoZXJDaGFpbmluZyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2FsdFZhbHVlOiBCdWZmZXIuZnJvbShrZXlEYXRhTm9kZS5hdHRyaWJ1dGVzLnNhbHRWYWx1ZSwgXCJiYXNlNjRcIiksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhc2hBbGdvcml0aG06IGtleURhdGFOb2RlLmF0dHJpYnV0ZXMuaGFzaEFsZ29yaXRobSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2tTaXplOiBrZXlEYXRhTm9kZS5hdHRyaWJ1dGVzLmJsb2NrU2l6ZVxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAga2V5OiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVuY3J5cHRlZEtleVZhbHVlOiBCdWZmZXIuZnJvbShlbmNyeXB0ZWRLZXlOb2RlLmF0dHJpYnV0ZXMuZW5jcnlwdGVkS2V5VmFsdWUsIFwiYmFzZTY0XCIpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaXBoZXJBbGdvcml0aG06IGVuY3J5cHRlZEtleU5vZGUuYXR0cmlidXRlcy5jaXBoZXJBbGdvcml0aG0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNpcGhlckNoYWluaW5nOiBlbmNyeXB0ZWRLZXlOb2RlLmF0dHJpYnV0ZXMuY2lwaGVyQ2hhaW5pbmcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNhbHRWYWx1ZTogQnVmZmVyLmZyb20oZW5jcnlwdGVkS2V5Tm9kZS5hdHRyaWJ1dGVzLnNhbHRWYWx1ZSwgXCJiYXNlNjRcIiksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhc2hBbGdvcml0aG06IGVuY3J5cHRlZEtleU5vZGUuYXR0cmlidXRlcy5oYXNoQWxnb3JpdGhtLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzcGluQ291bnQ6IGVuY3J5cHRlZEtleU5vZGUuYXR0cmlidXRlcy5zcGluQ291bnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleUJpdHM6IGVuY3J5cHRlZEtleU5vZGUuYXR0cmlidXRlcy5rZXlCaXRzXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxjdWxhdGUgYSBoYXNoIG9mIHRoZSBjb25jYXRlbmF0ZWQgYnVmZmVycyB3aXRoIHRoZSBnaXZlbiBhbGdvcml0aG0uXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYWxnb3JpdGhtIC0gVGhlIGhhc2ggYWxnb3JpdGhtLlxyXG4gICAgICogQHBhcmFtIHtBcnJheS48QnVmZmVyPn0gYnVmZmVycyAtIFRoZSBidWZmZXJzIHRvIGNvbmNhdCBhbmQgaGFzaFxyXG4gICAgICogQHJldHVybnMge0J1ZmZlcn0gVGhlIGhhc2hcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIF9oYXNoKGFsZ29yaXRobSwgLi4uYnVmZmVycykge1xyXG4gICAgICAgIGFsZ29yaXRobSA9IGFsZ29yaXRobS50b0xvd2VyQ2FzZSgpO1xyXG4gICAgICAgIGNvbnN0IGhhc2hlcyA9IGNyeXB0by5nZXRIYXNoZXMoKTtcclxuICAgICAgICBpZiAoaGFzaGVzLmluZGV4T2YoYWxnb3JpdGhtKSA8IDApIHRocm93IG5ldyBFcnJvcihgSGFzaCBhbGdvcml0aG0gJyR7YWxnb3JpdGhtfScgbm90IHN1cHBvcnRlZCFgKTtcclxuXHJcbiAgICAgICAgY29uc3QgaGFzaCA9IGNyeXB0by5jcmVhdGVIYXNoKGFsZ29yaXRobSk7XHJcbiAgICAgICAgaGFzaC51cGRhdGUoQnVmZmVyLmNvbmNhdChidWZmZXJzKSk7XHJcbiAgICAgICAgcmV0dXJuIGhhc2guZGlnZXN0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxjdWxhdGUgYW4gSE1BQyBvZiB0aGUgY29uY2F0ZW5hdGVkIGJ1ZmZlcnMgd2l0aCB0aGUgZ2l2ZW4gYWxnb3JpdGhtIGFuZCBrZXlcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhbGdvcml0aG0gLSBUaGUgYWxnb3JpdGhtLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIFRoZSBrZXlcclxuICAgICAqIEBwYXJhbSB7QXJyYXkuPEJ1ZmZlcj59IGJ1ZmZlcnMgLSBUaGUgYnVmZmVyIHRvIGNvbmNhdCBhbmQgSE1BQ1xyXG4gICAgICogQHJldHVybnMge0J1ZmZlcn0gVGhlIEhNQUNcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIF9obWFjKGFsZ29yaXRobSwga2V5LCAuLi5idWZmZXJzKSB7XHJcbiAgICAgICAgYWxnb3JpdGhtID0gYWxnb3JpdGhtLnRvTG93ZXJDYXNlKCk7XHJcbiAgICAgICAgY29uc3QgaGFzaGVzID0gY3J5cHRvLmdldEhhc2hlcygpO1xyXG4gICAgICAgIGlmIChoYXNoZXMuaW5kZXhPZihhbGdvcml0aG0pIDwgMCkgdGhyb3cgbmV3IEVycm9yKGBITUFDIGFsZ29yaXRobSAnJHthbGdvcml0aG19JyBub3Qgc3VwcG9ydGVkIWApO1xyXG5cclxuICAgICAgICBjb25zdCBobWFjID0gY3J5cHRvLmNyZWF0ZUhtYWMoYWxnb3JpdGhtLCBrZXkpO1xyXG4gICAgICAgIGhtYWMudXBkYXRlKEJ1ZmZlci5jb25jYXQoYnVmZmVycykpO1xyXG4gICAgICAgIHJldHVybiBobWFjLmRpZ2VzdCgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRW5jcnlwdC9kZWNyeXB0IGlucHV0XHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGVuY3J5cHQgLSBUcnVlIHRvIGVuY3J5cHQsIGZhbHNlIHRvIGRlY3J5cHRcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjaXBoZXJBbGdvcml0aG0gLSBUaGUgY2lwaGVyIGFsZ29yaXRobVxyXG4gICAgICogQHBhcmFtIHtzcmluZ30gY2lwaGVyQ2hhaW5pbmcgLSBUaGUgY2lwaGVyIGNoYWluaW5nIG1vZGVcclxuICAgICAqIEBwYXJhbSB7QnVmZmVyfSBrZXkgLSBUaGUgZW5jcnlwdGlvbiBrZXlcclxuICAgICAqIEBwYXJhbSB7QnVmZmVyfSBpdiAtIFRoZSBpbml0aWFsaXphdGlvbiB2ZWN0b3JcclxuICAgICAqIEBwYXJhbSB7QnVmZmVyfSBpbnB1dCAtIFRoZSBpbnB1dFxyXG4gICAgICogQHJldHVybnMge0J1ZmZlcn0gVGhlIG91dHB1dFxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgX2NyeXB0KGVuY3J5cHQsIGNpcGhlckFsZ29yaXRobSwgY2lwaGVyQ2hhaW5pbmcsIGtleSwgaXYsIGlucHV0KSB7XHJcbiAgICAgICAgbGV0IGFsZ29yaXRobSA9IGAke2NpcGhlckFsZ29yaXRobS50b0xvd2VyQ2FzZSgpfS0ke2tleS5sZW5ndGggKiA4fWA7XHJcbiAgICAgICAgaWYgKGNpcGhlckNoYWluaW5nID09PSAnQ2hhaW5pbmdNb2RlQ0JDJykgYWxnb3JpdGhtICs9ICctY2JjJztcclxuICAgICAgICBlbHNlIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBjaXBoZXIgY2hhaW5pbmc6ICR7Y2lwaGVyQ2hhaW5pbmd9YCk7XHJcblxyXG4gICAgICAgIGNvbnN0IGNpcGhlciA9IGNyeXB0b1tlbmNyeXB0ID8gJ2NyZWF0ZUNpcGhlcml2JyA6ICdjcmVhdGVEZWNpcGhlcml2J10oYWxnb3JpdGhtLCBrZXksIGl2KTtcclxuICAgICAgICBjaXBoZXIuc2V0QXV0b1BhZGRpbmcoZmFsc2UpO1xyXG4gICAgICAgIGxldCBvdXRwdXQgPSBjaXBoZXIudXBkYXRlKGlucHV0KTtcclxuICAgICAgICBvdXRwdXQgPSBCdWZmZXIuY29uY2F0KFtvdXRwdXQsIGNpcGhlci5maW5hbCgpXSk7XHJcbiAgICAgICAgcmV0dXJuIG91dHB1dDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEVuY3J5cHQvZGVjcnlwdCB0aGUgcGFja2FnZVxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBlbmNyeXB0IC0gVHJ1ZSB0byBlbmNyeXB0LCBmYWxzZSB0byBkZWNyeXB0XHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY2lwaGVyQWxnb3JpdGhtIC0gVGhlIGNpcGhlciBhbGdvcml0aG1cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjaXBoZXJDaGFpbmluZyAtIFRoZSBjaXBoZXIgY2hhaW5pbmcgbW9kZVxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGhhc2hBbGdvcml0aG0gLSBUaGUgaGFzaCBhbGdvcml0aG1cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBibG9ja1NpemUgLSBUaGUgSVYgYmxvY2sgc2l6ZVxyXG4gICAgICogQHBhcmFtIHtCdWZmZXJ9IHNhbHRWYWx1ZSAtIFRoZSBzYWx0XHJcbiAgICAgKiBAcGFyYW0ge0J1ZmZlcn0ga2V5IC0gVGhlIGVuY3J5cHRpb24ga2V5XHJcbiAgICAgKiBAcGFyYW0ge0J1ZmZlcn0gaW5wdXQgLSBUaGUgcGFja2FnZSBpbnB1dFxyXG4gICAgICogQHJldHVybnMge0J1ZmZlcn0gVGhlIG91dHB1dFxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgX2NyeXB0UGFja2FnZShlbmNyeXB0LCBjaXBoZXJBbGdvcml0aG0sIGNpcGhlckNoYWluaW5nLCBoYXNoQWxnb3JpdGhtLCBibG9ja1NpemUsIHNhbHRWYWx1ZSwga2V5LCBpbnB1dCkge1xyXG4gICAgICAgIC8vIFRoZSBmaXJzdCA4IGJ5dGVzIGlzIHN1cHBvc2VkIHRvIGJlIHRoZSBsZW5ndGgsIGJ1dCBpdCBzZWVtcyBsaWtlIGl0IGlzIHJlYWxseSB0aGUgbGVuZ3RoIC0gNC4uXHJcbiAgICAgICAgY29uc3Qgb3V0cHV0Q2h1bmtzID0gW107XHJcbiAgICAgICAgY29uc3Qgb2Zmc2V0ID0gZW5jcnlwdCA/IDAgOiBQQUNLQUdFX09GRlNFVDtcclxuXHJcbiAgICAgICAgLy8gVGhlIHBhY2thZ2UgaXMgZW5jb2RlZCBpbiBjaHVua3MuIEVuY3J5cHQvZGVjcnlwdCBlYWNoIGFuZCBjb25jYXQuXHJcbiAgICAgICAgbGV0IGkgPSAwLCBzdGFydCA9IDAsIGVuZCA9IDA7XHJcbiAgICAgICAgd2hpbGUgKGVuZCA8IGlucHV0Lmxlbmd0aCkge1xyXG4gICAgICAgICAgICBzdGFydCA9IGVuZDtcclxuICAgICAgICAgICAgZW5kID0gc3RhcnQgKyBQQUNLQUdFX0VOQ1JZUFRJT05fQ0hVTktfU0laRTtcclxuICAgICAgICAgICAgaWYgKGVuZCA+IGlucHV0Lmxlbmd0aCkgZW5kID0gaW5wdXQubGVuZ3RoO1xyXG5cclxuICAgICAgICAgICAgLy8gR3JhYiB0aGUgbmV4dCBjaHVua1xyXG4gICAgICAgICAgICBsZXQgaW5wdXRDaHVuayA9IGlucHV0LnNsaWNlKHN0YXJ0ICsgb2Zmc2V0LCBlbmQgKyBvZmZzZXQpO1xyXG5cclxuICAgICAgICAgICAgLy8gUGFkIHRoZSBjaHVuayBpZiBpdCBpcyBub3QgYW4gaW50ZWdlciBtdWx0aXBsZSBvZiB0aGUgYmxvY2sgc2l6ZVxyXG4gICAgICAgICAgICBjb25zdCByZW1haW5kZXIgPSBpbnB1dENodW5rLmxlbmd0aCAlIGJsb2NrU2l6ZTtcclxuICAgICAgICAgICAgaWYgKHJlbWFpbmRlcikgaW5wdXRDaHVuayA9IEJ1ZmZlci5jb25jYXQoW2lucHV0Q2h1bmssIEJ1ZmZlci5hbGxvYyhibG9ja1NpemUgLSByZW1haW5kZXIpXSk7XHJcblxyXG4gICAgICAgICAgICAvLyBDcmVhdGUgdGhlIGluaXRpYWxpemF0aW9uIHZlY3RvclxyXG4gICAgICAgICAgICBjb25zdCBpdiA9IHRoaXMuX2NyZWF0ZUlWKGhhc2hBbGdvcml0aG0sIHNhbHRWYWx1ZSwgYmxvY2tTaXplLCBpKTtcclxuXHJcbiAgICAgICAgICAgIC8vIEVuY3J5cHQvZGVjcnlwdCB0aGUgY2h1bmsgYW5kIGFkZCBpdCB0byB0aGUgYXJyYXlcclxuICAgICAgICAgICAgY29uc3Qgb3V0cHV0Q2h1bmsgPSB0aGlzLl9jcnlwdChlbmNyeXB0LCBjaXBoZXJBbGdvcml0aG0sIGNpcGhlckNoYWluaW5nLCBrZXksIGl2LCBpbnB1dENodW5rKTtcclxuICAgICAgICAgICAgb3V0cHV0Q2h1bmtzLnB1c2gob3V0cHV0Q2h1bmspO1xyXG5cclxuICAgICAgICAgICAgaSsrO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQ29uY2F0IGFsbCBvZiB0aGUgb3V0cHV0IGNodW5rcy5cclxuICAgICAgICBsZXQgb3V0cHV0ID0gQnVmZmVyLmNvbmNhdChvdXRwdXRDaHVua3MpO1xyXG5cclxuICAgICAgICBpZiAoZW5jcnlwdCkge1xyXG4gICAgICAgICAgICAvLyBQdXQgdGhlIGxlbmd0aCBvZiB0aGUgcGFja2FnZSBpbiB0aGUgZmlyc3QgOCBieXRlc1xyXG4gICAgICAgICAgICBvdXRwdXQgPSBCdWZmZXIuY29uY2F0KFt0aGlzLl9jcmVhdGVVSW50MzJMRUJ1ZmZlcihpbnB1dC5sZW5ndGgsIFBBQ0tBR0VfT0ZGU0VUKSwgb3V0cHV0XSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gVHJ1bmNhdGUgdGhlIGJ1ZmZlciB0byB0aGUgc2l6ZSBpbiB0aGUgcHJlZml4XHJcbiAgICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IGlucHV0LnJlYWRVSW50MzJMRSgwKTtcclxuICAgICAgICAgICAgb3V0cHV0ID0gb3V0cHV0LnNsaWNlKDAsIGxlbmd0aCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gb3V0cHV0O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlIGEgYnVmZmVyIG9mIGFuIGludGVnZXIgZW5jb2RlZCBhcyBhIHVpbnQzMmxlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgLSBUaGUgaW50ZWdlciB0byBlbmNvZGVcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYnVmZmVyU2l6ZT00XSBUaGUgb3V0cHV0IGJ1ZmZlciBzaXplIGluIGJ5dGVzXHJcbiAgICAgKiBAcmV0dXJucyB7QnVmZmVyfSBUaGUgYnVmZmVyXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICBfY3JlYXRlVUludDMyTEVCdWZmZXIodmFsdWUsIGJ1ZmZlclNpemUgPSA0KSB7XHJcbiAgICAgICAgY29uc3QgYnVmZmVyID0gQnVmZmVyLmFsbG9jKGJ1ZmZlclNpemUpO1xyXG4gICAgICAgIGJ1ZmZlci53cml0ZVVJbnQzMkxFKHZhbHVlLCAwKTtcclxuICAgICAgICByZXR1cm4gYnVmZmVyO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydCBhIHBhc3N3b3JkIGludG8gYW4gZW5jcnlwdGlvbiBrZXlcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXNzd29yZCAtIFRoZSBwYXNzd29yZFxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGhhc2hBbGdvcml0aG0gLSBUaGUgaGFzaCBhbGdvcml0bVxyXG4gICAgICogQHBhcmFtIHtCdWZmZXJ9IHNhbHRWYWx1ZSAtIFRoZSBzYWx0IHZhbHVlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3BpbkNvdW50IC0gVGhlIHNwaW4gY291bnRcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBrZXlCaXRzIC0gVGhlIGxlbmd0aCBvZiB0aGUga2V5IGluIGJpdHNcclxuICAgICAqIEBwYXJhbSB7QnVmZmVyfSBibG9ja0tleSAtIFRoZSBibG9jayBrZXlcclxuICAgICAqIEByZXR1cm5zIHtCdWZmZXJ9IFRoZSBlbmNyeXB0aW9uIGtleVxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgX2NvbnZlcnRQYXNzd29yZFRvS2V5KHBhc3N3b3JkLCBoYXNoQWxnb3JpdGhtLCBzYWx0VmFsdWUsIHNwaW5Db3VudCwga2V5Qml0cywgYmxvY2tLZXkpIHtcclxuICAgICAgICAvLyBQYXNzd29yZCBtdXN0IGJlIGluIHVuaWNvZGUgYnVmZmVyXHJcbiAgICAgICAgY29uc3QgcGFzc3dvcmRCdWZmZXIgPSBCdWZmZXIuZnJvbShwYXNzd29yZCwgJ3V0ZjE2bGUnKTtcclxuXHJcbiAgICAgICAgLy8gR2VuZXJhdGUgdGhlIGluaXRpYWwgaGFzaFxyXG4gICAgICAgIGxldCBrZXkgPSB0aGlzLl9oYXNoKGhhc2hBbGdvcml0aG0sIHNhbHRWYWx1ZSwgcGFzc3dvcmRCdWZmZXIpO1xyXG5cclxuICAgICAgICAvLyBOb3cgcmVnZW5lcmF0ZSB1bnRpbCBzcGluIGNvdW50XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzcGluQ291bnQ7IGkrKykge1xyXG4gICAgICAgICAgICBjb25zdCBpdGVyYXRvciA9IHRoaXMuX2NyZWF0ZVVJbnQzMkxFQnVmZmVyKGkpO1xyXG4gICAgICAgICAgICBrZXkgPSB0aGlzLl9oYXNoKGhhc2hBbGdvcml0aG0sIGl0ZXJhdG9yLCBrZXkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gTm93IGdlbmVyYXRlIHRoZSBmaW5hbCBoYXNoXHJcbiAgICAgICAga2V5ID0gdGhpcy5faGFzaChoYXNoQWxnb3JpdGhtLCBrZXksIGJsb2NrS2V5KTtcclxuXHJcbiAgICAgICAgLy8gVHJ1bmNhdGUgb3IgcGFkIGFzIG5lZWRlZCB0byBnZXQgdG8gbGVuZ3RoIG9mIGtleUJpdHNcclxuICAgICAgICBjb25zdCBrZXlCeXRlcyA9IGtleUJpdHMgLyA4O1xyXG4gICAgICAgIGlmIChrZXkubGVuZ3RoIDwga2V5Qnl0ZXMpIHtcclxuICAgICAgICAgICAgY29uc3QgdG1wID0gQnVmZmVyLmFsbG9jKGtleUJ5dGVzLCAweDM2KTtcclxuICAgICAgICAgICAga2V5LmNvcHkodG1wKTtcclxuICAgICAgICAgICAga2V5ID0gdG1wO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoa2V5Lmxlbmd0aCA+IGtleUJ5dGVzKSB7XHJcbiAgICAgICAgICAgIGtleSA9IGtleS5zbGljZSgwLCBrZXlCeXRlcyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4ga2V5O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlIGFuIGluaXRpYWxpemF0aW9uIHZlY3RvciAoSVYpXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gaGFzaEFsZ29yaXRobSAtIFRoZSBoYXNoIGFsZ29yaXRobVxyXG4gICAgICogQHBhcmFtIHtCdWZmZXJ9IHNhbHRWYWx1ZSAtIFRoZSBzYWx0IHZhbHVlXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYmxvY2tTaXplIC0gVGhlIHNpemUgb2YgdGhlIElWXHJcbiAgICAgKiBAcGFyYW0ge0J1ZmZlcnxudW1iZXJ9IGJsb2NrS2V5IC0gVGhlIGJsb2NrIGtleSBvciBhbiBpbnQgdG8gY29udmVydCB0byBhIGJ1ZmZlclxyXG4gICAgICogQHJldHVybnMge0J1ZmZlcn0gVGhlIElWXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICBfY3JlYXRlSVYoaGFzaEFsZ29yaXRobSwgc2FsdFZhbHVlLCBibG9ja1NpemUsIGJsb2NrS2V5KSB7XHJcbiAgICAgICAgLy8gQ3JlYXRlIHRoZSBibG9jayBrZXkgZnJvbSB0aGUgY3VycmVudCBpbmRleFxyXG4gICAgICAgIGlmICh0eXBlb2YgYmxvY2tLZXkgPT09IFwibnVtYmVyXCIpIGJsb2NrS2V5ID0gdGhpcy5fY3JlYXRlVUludDMyTEVCdWZmZXIoYmxvY2tLZXkpO1xyXG5cclxuICAgICAgICAvLyBDcmVhdGUgdGhlIGluaXRpYWxpemF0aW9uIHZlY3RvciBieSBoYXNoaW5nIHRoZSBzYWx0IHdpdGggdGhlIGJsb2NrIGtleS5cclxuICAgICAgICAvLyBUcnVuY2F0ZSBvciBwYWQgYXMgbmVlZGVkIHRvIG1lZXQgdGhlIGJsb2NrIHNpemUuXHJcbiAgICAgICAgbGV0IGl2ID0gdGhpcy5faGFzaChoYXNoQWxnb3JpdGhtLCBzYWx0VmFsdWUsIGJsb2NrS2V5KTtcclxuICAgICAgICBpZiAoaXYubGVuZ3RoIDwgYmxvY2tTaXplKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRtcCA9IEJ1ZmZlci5hbGxvYyhibG9ja1NpemUsIDB4MzYpO1xyXG4gICAgICAgICAgICBpdi5jb3B5KHRtcCk7XHJcbiAgICAgICAgICAgIGl2ID0gdG1wO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoaXYubGVuZ3RoID4gYmxvY2tTaXplKSB7XHJcbiAgICAgICAgICAgIGl2ID0gaXYuc2xpY2UoMCwgYmxvY2tTaXplKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBpdjtcclxuICAgIH1cclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBFbmNyeXB0b3I7XHJcbiIsIlwidXNlIHN0cmljdFwiO1xyXG5cclxuY29uc3QgXyA9IHJlcXVpcmUoXCJsb2Rhc2hcIik7XHJcblxyXG4vKipcclxuICogQSBmb3JtdWxhIGVycm9yIChlLmcuICNESVYvMCEpLlxyXG4gKi9cclxuY2xhc3MgRm9ybXVsYUVycm9yIHtcclxuICAgIC8vIC8qKlxyXG4gICAgLy8gICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBGb3JtdWxhIEVycm9yLlxyXG4gICAgLy8gICogQHBhcmFtIHtzdHJpbmd9IGVycm9yIC0gVGhlIGVycm9yIGNvZGUuXHJcbiAgICAvLyAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGVycm9yKSB7XHJcbiAgICAgICAgdGhpcy5fZXJyb3IgPSBlcnJvcjtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldCB0aGUgZXJyb3IgY29kZS5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBlcnJvciBjb2RlLlxyXG4gICAgICovXHJcbiAgICBlcnJvcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZXJyb3I7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBcXCNESVYvMCEgZXJyb3IuXHJcbiAqIEB0eXBlIHtGb3JtdWxhRXJyb3J9XHJcbiAqL1xyXG5Gb3JtdWxhRXJyb3IuRElWMCA9IG5ldyBGb3JtdWxhRXJyb3IoXCIjRElWLzAhXCIpO1xyXG5cclxuLyoqXHJcbiAqIFxcI04vQSBlcnJvci5cclxuICogQHR5cGUge0Zvcm11bGFFcnJvcn1cclxuICovXHJcbkZvcm11bGFFcnJvci5OQSA9IG5ldyBGb3JtdWxhRXJyb3IoXCIjTi9BXCIpO1xyXG5cclxuLyoqXHJcbiAqIFxcI05BTUU/IGVycm9yLlxyXG4gKiBAdHlwZSB7Rm9ybXVsYUVycm9yfVxyXG4gKi9cclxuRm9ybXVsYUVycm9yLk5BTUUgPSBuZXcgRm9ybXVsYUVycm9yKFwiI05BTUU/XCIpO1xyXG5cclxuLyoqXHJcbiAqIFxcI05VTEwhIGVycm9yLlxyXG4gKiBAdHlwZSB7Rm9ybXVsYUVycm9yfVxyXG4gKi9cclxuRm9ybXVsYUVycm9yLk5VTEwgPSBuZXcgRm9ybXVsYUVycm9yKFwiI05VTEwhXCIpO1xyXG5cclxuLyoqXHJcbiAqIFxcI05VTSEgZXJyb3IuXHJcbiAqIEB0eXBlIHtGb3JtdWxhRXJyb3J9XHJcbiAqL1xyXG5Gb3JtdWxhRXJyb3IuTlVNID0gbmV3IEZvcm11bGFFcnJvcihcIiNOVU0hXCIpO1xyXG5cclxuLyoqXHJcbiAqIFxcI1JFRiEgZXJyb3IuXHJcbiAqIEB0eXBlIHtGb3JtdWxhRXJyb3J9XHJcbiAqL1xyXG5Gb3JtdWxhRXJyb3IuUkVGID0gbmV3IEZvcm11bGFFcnJvcihcIiNSRUYhXCIpO1xyXG5cclxuLyoqXHJcbiAqIFxcI1ZBTFVFISBlcnJvci5cclxuICogQHR5cGUge0Zvcm11bGFFcnJvcn1cclxuICovXHJcbkZvcm11bGFFcnJvci5WQUxVRSA9IG5ldyBGb3JtdWxhRXJyb3IoXCIjVkFMVUUhXCIpO1xyXG5cclxuLyoqXHJcbiAqIEdldCB0aGUgbWF0Y2hpbmcgRm9ybXVsYUVycm9yIG9iamVjdC5cclxuICogQHBhcmFtIHtzdHJpbmd9IGVycm9yIC0gVGhlIGVycm9yIGNvZGUuXHJcbiAqIEByZXR1cm5zIHtGb3JtdWxhRXJyb3J9IFRoZSBtYXRjaGluZyBGb3JtdWxhRXJyb3Igb3IgYSBuZXcgb2JqZWN0IGlmIG5vIG1hdGNoLlxyXG4gKiBAaWdub3JlXHJcbiAqL1xyXG5Gb3JtdWxhRXJyb3IuZ2V0RXJyb3IgPSBlcnJvciA9PiB7XHJcbiAgICByZXR1cm4gXy5maW5kKEZvcm11bGFFcnJvciwgdmFsdWUgPT4ge1xyXG4gICAgICAgIHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIEZvcm11bGFFcnJvciAmJiB2YWx1ZS5lcnJvcigpID09PSBlcnJvcjtcclxuICAgIH0pIHx8IG5ldyBGb3JtdWxhRXJyb3IoZXJyb3IpO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBGb3JtdWxhRXJyb3I7XHJcbiIsIlwidXNlIHN0cmljdFwiO1xyXG5cclxuLyoqXHJcbiAqIFBhZ2VCcmVha3NcclxuICovXHJcbmNsYXNzIFBhZ2VCcmVha3Mge1xyXG4gICAgY29uc3RydWN0b3Iobm9kZSkge1xyXG4gICAgICAgIHRoaXMuX25vZGUgPSBub2RlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogYWRkIHBhZ2UtYnJlYWtzIGJ5IHJvdy9jb2x1bW4gaWRcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpZCAtIHJvdy9jb2x1bW4gaWQgKHJvd051bWJlci9jb2xOdW1iZXIpXHJcbiAgICAgKiBAcmV0dXJuIHtQYWdlQnJlYWtzfSB0aGUgcGFnZS1icmVha3NcclxuICAgICAqL1xyXG4gICAgYWRkKGlkKSB7XHJcbiAgICAgICAgdGhpcy5fbm9kZS5jaGlsZHJlbi5wdXNoKHtcclxuICAgICAgICAgICAgbmFtZTogXCJicmtcIixcclxuICAgICAgICAgICAgY2hpbGRyZW46IFtdLFxyXG4gICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XHJcbiAgICAgICAgICAgICAgICBpZCxcclxuICAgICAgICAgICAgICAgIG1heDogMTYzODMsXHJcbiAgICAgICAgICAgICAgICBtYW46IDFcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuX25vZGUuYXR0cmlidXRlcy5jb3VudCsrO1xyXG4gICAgICAgIHRoaXMuX25vZGUuYXR0cmlidXRlcy5tYW51YWxCcmVha0NvdW50Kys7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogcmVtb3ZlIHBhZ2UtYnJlYWtzIGJ5IGluZGV4XHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggLSBpbmRleCBvZiBsaXN0XHJcbiAgICAgKiBAcmV0dXJuIHtQYWdlQnJlYWtzfSB0aGUgcGFnZS1icmVha3NcclxuICAgICAqL1xyXG4gICAgcmVtb3ZlKGluZGV4KSB7XHJcbiAgICAgICAgY29uc3QgYnJrID0gdGhpcy5fbm9kZS5jaGlsZHJlbltpbmRleF07XHJcbiAgICAgICAgaWYgKGJyaykge1xyXG4gICAgICAgICAgICB0aGlzLl9ub2RlLmNoaWxkcmVuLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgICAgIHRoaXMuX25vZGUuYXR0cmlidXRlcy5jb3VudC0tO1xyXG4gICAgICAgICAgICBpZiAoYnJrLm1hbikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fbm9kZS5hdHRyaWJ1dGVzLm1hbnVhbEJyZWFrQ291bnQtLTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBnZXQgY291bnQgb2YgdGhlIHBhZ2UtYnJlYWtzXHJcbiAgICAgKiBAcmV0dXJuIHtudW1iZXJ9IHRoZSBwYWdlLWJyZWFrcycgY291bnRcclxuICAgICAqL1xyXG4gICAgZ2V0IGNvdW50KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9ub2RlLmF0dHJpYnV0ZXMuY291bnQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBnZXQgbGlzdCBvZiBwYWdlLWJyZWFrc1xyXG4gICAgICogQHJldHVybiB7QXJyYXl9IGxpc3Qgb2YgdGhlIHBhZ2UtYnJlYWtzXHJcbiAgICAgKi9cclxuICAgIGdldCBsaXN0KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9ub2RlLmNoaWxkcmVuLm1hcChicmsgPT4gKHtcclxuICAgICAgICAgICAgaWQ6IGJyay5pZCxcclxuICAgICAgICAgICAgaXNNYW51YWw6ICEhYnJrLm1hblxyXG4gICAgICAgIH0pKTtcclxuICAgIH1cclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBQYWdlQnJlYWtzO1xyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxuXHJcbmNvbnN0IEFyZ0hhbmRsZXIgPSByZXF1aXJlKFwiLi9BcmdIYW5kbGVyXCIpO1xyXG5jb25zdCBhZGRyZXNzQ29udmVydGVyID0gcmVxdWlyZShcIi4vYWRkcmVzc0NvbnZlcnRlclwiKTtcclxuXHJcbi8qKlxyXG4gKiBBIHJhbmdlIG9mIGNlbGxzLlxyXG4gKi9cclxuY2xhc3MgUmFuZ2Uge1xyXG4gICAgLy8gLyoqXHJcbiAgICAvLyAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIFJhbmdlLlxyXG4gICAgLy8gICogQHBhcmFtIHtDZWxsfSBzdGFydENlbGwgLSBUaGUgc3RhcnQgY2VsbC5cclxuICAgIC8vICAqIEBwYXJhbSB7Q2VsbH0gZW5kQ2VsbCAtIFRoZSBlbmQgY2VsbC5cclxuICAgIC8vICAqL1xyXG4gICAgY29uc3RydWN0b3Ioc3RhcnRDZWxsLCBlbmRDZWxsKSB7XHJcbiAgICAgICAgdGhpcy5fc3RhcnRDZWxsID0gc3RhcnRDZWxsO1xyXG4gICAgICAgIHRoaXMuX2VuZENlbGwgPSBlbmRDZWxsO1xyXG4gICAgICAgIHRoaXMuX2ZpbmRSYW5nZUV4dGVudChzdGFydENlbGwsIGVuZENlbGwpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0IHRoZSBhZGRyZXNzIG9mIHRoZSByYW5nZS5cclxuICAgICAqIEBwYXJhbSB7e319IFtvcHRzXSAtIE9wdGlvbnNcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuaW5jbHVkZVNoZWV0TmFtZV0gLSBJbmNsdWRlIHRoZSBzaGVldCBuYW1lIGluIHRoZSBhZGRyZXNzLlxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5zdGFydFJvd0FuY2hvcmVkXSAtIEFuY2hvciB0aGUgc3RhcnQgcm93LlxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5zdGFydENvbHVtbkFuY2hvcmVkXSAtIEFuY2hvciB0aGUgc3RhcnQgY29sdW1uLlxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5lbmRSb3dBbmNob3JlZF0gLSBBbmNob3IgdGhlIGVuZCByb3cuXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLmVuZENvbHVtbkFuY2hvcmVkXSAtIEFuY2hvciB0aGUgZW5kIGNvbHVtbi5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuYW5jaG9yZWRdIC0gQW5jaG9yIGFsbCByb3cgYW5kIGNvbHVtbnMuXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgYWRkcmVzcy5cclxuICAgICAqL1xyXG4gICAgYWRkcmVzcyhvcHRzKSB7XHJcbiAgICAgICAgcmV0dXJuIGFkZHJlc3NDb252ZXJ0ZXIudG9BZGRyZXNzKHtcclxuICAgICAgICAgICAgdHlwZTogJ3JhbmdlJyxcclxuICAgICAgICAgICAgc3RhcnRSb3dOdW1iZXI6IHRoaXMuc3RhcnRDZWxsKCkucm93TnVtYmVyKCksXHJcbiAgICAgICAgICAgIHN0YXJ0Um93QW5jaG9yZWQ6IG9wdHMgJiYgKG9wdHMuc3RhcnRSb3dBbmNob3JlZCB8fCBvcHRzLmFuY2hvcmVkKSxcclxuICAgICAgICAgICAgc3RhcnRDb2x1bW5OYW1lOiB0aGlzLnN0YXJ0Q2VsbCgpLmNvbHVtbk5hbWUoKSxcclxuICAgICAgICAgICAgc3RhcnRDb2x1bW5BbmNob3JlZDogb3B0cyAmJiAob3B0cy5zdGFydENvbHVtbkFuY2hvcmVkIHx8IG9wdHMuYW5jaG9yZWQpLFxyXG4gICAgICAgICAgICBlbmRSb3dOdW1iZXI6IHRoaXMuZW5kQ2VsbCgpLnJvd051bWJlcigpLFxyXG4gICAgICAgICAgICBlbmRSb3dBbmNob3JlZDogb3B0cyAmJiAob3B0cy5lbmRSb3dBbmNob3JlZCB8fCBvcHRzLmFuY2hvcmVkKSxcclxuICAgICAgICAgICAgZW5kQ29sdW1uTmFtZTogdGhpcy5lbmRDZWxsKCkuY29sdW1uTmFtZSgpLFxyXG4gICAgICAgICAgICBlbmRDb2x1bW5BbmNob3JlZDogb3B0cyAmJiAob3B0cy5lbmRDb2x1bW5BbmNob3JlZCB8fCBvcHRzLmFuY2hvcmVkKSxcclxuICAgICAgICAgICAgc2hlZXROYW1lOiBvcHRzICYmIG9wdHMuaW5jbHVkZVNoZWV0TmFtZSAmJiB0aGlzLnNoZWV0KCkubmFtZSgpXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIGEgY2VsbCB3aXRoaW4gdGhlIHJhbmdlLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJpIC0gUm93IGluZGV4IHJlbGF0aXZlIHRvIHRoZSB0b3AtbGVmdCBjb3JuZXIgb2YgdGhlIHJhbmdlICgwLWJhc2VkKS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBjaSAtIENvbHVtbiBpbmRleCByZWxhdGl2ZSB0byB0aGUgdG9wLWxlZnQgY29ybmVyIG9mIHRoZSByYW5nZSAoMC1iYXNlZCkuXHJcbiAgICAgKiBAcmV0dXJucyB7Q2VsbH0gVGhlIGNlbGwuXHJcbiAgICAgKi9cclxuICAgIGNlbGwocmksIGNpKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc2hlZXQoKS5jZWxsKHRoaXMuX21pblJvd051bWJlciArIHJpLCB0aGlzLl9taW5Db2x1bW5OdW1iZXIgKyBjaSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZXRzIHNoZWV0IGF1dG9GaWx0ZXIgdG8gdGhpcyByYW5nZS5cclxuICAgICAqIEByZXR1cm5zIHtSYW5nZX0gVGhpcyByYW5nZS5cclxuICAgICAqL1xyXG4gICAgYXV0b0ZpbHRlcigpIHtcclxuICAgICAgICB0aGlzLnNoZWV0KCkuYXV0b0ZpbHRlcih0aGlzKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXQgdGhlIGNlbGxzIGluIHRoZSByYW5nZSBhcyBhIDJEIGFycmF5LlxyXG4gICAgICogQHJldHVybnMge0FycmF5LjxBcnJheS48Q2VsbD4+fSBUaGUgY2VsbHMuXHJcbiAgICAgKi9cclxuICAgIGNlbGxzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm1hcChjZWxsID0+IGNlbGwpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2xlYXIgdGhlIGNvbnRlbnRzIG9mIGFsbCB0aGUgY2VsbHMgaW4gdGhlIHJhbmdlLlxyXG4gICAgICogQHJldHVybnMge1JhbmdlfSBUaGUgcmFuZ2UuXHJcbiAgICAgKi9cclxuICAgIGNsZWFyKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlKHVuZGVmaW5lZCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXQgdGhlIGVuZCBjZWxsIG9mIHRoZSByYW5nZS5cclxuICAgICAqIEByZXR1cm5zIHtDZWxsfSBUaGUgZW5kIGNlbGwuXHJcbiAgICAgKi9cclxuICAgIGVuZENlbGwoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VuZENlbGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsYmFjayB1c2VkIGJ5IGZvckVhY2guXHJcbiAgICAgKiBAY2FsbGJhY2sgUmFuZ2V+Zm9yRWFjaENhbGxiYWNrXHJcbiAgICAgKiBAcGFyYW0ge0NlbGx9IGNlbGwgLSBUaGUgY2VsbC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByaSAtIFRoZSByZWxhdGl2ZSByb3cgaW5kZXguXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gY2kgLSBUaGUgcmVsYXRpdmUgY29sdW1uIGluZGV4LlxyXG4gICAgICogQHBhcmFtIHtSYW5nZX0gcmFuZ2UgLSBUaGUgcmFuZ2UuXHJcbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gICAgICovXHJcbiAgICAvKipcclxuICAgICAqIENhbGwgYSBmdW5jdGlvbiBmb3IgZWFjaCBjZWxsIGluIHRoZSByYW5nZS4gR29lcyBieSByb3cgdGhlbiBjb2x1bW4uXHJcbiAgICAgKiBAcGFyYW0ge1JhbmdlfmZvckVhY2hDYWxsYmFja30gY2FsbGJhY2sgLSBGdW5jdGlvbiBjYWxsZWQgZm9yIGVhY2ggY2VsbCBpbiB0aGUgcmFuZ2UuXHJcbiAgICAgKiBAcmV0dXJucyB7UmFuZ2V9IFRoZSByYW5nZS5cclxuICAgICAqL1xyXG4gICAgZm9yRWFjaChjYWxsYmFjaykge1xyXG4gICAgICAgIGZvciAobGV0IHJpID0gMDsgcmkgPCB0aGlzLl9udW1Sb3dzOyByaSsrKSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGNpID0gMDsgY2kgPCB0aGlzLl9udW1Db2x1bW5zOyBjaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBjYWxsYmFjayh0aGlzLmNlbGwocmksIGNpKSwgcmksIGNpLCB0aGlzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBzaGFyZWQgZm9ybXVsYSBpbiB0aGUgc3RhcnQgY2VsbCAoYXNzdW1pbmcgaXQncyB0aGUgc291cmNlIG9mIHRoZSBzaGFyZWQgZm9ybXVsYSkuXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfHVuZGVmaW5lZH0gVGhlIHNoYXJlZCBmb3JtdWxhLlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXRzIHRoZSBzaGFyZWQgZm9ybXVsYSBpbiB0aGUgcmFuZ2UuIFRoZSBmb3JtdWxhIHdpbGwgYmUgdHJhbnNsYXRlZCBmb3IgZWFjaCBjZWxsLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGZvcm11bGEgLSBUaGUgZm9ybXVsYSB0byBzZXQuXHJcbiAgICAgKiBAcmV0dXJucyB7UmFuZ2V9IFRoZSByYW5nZS5cclxuICAgICAqL1xyXG4gICAgZm9ybXVsYSgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEFyZ0hhbmRsZXIoXCJSYW5nZS5mb3JtdWxhXCIpXHJcbiAgICAgICAgICAgIC5jYXNlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnN0YXJ0Q2VsbCgpLmdldFNoYXJlZFJlZkZvcm11bGEoKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoJ3N0cmluZycsIGZvcm11bGEgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc2hhcmVkRm9ybXVsYUlkID0gdGhpcy5zaGVldCgpLmluY3JlbWVudE1heFNoYXJlZEZvcm11bGFJZCgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5mb3JFYWNoKChjZWxsLCByaSwgY2kpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocmkgPT09IDAgJiYgY2kgPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC5zZXRTaGFyZWRGb3JtdWxhKHNoYXJlZEZvcm11bGFJZCwgZm9ybXVsYSwgdGhpcy5hZGRyZXNzKCkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuc2V0U2hhcmVkRm9ybXVsYShzaGFyZWRGb3JtdWxhSWQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuaGFuZGxlKGFyZ3VtZW50cyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsYmFjayB1c2VkIGJ5IG1hcC5cclxuICAgICAqIEBjYWxsYmFjayBSYW5nZX5tYXBDYWxsYmFja1xyXG4gICAgICogQHBhcmFtIHtDZWxsfSBjZWxsIC0gVGhlIGNlbGwuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcmkgLSBUaGUgcmVsYXRpdmUgcm93IGluZGV4LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGNpIC0gVGhlIHJlbGF0aXZlIGNvbHVtbiBpbmRleC5cclxuICAgICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlIC0gVGhlIHJhbmdlLlxyXG4gICAgICogQHJldHVybnMgeyp9IFRoZSB2YWx1ZSB0byBtYXAgdG8uXHJcbiAgICAgKi9cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIDJEIGFycmF5IG9mIHZhbHVlcyBieSBydW5uaW5nIGVhY2ggY2VsbCB0aHJvdWdoIGEgY2FsbGJhY2suXHJcbiAgICAgKiBAcGFyYW0ge1Jhbmdlfm1hcENhbGxiYWNrfSBjYWxsYmFjayAtIEZ1bmN0aW9uIGNhbGxlZCBmb3IgZWFjaCBjZWxsIGluIHRoZSByYW5nZS5cclxuICAgICAqIEByZXR1cm5zIHtBcnJheS48QXJyYXkuPCo+Pn0gVGhlIDJEIGFycmF5IG9mIHJldHVybiB2YWx1ZXMuXHJcbiAgICAgKi9cclxuICAgIG1hcChjYWxsYmFjaykge1xyXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IFtdO1xyXG4gICAgICAgIHRoaXMuZm9yRWFjaCgoY2VsbCwgcmksIGNpKSA9PiB7XHJcbiAgICAgICAgICAgIGlmICghcmVzdWx0W3JpXSkgcmVzdWx0W3JpXSA9IFtdO1xyXG4gICAgICAgICAgICByZXN1bHRbcmldW2NpXSA9IGNhbGxiYWNrKGNlbGwsIHJpLCBjaSwgdGhpcyk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIGEgdmFsdWUgaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBjZWxscyBpbiB0aGUgcmFuZ2UgYXJlIG1lcmdlZC5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUaGUgdmFsdWUuXHJcbiAgICAgKi8vKipcclxuICAgICAqIFNldHMgYSB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGNlbGxzIGluIHRoZSByYW5nZSBzaG91bGQgYmUgbWVyZ2VkLlxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBtZXJnZWQgLSBUcnVlIHRvIG1lcmdlLCBmYWxzZSB0byB1bm1lcmdlLlxyXG4gICAgICogQHJldHVybnMge1JhbmdlfSBUaGUgcmFuZ2UuXHJcbiAgICAgKi9cclxuICAgIG1lcmdlZChtZXJnZWQpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEFyZ0hhbmRsZXIoJ1JhbmdlLm1lcmdlZCcpXHJcbiAgICAgICAgICAgIC5jYXNlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNoZWV0KCkubWVyZ2VkKHRoaXMuYWRkcmVzcygpKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoJyonLCBtZXJnZWQgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zaGVldCgpLm1lcmdlZCh0aGlzLmFkZHJlc3MoKSwgbWVyZ2VkKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuaGFuZGxlKGFyZ3VtZW50cyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBkYXRhIHZhbGlkYXRpb24gb2JqZWN0IGF0dGFjaGVkIHRvIHRoZSBSYW5nZS5cclxuICAgICAqIEByZXR1cm5zIHtvYmplY3R8dW5kZWZpbmVkfSBUaGUgZGF0YSB2YWxpZGF0aW9uIG9iamVjdCBvciB1bmRlZmluZWQgaWYgbm90IHNldC5cclxuICAgICAqLy8qKlxyXG4gICAgICogU2V0IG9yIGNsZWFyIHRoZSBkYXRhIHZhbGlkYXRpb24gb2JqZWN0IG9mIHRoZSBlbnRpcmUgcmFuZ2UuXHJcbiAgICAgKiBAcGFyYW0ge29iamVjdHx1bmRlZmluZWR9IGRhdGFWYWxpZGF0aW9uIC0gT2JqZWN0IG9yIG51bGwgdG8gY2xlYXIuXHJcbiAgICAgKiBAcmV0dXJucyB7UmFuZ2V9IFRoZSByYW5nZS5cclxuICAgICAqL1xyXG4gICAgZGF0YVZhbGlkYXRpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBcmdIYW5kbGVyKCdSYW5nZS5kYXRhVmFsaWRhdGlvbicpXHJcbiAgICAgICAgICAgIC5jYXNlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNoZWV0KCkuZGF0YVZhbGlkYXRpb24odGhpcy5hZGRyZXNzKCkpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnYm9vbGVhbicsIG9iaiA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zaGVldCgpLmRhdGFWYWxpZGF0aW9uKHRoaXMuYWRkcmVzcygpLCBvYmopO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnKicsIG9iaiA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNoZWV0KCkuZGF0YVZhbGlkYXRpb24odGhpcy5hZGRyZXNzKCksIG9iaik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmhhbmRsZShhcmd1bWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGJhY2sgdXNlZCBieSByZWR1Y2UuXHJcbiAgICAgKiBAY2FsbGJhY2sgUmFuZ2V+cmVkdWNlQ2FsbGJhY2tcclxuICAgICAqIEBwYXJhbSB7Kn0gYWNjdW11bGF0b3IgLSBUaGUgYWNjdW11bGF0ZWQgdmFsdWUuXHJcbiAgICAgKiBAcGFyYW0ge0NlbGx9IGNlbGwgLSBUaGUgY2VsbC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByaSAtIFRoZSByZWxhdGl2ZSByb3cgaW5kZXguXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gY2kgLSBUaGUgcmVsYXRpdmUgY29sdW1uIGluZGV4LlxyXG4gICAgICogQHBhcmFtIHtSYW5nZX0gcmFuZ2UgLSBUaGUgcmFuZ2UuXHJcbiAgICAgKiBAcmV0dXJucyB7Kn0gVGhlIHZhbHVlIHRvIG1hcCB0by5cclxuICAgICAqL1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZWR1Y2VzIHRoZSByYW5nZSB0byBhIHNpbmdsZSB2YWx1ZSBhY2N1bXVsYXRlZCBmcm9tIHRoZSByZXN1bHQgb2YgYSBmdW5jdGlvbiBjYWxsZWQgZm9yIGVhY2ggY2VsbC5cclxuICAgICAqIEBwYXJhbSB7UmFuZ2V+cmVkdWNlQ2FsbGJhY2t9IGNhbGxiYWNrIC0gRnVuY3Rpb24gY2FsbGVkIGZvciBlYWNoIGNlbGwgaW4gdGhlIHJhbmdlLlxyXG4gICAgICogQHBhcmFtIHsqfSBbaW5pdGlhbFZhbHVlXSAtIFRoZSBpbml0aWFsIHZhbHVlLlxyXG4gICAgICogQHJldHVybnMgeyp9IFRoZSBhY2N1bXVsYXRlZCB2YWx1ZS5cclxuICAgICAqL1xyXG4gICAgcmVkdWNlKGNhbGxiYWNrLCBpbml0aWFsVmFsdWUpIHtcclxuICAgICAgICBsZXQgYWNjdW11bGF0b3IgPSBpbml0aWFsVmFsdWU7XHJcbiAgICAgICAgdGhpcy5mb3JFYWNoKChjZWxsLCByaSwgY2kpID0+IHtcclxuICAgICAgICAgICAgYWNjdW11bGF0b3IgPSBjYWxsYmFjayhhY2N1bXVsYXRvciwgY2VsbCwgcmksIGNpLCB0aGlzKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgcGFyZW50IHNoZWV0IG9mIHRoZSByYW5nZS5cclxuICAgICAqIEByZXR1cm5zIHtTaGVldH0gVGhlIHBhcmVudCBzaGVldC5cclxuICAgICAqL1xyXG4gICAgc2hlZXQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhcnRDZWxsKCkuc2hlZXQoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIHN0YXJ0IGNlbGwgb2YgdGhlIHJhbmdlLlxyXG4gICAgICogQHJldHVybnMge0NlbGx9IFRoZSBzdGFydCBjZWxsLlxyXG4gICAgICovXHJcbiAgICBzdGFydENlbGwoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXJ0Q2VsbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgYSBzaW5nbGUgc3R5bGUgZm9yIGVhY2ggY2VsbC5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHN0eWxlLlxyXG4gICAgICogQHJldHVybnMge0FycmF5LjxBcnJheS48Kj4+fSAyRCBhcnJheSBvZiBzdHlsZSB2YWx1ZXMuXHJcbiAgICAgKi8vKipcclxuICAgICAqIEdldHMgbXVsdGlwbGUgc3R5bGVzIGZvciBlYWNoIGNlbGwuXHJcbiAgICAgKiBAcGFyYW0ge0FycmF5LjxzdHJpbmc+fSBuYW1lcyAtIFRoZSBuYW1lcyBvZiB0aGUgc3R5bGVzLlxyXG4gICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCBBcnJheS48QXJyYXkuPCo+Pj59IE9iamVjdCB3aG9zZSBrZXlzIGFyZSBzdHlsZSBuYW1lcyBhbmQgdmFsdWVzIGFyZSAyRCBhcnJheXMgb2Ygc3R5bGUgdmFsdWVzLlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXQgdGhlIHN0eWxlIGluIGVhY2ggY2VsbCB0byB0aGUgcmVzdWx0IG9mIGEgZnVuY3Rpb24gY2FsbGVkIGZvciBlYWNoLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgc3R5bGUuXHJcbiAgICAgKiBAcGFyYW0ge1Jhbmdlfm1hcENhbGxiYWNrfSBjYWxsYmFjayAtIFRoZSBjYWxsYmFjayB0byBwcm92aWRlIHZhbHVlIGZvciB0aGUgY2VsbC5cclxuICAgICAqIEByZXR1cm5zIHtSYW5nZX0gVGhlIHJhbmdlLlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXRzIHRoZSBzdHlsZSBpbiBlYWNoIGNlbGwgdG8gdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWUgaW4gdGhlIGdpdmVuIDJEIGFycmF5IG9mIHZhbHVlcy5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHN0eWxlLlxyXG4gICAgICogQHBhcmFtIHtBcnJheS48QXJyYXkuPCo+Pn0gdmFsdWVzIC0gVGhlIHN0eWxlIHZhbHVlcyB0byBzZXQuXHJcbiAgICAgKiBAcmV0dXJucyB7UmFuZ2V9IFRoZSByYW5nZS5cclxuICAgICAqLy8qKlxyXG4gICAgICogU2V0IHRoZSBzdHlsZSBvZiBhbGwgY2VsbHMgaW4gdGhlIHJhbmdlIHRvIGEgc2luZ2xlIHN0eWxlIHZhbHVlLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgc3R5bGUuXHJcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIC0gVGhlIHZhbHVlIHRvIHNldC5cclxuICAgICAqIEByZXR1cm5zIHtSYW5nZX0gVGhlIHJhbmdlLlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXQgbXVsdGlwbGUgc3R5bGVzIGZvciB0aGUgY2VsbHMgaW4gdGhlIHJhbmdlLlxyXG4gICAgICogQHBhcmFtIHtvYmplY3QuPHN0cmluZyxSYW5nZX5tYXBDYWxsYmFja3xBcnJheS48QXJyYXkuPCo+PnwqPn0gc3R5bGVzIC0gT2JqZWN0IHdob3NlIGtleXMgYXJlIHN0eWxlIG5hbWVzIGFuZCB2YWx1ZXMgYXJlIGVpdGhlciBmdW5jdGlvbiBjYWxsYmFja3MsIDJEIGFycmF5cyBvZiBzdHlsZSB2YWx1ZXMsIG9yIGEgc2luZ2xlIHZhbHVlIGZvciBhbGwgdGhlIGNlbGxzLlxyXG4gICAgICogQHJldHVybnMge1JhbmdlfSBUaGUgcmFuZ2UuXHJcbiAgICAgKi8vKipcclxuXHQgKiBTZXRzIHRvIGEgc3BlY2lmaWMgc3R5bGVcclxuXHQgKiBAcGFyYW0ge1N0eWxlfSBzdHlsZSAtIFN0eWxlIG9iamVjdCBnaXZlbiBmcm9tIHN0eWxlc2hlZXQuY3JlYXRlU3R5bGVcclxuXHQgKiBAcmV0dXJucyB7UmFuZ2V9IFRoZSByYW5nZS5cclxuXHQgKi9cclxuICAgIHN0eWxlKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQXJnSGFuZGxlcihcIlJhbmdlLnN0eWxlXCIpXHJcbiAgICAgICAgICAgIC5jYXNlKCdzdHJpbmcnLCBuYW1lID0+IHtcclxuICAgICAgICAgICAgICAgIC8vIEdldCBzaW5nbGUgdmFsdWVcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm1hcChjZWxsID0+IGNlbGwuc3R5bGUobmFtZSkpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnYXJyYXknLCBuYW1lcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBHZXQgbGlzdCBvZiB2YWx1ZXNcclxuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlcyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgbmFtZXMuZm9yRWFjaChuYW1lID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXNbbmFtZV0gPSB0aGlzLnN0eWxlKG5hbWUpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoWydzdHJpbmcnLCAnZnVuY3Rpb24nXSwgKG5hbWUsIGNhbGxiYWNrKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBTZXQgYSBzaW5nbGUgdmFsdWUgZm9yIHRoZSBjZWxscyB0byB0aGUgcmVzdWx0IG9mIGEgZnVuY3Rpb25cclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZvckVhY2goKGNlbGwsIHJpLCBjaSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNlbGwuc3R5bGUobmFtZSwgY2FsbGJhY2soY2VsbCwgcmksIGNpLCB0aGlzKSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoWydzdHJpbmcnLCAnYXJyYXknXSwgKG5hbWUsIHZhbHVlcykgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gU2V0IGEgc2luZ2xlIHZhbHVlIGZvciB0aGUgY2VsbHMgdXNpbmcgYW4gYXJyYXkgb2YgbWF0Y2hpbmcgZGltZW5zaW9uXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JFYWNoKChjZWxsLCByaSwgY2kpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWVzW3JpXSAmJiB2YWx1ZXNbcmldW2NpXSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuc3R5bGUobmFtZSwgdmFsdWVzW3JpXVtjaV0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZShbJ3N0cmluZycsICcqJ10sIChuYW1lLCB2YWx1ZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gU2V0IGEgc2luZ2xlIHZhbHVlIGZvciBhbGwgY2VsbHMgdG8gYSBzaW5nbGUgdmFsdWVcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZvckVhY2goY2VsbCA9PiBjZWxsLnN0eWxlKG5hbWUsIHZhbHVlKSk7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKCdvYmplY3QnLCBuYW1lVmFsdWVzID0+IHtcclxuICAgICAgICAgICAgICAgIC8vIE9iamVjdCBvZiBrZXkgdmFsdWUgcGFpcnMgdG8gc2V0XHJcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IG5hbWUgaW4gbmFtZVZhbHVlcykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghbmFtZVZhbHVlcy5oYXNPd25Qcm9wZXJ0eShuYW1lKSkgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBuYW1lVmFsdWVzW25hbWVdO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3R5bGUobmFtZSwgdmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnU3R5bGUnLCBzdHlsZSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zdHlsZSA9IHN0eWxlO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm9yRWFjaChjZWxsID0+IGNlbGwuc3R5bGUoc3R5bGUpKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmhhbmRsZShhcmd1bWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGJhY2sgdXNlZCBieSB0YXAuXHJcbiAgICAgKiBAY2FsbGJhY2sgUmFuZ2V+dGFwQ2FsbGJhY2tcclxuICAgICAqIEBwYXJhbSB7UmFuZ2V9IHJhbmdlIC0gVGhlIHJhbmdlLlxyXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICAgICAqL1xyXG4gICAgLyoqXHJcbiAgICAgKiBJbnZva2UgYSBjYWxsYmFjayBvbiB0aGUgcmFuZ2UgYW5kIHJldHVybiB0aGUgcmFuZ2UuIFVzZWZ1bCBmb3IgbWV0aG9kIGNoYWluaW5nLlxyXG4gICAgICogQHBhcmFtIHtSYW5nZX50YXBDYWxsYmFja30gY2FsbGJhY2sgLSBUaGUgY2FsbGJhY2sgZnVuY3Rpb24uXHJcbiAgICAgKiBAcmV0dXJucyB7UmFuZ2V9IFRoZSByYW5nZS5cclxuICAgICAqL1xyXG4gICAgdGFwKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgY2FsbGJhY2sodGhpcyk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsYmFjayB1c2VkIGJ5IHRocnUuXHJcbiAgICAgKiBAY2FsbGJhY2sgUmFuZ2V+dGhydUNhbGxiYWNrXHJcbiAgICAgKiBAcGFyYW0ge1JhbmdlfSByYW5nZSAtIFRoZSByYW5nZS5cclxuICAgICAqIEByZXR1cm5zIHsqfSBUaGUgdmFsdWUgdG8gcmV0dXJuIGZyb20gdGhydS5cclxuICAgICAqL1xyXG4gICAgLyoqXHJcbiAgICAgKiBJbnZva2UgYSBjYWxsYmFjayBvbiB0aGUgcmFuZ2UgYW5kIHJldHVybiB0aGUgdmFsdWUgcHJvdmlkZWQgYnkgdGhlIGNhbGxiYWNrLiBVc2VmdWwgZm9yIG1ldGhvZCBjaGFpbmluZy5cclxuICAgICAqIEBwYXJhbSB7UmFuZ2V+dGhydUNhbGxiYWNrfSBjYWxsYmFjayAtIFRoZSBjYWxsYmFjayBmdW5jdGlvbi5cclxuICAgICAqIEByZXR1cm5zIHsqfSBUaGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBjYWxsYmFjay5cclxuICAgICAqL1xyXG4gICAgdGhydShjYWxsYmFjaykge1xyXG4gICAgICAgIHJldHVybiBjYWxsYmFjayh0aGlzKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldCB0aGUgdmFsdWVzIG9mIGVhY2ggY2VsbCBpbiB0aGUgcmFuZ2UgYXMgYSAyRCBhcnJheS5cclxuICAgICAqIEByZXR1cm5zIHtBcnJheS48QXJyYXkuPCo+Pn0gVGhlIHZhbHVlcy5cclxuICAgICAqLy8qKlxyXG4gICAgICogU2V0IHRoZSB2YWx1ZXMgaW4gZWFjaCBjZWxsIHRvIHRoZSByZXN1bHQgb2YgYSBmdW5jdGlvbiBjYWxsZWQgZm9yIGVhY2guXHJcbiAgICAgKiBAcGFyYW0ge1Jhbmdlfm1hcENhbGxiYWNrfSBjYWxsYmFjayAtIFRoZSBjYWxsYmFjayB0byBwcm92aWRlIHZhbHVlIGZvciB0aGUgY2VsbC5cclxuICAgICAqIEByZXR1cm5zIHtSYW5nZX0gVGhlIHJhbmdlLlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXRzIHRoZSB2YWx1ZSBpbiBlYWNoIGNlbGwgdG8gdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWUgaW4gdGhlIGdpdmVuIDJEIGFycmF5IG9mIHZhbHVlcy5cclxuICAgICAqIEBwYXJhbSB7QXJyYXkuPEFycmF5LjwqPj59IHZhbHVlcyAtIFRoZSB2YWx1ZXMgdG8gc2V0LlxyXG4gICAgICogQHJldHVybnMge1JhbmdlfSBUaGUgcmFuZ2UuXHJcbiAgICAgKi8vKipcclxuICAgICAqIFNldCB0aGUgdmFsdWUgb2YgYWxsIGNlbGxzIGluIHRoZSByYW5nZSB0byBhIHNpbmdsZSB2YWx1ZS5cclxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gc2V0LlxyXG4gICAgICogQHJldHVybnMge1JhbmdlfSBUaGUgcmFuZ2UuXHJcbiAgICAgKi9cclxuICAgIHZhbHVlKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQXJnSGFuZGxlcihcIlJhbmdlLnZhbHVlXCIpXHJcbiAgICAgICAgICAgIC5jYXNlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIC8vIEdldCB2YWx1ZXNcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm1hcChjZWxsID0+IGNlbGwudmFsdWUoKSk7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKCdmdW5jdGlvbicsIGNhbGxiYWNrID0+IHtcclxuICAgICAgICAgICAgICAgIC8vIFNldCBhIHZhbHVlIGZvciB0aGUgY2VsbHMgdG8gdGhlIHJlc3VsdCBvZiBhIGZ1bmN0aW9uXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JFYWNoKChjZWxsLCByaSwgY2kpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBjZWxsLnZhbHVlKGNhbGxiYWNrKGNlbGwsIHJpLCBjaSwgdGhpcykpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKCdhcnJheScsIHZhbHVlcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBTZXQgdmFsdWUgZm9yIHRoZSBjZWxscyB1c2luZyBhbiBhcnJheSBvZiBtYXRjaGluZyBkaW1lbnNpb25cclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZvckVhY2goKGNlbGwsIHJpLCBjaSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZXNbcmldICYmIHZhbHVlc1tyaV1bY2ldICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2VsbC52YWx1ZSh2YWx1ZXNbcmldW2NpXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKCcqJywgdmFsdWUgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gU2V0IHRoZSB2YWx1ZSBmb3IgYWxsIGNlbGxzIHRvIGEgc2luZ2xlIHZhbHVlXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JFYWNoKGNlbGwgPT4gY2VsbC52YWx1ZSh2YWx1ZSkpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuaGFuZGxlKGFyZ3VtZW50cyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBwYXJlbnQgd29ya2Jvb2suXHJcbiAgICAgKiBAcmV0dXJucyB7V29ya2Jvb2t9IFRoZSBwYXJlbnQgd29ya2Jvb2suXHJcbiAgICAgKi9cclxuICAgIHdvcmtib29rKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNoZWV0KCkud29ya2Jvb2soKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpbmQgdGhlIGV4dGVudCBvZiB0aGUgcmFuZ2UuXHJcbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgX2ZpbmRSYW5nZUV4dGVudCgpIHtcclxuICAgICAgICB0aGlzLl9taW5Sb3dOdW1iZXIgPSBNYXRoLm1pbih0aGlzLl9zdGFydENlbGwucm93TnVtYmVyKCksIHRoaXMuX2VuZENlbGwucm93TnVtYmVyKCkpO1xyXG4gICAgICAgIHRoaXMuX21heFJvd051bWJlciA9IE1hdGgubWF4KHRoaXMuX3N0YXJ0Q2VsbC5yb3dOdW1iZXIoKSwgdGhpcy5fZW5kQ2VsbC5yb3dOdW1iZXIoKSk7XHJcbiAgICAgICAgdGhpcy5fbWluQ29sdW1uTnVtYmVyID0gTWF0aC5taW4odGhpcy5fc3RhcnRDZWxsLmNvbHVtbk51bWJlcigpLCB0aGlzLl9lbmRDZWxsLmNvbHVtbk51bWJlcigpKTtcclxuICAgICAgICB0aGlzLl9tYXhDb2x1bW5OdW1iZXIgPSBNYXRoLm1heCh0aGlzLl9zdGFydENlbGwuY29sdW1uTnVtYmVyKCksIHRoaXMuX2VuZENlbGwuY29sdW1uTnVtYmVyKCkpO1xyXG4gICAgICAgIHRoaXMuX251bVJvd3MgPSB0aGlzLl9tYXhSb3dOdW1iZXIgLSB0aGlzLl9taW5Sb3dOdW1iZXIgKyAxO1xyXG4gICAgICAgIHRoaXMuX251bUNvbHVtbnMgPSB0aGlzLl9tYXhDb2x1bW5OdW1iZXIgLSB0aGlzLl9taW5Db2x1bW5OdW1iZXIgKyAxO1xyXG4gICAgfVxyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IFJhbmdlO1xyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxuXHJcbmNvbnN0IF8gPSByZXF1aXJlKFwibG9kYXNoXCIpO1xyXG5cclxuY29uc3QgUkVMQVRJT05TSElQX1NDSEVNQV9QUkVGSVggPSBcImh0dHA6Ly9zY2hlbWFzLm9wZW54bWxmb3JtYXRzLm9yZy9vZmZpY2VEb2N1bWVudC8yMDA2L3JlbGF0aW9uc2hpcHMvXCI7XHJcblxyXG4vKipcclxuICogQSByZWxhdGlvbnNoaXAgY29sbGVjdGlvbi5cclxuICogQGlnbm9yZVxyXG4gKi9cclxuY2xhc3MgUmVsYXRpb25zaGlwcyB7XHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgX1JlbGF0aW9uc2hpcHMuXHJcbiAgICAgKiBAcGFyYW0ge3t9fSBub2RlIC0gVGhlIG5vZGUuXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKG5vZGUpIHtcclxuICAgICAgICB0aGlzLl9pbml0KG5vZGUpO1xyXG4gICAgICAgIHRoaXMuX2dldFN0YXJ0aW5nSWQoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFkZCBhIG5ldyByZWxhdGlvbnNoaXAuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSAtIFRoZSB0eXBlIG9mIHJlbGF0aW9uc2hpcC5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0YXJnZXQgLSBUaGUgdGFyZ2V0IG9mIHRoZSByZWxhdGlvbnNoaXAuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3RhcmdldE1vZGVdIC0gVGhlIHRhcmdldCBtb2RlIG9mIHRoZSByZWxhdGlvbnNoaXAuXHJcbiAgICAgKiBAcmV0dXJucyB7e319IFRoZSBuZXcgcmVsYXRpb25zaGlwLlxyXG4gICAgICovXHJcbiAgICBhZGQodHlwZSwgdGFyZ2V0LCB0YXJnZXRNb2RlKSB7XHJcbiAgICAgICAgY29uc3Qgbm9kZSA9IHtcclxuICAgICAgICAgICAgbmFtZTogXCJSZWxhdGlvbnNoaXBcIixcclxuICAgICAgICAgICAgYXR0cmlidXRlczoge1xyXG4gICAgICAgICAgICAgICAgSWQ6IGBySWQke3RoaXMuX25leHRJZCsrfWAsXHJcbiAgICAgICAgICAgICAgICBUeXBlOiBgJHtSRUxBVElPTlNISVBfU0NIRU1BX1BSRUZJWH0ke3R5cGV9YCxcclxuICAgICAgICAgICAgICAgIFRhcmdldDogdGFyZ2V0XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBpZiAodGFyZ2V0TW9kZSkge1xyXG4gICAgICAgICAgICBub2RlLmF0dHJpYnV0ZXMuVGFyZ2V0TW9kZSA9IHRhcmdldE1vZGU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl9ub2RlLmNoaWxkcmVuLnB1c2gobm9kZSk7XHJcbiAgICAgICAgcmV0dXJuIG5vZGU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaW5kIGEgcmVsYXRpb25zaGlwIGJ5IElELlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGlkIC0gVGhlIHJlbGF0aW9uc2hpcCBJRC5cclxuICAgICAqIEByZXR1cm5zIHt7fXx1bmRlZmluZWR9IFRoZSBtYXRjaGluZyByZWxhdGlvbnNoaXAgb3IgdW5kZWZpbmVkIGlmIG5vdCBmb3VuZC5cclxuICAgICAqL1xyXG4gICAgZmluZEJ5SWQoaWQpIHtcclxuICAgICAgICByZXR1cm4gXy5maW5kKHRoaXMuX25vZGUuY2hpbGRyZW4sIG5vZGUgPT4gbm9kZS5hdHRyaWJ1dGVzLklkID09PSBpZCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaW5kIGEgcmVsYXRpb25zaGlwIGJ5IHR5cGUuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSAtIFRoZSB0eXBlIHRvIHNlYXJjaCBmb3IuXHJcbiAgICAgKiBAcmV0dXJucyB7e318dW5kZWZpbmVkfSBUaGUgbWF0Y2hpbmcgcmVsYXRpb25zaGlwIG9yIHVuZGVmaW5lZCBpZiBub3QgZm91bmQuXHJcbiAgICAgKi9cclxuICAgIGZpbmRCeVR5cGUodHlwZSkge1xyXG4gICAgICAgIHJldHVybiBfLmZpbmQodGhpcy5fbm9kZS5jaGlsZHJlbiwgbm9kZSA9PiBub2RlLmF0dHJpYnV0ZXMuVHlwZSA9PT0gYCR7UkVMQVRJT05TSElQX1NDSEVNQV9QUkVGSVh9JHt0eXBlfWApO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydCB0aGUgY29sbGVjdGlvbiB0byBhbiBYTUwgb2JqZWN0LlxyXG4gICAgICogQHJldHVybnMge3t9fHVuZGVmaW5lZH0gVGhlIFhNTCBvciB1bmRlZmluZWQgaWYgZW1wdHkuXHJcbiAgICAgKi9cclxuICAgIHRvWG1sKCkge1xyXG4gICAgICAgIGlmICghdGhpcy5fbm9kZS5jaGlsZHJlbi5sZW5ndGgpIHJldHVybjtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbm9kZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldCB0aGUgc3RhcnRpbmcgcmVsYXRpb25zaGlwIElEIHRvIHVzZSBmb3IgbmV3IHJlbGF0aW9uc2hpcHMuXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICAgICAqL1xyXG4gICAgX2dldFN0YXJ0aW5nSWQoKSB7XHJcbiAgICAgICAgdGhpcy5fbmV4dElkID0gMTtcclxuICAgICAgICB0aGlzLl9ub2RlLmNoaWxkcmVuLmZvckVhY2gobm9kZSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGlkID0gcGFyc2VJbnQobm9kZS5hdHRyaWJ1dGVzLklkLnN1YnN0cigzKSk7XHJcbiAgICAgICAgICAgIGlmIChpZCA+PSB0aGlzLl9uZXh0SWQpIHRoaXMuX25leHRJZCA9IGlkICsgMTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEluaXRpYWxpemUgdGhlIG5vZGUuXHJcbiAgICAgKiBAcGFyYW0ge3t9fSBbbm9kZV0gLSBUaGUgcmVsYXRpb25zaGlwcyBub2RlLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEByZXR1cm5zIHt1bmRlZmluZWR9XHJcbiAgICAgKi9cclxuICAgIF9pbml0KG5vZGUpIHtcclxuICAgICAgICBpZiAoIW5vZGUpIG5vZGUgPSB7XHJcbiAgICAgICAgICAgIG5hbWU6IFwiUmVsYXRpb25zaGlwc1wiLFxyXG4gICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XHJcbiAgICAgICAgICAgICAgICB4bWxuczogXCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvcGFja2FnZS8yMDA2L3JlbGF0aW9uc2hpcHNcIlxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBjaGlsZHJlbjogW11cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICB0aGlzLl9ub2RlID0gbm9kZTtcclxuICAgIH1cclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBSZWxhdGlvbnNoaXBzO1xyXG5cclxuLypcclxueGwvX3JlbHMvd29ya2Jvb2sueG1sLnJlbHNcclxuXHJcbjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIlVURi04XCIgc3RhbmRhbG9uZT1cInllc1wiPz5cclxuPFJlbGF0aW9uc2hpcHMgeG1sbnM9XCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvcGFja2FnZS8yMDA2L3JlbGF0aW9uc2hpcHNcIj5cclxuICAgIDxSZWxhdGlvbnNoaXAgSWQ9XCJySWQzXCIgVHlwZT1cImh0dHA6Ly9zY2hlbWFzLm9wZW54bWxmb3JtYXRzLm9yZy9vZmZpY2VEb2N1bWVudC8yMDA2L3JlbGF0aW9uc2hpcHMvc3R5bGVzXCIgVGFyZ2V0PVwic3R5bGVzLnhtbFwiLz5cclxuICAgIDxSZWxhdGlvbnNoaXAgSWQ9XCJySWQyXCIgVHlwZT1cImh0dHA6Ly9zY2hlbWFzLm9wZW54bWxmb3JtYXRzLm9yZy9vZmZpY2VEb2N1bWVudC8yMDA2L3JlbGF0aW9uc2hpcHMvdGhlbWVcIiBUYXJnZXQ9XCJ0aGVtZS90aGVtZTEueG1sXCIvPlxyXG4gICAgPFJlbGF0aW9uc2hpcCBJZD1cInJJZDFcIiBUeXBlPVwiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL29mZmljZURvY3VtZW50LzIwMDYvcmVsYXRpb25zaGlwcy93b3Jrc2hlZXRcIiBUYXJnZXQ9XCJ3b3Jrc2hlZXRzL3NoZWV0MS54bWxcIi8+XHJcbiAgICA8UmVsYXRpb25zaGlwIElkPVwicklkNVwiIFR5cGU9XCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvb2ZmaWNlRG9jdW1lbnQvMjAwNi9yZWxhdGlvbnNoaXBzL2NhbGNDaGFpblwiIFRhcmdldD1cImNhbGNDaGFpbi54bWxcIi8+XHJcbiAgICA8UmVsYXRpb25zaGlwIElkPVwicklkNFwiIFR5cGU9XCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvb2ZmaWNlRG9jdW1lbnQvMjAwNi9yZWxhdGlvbnNoaXBzL3NoYXJlZFN0cmluZ3NcIiBUYXJnZXQ9XCJzaGFyZWRTdHJpbmdzLnhtbFwiLz5cclxuPC9SZWxhdGlvbnNoaXBzPlxyXG4qL1xyXG5cclxuIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG5jb25zdCBfID0gcmVxdWlyZShcImxvZGFzaFwiKTtcclxuY29uc3QgUmljaFRleHRGcmFnbWVudCA9IHJlcXVpcmUoXCIuL1JpY2hUZXh0RnJhZ21lbnRcIik7XHJcblxyXG4vKipcclxuICogQSBSaWNoVGV4dCBjbGFzcyB0aGF0IGNvbnRhaW5zIG1hbnkge0BsaW5rIFJpY2hUZXh0RnJhZ21lbnR9LlxyXG4gKi9cclxuY2xhc3MgUmljaFRleHQge1xyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIFJpY2hUZXh0LiBJZiB5b3UgZ2V0IHRoZSBpbnN0YW5jZSBieSBjYWxsaW5nIGBDZWxsLnZhbHVlKClgLFxyXG4gICAgICogYWRkaW5nIGEgdGV4dCBjb250YWlucyBsaW5lIHNlcGFyYXRvciB3aWxsIHRyaWdnZXIge0BsaW5rIENlbGwuc3R5bGV9KCd3cmFwVGV4dCcsIHRydWUpLCB3aGljaFxyXG4gICAgICogd2lsbCBtYWtlIE1TIEV4Y2VsIHNob3cgdGhlIG5ldyBsaW5lLiBpLmUuIEluIE1TIEV4Y2VsLCBUYXAgXCJhbHQrRW50ZXJcIiBpbiBhIGNlbGwsIHRoZSBjZWxsXHJcbiAgICAgKiB3aWxsIHNldCB3cmFwIHRleHQgdG8gdHJ1ZSBhdXRvbWF0aWNhbGx5LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7dW5kZWZpbmVkfG51bGx8T2JqZWN0fSBbbm9kZV0gLSBUaGUgbm9kZSBzdG9yZWQgaW4gdGhlIHNoYXJlZCBzdHJpbmdcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3Iobm9kZSkge1xyXG4gICAgICAgIHRoaXMuX25vZGUgPSBbXTtcclxuICAgICAgICB0aGlzLl9jZWxsID0gbnVsbDtcclxuICAgICAgICB0aGlzLl9yZW1haW5pbmdOb2RlcyA9IFtdO1xyXG4gICAgICAgIGlmIChub2RlKSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZnJhZ21lbnQgPSBub2RlW2ldO1xyXG4gICAgICAgICAgICAgICAgaWYgKGZyYWdtZW50Lm5hbWUgPT09ICdyJykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25vZGUucHVzaChuZXcgUmljaFRleHRGcmFnbWVudChmcmFnbWVudCwgbnVsbCwgdGhpcykpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBzcGVjaWFsIG5vZGUsIGUuZy4gclBoLCBwaG9uZXRpY1ByIGluIEphcGFuZXNlIGxhbmd1YWdlLlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3JlbWFpbmluZ05vZGVzLnB1c2goZnJhZ21lbnQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB3aGljaCBjZWxsIHRoaXMge0BsaW5rIFJpY2hUZXh0fSBpbnN0YW5jZSBiZWxvbmdzIHRvLlxyXG4gICAgICogQHJldHVybiB7Q2VsbHx1bmRlZmluZWR9IFRoZSBjZWxsIHRoaXMgaW5zdGFuY2UgYmVsb25ncyB0by5cclxuICAgICAqL1xyXG4gICAgZ2V0IGNlbGwoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NlbGw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBob3cgbWFueSByaWNoIHRleHQgZnJhZ21lbnQgdGhpcyB7QGxpbmsgUmljaFRleHR9IGluc3RhbmNlIGNvbnRhaW5zXHJcbiAgICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBudW1iZXIgb2YgZnJhZ21lbnRzIHRoaXMge0BsaW5rIFJpY2hUZXh0fSBpbnN0YW5jZSBoYXMuXHJcbiAgICAgKi9cclxuICAgIGdldCBsZW5ndGgoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX25vZGUubGVuZ3RoO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBjb25jYXRlbmF0ZWQgdGV4dCB3aXRob3V0IHN0eWxlcy5cclxuICAgICAqIEByZXR1cm4ge3N0cmluZ30gY29uY2F0ZW5hdGVkIHRleHRcclxuICAgICAqL1xyXG4gICAgdGV4dCgpIHtcclxuICAgICAgICBsZXQgdGV4dCA9ICcnO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbm9kZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB0ZXh0ICs9IHRoaXMuZ2V0KGkpLnZhbHVlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0ZXh0O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgaW5zdGFuY2Ugd2l0aCBjZWxsIHJlZmVyZW5jZSBkZWZpbmVkLlxyXG4gICAgICogQHBhcmFtIHtDZWxsfSBjZWxsIC0gQ2VsbCByZWZlcmVuY2UuXHJcbiAgICAgKiBAcmV0dXJuIHtSaWNoVGV4dH0gVGhlIGluc3RhbmNlIHdpdGggY2VsbCByZWZlcmVuY2UgZGVmaW5lZC5cclxuICAgICAqL1xyXG4gICAgZ2V0SW5zdGFuY2VXaXRoQ2VsbFJlZihjZWxsKSB7XHJcbiAgICAgICAgdGhpcy5fY2VsbCA9IGNlbGw7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIGEgZGVlcCBjb3B5IG9mIHRoaXMgaW5zdGFuY2UuXHJcbiAgICAgKiBJZiBjZWxsIHJlZmVyZW5jZSBpcyBwcm92aWRlZCwgaXQgY2hlY2tzIGxpbmUgc2VwYXJhdG9ycyBhbmQgY2FsbHNcclxuICAgICAqIGBjZWxsLnN0eWxlKCd3cmFwVGV4dCcsIHRydWUpYCB3aGVuIG5lZWRlZC5cclxuICAgICAqIEBwYXJhbSB7Q2VsbHx1bmRlZmluZWR9IFtjZWxsXSAtIFRoZSBjZWxsIHJlZmVyZW5jZS5cclxuICAgICAqIEByZXR1cm4ge1JpY2hUZXh0fSBBIGRlZXAgY29waWVkIGluc3RhbmNlXHJcbiAgICAgKi9cclxuICAgIGNvcHkoY2VsbCkge1xyXG4gICAgICAgIGNvbnN0IG5ld1JpY2hUZXh0ID0gbmV3IFJpY2hUZXh0KF8uY2xvbmVEZWVwKHRoaXMudG9YbWwoKSkpO1xyXG4gICAgICAgIGlmIChjZWxsICYmIF8uaW5jbHVkZXModGhpcy50ZXh0KCksICdcXG4nKSkge1xyXG4gICAgICAgICAgICBjZWxsLnN0eWxlKCd3cmFwVGV4dCcsIHRydWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbmV3UmljaFRleHQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBpdGggZnJhZ21lbnQgb2YgdGhpcyB7QGxpbmsgUmljaFRleHR9IGluc3RhbmNlLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IC0gVGhlIGluZGV4XHJcbiAgICAgKiBAcmV0dXJuIHtSaWNoVGV4dEZyYWdtZW50fSBBIHJpY2ggdGV4dCBmcmFnbWVudFxyXG4gICAgICovXHJcbiAgICBnZXQoaW5kZXgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbm9kZVtpbmRleF07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmVzIGEgcmljaCB0ZXh0IGZyYWdtZW50LiBUaGlzIGluc3RhbmNlIHdpbGwgYmUgbXV0YXRlZC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCAtIHRoZSBpbmRleCBvZiB0aGUgZnJhZ21lbnQgdG8gcmVtb3ZlXHJcbiAgICAgKiBAcmV0dXJuIHtSaWNoVGV4dH0gdGhlIHJpY2ggdGV4dCBpbnN0YW5jZVxyXG4gICAgICovXHJcbiAgICByZW1vdmUoaW5kZXgpIHtcclxuICAgICAgICB0aGlzLl9ub2RlLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgdGhpcy5yZW1vdmVVbnN1cHBvcnRlZE5vZGVzKCk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBZGRzIGEgcmljaCB0ZXh0IGZyYWdtZW50IHRvIHRoZSBsYXN0IG9yIGFmdGVyIHRoZSBnaXZlbiBpbmRleC4gVGhpcyBpbnN0YW5jZSB3aWxsIGJlIG11dGF0ZWQuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIHRoZSB0ZXh0XHJcbiAgICAgKiBAcGFyYW0ge3t9fSBbc3R5bGVzXSAtIHRoZSBzdHlsZXMganMgb2JqZWN0LCBpLmUuIHtmb250U2l6ZTogMTJ9XHJcbiAgICAgKiBAcGFyYW0ge251bWJlcnx1bmRlZmluZWR8bnVsbH0gW2luZGV4XSAtIHRoZSBpbmRleCBvZiB0aGUgZnJhZ21lbnQgdG8gYWRkXHJcbiAgICAgKiBAcmV0dXJuIHtSaWNoVGV4dH0gdGhlIHJpY2ggdGV4dCBpbnN0YW5jZVxyXG4gICAgICovXHJcbiAgICBhZGQodGV4dCwgc3R5bGVzLCBpbmRleCkge1xyXG4gICAgICAgIGlmIChpbmRleCA9PT0gdW5kZWZpbmVkIHx8IGluZGV4ID09PSBudWxsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX25vZGUucHVzaChuZXcgUmljaFRleHRGcmFnbWVudCh0ZXh0LCBzdHlsZXMsIHRoaXMpKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9ub2RlLnNwbGljZShpbmRleCwgMCwgbmV3IFJpY2hUZXh0RnJhZ21lbnQodGV4dCwgc3R5bGVzLCB0aGlzKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMucmVtb3ZlVW5zdXBwb3J0ZWROb2RlcygpO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2xlYXJzIHRoaXMgcmljaCB0ZXh0XHJcbiAgICAgKiBAcmV0dXJuIHtSaWNoVGV4dH0gdGhlIHJpY2ggdGV4dCBpbnN0YW5jZVxyXG4gICAgICovXHJcbiAgICBjbGVhcigpIHtcclxuICAgICAgICB0aGlzLl9ub2RlID0gW107XHJcbiAgICAgICAgdGhpcy5fcmVtYWluaW5nTm9kZXMgPSBbXTtcclxuICAgICAgICB0aGlzLl9jZWxsID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVtb3ZlIGFsbCB1bnN1cHBvcnRlZCBub2RlcyAocGhvbmV0aWNQciwgclBoIGZvciBKYXBhbmVzZSBsYW5ndWFnZSkuXHJcbiAgICAgKiBAcmV0dXJuIHt1bmRlZmluZWR9XHJcbiAgICAgKi9cclxuICAgIHJlbW92ZVVuc3VwcG9ydGVkTm9kZXMoKSB7XHJcbiAgICAgICAgdGhpcy5fcmVtYWluaW5nTm9kZXMgPSBbXTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnQgdGhlIHJpY2ggdGV4dCB0byBhbiBYTUwgb2JqZWN0LlxyXG4gICAgICogQHJldHVybnMge0FycmF5Ljx7fT59IFRoZSBYTUwgZm9ybS5cclxuICAgICAqIEBpZ25vcmVcclxuICAgICAqL1xyXG4gICAgdG9YbWwoKSB7XHJcbiAgICAgICAgY29uc3Qgbm9kZSA9IFtdO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbm9kZS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBub2RlLnB1c2godGhpcy5fbm9kZVtpXS50b1htbCgpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG5vZGUuY29uY2F0KHRoaXMuX3JlbWFpbmluZ05vZGVzKTtcclxuICAgIH1cclxufVxyXG5cclxuLy8gSUUgZG9lc24ndCBzdXBwb3J0IGZ1bmN0aW9uIG5hbWVzIHNvIGV4cGxpY2l0bHkgc2V0IGl0LlxyXG5pZiAoIVJpY2hUZXh0Lm5hbWUpIFJpY2hUZXh0Lm5hbWUgPSBcIlJpY2hUZXh0XCI7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IFJpY2hUZXh0O1xyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxuXHJcbi8qIGVzbGludCBjYW1lbGNhc2U6b2ZmICovXHJcblxyXG5jb25zdCBBcmdIYW5kbGVyID0gcmVxdWlyZShcIi4vQXJnSGFuZGxlclwiKTtcclxuY29uc3QgXyA9IHJlcXVpcmUoXCJsb2Rhc2hcIik7XHJcbmNvbnN0IHhtbHEgPSByZXF1aXJlKFwiLi94bWxxXCIpO1xyXG5jb25zdCBjb2xvckluZGV4ZXMgPSByZXF1aXJlKFwiLi9jb2xvckluZGV4ZXNcIik7XHJcblxyXG4vKipcclxuICogQSBSaWNoIHRleHQgZnJhZ21lbnQuXHJcbiAqL1xyXG5jbGFzcyBSaWNoVGV4dEZyYWdtZW50IHtcclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBSaWNoVGV4dEZyYWdtZW50LlxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xPYmplY3R9IHZhbHVlIC0gVGV4dCB2YWx1ZSBvciBYTUwgbm9kZVxyXG4gICAgICogQHBhcmFtIHtvYmplY3R8dW5kZWZpbmVkfG51bGx9IFtzdHlsZXNdIC0gTXVsdGlwbGUgc3R5bGVzLlxyXG4gICAgICogQHBhcmFtIHtSaWNoVGV4dH0gcmljaFRleHQgLSBUaGUgcmljaCB0ZXh0IGluc3RhbmNlIHdoZXJlIHRoaXMgZnJhZ21lbnQgYmVsb25ncyB0by5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IodmFsdWUsIHN0eWxlcywgcmljaFRleHQpIHtcclxuICAgICAgICB0aGlzLl9yaWNoVGV4dCA9IHJpY2hUZXh0O1xyXG4gICAgICAgIGlmICh2YWx1ZS5uYW1lID09PSAncicpIHtcclxuICAgICAgICAgICAgdGhpcy5fbm9kZSA9IHZhbHVlO1xyXG4gICAgICAgICAgICB0aGlzLl9mb250Tm9kZSA9IHhtbHEuZmluZENoaWxkKHRoaXMuX25vZGUsICdyUHInKTtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLl9mb250Tm9kZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZm9udE5vZGUgPSB7IG5hbWU6ICdyUHInLCBhdHRyaWJ1dGVzOiB7fSwgY2hpbGRyZW46IFtdIH07XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9ub2RlLmNoaWxkcmVuLnVuc2hpZnQodGhpcy5fZm9udE5vZGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuX3ZhbHVlTm9kZSA9IHhtbHEuZmluZENoaWxkKHRoaXMuX25vZGUsICd0Jyk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5fbm9kZSA9IHtcclxuICAgICAgICAgICAgICAgIG5hbWU6ICdyJyxcclxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHt9LFxyXG4gICAgICAgICAgICAgICAgY2hpbGRyZW46IFtcclxuICAgICAgICAgICAgICAgICAgICB7IG5hbWU6ICdyUHInLCBhdHRyaWJ1dGVzOiB7fSwgY2hpbGRyZW46IFtdIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgeyBuYW1lOiAndCcsIGF0dHJpYnV0ZXM6IHt9LCBjaGlsZHJlbjogW10gfVxyXG4gICAgICAgICAgICAgICAgXVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB0aGlzLl9mb250Tm9kZSA9IHhtbHEuZmluZENoaWxkKHRoaXMuX25vZGUsICdyUHInKTtcclxuICAgICAgICAgICAgdGhpcy5fdmFsdWVOb2RlID0geG1scS5maW5kQ2hpbGQodGhpcy5fbm9kZSwgJ3QnKTtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZSh2YWx1ZSk7XHJcbiAgICAgICAgICAgIGlmIChzdHlsZXMpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc3R5bGUoc3R5bGVzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIHZhbHVlIG9mIHRoaXMgcGFydCBvZiByaWNoIHRleHRcclxuICAgICAqIEByZXR1cm4ge3N0cmluZ30gdGV4dFxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXRzIHRoZSB2YWx1ZSBvZiB0aGlzIHBhcnQgb2YgcmljaCB0ZXh0XHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCAtIHRoZSB0ZXh0IHRvIHNldFxyXG4gICAgICogQHJldHVybiB7UmljaFRleHRGcmFnbWVudH0gLSBSaWNoVGV4dEZyYWdtZW50XHJcbiAgICAgKi9cclxuICAgIHZhbHVlKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQXJnSGFuZGxlcihcIl9SaWNoVGV4dC52YWx1ZVwiKVxyXG4gICAgICAgICAgICAuY2FzZSgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fdmFsdWVOb2RlLmNoaWxkcmVuWzBdO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnc3RyaW5nJywgdmFsdWUgPT4ge1xyXG4gICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC8oPzpcXHJcXG58XFxyfFxcbikvZywgJ1xcclxcbicpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaGFzTGluZVNlcGFyYXRvciA9IHZhbHVlLmluZGV4T2YoJ1xcclxcbicpICE9PSAtMTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3ZhbHVlTm9kZS5jaGlsZHJlblswXSA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlLmNoYXJBdCgwKSA9PT0gJyAnKSB4bWxxLnNldEF0dHJpYnV0ZXModGhpcy5fdmFsdWVOb2RlLCB7ICd4bWw6c3BhY2UnOiAncHJlc2VydmUnIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9yaWNoVGV4dCkgdGhpcy5fcmljaFRleHQucmVtb3ZlVW5zdXBwb3J0ZWROb2RlcygpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGhhc0xpbmVTZXBhcmF0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBzZXQgd3JhcFRleHQgPSB0cnVlIGlmIGl0IGNvbnRhaW5zIGxpbmUgc2VwYXJhdG9yLCBleGNlbCB3aWxsIG9ubHkgZGlzcGxheSBuZXcgbGluZXMgaWYgaXQgc2V0cy5cclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fcmljaFRleHQuY2VsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9yaWNoVGV4dC5jZWxsLnN0eWxlKCd3cmFwVGV4dCcsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB4bWxxLnNldEF0dHJpYnV0ZXModGhpcy5fdmFsdWVOb2RlLCB7ICd4bWw6c3BhY2UnOiAncHJlc2VydmUnIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5oYW5kbGUoYXJndW1lbnRzKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnQgdGhlIHJpY2ggdGV4dCB0byBhbiBYTUwgb2JqZWN0LlxyXG4gICAgICogQHJldHVybnMge3t9fSBUaGUgWE1MIGZvcm0uXHJcbiAgICAgKiBAaWdub3JlXHJcbiAgICAgKi9cclxuICAgIHRvWG1sKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9ub2RlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBhbiBpbmRpdmlkdWFsIHN0eWxlLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgc3R5bGUuXHJcbiAgICAgKiBAcmV0dXJucyB7Kn0gVGhlIHN0eWxlLlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBHZXRzIG11bHRpcGxlIHN0eWxlcy5cclxuICAgICAqIEBwYXJhbSB7QXJyYXkuPHN0cmluZz59IG5hbWVzIC0gVGhlIG5hbWVzIG9mIHRoZSBzdHlsZS5cclxuICAgICAqIEByZXR1cm5zIHtvYmplY3QuPHN0cmluZywgKj59IE9iamVjdCB3aG9zZSBrZXlzIGFyZSB0aGUgc3R5bGUgbmFtZXMgYW5kIHZhbHVlcyBhcmUgdGhlIHN0eWxlcy5cclxuICAgICAqLy8qKlxyXG4gICAgICogU2V0cyBhbiBpbmRpdmlkdWFsIHN0eWxlLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgc3R5bGUuXHJcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIC0gVGhlIHZhbHVlIHRvIHNldC5cclxuICAgICAqIEByZXR1cm5zIHtSaWNoVGV4dEZyYWdtZW50fSBUaGlzIFJpY2hUZXh0RnJhZ21lbnQuXHJcbiAgICAgKi8vKipcclxuICAgICAqIFNldHMgbXVsdGlwbGUgc3R5bGVzLlxyXG4gICAgICogQHBhcmFtIHtvYmplY3QuPHN0cmluZywgKj59IHN0eWxlcyAtIE9iamVjdCB3aG9zZSBrZXlzIGFyZSB0aGUgc3R5bGUgbmFtZXMgYW5kIHZhbHVlcyBhcmUgdGhlIHN0eWxlcyB0byBzZXQuXHJcbiAgICAgKiBAcmV0dXJucyB7UmljaFRleHRGcmFnbWVudH0gVGhpcyBSaWNoVGV4dEZyYWdtZW50LlxyXG4gICAgICovXHJcbiAgICBzdHlsZSgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEFyZ0hhbmRsZXIoXCJfUmljaFRleHQuc3R5bGVcIilcclxuICAgICAgICAgICAgLmNhc2UoJ3N0cmluZycsIG5hbWUgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gR2V0IHNpbmdsZSB2YWx1ZVxyXG4gICAgICAgICAgICAgICAgY29uc3QgZ2V0dGVyTmFtZSA9IGBfZ2V0XyR7bmFtZX1gO1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzW2dldHRlck5hbWVdKSB0aHJvdyBuZXcgRXJyb3IoYF9SaWNoVGV4dC5zdHlsZTogJyR7bmFtZX0nIGlzIG5vdCBhIHZhbGlkIHN0eWxlYCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpc1tnZXR0ZXJOYW1lXSgpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnYXJyYXknLCBuYW1lcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBHZXQgbGlzdCBvZiB2YWx1ZXNcclxuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlcyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgbmFtZXMuZm9yRWFjaChuYW1lID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXNbbmFtZV0gPSB0aGlzLnN0eWxlKG5hbWUpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZShbJ3N0cmluZycsICcqJ10sIChuYW1lLCB2YWx1ZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gU2V0IGEgc2luZ2xlIHZhbHVlXHJcbiAgICAgICAgICAgICAgICBjb25zdCBzZXR0ZXJOYW1lID0gYF9zZXRfJHtuYW1lfWA7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXNbc2V0dGVyTmFtZV0pIHRocm93IG5ldyBFcnJvcihgX1JpY2hUZXh0LnN0eWxlOiAnJHtuYW1lfScgaXMgbm90IGEgdmFsaWQgc3R5bGVgKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzW3NldHRlck5hbWVdKHZhbHVlKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoJ29iamVjdCcsIG5hbWVWYWx1ZXMgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gT2JqZWN0IG9mIGtleSB2YWx1ZSBwYWlycyB0byBzZXRcclxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgbmFtZSBpbiBuYW1lVmFsdWVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFuYW1lVmFsdWVzLmhhc093blByb3BlcnR5KG5hbWUpKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IG5hbWVWYWx1ZXNbbmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHlsZShuYW1lLCB2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmhhbmRsZShhcmd1bWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRDb2xvcihub2RlLCBuYW1lKSB7XHJcbiAgICAgICAgY29uc3QgY2hpbGQgPSB4bWxxLmZpbmRDaGlsZChub2RlLCBuYW1lKTtcclxuICAgICAgICBpZiAoIWNoaWxkIHx8ICFjaGlsZC5hdHRyaWJ1dGVzKSByZXR1cm47XHJcblxyXG4gICAgICAgIGNvbnN0IGNvbG9yID0ge307XHJcbiAgICAgICAgaWYgKGNoaWxkLmF0dHJpYnV0ZXMuaGFzT3duUHJvcGVydHkoJ3JnYicpKSBjb2xvci5yZ2IgPSBjaGlsZC5hdHRyaWJ1dGVzLnJnYjtcclxuICAgICAgICBlbHNlIGlmIChjaGlsZC5hdHRyaWJ1dGVzLmhhc093blByb3BlcnR5KCd0aGVtZScpKSBjb2xvci50aGVtZSA9IGNoaWxkLmF0dHJpYnV0ZXMudGhlbWU7XHJcbiAgICAgICAgZWxzZSBpZiAoY2hpbGQuYXR0cmlidXRlcy5oYXNPd25Qcm9wZXJ0eSgnaW5kZXhlZCcpKSBjb2xvci5yZ2IgPSBjb2xvckluZGV4ZXNbY2hpbGQuYXR0cmlidXRlcy5pbmRleGVkXTtcclxuXHJcbiAgICAgICAgaWYgKGNoaWxkLmF0dHJpYnV0ZXMuaGFzT3duUHJvcGVydHkoJ3RpbnQnKSkgY29sb3IudGludCA9IGNoaWxkLmF0dHJpYnV0ZXMudGludDtcclxuXHJcbiAgICAgICAgaWYgKF8uaXNFbXB0eShjb2xvcikpIHJldHVybjtcclxuXHJcbiAgICAgICAgcmV0dXJuIGNvbG9yO1xyXG4gICAgfVxyXG5cclxuICAgIF9zZXRDb2xvcihub2RlLCBuYW1lLCBjb2xvcikge1xyXG4gICAgICAgIGlmICh0eXBlb2YgY29sb3IgPT09IFwic3RyaW5nXCIpIGNvbG9yID0geyByZ2I6IGNvbG9yIH07XHJcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIGNvbG9yID09PSBcIm51bWJlclwiKSBjb2xvciA9IHsgdGhlbWU6IGNvbG9yIH07XHJcblxyXG4gICAgICAgIHhtbHEuc2V0Q2hpbGRBdHRyaWJ1dGVzKG5vZGUsIG5hbWUsIHtcclxuICAgICAgICAgICAgcmdiOiBjb2xvciAmJiBjb2xvci5yZ2IgJiYgY29sb3IucmdiLnRvVXBwZXJDYXNlKCksXHJcbiAgICAgICAgICAgIGluZGV4ZWQ6IG51bGwsXHJcbiAgICAgICAgICAgIHRoZW1lOiBjb2xvciAmJiBjb2xvci50aGVtZSxcclxuICAgICAgICAgICAgdGludDogY29sb3IgJiYgY29sb3IudGludFxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB4bWxxLnJlbW92ZUNoaWxkSWZFbXB0eShub2RlLCAnY29sb3InKTtcclxuICAgIH1cclxuXHJcbiAgICBfZ2V0X2JvbGQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHhtbHEuaGFzQ2hpbGQodGhpcy5fZm9udE5vZGUsICdiJyk7XHJcbiAgICB9XHJcblxyXG4gICAgX3NldF9ib2xkKGJvbGQpIHtcclxuICAgICAgICBpZiAoYm9sZCkgeG1scS5hcHBlbmRDaGlsZElmTm90Rm91bmQodGhpcy5fZm9udE5vZGUsIFwiYlwiKTtcclxuICAgICAgICBlbHNlIHhtbHEucmVtb3ZlQ2hpbGQodGhpcy5fZm9udE5vZGUsICdiJyk7XHJcbiAgICB9XHJcblxyXG4gICAgX2dldF9pdGFsaWMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHhtbHEuaGFzQ2hpbGQodGhpcy5fZm9udE5vZGUsICdpJyk7XHJcbiAgICB9XHJcblxyXG4gICAgX3NldF9pdGFsaWMoaXRhbGljKSB7XHJcbiAgICAgICAgaWYgKGl0YWxpYykgeG1scS5hcHBlbmRDaGlsZElmTm90Rm91bmQodGhpcy5fZm9udE5vZGUsIFwiaVwiKTtcclxuICAgICAgICBlbHNlIHhtbHEucmVtb3ZlQ2hpbGQodGhpcy5fZm9udE5vZGUsICdpJyk7XHJcbiAgICB9XHJcblxyXG4gICAgX2dldF91bmRlcmxpbmUoKSB7XHJcbiAgICAgICAgY29uc3QgdU5vZGUgPSB4bWxxLmZpbmRDaGlsZCh0aGlzLl9mb250Tm9kZSwgJ3UnKTtcclxuICAgICAgICByZXR1cm4gdU5vZGUgPyB1Tm9kZS5hdHRyaWJ1dGVzLnZhbCB8fCB0cnVlIDogZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgX3NldF91bmRlcmxpbmUodW5kZXJsaW5lKSB7XHJcbiAgICAgICAgaWYgKHVuZGVybGluZSkge1xyXG4gICAgICAgICAgICBjb25zdCB1Tm9kZSA9IHhtbHEuYXBwZW5kQ2hpbGRJZk5vdEZvdW5kKHRoaXMuX2ZvbnROb2RlLCBcInVcIik7XHJcbiAgICAgICAgICAgIGNvbnN0IHZhbCA9IHR5cGVvZiB1bmRlcmxpbmUgPT09ICdzdHJpbmcnID8gdW5kZXJsaW5lIDogbnVsbDtcclxuICAgICAgICAgICAgeG1scS5zZXRBdHRyaWJ1dGVzKHVOb2RlLCB7IHZhbCB9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB4bWxxLnJlbW92ZUNoaWxkKHRoaXMuX2ZvbnROb2RlLCAndScpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfZ2V0X3N0cmlrZXRocm91Z2goKSB7XHJcbiAgICAgICAgcmV0dXJuIHhtbHEuaGFzQ2hpbGQodGhpcy5fZm9udE5vZGUsICdzdHJpa2UnKTtcclxuICAgIH1cclxuXHJcbiAgICBfc2V0X3N0cmlrZXRocm91Z2goc3RyaWtldGhyb3VnaCkge1xyXG4gICAgICAgIGlmIChzdHJpa2V0aHJvdWdoKSB4bWxxLmFwcGVuZENoaWxkSWZOb3RGb3VuZCh0aGlzLl9mb250Tm9kZSwgXCJzdHJpa2VcIik7XHJcbiAgICAgICAgZWxzZSB4bWxxLnJlbW92ZUNoaWxkKHRoaXMuX2ZvbnROb2RlLCAnc3RyaWtlJyk7XHJcbiAgICB9XHJcblxyXG4gICAgX2dldEZvbnRWZXJ0aWNhbEFsaWdubWVudCgpIHtcclxuICAgICAgICByZXR1cm4geG1scS5nZXRDaGlsZEF0dHJpYnV0ZSh0aGlzLl9mb250Tm9kZSwgJ3ZlcnRBbGlnbicsIFwidmFsXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIF9zZXRGb250VmVydGljYWxBbGlnbm1lbnQoYWxpZ25tZW50KSB7XHJcbiAgICAgICAgeG1scS5zZXRDaGlsZEF0dHJpYnV0ZXModGhpcy5fZm9udE5vZGUsICd2ZXJ0QWxpZ24nLCB7IHZhbDogYWxpZ25tZW50IH0pO1xyXG4gICAgICAgIHhtbHEucmVtb3ZlQ2hpbGRJZkVtcHR5KHRoaXMuX2ZvbnROb2RlLCAndmVydEFsaWduJyk7XHJcbiAgICB9XHJcblxyXG4gICAgX2dldF9zdWJzY3JpcHQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldEZvbnRWZXJ0aWNhbEFsaWdubWVudCgpID09PSBcInN1YnNjcmlwdFwiO1xyXG4gICAgfVxyXG5cclxuICAgIF9zZXRfc3Vic2NyaXB0KHN1YnNjcmlwdCkge1xyXG4gICAgICAgIHRoaXMuX3NldEZvbnRWZXJ0aWNhbEFsaWdubWVudChzdWJzY3JpcHQgPyBcInN1YnNjcmlwdFwiIDogbnVsbCk7XHJcbiAgICB9XHJcblxyXG4gICAgX2dldF9zdXBlcnNjcmlwdCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Rm9udFZlcnRpY2FsQWxpZ25tZW50KCkgPT09IFwic3VwZXJzY3JpcHRcIjtcclxuICAgIH1cclxuXHJcbiAgICBfc2V0X3N1cGVyc2NyaXB0KHN1cGVyc2NyaXB0KSB7XHJcbiAgICAgICAgdGhpcy5fc2V0Rm9udFZlcnRpY2FsQWxpZ25tZW50KHN1cGVyc2NyaXB0ID8gXCJzdXBlcnNjcmlwdFwiIDogbnVsbCk7XHJcbiAgICB9XHJcblxyXG4gICAgX2dldF9mb250U2l6ZSgpIHtcclxuICAgICAgICByZXR1cm4geG1scS5nZXRDaGlsZEF0dHJpYnV0ZSh0aGlzLl9mb250Tm9kZSwgJ3N6JywgXCJ2YWxcIik7XHJcbiAgICB9XHJcblxyXG4gICAgX3NldF9mb250U2l6ZShzaXplKSB7XHJcbiAgICAgICAgeG1scS5zZXRDaGlsZEF0dHJpYnV0ZXModGhpcy5fZm9udE5vZGUsICdzeicsIHsgdmFsOiBzaXplIH0pO1xyXG4gICAgICAgIHhtbHEucmVtb3ZlQ2hpbGRJZkVtcHR5KHRoaXMuX2ZvbnROb2RlLCAnc3onKTtcclxuICAgIH1cclxuXHJcbiAgICBfZ2V0X2ZvbnRGYW1pbHkoKSB7XHJcbiAgICAgICAgcmV0dXJuIHhtbHEuZ2V0Q2hpbGRBdHRyaWJ1dGUodGhpcy5fZm9udE5vZGUsICdyRm9udCcsIFwidmFsXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIF9zZXRfZm9udEZhbWlseShmYW1pbHkpIHtcclxuICAgICAgICB4bWxxLnNldENoaWxkQXR0cmlidXRlcyh0aGlzLl9mb250Tm9kZSwgJ3JGb250JywgeyB2YWw6IGZhbWlseSB9KTtcclxuICAgICAgICB4bWxxLnJlbW92ZUNoaWxkSWZFbXB0eSh0aGlzLl9mb250Tm9kZSwgJ3JGb250Jyk7XHJcbiAgICB9XHJcblxyXG4gICAgX2dldF9mb250R2VuZXJpY0ZhbWlseSgpIHtcclxuICAgICAgICByZXR1cm4geG1scS5nZXRDaGlsZEF0dHJpYnV0ZSh0aGlzLl9mb250Tm9kZSwgJ2ZhbWlseScsIFwidmFsXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGdlbmVyaWNGYW1pbHkgLSAxOiBTZXJpZiwgMjogU2FucyBTZXJpZiwgMzogTW9ub3NwYWNlLFxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEByZXR1cm4ge3VuZGVmaW5lZH1cclxuICAgICAqL1xyXG4gICAgX3NldF9mb250R2VuZXJpY0ZhbWlseShnZW5lcmljRmFtaWx5KSB7XHJcbiAgICAgICAgeG1scS5zZXRDaGlsZEF0dHJpYnV0ZXModGhpcy5fZm9udE5vZGUsICdmYW1pbHknLCB7IHZhbDogZ2VuZXJpY0ZhbWlseSB9KTtcclxuICAgICAgICB4bWxxLnJlbW92ZUNoaWxkSWZFbXB0eSh0aGlzLl9mb250Tm9kZSwgJ2ZhbWlseScpO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRfZm9udENvbG9yKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRDb2xvcih0aGlzLl9mb250Tm9kZSwgXCJjb2xvclwiKTtcclxuICAgIH1cclxuXHJcbiAgICBfc2V0X2ZvbnRDb2xvcihjb2xvcikge1xyXG4gICAgICAgIHRoaXMuX3NldENvbG9yKHRoaXMuX2ZvbnROb2RlLCBcImNvbG9yXCIsIGNvbG9yKTtcclxuICAgIH1cclxuXHJcbiAgICBfZ2V0X2ZvbnRTY2hlbWUoKSB7XHJcbiAgICAgICAgLy8gY2FuIGJlICdtaW5vcicsICdtYWpvcicsICdub25lJ1xyXG4gICAgICAgIHJldHVybiB4bWxxLmdldENoaWxkQXR0cmlidXRlKHRoaXMuX2ZvbnROb2RlLCAnc2NoZW1lJywgXCJ2YWxcIik7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc2NoZW1lIC0gJ21pbm9yJ3wnbWFqb3InfCdub25lJ1xyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEByZXR1cm4ge3VuZGVmaW5lZH1cclxuICAgICAqL1xyXG4gICAgX3NldF9mb250U2NoZW1lKHNjaGVtZSkge1xyXG4gICAgICAgIHhtbHEuc2V0Q2hpbGRBdHRyaWJ1dGVzKHRoaXMuX2ZvbnROb2RlLCAnc2NoZW1lJywgeyB2YWw6IHNjaGVtZSB9KTtcclxuICAgICAgICB4bWxxLnJlbW92ZUNoaWxkSWZFbXB0eSh0aGlzLl9mb250Tm9kZSwgJ3NjaGVtZScpO1xyXG4gICAgfVxyXG59XHJcblxyXG4vLyBJRSBkb2Vzbid0IHN1cHBvcnQgZnVuY3Rpb24gbmFtZXMgc28gZXhwbGljaXRseSBzZXQgaXQuXHJcbmlmICghUmljaFRleHRGcmFnbWVudC5uYW1lKSBSaWNoVGV4dEZyYWdtZW50Lm5hbWUgPSBcIlJpY2hUZXh0RnJhZ21lbnRcIjtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gUmljaFRleHRGcmFnbWVudDtcclxuIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG5jb25zdCBfID0gcmVxdWlyZShcImxvZGFzaFwiKTtcclxuY29uc3QgQ2VsbCA9IHJlcXVpcmUoXCIuL0NlbGxcIik7XHJcbmNvbnN0IHJlZ2V4aWZ5ID0gcmVxdWlyZShcIi4vcmVnZXhpZnlcIik7XHJcbmNvbnN0IEFyZ0hhbmRsZXIgPSByZXF1aXJlKFwiLi9BcmdIYW5kbGVyXCIpO1xyXG5jb25zdCBhZGRyZXNzQ29udmVydGVyID0gcmVxdWlyZSgnLi9hZGRyZXNzQ29udmVydGVyJyk7XHJcblxyXG4vKipcclxuICogQSByb3cuXHJcbiAqL1xyXG5jbGFzcyBSb3cge1xyXG4gICAgLy8gLyoqXHJcbiAgICAvLyAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIFJvdy5cclxuICAgIC8vICAqIEBwYXJhbSB7U2hlZXR9IHNoZWV0IC0gVGhlIHBhcmVudCBzaGVldC5cclxuICAgIC8vICAqIEBwYXJhbSB7e319IG5vZGUgLSBUaGUgcm93IG5vZGUuXHJcbiAgICAvLyAgKi9cclxuICAgIGNvbnN0cnVjdG9yKHNoZWV0LCBub2RlKSB7XHJcbiAgICAgICAgdGhpcy5fc2hlZXQgPSBzaGVldDtcclxuICAgICAgICB0aGlzLl9pbml0KG5vZGUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qIFBVQkxJQyAqL1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0IHRoZSBhZGRyZXNzIG9mIHRoZSByb3cuXHJcbiAgICAgKiBAcGFyYW0ge3t9fSBbb3B0c10gLSBPcHRpb25zXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLmluY2x1ZGVTaGVldE5hbWVdIC0gSW5jbHVkZSB0aGUgc2hlZXQgbmFtZSBpbiB0aGUgYWRkcmVzcy5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuYW5jaG9yZWRdIC0gQW5jaG9yIHRoZSBhZGRyZXNzLlxyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGFkZHJlc3NcclxuICAgICAqL1xyXG4gICAgYWRkcmVzcyhvcHRzKSB7XHJcbiAgICAgICAgcmV0dXJuIGFkZHJlc3NDb252ZXJ0ZXIudG9BZGRyZXNzKHtcclxuICAgICAgICAgICAgdHlwZTogJ3JvdycsXHJcbiAgICAgICAgICAgIHJvd051bWJlcjogdGhpcy5yb3dOdW1iZXIoKSxcclxuICAgICAgICAgICAgc2hlZXROYW1lOiBvcHRzICYmIG9wdHMuaW5jbHVkZVNoZWV0TmFtZSAmJiB0aGlzLnNoZWV0KCkubmFtZSgpLFxyXG4gICAgICAgICAgICByb3dBbmNob3JlZDogb3B0cyAmJiBvcHRzLmFuY2hvcmVkXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXQgYSBjZWxsIGluIHRoZSByb3cuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IGNvbHVtbk5hbWVPck51bWJlciAtIFRoZSBuYW1lIG9yIG51bWJlciBvZiB0aGUgY29sdW1uLlxyXG4gICAgICogQHJldHVybnMge0NlbGx9IFRoZSBjZWxsLlxyXG4gICAgICovXHJcbiAgICBjZWxsKGNvbHVtbk5hbWVPck51bWJlcikge1xyXG4gICAgICAgIGxldCBjb2x1bW5OdW1iZXIgPSBjb2x1bW5OYW1lT3JOdW1iZXI7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBjb2x1bW5OYW1lT3JOdW1iZXIgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIGNvbHVtbk51bWJlciA9IGFkZHJlc3NDb252ZXJ0ZXIuY29sdW1uTmFtZVRvTnVtYmVyKGNvbHVtbk5hbWVPck51bWJlcik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoY29sdW1uTnVtYmVyIDwgMSkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYEludmFsaWQgY29sdW1uIG51bWJlciAke2NvbHVtbk51bWJlcn0uIFJlbWVtYmVyIHRoYXQgc3ByZWFkc2hlZXRzIHVzZSAxLWJhc2VkIGluZGV4aW5nLmApO1xyXG5cclxuICAgICAgICAvLyBSZXR1cm4gYW4gZXhpc3RpbmcgY2VsbC5cclxuICAgICAgICBpZiAodGhpcy5fY2VsbHNbY29sdW1uTnVtYmVyXSkgcmV0dXJuIHRoaXMuX2NlbGxzW2NvbHVtbk51bWJlcl07XHJcblxyXG4gICAgICAgIC8vIE5vIGNlbGwgZXhpc3RzIGZvciB0aGlzLlxyXG4gICAgICAgIC8vIENoZWNrIGlmIHRoZXJlIGlzIGFuIGV4aXN0aW5nIHJvdy9jb2x1bW4gc3R5bGUgZm9yIHRoZSBuZXcgY2VsbC5cclxuICAgICAgICBsZXQgc3R5bGVJZDtcclxuICAgICAgICBjb25zdCByb3dTdHlsZUlkID0gdGhpcy5fbm9kZS5hdHRyaWJ1dGVzLnM7XHJcbiAgICAgICAgY29uc3QgY29sdW1uU3R5bGVJZCA9IHRoaXMuc2hlZXQoKS5leGlzdGluZ0NvbHVtblN0eWxlSWQoY29sdW1uTnVtYmVyKTtcclxuXHJcbiAgICAgICAgLy8gUm93IHN0eWxlIHRha2VzIHByaW9yaXR5LiBJZiBhIGNlbGwgaGFzIGJvdGggcm93IGFuZCBjb2x1bW4gc3R5bGVzIGl0IHNob3VsZCBoYXZlIGNyZWF0ZWQgYSBjZWxsIGVudHJ5IHdpdGggYSBjZWxsLXNwZWNpZmljIHN0eWxlLlxyXG4gICAgICAgIGlmICghXy5pc05pbChyb3dTdHlsZUlkKSkgc3R5bGVJZCA9IHJvd1N0eWxlSWQ7XHJcbiAgICAgICAgZWxzZSBpZiAoIV8uaXNOaWwoY29sdW1uU3R5bGVJZCkpIHN0eWxlSWQgPSBjb2x1bW5TdHlsZUlkO1xyXG5cclxuICAgICAgICAvLyBDcmVhdGUgdGhlIG5ldyBjZWxsLlxyXG4gICAgICAgIGNvbnN0IGNlbGwgPSBuZXcgQ2VsbCh0aGlzLCBjb2x1bW5OdW1iZXIsIHN0eWxlSWQpO1xyXG4gICAgICAgIHRoaXMuX2NlbGxzW2NvbHVtbk51bWJlcl0gPSBjZWxsO1xyXG4gICAgICAgIHJldHVybiBjZWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgcm93IGhlaWdodC5cclxuICAgICAqIEByZXR1cm5zIHt1bmRlZmluZWR8bnVtYmVyfSBUaGUgaGVpZ2h0IChvciB1bmRlZmluZWQpLlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXRzIHRoZSByb3cgaGVpZ2h0LlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodCAtIFRoZSBoZWlnaHQgb2YgdGhlIHJvdy5cclxuICAgICAqIEByZXR1cm5zIHtSb3d9IFRoZSByb3cuXHJcbiAgICAgKi9cclxuICAgIGhlaWdodCgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEFyZ0hhbmRsZXIoJ1Jvdy5oZWlnaHQnKVxyXG4gICAgICAgICAgICAuY2FzZSgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbm9kZS5hdHRyaWJ1dGVzLmN1c3RvbUhlaWdodCA/IHRoaXMuX25vZGUuYXR0cmlidXRlcy5odCA6IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoJ251bWJlcicsIGhlaWdodCA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9ub2RlLmF0dHJpYnV0ZXMuaHQgPSBoZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9ub2RlLmF0dHJpYnV0ZXMuY3VzdG9tSGVpZ2h0ID0gMTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnbmlsJywgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX25vZGUuYXR0cmlidXRlcy5odDtcclxuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9ub2RlLmF0dHJpYnV0ZXMuY3VzdG9tSGVpZ2h0O1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5oYW5kbGUoYXJndW1lbnRzKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgYSB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIHJvdyBpcyBoaWRkZW4uXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gQSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGUgcm93IGlzIGhpZGRlbi5cclxuICAgICAqLy8qKlxyXG4gICAgICogU2V0cyB3aGV0aGVyIHRoZSByb3cgaXMgaGlkZGVuLlxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBoaWRkZW4gLSBBIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRvIGhpZGUgdGhlIHJvdy5cclxuICAgICAqIEByZXR1cm5zIHtSb3d9IFRoZSByb3cuXHJcbiAgICAgKi9cclxuICAgIGhpZGRlbigpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEFyZ0hhbmRsZXIoXCJSb3cuaGlkZGVuXCIpXHJcbiAgICAgICAgICAgIC5jYXNlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9ub2RlLmF0dHJpYnV0ZXMuaGlkZGVuID09PSAxO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnYm9vbGVhbicsIGhpZGRlbiA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaGlkZGVuKSB0aGlzLl9ub2RlLmF0dHJpYnV0ZXMuaGlkZGVuID0gMTtcclxuICAgICAgICAgICAgICAgIGVsc2UgZGVsZXRlIHRoaXMuX25vZGUuYXR0cmlidXRlcy5oaWRkZW47XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmhhbmRsZShhcmd1bWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgcm93IG51bWJlci5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFRoZSByb3cgbnVtYmVyLlxyXG4gICAgICovXHJcbiAgICByb3dOdW1iZXIoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX25vZGUuYXR0cmlidXRlcy5yO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgcGFyZW50IHNoZWV0IG9mIHRoZSByb3cuXHJcbiAgICAgKiBAcmV0dXJucyB7U2hlZXR9IFRoZSBwYXJlbnQgc2hlZXQuXHJcbiAgICAgKi9cclxuICAgIHNoZWV0KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaGVldDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgYW4gaW5kaXZpZHVhbCBzdHlsZS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHN0eWxlLlxyXG4gICAgICogQHJldHVybnMgeyp9IFRoZSBzdHlsZS5cclxuICAgICAqLy8qKlxyXG4gICAgICogR2V0cyBtdWx0aXBsZSBzdHlsZXMuXHJcbiAgICAgKiBAcGFyYW0ge0FycmF5LjxzdHJpbmc+fSBuYW1lcyAtIFRoZSBuYW1lcyBvZiB0aGUgc3R5bGUuXHJcbiAgICAgKiBAcmV0dXJucyB7b2JqZWN0LjxzdHJpbmcsICo+fSBPYmplY3Qgd2hvc2Uga2V5cyBhcmUgdGhlIHN0eWxlIG5hbWVzIGFuZCB2YWx1ZXMgYXJlIHRoZSBzdHlsZXMuXHJcbiAgICAgKi8vKipcclxuICAgICAqIFNldHMgYW4gaW5kaXZpZHVhbCBzdHlsZS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHN0eWxlLlxyXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBzZXQuXHJcbiAgICAgKiBAcmV0dXJucyB7Q2VsbH0gVGhlIGNlbGwuXHJcbiAgICAgKi8vKipcclxuXHQgKiBTZXRzIG11bHRpcGxlIHN0eWxlcy5cclxuXHQgKiBAcGFyYW0ge29iamVjdC48c3RyaW5nLCAqPn0gc3R5bGVzIC0gT2JqZWN0IHdob3NlIGtleXMgYXJlIHRoZSBzdHlsZSBuYW1lcyBhbmQgdmFsdWVzIGFyZSB0aGUgc3R5bGVzIHRvIHNldC5cclxuXHQgKiBAcmV0dXJucyB7Q2VsbH0gVGhlIGNlbGwuXHJcbiAgICAgKi8vKipcclxuICAgICAqIFNldHMgdG8gYSBzcGVjaWZpYyBzdHlsZVxyXG4gICAgICogQHBhcmFtIHtTdHlsZX0gc3R5bGUgLSBTdHlsZSBvYmplY3QgZ2l2ZW4gZnJvbSBzdHlsZXNoZWV0LmNyZWF0ZVN0eWxlXHJcbiAgICAgKiBAcmV0dXJucyB7Q2VsbH0gVGhlIGNlbGwuXHJcbiAgICAgKi9cclxuICAgIHN0eWxlKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQXJnSGFuZGxlcihcIlJvdy5zdHlsZVwiKVxyXG4gICAgICAgICAgICAuY2FzZSgnc3RyaW5nJywgbmFtZSA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBHZXQgc2luZ2xlIHZhbHVlXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9jcmVhdGVTdHlsZUlmTmVlZGVkKCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fc3R5bGUuc3R5bGUobmFtZSk7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKCdhcnJheScsIG5hbWVzID0+IHtcclxuICAgICAgICAgICAgICAgIC8vIEdldCBsaXN0IG9mIHZhbHVlc1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWVzID0ge307XHJcbiAgICAgICAgICAgICAgICBuYW1lcy5mb3JFYWNoKG5hbWUgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlc1tuYW1lXSA9IHRoaXMuc3R5bGUobmFtZSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZShbJ3N0cmluZycsICcqJ10sIChuYW1lLCB2YWx1ZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fY3JlYXRlQ2VsbFN0eWxlc0lmTmVlZGVkKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gU3R5bGUgZWFjaCBleGlzdGluZyBjZWxsIHdpdGhpbiB0aGlzIHJvdy4gKENlbGxzIGRvbid0IGluaGVyaXQgb3cvY29sdW1uIHN0eWxlcy4pXHJcbiAgICAgICAgICAgICAgICBfLmZvckVhY2godGhpcy5fY2VsbHMsIGNlbGwgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjZWxsKSBjZWxsLnN0eWxlKG5hbWUsIHZhbHVlKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIFNldCB0aGUgc3R5bGUgb24gdGhlIHJvdy5cclxuICAgICAgICAgICAgICAgIHRoaXMuX2NyZWF0ZVN0eWxlSWZOZWVkZWQoKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3N0eWxlLnN0eWxlKG5hbWUsIHZhbHVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoJ29iamVjdCcsIG5hbWVWYWx1ZXMgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gT2JqZWN0IG9mIGtleSB2YWx1ZSBwYWlycyB0byBzZXRcclxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgbmFtZSBpbiBuYW1lVmFsdWVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFuYW1lVmFsdWVzLmhhc093blByb3BlcnR5KG5hbWUpKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IG5hbWVWYWx1ZXNbbmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHlsZShuYW1lLCB2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKCdTdHlsZScsIHN0eWxlID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2NyZWF0ZUNlbGxTdHlsZXNJZk5lZWRlZCgpO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIFN0eWxlIGVhY2ggZXhpc3RpbmcgY2VsbCB3aXRoaW4gdGhpcyByb3cuIChDZWxscyBkb24ndCBpbmhlcml0IG93L2NvbHVtbiBzdHlsZXMuKVxyXG4gICAgICAgICAgICAgICAgXy5mb3JFYWNoKHRoaXMuX2NlbGxzLCBjZWxsID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2VsbCkgY2VsbC5zdHlsZShzdHlsZSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zdHlsZSA9IHN0eWxlO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fbm9kZS5hdHRyaWJ1dGVzLnMgPSBzdHlsZS5pZCgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fbm9kZS5hdHRyaWJ1dGVzLmN1c3RvbUZvcm1hdCA9IDE7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5oYW5kbGUoYXJndW1lbnRzKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldCB0aGUgcGFyZW50IHdvcmtib29rLlxyXG4gICAgICogQHJldHVybnMge1dvcmtib29rfSBUaGUgcGFyZW50IHdvcmtib29rLlxyXG4gICAgICovXHJcbiAgICB3b3JrYm9vaygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zaGVldCgpLndvcmtib29rKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBcHBlbmQgaG9yaXpvbnRhbCBwYWdlIGJyZWFrIGFmdGVyIHRoZSByb3cuXHJcbiAgICAgKiBAcmV0dXJucyB7Um93fSB0aGUgcm93LlxyXG4gICAgICovXHJcbiAgICBhZGRQYWdlQnJlYWsoKSB7XHJcbiAgICAgICAgdGhpcy5zaGVldCgpLmhvcml6b250YWxQYWdlQnJlYWtzKCkuYWRkKHRoaXMucm93TnVtYmVyKCkpO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qIElOVEVSTkFMICovXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDbGVhciBjZWxscyB0aGF0IGFyZSB1c2luZyBhIGdpdmVuIHNoYXJlZCBmb3JtdWxhIElELlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHNoYXJlZEZvcm11bGFJZCAtIFRoZSBzaGFyZWQgZm9ybXVsYSBJRC5cclxuICAgICAqIEByZXR1cm5zIHt1bmRlZmluZWR9XHJcbiAgICAgKiBAaWdub3JlXHJcbiAgICAgKi9cclxuICAgIGNsZWFyQ2VsbHNVc2luZ1NoYXJlZEZvcm11bGEoc2hhcmVkRm9ybXVsYUlkKSB7XHJcbiAgICAgICAgdGhpcy5fY2VsbHMuZm9yRWFjaChjZWxsID0+IHtcclxuICAgICAgICAgICAgaWYgKCFjZWxsKSByZXR1cm47XHJcbiAgICAgICAgICAgIGlmIChjZWxsLnNoYXJlc0Zvcm11bGEoc2hhcmVkRm9ybXVsYUlkKSkgY2VsbC5jbGVhcigpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmluZCBhIHBhdHRlcm4gaW4gdGhlIHJvdyBhbmQgb3B0aW9uYWxseSByZXBsYWNlIGl0LlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd8UmVnRXhwfSBwYXR0ZXJuIC0gVGhlIHNlYXJjaCBwYXR0ZXJuLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtyZXBsYWNlbWVudF0gLSBUaGUgcmVwbGFjZW1lbnQgdGV4dC5cclxuICAgICAqIEByZXR1cm5zIHtBcnJheS48Q2VsbD59IFRoZSBtYXRjaGVkIGNlbGxzLlxyXG4gICAgICogQGlnbm9yZVxyXG4gICAgICovXHJcbiAgICBmaW5kKHBhdHRlcm4sIHJlcGxhY2VtZW50KSB7XHJcbiAgICAgICAgcGF0dGVybiA9IHJlZ2V4aWZ5KHBhdHRlcm4pO1xyXG5cclxuICAgICAgICBjb25zdCBtYXRjaGVzID0gW107XHJcbiAgICAgICAgdGhpcy5fY2VsbHMuZm9yRWFjaChjZWxsID0+IHtcclxuICAgICAgICAgICAgaWYgKCFjZWxsKSByZXR1cm47XHJcbiAgICAgICAgICAgIGlmIChjZWxsLmZpbmQocGF0dGVybiwgcmVwbGFjZW1lbnQpKSBtYXRjaGVzLnB1c2goY2VsbCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBtYXRjaGVzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2hlY2sgaWYgdGhlIHJvdyBoYXMgYSBjZWxsIGF0IHRoZSBnaXZlbiBjb2x1bW4gbnVtYmVyLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGNvbHVtbk51bWJlciAtIFRoZSBjb2x1bW4gbnVtYmVyLlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgYSBjZWxsIGV4aXN0cywgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICogQGlnbm9yZVxyXG4gICAgICovXHJcbiAgICBoYXNDZWxsKGNvbHVtbk51bWJlcikge1xyXG4gICAgICAgIGlmIChjb2x1bW5OdW1iZXIgPCAxKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgSW52YWxpZCBjb2x1bW4gbnVtYmVyICR7Y29sdW1uTnVtYmVyfS4gUmVtZW1iZXIgdGhhdCBzcHJlYWRzaGVldHMgdXNlIDEtYmFzZWQgaW5kZXhpbmcuYCk7XHJcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fY2VsbHNbY29sdW1uTnVtYmVyXTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENoZWNrIGlmIHRoZSBjb2x1bW4gaGFzIGEgc3R5bGUgZGVmaW5lZC5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIGEgc3R5bGUgZXhpc3RzLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAgICAgKiBAaWdub3JlXHJcbiAgICAgKi9cclxuICAgIGhhc1N0eWxlKCkge1xyXG4gICAgICAgIHJldHVybiAhXy5pc05pbCh0aGlzLl9ub2RlLmF0dHJpYnV0ZXMucyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBuYXggdXNlZCBjb2x1bW4gbnVtYmVyLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVGhlIG1heCB1c2VkIGNvbHVtbiBudW1iZXIuXHJcbiAgICAgKiBAaWdub3JlXHJcbiAgICAgKi9cclxuICAgIG1pblVzZWRDb2x1bW5OdW1iZXIoKSB7XHJcbiAgICAgICAgcmV0dXJuIF8uZmluZEluZGV4KHRoaXMuX2NlbGxzKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIG5heCB1c2VkIGNvbHVtbiBudW1iZXIuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgbWF4IHVzZWQgY29sdW1uIG51bWJlci5cclxuICAgICAqIEBpZ25vcmVcclxuICAgICAqL1xyXG4gICAgbWF4VXNlZENvbHVtbk51bWJlcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fY2VsbHMubGVuZ3RoIC0gMTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnQgdGhlIHJvdyB0byBhbiBvYmplY3QuXHJcbiAgICAgKiBAcmV0dXJucyB7e319IFRoZSBvYmplY3QgZm9ybS5cclxuICAgICAqIEBpZ25vcmVcclxuICAgICAqL1xyXG4gICAgdG9YbWwoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX25vZGU7XHJcbiAgICB9XHJcblxyXG4gICAgLyogUFJJVkFURSAqL1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSWYgYSBjb2x1bW4gbm9kZSBpcyBhbHJlYWR5IGRlZmluZWQgdGhhdCBpbnRlcnNlY3RzIHdpdGggdGhpcyByb3cgYW5kIHRoYXQgY29sdW1uIGhhcyBhIHN0eWxlIHNldCwgd2VcclxuICAgICAqIG5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgYSBjZWxsIG5vZGUgZXhpc3RzIGF0IHRoZSBpbnRlcnNlY3Rpb24gc28gd2UgY2FuIHN0eWxlIGl0IGFwcHJvcHJpYXRlbHkuXHJcbiAgICAgKiBGZXRjaGluZyB0aGUgY2VsbCB3aWxsIGZvcmNlIGEgbmV3IGNlbGwgbm9kZSB0byBiZSBjcmVhdGVkIHdpdGggYSBzdHlsZSBtYXRjaGluZyB0aGUgY29sdW1uLlxyXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIF9jcmVhdGVDZWxsU3R5bGVzSWZOZWVkZWQoKSB7XHJcbiAgICAgICAgdGhpcy5zaGVldCgpLmZvckVhY2hFeGlzdGluZ0NvbHVtbk51bWJlcihjb2x1bW5OdW1iZXIgPT4ge1xyXG4gICAgICAgICAgICBpZiAoIV8uaXNOaWwodGhpcy5zaGVldCgpLmV4aXN0aW5nQ29sdW1uU3R5bGVJZChjb2x1bW5OdW1iZXIpKSkgdGhpcy5jZWxsKGNvbHVtbk51bWJlcik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGUgYSBzdHlsZSBmb3IgdGhpcyByb3cgaWYgaXQgZG9lc24ndCBhbHJlYWR5IGV4aXN0LlxyXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIF9jcmVhdGVTdHlsZUlmTmVlZGVkKCkge1xyXG4gICAgICAgIGlmICghdGhpcy5fc3R5bGUpIHtcclxuICAgICAgICAgICAgY29uc3Qgc3R5bGVJZCA9IHRoaXMuX25vZGUuYXR0cmlidXRlcy5zO1xyXG4gICAgICAgICAgICB0aGlzLl9zdHlsZSA9IHRoaXMud29ya2Jvb2soKS5zdHlsZVNoZWV0KCkuY3JlYXRlU3R5bGUoc3R5bGVJZCk7XHJcbiAgICAgICAgICAgIHRoaXMuX25vZGUuYXR0cmlidXRlcy5zID0gdGhpcy5fc3R5bGUuaWQoKTtcclxuICAgICAgICAgICAgdGhpcy5fbm9kZS5hdHRyaWJ1dGVzLmN1c3RvbUZvcm1hdCA9IDE7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5pdGlhbGl6ZSB0aGUgcm93IG5vZGUuXHJcbiAgICAgKiBAcGFyYW0ge3t9fSBub2RlIC0gVGhlIHJvdyBub2RlLlxyXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIF9pbml0KG5vZGUpIHtcclxuICAgICAgICB0aGlzLl9ub2RlID0gbm9kZTtcclxuICAgICAgICB0aGlzLl9jZWxscyA9IFtdO1xyXG4gICAgICAgIHRoaXMuX25vZGUuY2hpbGRyZW4uZm9yRWFjaChjZWxsTm9kZSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNlbGwgPSBuZXcgQ2VsbCh0aGlzLCBjZWxsTm9kZSk7XHJcbiAgICAgICAgICAgIHRoaXMuX2NlbGxzW2NlbGwuY29sdW1uTnVtYmVyKCldID0gY2VsbDtcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLl9ub2RlLmNoaWxkcmVuID0gdGhpcy5fY2VsbHM7XHJcbiAgICB9XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gUm93O1xyXG5cclxuLypcclxuPHJvdyByPVwiNlwiIHNwYW5zPVwiMTo5XCIgeDE0YWM6ZHlEZXNjZW50PVwiMC4yNVwiPlxyXG4gICAgPGMgcj1cIkE2XCIgcz1cIjFcIiB0PVwic1wiPlxyXG4gICAgICAgIDx2PjI8L3Y+XHJcbiAgICA8L2M+XHJcbiAgICA8YyByPVwiQjZcIiBzPVwiMVwiLz5cclxuICAgIDxjIHI9XCJDNlwiIHM9XCIxXCIvPlxyXG48L3Jvdz5cclxuKi9cclxuIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG5jb25zdCBfID0gcmVxdWlyZShcImxvZGFzaFwiKTtcclxuXHJcbi8qKlxyXG4gKiBUaGUgc2hhcmVkIHN0cmluZ3MgdGFibGUuXHJcbiAqIEBpZ25vcmVcclxuICovXHJcbmNsYXNzIFNoYXJlZFN0cmluZ3Mge1xyXG4gICAgLyoqXHJcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGluc3RhbmNlIG9mIF9TaGFyZWRTdHJpbmdzLlxyXG4gICAgICogQHBhcmFtIHt7fX0gbm9kZSAtIFRoZSBub2RlLlxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3Rvcihub2RlKSB7XHJcbiAgICAgICAgdGhpcy5fc3RyaW5nQXJyYXkgPSBbXTtcclxuICAgICAgICB0aGlzLl9pbmRleE1hcCA9IHt9O1xyXG5cclxuICAgICAgICB0aGlzLl9pbml0KG5vZGUpO1xyXG4gICAgICAgIHRoaXMuX2NhY2hlRXhpc3RpbmdTaGFyZWRTdHJpbmdzKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBpbmRleCBmb3IgYSBzdHJpbmdcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfEFycmF5Ljx7fT59IHN0cmluZyAtIFRoZSBzdHJpbmcgb3IgcmljaCB0ZXh0IGFycmF5LlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVGhlIGluZGV4XHJcbiAgICAgKi9cclxuICAgIGdldEluZGV4Rm9yU3RyaW5nKHN0cmluZykge1xyXG4gICAgICAgIC8vIElmIHRoZSBzdHJpbmcgaXMgZm91bmQgaW4gdGhlIGNhY2hlLCByZXR1cm4gdGhlIGluZGV4LlxyXG4gICAgICAgIGNvbnN0IGtleSA9IF8uaXNBcnJheShzdHJpbmcpID8gSlNPTi5zdHJpbmdpZnkoc3RyaW5nKSA6IHN0cmluZztcclxuICAgICAgICBsZXQgaW5kZXggPSB0aGlzLl9pbmRleE1hcFtrZXldO1xyXG4gICAgICAgIGlmIChpbmRleCA+PSAwKSByZXR1cm4gaW5kZXg7XHJcblxyXG4gICAgICAgIC8vIE90aGVyd2lzZSwgYWRkIGl0IHRvIHRoZSBjYWNoZXMuXHJcbiAgICAgICAgaW5kZXggPSB0aGlzLl9zdHJpbmdBcnJheS5sZW5ndGg7XHJcbiAgICAgICAgdGhpcy5fc3RyaW5nQXJyYXkucHVzaChzdHJpbmcpO1xyXG4gICAgICAgIHRoaXMuX2luZGV4TWFwW2tleV0gPSBpbmRleDtcclxuXHJcbiAgICAgICAgLy8gQXBwZW5kIGEgbmV3IHNpIG5vZGUuXHJcbiAgICAgICAgdGhpcy5fbm9kZS5jaGlsZHJlbi5wdXNoKHtcclxuICAgICAgICAgICAgbmFtZTogXCJzaVwiLFxyXG4gICAgICAgICAgICBjaGlsZHJlbjogXy5pc0FycmF5KHN0cmluZykgPyBzdHJpbmcgOiBbXHJcbiAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJ0XCIsXHJcbiAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlczogeyAneG1sOnNwYWNlJzogXCJwcmVzZXJ2ZVwiIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW46IFtzdHJpbmddXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIF1cclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGluZGV4O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0IHRoZSBzdHJpbmcgZm9yIGEgZ2l2ZW4gaW5kZXhcclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCAtIFRoZSBpbmRleFxyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHN0cmluZ1xyXG4gICAgICovXHJcbiAgICBnZXRTdHJpbmdCeUluZGV4KGluZGV4KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0cmluZ0FycmF5W2luZGV4XTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnQgdGhlIGNvbGxlY3Rpb24gdG8gYW4gWE1MIG9iamVjdC5cclxuICAgICAqIEByZXR1cm5zIHt7fX0gVGhlIFhNTCBvYmplY3QuXHJcbiAgICAgKi9cclxuICAgIHRvWG1sKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9ub2RlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogU3RvcmUgYW55IGV4aXN0aW5nIHZhbHVlcyBpbiB0aGUgY2FjaGVzLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEByZXR1cm5zIHt1bmRlZmluZWR9XHJcbiAgICAgKi9cclxuICAgIF9jYWNoZUV4aXN0aW5nU2hhcmVkU3RyaW5ncygpIHtcclxuICAgICAgICB0aGlzLl9ub2RlLmNoaWxkcmVuLmZvckVhY2goKG5vZGUsIGkpID0+IHtcclxuICAgICAgICAgICAgY29uc3QgY29udGVudCA9IG5vZGUuY2hpbGRyZW5bMF07XHJcbiAgICAgICAgICAgIGlmIChjb250ZW50Lm5hbWUgPT09IFwidFwiKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmcgPSBjb250ZW50LmNoaWxkcmVuWzBdO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fc3RyaW5nQXJyYXkucHVzaChzdHJpbmcpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5faW5kZXhNYXBbc3RyaW5nXSA9IGk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBQcm9wZXJseSBzdXBwb3J0IHJpY2ggdGV4dCBub2RlcyBpbiB0aGUgZnV0dXJlLiBGb3Igbm93IGp1c3Qgc3RvcmUgdGhlIG9iamVjdCBhcyBhIHBsYWNlaG9sZGVyLlxyXG4gICAgICAgICAgICAgICAgdGhpcy5fc3RyaW5nQXJyYXkucHVzaChub2RlLmNoaWxkcmVuKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2luZGV4TWFwW0pTT04uc3RyaW5naWZ5KG5vZGUuY2hpbGRyZW4pXSA9IGk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEluaXRpYWxpemUgdGhlIG5vZGUuXHJcbiAgICAgKiBAcGFyYW0ge3t9fSBbbm9kZV0gLSBUaGUgc2hhcmVkIHN0cmluZ3Mgbm9kZS5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gICAgICovXHJcbiAgICBfaW5pdChub2RlKSB7XHJcbiAgICAgICAgaWYgKCFub2RlKSBub2RlID0ge1xyXG4gICAgICAgICAgICBuYW1lOiBcInNzdFwiLFxyXG4gICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XHJcbiAgICAgICAgICAgICAgICB4bWxuczogXCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvc3ByZWFkc2hlZXRtbC8yMDA2L21haW5cIlxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBjaGlsZHJlbjogW11cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICB0aGlzLl9ub2RlID0gbm9kZTtcclxuXHJcbiAgICAgICAgZGVsZXRlIHRoaXMuX25vZGUuYXR0cmlidXRlcy5jb3VudDtcclxuICAgICAgICBkZWxldGUgdGhpcy5fbm9kZS5hdHRyaWJ1dGVzLnVuaXF1ZUNvdW50O1xyXG4gICAgfVxyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IFNoYXJlZFN0cmluZ3M7XHJcblxyXG4vKlxyXG54bC9zaGFyZWRTdHJpbmdzLnhtbFxyXG5cclxuPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVRGLThcIiBzdGFuZGFsb25lPVwieWVzXCI/PlxyXG48c3N0IHhtbG5zPVwiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL3NwcmVhZHNoZWV0bWwvMjAwNi9tYWluXCIgY291bnQ9XCIxM1wiIHVuaXF1ZUNvdW50PVwiNFwiPlxyXG5cdDxzaT5cclxuXHRcdDx0PkZvbzwvdD5cclxuXHQ8L3NpPlxyXG5cdDxzaT5cclxuXHRcdDx0PkJhcjwvdD5cclxuXHQ8L3NpPlxyXG5cdDxzaT5cclxuXHRcdDx0PkdvbzwvdD5cclxuXHQ8L3NpPlxyXG5cdDxzaT5cclxuXHRcdDxyPlxyXG5cdFx0XHQ8dD5zPC90PlxyXG5cdFx0PC9yPjxyPlxyXG5cdFx0XHQ8clByPlxyXG5cdFx0XHRcdDxiLz5cclxuXHRcdFx0XHQ8c3ogdmFsPVwiMTFcIi8+XHJcblx0XHRcdFx0PGNvbG9yIHRoZW1lPVwiMVwiLz5cclxuXHRcdFx0XHQ8ckZvbnQgdmFsPVwiQ2FsaWJyaVwiLz5cclxuXHRcdFx0XHQ8ZmFtaWx5IHZhbD1cIjJcIi8+XHJcblx0XHRcdFx0PHNjaGVtZSB2YWw9XCJtaW5vclwiLz5cclxuXHRcdFx0PC9yUHI+PHQ+ZDs8L3Q+XHJcblx0XHQ8L3I+PHI+XHJcblx0XHRcdDxyUHI+XHJcblx0XHRcdFx0PHN6IHZhbD1cIjExXCIvPlxyXG5cdFx0XHRcdDxjb2xvciB0aGVtZT1cIjFcIi8+XHJcblx0XHRcdFx0PHJGb250IHZhbD1cIkNhbGlicmlcIi8+XHJcblx0XHRcdFx0PGZhbWlseSB2YWw9XCIyXCIvPlxyXG5cdFx0XHRcdDxzY2hlbWUgdmFsPVwibWlub3JcIi8+XHJcblx0XHRcdDwvclByPjx0PmxmaztsPC90PlxyXG5cdFx0PC9yPlxyXG5cdDwvc2k+XHJcbjwvc3N0PlxyXG4qL1xyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxuXHJcbmNvbnN0IF8gPSByZXF1aXJlKFwibG9kYXNoXCIpO1xyXG5jb25zdCBDZWxsID0gcmVxdWlyZShcIi4vQ2VsbFwiKTtcclxuY29uc3QgUm93ID0gcmVxdWlyZShcIi4vUm93XCIpO1xyXG5jb25zdCBDb2x1bW4gPSByZXF1aXJlKFwiLi9Db2x1bW5cIik7XHJcbmNvbnN0IFJhbmdlID0gcmVxdWlyZShcIi4vUmFuZ2VcIik7XHJcbmNvbnN0IFJlbGF0aW9uc2hpcHMgPSByZXF1aXJlKFwiLi9SZWxhdGlvbnNoaXBzXCIpO1xyXG5jb25zdCB4bWxxID0gcmVxdWlyZShcIi4veG1scVwiKTtcclxuY29uc3QgcmVnZXhpZnkgPSByZXF1aXJlKFwiLi9yZWdleGlmeVwiKTtcclxuY29uc3QgYWRkcmVzc0NvbnZlcnRlciA9IHJlcXVpcmUoXCIuL2FkZHJlc3NDb252ZXJ0ZXJcIik7XHJcbmNvbnN0IEFyZ0hhbmRsZXIgPSByZXF1aXJlKFwiLi9BcmdIYW5kbGVyXCIpO1xyXG5jb25zdCBjb2xvckluZGV4ZXMgPSByZXF1aXJlKFwiLi9jb2xvckluZGV4ZXNcIik7XHJcbmNvbnN0IFBhZ2VCcmVha3MgPSByZXF1aXJlKFwiLi9QYWdlQnJlYWtzXCIpO1xyXG5cclxuLy8gT3JkZXIgb2YgdGhlIG5vZGVzIGFzIGRlZmluZWQgYnkgdGhlIHNwZWMuXHJcbmNvbnN0IG5vZGVPcmRlciA9IFtcclxuICAgIFwic2hlZXRQclwiLCBcImRpbWVuc2lvblwiLCBcInNoZWV0Vmlld3NcIiwgXCJzaGVldEZvcm1hdFByXCIsIFwiY29sc1wiLCBcInNoZWV0RGF0YVwiLFxyXG4gICAgXCJzaGVldENhbGNQclwiLCBcInNoZWV0UHJvdGVjdGlvblwiLCBcImF1dG9GaWx0ZXJcIiwgXCJwcm90ZWN0ZWRSYW5nZXNcIiwgXCJzY2VuYXJpb3NcIiwgXCJhdXRvRmlsdGVyXCIsXHJcbiAgICBcInNvcnRTdGF0ZVwiLCBcImRhdGFDb25zb2xpZGF0ZVwiLCBcImN1c3RvbVNoZWV0Vmlld3NcIiwgXCJtZXJnZUNlbGxzXCIsIFwicGhvbmV0aWNQclwiLFxyXG4gICAgXCJjb25kaXRpb25hbEZvcm1hdHRpbmdcIiwgXCJkYXRhVmFsaWRhdGlvbnNcIiwgXCJoeXBlcmxpbmtzXCIsIFwicHJpbnRPcHRpb25zXCIsXHJcbiAgICBcInBhZ2VNYXJnaW5zXCIsIFwicGFnZVNldHVwXCIsIFwiaGVhZGVyRm9vdGVyXCIsIFwicm93QnJlYWtzXCIsIFwiY29sQnJlYWtzXCIsXHJcbiAgICBcImN1c3RvbVByb3BlcnRpZXNcIiwgXCJjZWxsV2F0Y2hlc1wiLCBcImlnbm9yZWRFcnJvcnNcIiwgXCJzbWFydFRhZ3NcIiwgXCJkcmF3aW5nXCIsXHJcbiAgICBcImRyYXdpbmdIRlwiLCBcImxlZ2FjeURyYXdpbmdcIiwgXCJsZWdhY3lEcmF3aW5nSEZcIiwgXCJwaWN0dXJlXCIsIFwib2xlT2JqZWN0c1wiLCBcImNvbnRyb2xzXCIsIFwid2ViUHVibGlzaEl0ZW1zXCIsIFwidGFibGVQYXJ0c1wiLFxyXG4gICAgXCJleHRMc3RcIlxyXG5dO1xyXG5cclxuLyoqXHJcbiAqIEEgd29ya3NoZWV0LlxyXG4gKi9cclxuY2xhc3MgU2hlZXQge1xyXG4gICAgLy8gLyoqXHJcbiAgICAvLyAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIFNoZWV0LlxyXG4gICAgLy8gICogQHBhcmFtIHtXb3JrYm9va30gd29ya2Jvb2sgLSBUaGUgcGFyZW50IHdvcmtib29rLlxyXG4gICAgLy8gICogQHBhcmFtIHt7fX0gaWROb2RlIC0gVGhlIHNoZWV0IElEIG5vZGUgKGZyb20gdGhlIHBhcmVudCB3b3JrYm9vaykuXHJcbiAgICAvLyAgKiBAcGFyYW0ge3t9fSBub2RlIC0gVGhlIHNoZWV0IG5vZGUuXHJcbiAgICAvLyAgKiBAcGFyYW0ge3t9fSBbcmVsYXRpb25zaGlwc05vZGVdIC0gVGhlIG9wdGlvbmFsIHNoZWV0IHJlbGF0aW9uc2hpcHMgbm9kZS5cclxuICAgIC8vICAqL1xyXG4gICAgY29uc3RydWN0b3Iod29ya2Jvb2ssIGlkTm9kZSwgbm9kZSwgcmVsYXRpb25zaGlwc05vZGUpIHtcclxuICAgICAgICB0aGlzLl9pbml0KHdvcmtib29rLCBpZE5vZGUsIG5vZGUsIHJlbGF0aW9uc2hpcHNOb2RlKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiBQVUJMSUMgKi9cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgYSB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIHNoZWV0IGlzIHRoZSBhY3RpdmUgc2hlZXQgaW4gdGhlIHdvcmtib29rLlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgYWN0aXZlLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAgICAgKi8vKipcclxuICAgICAqIE1ha2UgdGhlIHNoZWV0IHRoZSBhY3RpdmUgc2hlZXQgaW4gdGhlIHdvcmtrYm9rLlxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBhY3RpdmUgLSBNdXN0IGJlIHNldCB0byBgdHJ1ZWAuIERlYWN0aXZhdGluZyBkaXJlY3RseSBpcyBub3Qgc3VwcG9ydGVkLiBUbyBkZWFjdGl2YXRlLCB5b3Ugc2hvdWxkIGFjdGl2YXRlIGEgZGlmZmVyZW50IHNoZWV0IGluc3RlYWQuXHJcbiAgICAgKiBAcmV0dXJucyB7U2hlZXR9IFRoZSBzaGVldC5cclxuICAgICAqL1xyXG4gICAgYWN0aXZlKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQXJnSGFuZGxlcignU2hlZXQuYWN0aXZlJylcclxuICAgICAgICAgICAgLmNhc2UoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMud29ya2Jvb2soKS5hY3RpdmVTaGVldCgpID09PSB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnYm9vbGVhbicsIGFjdGl2ZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWFjdGl2ZSkgdGhyb3cgbmV3IEVycm9yKFwiRGVhY3RpdmF0aW5nIHNoZWV0IGRpcmVjdGx5IG5vdCBzdXBwb3J0ZWQuIEFjdGl2YXRlIGEgZGlmZmVyZW50IHNoZWV0IGluc3RlYWQuXCIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy53b3JrYm9vaygpLmFjdGl2ZVNoZWV0KHRoaXMpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5oYW5kbGUoYXJndW1lbnRzKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldCB0aGUgYWN0aXZlIGNlbGwgaW4gdGhlIHNoZWV0LlxyXG4gICAgICogQHJldHVybnMge0NlbGx9IFRoZSBhY3RpdmUgY2VsbC5cclxuICAgICAqLy8qKlxyXG4gICAgICogU2V0IHRoZSBhY3RpdmUgY2VsbCBpbiB0aGUgd29ya2Jvb2suXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xDZWxsfSBjZWxsIC0gVGhlIGNlbGwgb3IgYWRkcmVzcyBvZiBjZWxsIHRvIGFjdGl2YXRlLlxyXG4gICAgICogQHJldHVybnMge1NoZWV0fSBUaGUgc2hlZXQuXHJcbiAgICAgKi8vKipcclxuICAgICAqIFNldCB0aGUgYWN0aXZlIGNlbGwgaW4gdGhlIHdvcmtib29rIGJ5IHJvdyBhbmQgY29sdW1uLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJvd051bWJlciAtIFRoZSByb3cgbnVtYmVyIG9mIHRoZSBjZWxsLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBjb2x1bW5OYW1lT3JOdW1iZXIgLSBUaGUgY29sdW1uIG5hbWUgb3IgbnVtYmVyIG9mIHRoZSBjZWxsLlxyXG4gICAgICogQHJldHVybnMge1NoZWV0fSBUaGUgc2hlZXQuXHJcbiAgICAgKi9cclxuICAgIGFjdGl2ZUNlbGwoKSB7XHJcbiAgICAgICAgY29uc3Qgc2hlZXRWaWV3Tm9kZSA9IHRoaXMuX2dldE9yQ3JlYXRlU2hlZXRWaWV3Tm9kZSgpO1xyXG4gICAgICAgIGxldCBzZWxlY3Rpb25Ob2RlID0geG1scS5maW5kQ2hpbGQoc2hlZXRWaWV3Tm9kZSwgXCJzZWxlY3Rpb25cIik7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBcmdIYW5kbGVyKCdTaGVldC5hY3RpdmVDZWxsJylcclxuICAgICAgICAgICAgLmNhc2UoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY2VsbEFkZHJlc3MgPSBzZWxlY3Rpb25Ob2RlID8gc2VsZWN0aW9uTm9kZS5hdHRyaWJ1dGVzLmFjdGl2ZUNlbGwgOiBcIkExXCI7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jZWxsKGNlbGxBZGRyZXNzKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoWydudW1iZXInLCAnKiddLCAocm93TnVtYmVyLCBjb2x1bW5OYW1lT3JOdW1iZXIpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNlbGwgPSB0aGlzLmNlbGwocm93TnVtYmVyLCBjb2x1bW5OYW1lT3JOdW1iZXIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWN0aXZlQ2VsbChjZWxsKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoJyonLCBjZWxsID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICghc2VsZWN0aW9uTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGlvbk5vZGUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IFwic2VsZWN0aW9uXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHt9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbjogW11cclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB4bWxxLmFwcGVuZENoaWxkKHNoZWV0Vmlld05vZGUsIHNlbGVjdGlvbk5vZGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmICghKGNlbGwgaW5zdGFuY2VvZiBDZWxsKSkgY2VsbCA9IHRoaXMuY2VsbChjZWxsKTtcclxuICAgICAgICAgICAgICAgIHNlbGVjdGlvbk5vZGUuYXR0cmlidXRlcy5hY3RpdmVDZWxsID0gc2VsZWN0aW9uTm9kZS5hdHRyaWJ1dGVzLnNxcmVmID0gY2VsbC5hZGRyZXNzKCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmhhbmRsZShhcmd1bWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgY2VsbCB3aXRoIHRoZSBnaXZlbiBhZGRyZXNzLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGFkZHJlc3MgLSBUaGUgYWRkcmVzcyBvZiB0aGUgY2VsbC5cclxuICAgICAqIEByZXR1cm5zIHtDZWxsfSBUaGUgY2VsbC5cclxuICAgICAqLy8qKlxyXG4gICAgICogR2V0cyB0aGUgY2VsbCB3aXRoIHRoZSBnaXZlbiByb3cgYW5kIGNvbHVtbiBudW1iZXJzLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJvd051bWJlciAtIFRoZSByb3cgbnVtYmVyIG9mIHRoZSBjZWxsLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBjb2x1bW5OYW1lT3JOdW1iZXIgLSBUaGUgY29sdW1uIG5hbWUgb3IgbnVtYmVyIG9mIHRoZSBjZWxsLlxyXG4gICAgICogQHJldHVybnMge0NlbGx9IFRoZSBjZWxsLlxyXG4gICAgICovXHJcbiAgICBjZWxsKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQXJnSGFuZGxlcignU2hlZXQuY2VsbCcpXHJcbiAgICAgICAgICAgIC5jYXNlKCdzdHJpbmcnLCBhZGRyZXNzID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJlZiA9IGFkZHJlc3NDb252ZXJ0ZXIuZnJvbUFkZHJlc3MoYWRkcmVzcyk7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVmLnR5cGUgIT09ICdjZWxsJykgdGhyb3cgbmV3IEVycm9yKCdTaGVldC5jZWxsOiBJbnZhbGlkIGFkZHJlc3MuJyk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yb3cocmVmLnJvd051bWJlcikuY2VsbChyZWYuY29sdW1uTnVtYmVyKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoWydudW1iZXInLCAnKiddLCAocm93TnVtYmVyLCBjb2x1bW5OYW1lT3JOdW1iZXIpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnJvdyhyb3dOdW1iZXIpLmNlbGwoY29sdW1uTmFtZU9yTnVtYmVyKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmhhbmRsZShhcmd1bWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBhIGNvbHVtbiBpbiB0aGUgc2hlZXQuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IGNvbHVtbk5hbWVPck51bWJlciAtIFRoZSBuYW1lIG9yIG51bWJlciBvZiB0aGUgY29sdW1uLlxyXG4gICAgICogQHJldHVybnMge0NvbHVtbn0gVGhlIGNvbHVtbi5cclxuICAgICAqL1xyXG4gICAgY29sdW1uKGNvbHVtbk5hbWVPck51bWJlcikge1xyXG4gICAgICAgIGNvbnN0IGNvbHVtbk51bWJlciA9IHR5cGVvZiBjb2x1bW5OYW1lT3JOdW1iZXIgPT09IFwic3RyaW5nXCIgPyBhZGRyZXNzQ29udmVydGVyLmNvbHVtbk5hbWVUb051bWJlcihjb2x1bW5OYW1lT3JOdW1iZXIpIDogY29sdW1uTmFtZU9yTnVtYmVyO1xyXG5cclxuICAgICAgICAvLyBJZiB3ZSdyZSBhbHJlYWR5IGNyZWF0ZWQgYSBjb2x1bW4gZm9yIHRoaXMgY29sdW1uIG51bWJlciwgcmV0dXJuIGl0LlxyXG4gICAgICAgIGlmICh0aGlzLl9jb2x1bW5zW2NvbHVtbk51bWJlcl0pIHJldHVybiB0aGlzLl9jb2x1bW5zW2NvbHVtbk51bWJlcl07XHJcblxyXG4gICAgICAgIC8vIFdlIG5lZWQgdG8gY3JlYXRlIGEgbmV3IGNvbHVtbiwgd2hpY2ggcmVxdWlyZXMgYSBiYWNraW5nIGNvbCBub2RlLiBUaGVyZSBtYXkgYWxyZWFkeSBleGlzdCBhIG5vZGUgd2hvc2UgbWluL21heCBjb3ZlciBvdXIgY29sdW1uLlxyXG4gICAgICAgIC8vIEZpcnN0LCBzZWUgaWYgdGhlcmUgaXMgYW4gZXhpc3RpbmcgY29sIG5vZGUuXHJcbiAgICAgICAgY29uc3QgZXhpc3RpbmdDb2xOb2RlID0gdGhpcy5fY29sTm9kZXNbY29sdW1uTnVtYmVyXTtcclxuXHJcbiAgICAgICAgbGV0IGNvbE5vZGU7XHJcbiAgICAgICAgaWYgKGV4aXN0aW5nQ29sTm9kZSkge1xyXG4gICAgICAgICAgICAvLyBJZiB0aGUgZXhpc3Rpbmcgbm9kZSBjb3ZlcmVkIGVhcmxpZXIgY29sdW1ucyB0aGFuIHRoZSBuZXcgb25lLCB3ZSBuZWVkIHRvIGhhdmUgYSBjb2wgbm9kZSB0byBjb3ZlciB0aGUgbWluIHVwIHRvIG91ciBuZXcgbm9kZS5cclxuICAgICAgICAgICAgaWYgKGV4aXN0aW5nQ29sTm9kZS5hdHRyaWJ1dGVzLm1pbiA8IGNvbHVtbk51bWJlcikge1xyXG4gICAgICAgICAgICAgICAgLy8gQ2xvbmUgdGhlIG5vZGUgYW5kIHNldCB0aGUgbWF4IHRvIHRoZSBjb2x1bW4gYmVmb3JlIG91ciBuZXcgY29sLlxyXG4gICAgICAgICAgICAgICAgY29uc3QgYmVmb3JlQ29sTm9kZSA9IF8uY2xvbmVEZWVwKGV4aXN0aW5nQ29sTm9kZSk7XHJcbiAgICAgICAgICAgICAgICBiZWZvcmVDb2xOb2RlLmF0dHJpYnV0ZXMubWF4ID0gY29sdW1uTnVtYmVyIC0gMTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgdGhlIGNvbCBub2RlcyBjYWNoZS5cclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBiZWZvcmVDb2xOb2RlLmF0dHJpYnV0ZXMubWluOyBpIDw9IGJlZm9yZUNvbE5vZGUuYXR0cmlidXRlcy5tYXg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NvbE5vZGVzW2ldID0gYmVmb3JlQ29sTm9kZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gTWFrZSBhIGNsb25lIGZvciB0aGUgbmV3IGNvbHVtbi4gU2V0IHRoZSBtaW4vbWF4IHRvIHRoZSBjb2x1bW4gbnVtYmVyIGFuZCBjYWNoZSBpdC5cclxuICAgICAgICAgICAgY29sTm9kZSA9IF8uY2xvbmVEZWVwKGV4aXN0aW5nQ29sTm9kZSk7XHJcbiAgICAgICAgICAgIGNvbE5vZGUuYXR0cmlidXRlcy5taW4gPSBjb2x1bW5OdW1iZXI7XHJcbiAgICAgICAgICAgIGNvbE5vZGUuYXR0cmlidXRlcy5tYXggPSBjb2x1bW5OdW1iZXI7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvbE5vZGVzW2NvbHVtbk51bWJlcl0gPSBjb2xOb2RlO1xyXG5cclxuICAgICAgICAgICAgLy8gSWYgdGhlIG1heCBvZiB0aGUgZXhpc3Rpbmcgbm9kZSBpcyBncmVhdGVyIHRoYW4gdGhlIG5yZSBvbmUsIGNyZWF0ZSBhIGNvbCBub2RlIGZvciB0aGF0IHRvby5cclxuICAgICAgICAgICAgaWYgKGV4aXN0aW5nQ29sTm9kZS5hdHRyaWJ1dGVzLm1heCA+IGNvbHVtbk51bWJlcikge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYWZ0ZXJDb2xOb2RlID0gXy5jbG9uZURlZXAoZXhpc3RpbmdDb2xOb2RlKTtcclxuICAgICAgICAgICAgICAgIGFmdGVyQ29sTm9kZS5hdHRyaWJ1dGVzLm1pbiA9IGNvbHVtbk51bWJlciArIDE7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gYWZ0ZXJDb2xOb2RlLmF0dHJpYnV0ZXMubWluOyBpIDw9IGFmdGVyQ29sTm9kZS5hdHRyaWJ1dGVzLm1heDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY29sTm9kZXNbaV0gPSBhZnRlckNvbE5vZGU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBUaGUgd2FzIG5vIGV4aXN0aW5nIG5vZGUgc28gY3JlYXRlIGEgbmV3IG9uZS5cclxuICAgICAgICAgICAgY29sTm9kZSA9IHtcclxuICAgICAgICAgICAgICAgIG5hbWU6ICdjb2wnLFxyXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlczoge1xyXG4gICAgICAgICAgICAgICAgICAgIG1pbjogY29sdW1uTnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgICAgIG1heDogY29sdW1uTnVtYmVyXHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgY2hpbGRyZW46IFtdXHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9jb2xOb2Rlc1tjb2x1bW5OdW1iZXJdID0gY29sTm9kZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIENyZWF0ZSB0aGUgbmV3IGNvbHVtbiBhbmQgY2FjaGUgaXQuXHJcbiAgICAgICAgY29uc3QgY29sdW1uID0gbmV3IENvbHVtbih0aGlzLCBjb2xOb2RlKTtcclxuICAgICAgICB0aGlzLl9jb2x1bW5zW2NvbHVtbk51bWJlcl0gPSBjb2x1bW47XHJcbiAgICAgICAgcmV0dXJuIGNvbHVtbjtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgYSBkZWZpbmVkIG5hbWUgc2NvcGVkIHRvIHRoZSBzaGVldC5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gVGhlIGRlZmluZWQgbmFtZS5cclxuICAgICAqIEByZXR1cm5zIHt1bmRlZmluZWR8c3RyaW5nfENlbGx8UmFuZ2V8Um93fENvbHVtbn0gV2hhdCB0aGUgZGVmaW5lZCBuYW1lIHJlZmVycyB0byBvciB1bmRlZmluZWQgaWYgbm90IGZvdW5kLiBXaWxsIHJldHVybiB0aGUgc3RyaW5nIGZvcm11bGEgaWYgbm90IGEgUm93LCBDb2x1bW4sIENlbGwsIG9yIFJhbmdlLlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXQgYSBkZWZpbmVkIG5hbWUgc2NvcGVkIHRvIHRoZSBzaGVldC5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gVGhlIGRlZmluZWQgbmFtZS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfENlbGx8UmFuZ2V8Um93fENvbHVtbn0gcmVmZXJzVG8gLSBXaGF0IHRoZSBuYW1lIHJlZmVycyB0by5cclxuICAgICAqIEByZXR1cm5zIHtXb3JrYm9va30gVGhlIHdvcmtib29rLlxyXG4gICAgICovXHJcbiAgICBkZWZpbmVkTmFtZSgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEFyZ0hhbmRsZXIoXCJXb3JrYm9vay5kZWZpbmVkTmFtZVwiKVxyXG4gICAgICAgICAgICAuY2FzZSgnc3RyaW5nJywgbmFtZSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy53b3JrYm9vaygpLnNjb3BlZERlZmluZWROYW1lKHRoaXMsIG5hbWUpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZShbJ3N0cmluZycsICcqJ10sIChuYW1lLCByZWZlcnNUbykgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy53b3JrYm9vaygpLnNjb3BlZERlZmluZWROYW1lKHRoaXMsIG5hbWUsIHJlZmVyc1RvKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuaGFuZGxlKGFyZ3VtZW50cyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZWxldGVzIHRoZSBzaGVldCBhbmQgcmV0dXJucyB0aGUgcGFyZW50IHdvcmtib29rLlxyXG4gICAgICogQHJldHVybnMge1dvcmtib29rfSBUaGUgd29ya2Jvb2suXHJcbiAgICAgKi9cclxuICAgIGRlbGV0ZSgpIHtcclxuICAgICAgICB0aGlzLndvcmtib29rKCkuZGVsZXRlU2hlZXQodGhpcyk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMud29ya2Jvb2soKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpbmQgdGhlIGdpdmVuIHBhdHRlcm4gaW4gdGhlIHNoZWV0IGFuZCBvcHRpb25hbGx5IHJlcGxhY2UgaXQuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xSZWdFeHB9IHBhdHRlcm4gLSBUaGUgcGF0dGVybiB0byBsb29rIGZvci4gUHJvdmlkaW5nIGEgc3RyaW5nIHdpbGwgcmVzdWx0IGluIGEgY2FzZS1pbnNlbnNpdGl2ZSBzdWJzdHJpbmcgc2VhcmNoLiBVc2UgYSBSZWdFeHAgZm9yIG1vcmUgc29waGlzdGljYXRlZCBzZWFyY2hlcy5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfGZ1bmN0aW9ufSBbcmVwbGFjZW1lbnRdIC0gVGhlIHRleHQgdG8gcmVwbGFjZSBvciBhIFN0cmluZy5yZXBsYWNlIGNhbGxiYWNrIGZ1bmN0aW9uLiBJZiBwYXR0ZXJuIGlzIGEgc3RyaW5nLCBhbGwgb2NjdXJyZW5jZXMgb2YgdGhlIHBhdHRlcm4gaW4gZWFjaCBjZWxsIHdpbGwgYmUgcmVwbGFjZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7QXJyYXkuPENlbGw+fSBUaGUgbWF0Y2hpbmcgY2VsbHMuXHJcbiAgICAgKi9cclxuICAgIGZpbmQocGF0dGVybiwgcmVwbGFjZW1lbnQpIHtcclxuICAgICAgICBwYXR0ZXJuID0gcmVnZXhpZnkocGF0dGVybik7XHJcblxyXG4gICAgICAgIGxldCBtYXRjaGVzID0gW107XHJcbiAgICAgICAgdGhpcy5fcm93cy5mb3JFYWNoKHJvdyA9PiB7XHJcbiAgICAgICAgICAgIGlmICghcm93KSByZXR1cm47XHJcbiAgICAgICAgICAgIG1hdGNoZXMgPSBtYXRjaGVzLmNvbmNhdChyb3cuZmluZChwYXR0ZXJuLCByZXBsYWNlbWVudCkpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gbWF0Y2hlcztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgYSB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdGhpcyBzaGVldCdzIGdyaWQgbGluZXMgYXJlIHZpc2libGUuXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBzZWxlY3RlZCwgZmFsc2UgaWYgbm90LlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXRzIHdoZXRoZXIgdGhpcyBzaGVldCdzIGdyaWQgbGluZXMgYXJlIHZpc2libGUuXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHNlbGVjdGVkIC0gVHJ1ZSB0byBtYWtlIHZpc2libGUsIGZhbHNlIHRvIGhpZGUuXHJcbiAgICAgKiBAcmV0dXJucyB7U2hlZXR9IFRoZSBzaGVldC5cclxuICAgICAqL1xyXG4gICAgZ3JpZExpbmVzVmlzaWJsZSgpIHtcclxuICAgICAgICBjb25zdCBzaGVldFZpZXdOb2RlID0gdGhpcy5fZ2V0T3JDcmVhdGVTaGVldFZpZXdOb2RlKCk7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBcmdIYW5kbGVyKCdTaGVldC5ncmlkTGluZXNWaXNpYmxlJylcclxuICAgICAgICAgICAgLmNhc2UoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNoZWV0Vmlld05vZGUuYXR0cmlidXRlcy5zaG93R3JpZExpbmVzID09PSAxIHx8IHNoZWV0Vmlld05vZGUuYXR0cmlidXRlcy5zaG93R3JpZExpbmVzID09PSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKCdib29sZWFuJywgdmlzaWJsZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBzaGVldFZpZXdOb2RlLmF0dHJpYnV0ZXMuc2hvd0dyaWRMaW5lcyA9IHZpc2libGUgPyAxIDogMDtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuaGFuZGxlKGFyZ3VtZW50cyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIGEgdmFsdWUgaW5kaWNhdGluZyBpZiB0aGUgc2hlZXQgaXMgaGlkZGVuIG9yIG5vdC5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufHN0cmluZ30gVHJ1ZSBpZiBoaWRkZW4sIGZhbHNlIGlmIHZpc2libGUsIGFuZCAndmVyeScgaWYgdmVyeSBoaWRkZW4uXHJcbiAgICAgKi8vKipcclxuICAgICAqIFNldCB3aGV0aGVyIHRoZSBzaGVldCBpcyBoaWRkZW4gb3Igbm90LlxyXG4gICAgICogQHBhcmFtIHtib29sZWFufHN0cmluZ30gaGlkZGVuIC0gVHJ1ZSB0byBoaWRlLCBmYWxzZSB0byBzaG93LCBhbmQgJ3ZlcnknIHRvIG1ha2UgdmVyeSBoaWRkZW4uXHJcbiAgICAgKiBAcmV0dXJucyB7U2hlZXR9IFRoZSBzaGVldC5cclxuICAgICAqL1xyXG4gICAgaGlkZGVuKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQXJnSGFuZGxlcignU2hlZXQuaGlkZGVuJylcclxuICAgICAgICAgICAgLmNhc2UoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2lkTm9kZS5hdHRyaWJ1dGVzLnN0YXRlID09PSAnaGlkZGVuJykgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5faWROb2RlLmF0dHJpYnV0ZXMuc3RhdGUgPT09ICd2ZXJ5SGlkZGVuJykgcmV0dXJuIFwidmVyeVwiO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnKicsIGhpZGRlbiA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaGlkZGVuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmlzaWJsZVNoZWV0cyA9IF8uZmlsdGVyKHRoaXMud29ya2Jvb2soKS5zaGVldHMoKSwgc2hlZXQgPT4gIXNoZWV0LmhpZGRlbigpKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodmlzaWJsZVNoZWV0cy5sZW5ndGggPT09IDEgJiYgdmlzaWJsZVNoZWV0c1swXSA9PT0gdGhpcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIHNoZWV0IG1heSBub3QgYmUgaGlkZGVuIGFzIGEgd29ya2Jvb2sgbXVzdCBjb250YWluIGF0IGxlYXN0IG9uZSB2aXNpYmxlIHNoZWV0LlwiKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIElmIGFjdGl2YXRlLCBhY3RpdmF0ZSB0aGUgZmlyc3Qgb3RoZXIgdmlzaWJsZSBzaGVldC5cclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5hY3RpdmUoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhY3RpdmVJbmRleCA9IHZpc2libGVTaGVldHNbMF0gPT09IHRoaXMgPyAxIDogMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmlzaWJsZVNoZWV0c1thY3RpdmVJbmRleF0uYWN0aXZlKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoaGlkZGVuID09PSAndmVyeScpIHRoaXMuX2lkTm9kZS5hdHRyaWJ1dGVzLnN0YXRlID0gJ3ZlcnlIaWRkZW4nO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoaGlkZGVuKSB0aGlzLl9pZE5vZGUuYXR0cmlidXRlcy5zdGF0ZSA9ICdoaWRkZW4nO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBkZWxldGUgdGhpcy5faWROb2RlLmF0dHJpYnV0ZXMuc3RhdGU7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmhhbmRsZShhcmd1bWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTW92ZSB0aGUgc2hlZXQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcnxzdHJpbmd8U2hlZXR9IFtpbmRleE9yQmVmb3JlU2hlZXRdIFRoZSBpbmRleCB0byBtb3ZlIHRoZSBzaGVldCB0byBvciB0aGUgc2hlZXQgKG9yIG5hbWUgb2Ygc2hlZXQpIHRvIG1vdmUgdGhpcyBzaGVldCBiZWZvcmUuIE9taXQgdGhpcyBhcmd1bWVudCB0byBtb3ZlIHRvIHRoZSBlbmQgb2YgdGhlIHdvcmtib29rLlxyXG4gICAgICogQHJldHVybnMge1NoZWV0fSBUaGUgc2hlZXQuXHJcbiAgICAgKi9cclxuICAgIG1vdmUoaW5kZXhPckJlZm9yZVNoZWV0KSB7XHJcbiAgICAgICAgdGhpcy53b3JrYm9vaygpLm1vdmVTaGVldCh0aGlzLCBpbmRleE9yQmVmb3JlU2hlZXQpO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0IHRoZSBuYW1lIG9mIHRoZSBzaGVldC5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBzaGVldCBuYW1lLlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXQgdGhlIG5hbWUgb2YgdGhlIHNoZWV0LiAqTm90ZTogdGhpcyBtZXRob2QgZG9lcyBub3QgcmVuYW1lIHJlZmVyZW5jZXMgdG8gdGhlIHNoZWV0IHNvIGZvcm11bGFzLCBldGMuIGNhbiBiZSBicm9rZW4uIFVzZSB3aXRoIGNhdXRpb24hKlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSB0byBzZXQgdG8gdGhlIHNoZWV0LlxyXG4gICAgICogQHJldHVybnMge1NoZWV0fSBUaGUgc2hlZXQuXHJcbiAgICAgKi9cclxuICAgIG5hbWUoKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBcmdIYW5kbGVyKCdTaGVldC5uYW1lJylcclxuICAgICAgICAgICAgLmNhc2UoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke3RoaXMuX2lkTm9kZS5hdHRyaWJ1dGVzLm5hbWV9YDtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoJ3N0cmluZycsIG5hbWUgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5faWROb2RlLmF0dHJpYnV0ZXMubmFtZSA9IG5hbWU7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmhhbmRsZShhcmd1bWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBhIHJhbmdlIGZyb20gdGhlIGdpdmVuIHJhbmdlIGFkZHJlc3MuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYWRkcmVzcyAtIFRoZSByYW5nZSBhZGRyZXNzIChlLmcuICdBMTpCMycpLlxyXG4gICAgICogQHJldHVybnMge1JhbmdlfSBUaGUgcmFuZ2UuXHJcbiAgICAgKi8vKipcclxuICAgICAqIEdldHMgYSByYW5nZSBmcm9tIHRoZSBnaXZlbiBjZWxscyBvciBjZWxsIGFkZHJlc3Nlcy5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfENlbGx9IHN0YXJ0Q2VsbCAtIFRoZSBzdGFydGluZyBjZWxsIG9yIGNlbGwgYWRkcmVzcyAoZS5nLiAnQTEnKS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfENlbGx9IGVuZENlbGwgLSBUaGUgZW5kaW5nIGNlbGwgb3IgY2VsbCBhZGRyZXNzIChlLmcuICdCMycpLlxyXG4gICAgICogQHJldHVybnMge1JhbmdlfSBUaGUgcmFuZ2UuXHJcbiAgICAgKi8vKipcclxuICAgICAqIEdldHMgYSByYW5nZSBmcm9tIHRoZSBnaXZlbiByb3cgbnVtYmVycyBhbmQgY29sdW1uIG5hbWVzIG9yIG51bWJlcnMuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnRSb3dOdW1iZXIgLSBUaGUgc3RhcnRpbmcgY2VsbCByb3cgbnVtYmVyLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBzdGFydENvbHVtbk5hbWVPck51bWJlciAtIFRoZSBzdGFydGluZyBjZWxsIGNvbHVtbiBuYW1lIG9yIG51bWJlci5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBlbmRSb3dOdW1iZXIgLSBUaGUgZW5kaW5nIGNlbGwgcm93IG51bWJlci5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gZW5kQ29sdW1uTmFtZU9yTnVtYmVyIC0gVGhlIGVuZGluZyBjZWxsIGNvbHVtbiBuYW1lIG9yIG51bWJlci5cclxuICAgICAqIEByZXR1cm5zIHtSYW5nZX0gVGhlIHJhbmdlLlxyXG4gICAgICovXHJcbiAgICByYW5nZSgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEFyZ0hhbmRsZXIoJ1NoZWV0LnJhbmdlJylcclxuICAgICAgICAgICAgLmNhc2UoJ3N0cmluZycsIGFkZHJlc3MgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcmVmID0gYWRkcmVzc0NvbnZlcnRlci5mcm9tQWRkcmVzcyhhZGRyZXNzKTtcclxuICAgICAgICAgICAgICAgIGlmIChyZWYudHlwZSAhPT0gJ3JhbmdlJykgdGhyb3cgbmV3IEVycm9yKCdTaGVldC5yYW5nZTogSW52YWxpZCBhZGRyZXNzJyk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yYW5nZShyZWYuc3RhcnRSb3dOdW1iZXIsIHJlZi5zdGFydENvbHVtbk51bWJlciwgcmVmLmVuZFJvd051bWJlciwgcmVmLmVuZENvbHVtbk51bWJlcik7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKFsnKicsICcqJ10sIChzdGFydENlbGwsIGVuZENlbGwpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygc3RhcnRDZWxsID09PSBcInN0cmluZ1wiKSBzdGFydENlbGwgPSB0aGlzLmNlbGwoc3RhcnRDZWxsKTtcclxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZW5kQ2VsbCA9PT0gXCJzdHJpbmdcIikgZW5kQ2VsbCA9IHRoaXMuY2VsbChlbmRDZWxsKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUmFuZ2Uoc3RhcnRDZWxsLCBlbmRDZWxsKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoWydudW1iZXInLCAnKicsICdudW1iZXInLCAnKiddLCAoc3RhcnRSb3dOdW1iZXIsIHN0YXJ0Q29sdW1uTmFtZU9yTnVtYmVyLCBlbmRSb3dOdW1iZXIsIGVuZENvbHVtbk5hbWVPck51bWJlcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmFuZ2UodGhpcy5jZWxsKHN0YXJ0Um93TnVtYmVyLCBzdGFydENvbHVtbk5hbWVPck51bWJlciksIHRoaXMuY2VsbChlbmRSb3dOdW1iZXIsIGVuZENvbHVtbk5hbWVPck51bWJlcikpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuaGFuZGxlKGFyZ3VtZW50cyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBVbnNldHMgc2hlZXQgYXV0b0ZpbHRlci5cclxuICAgICAqIEByZXR1cm5zIHtTaGVldH0gVGhpcyBzaGVldC5cclxuICAgICAqLy8qKlxyXG4gICAgICogU2V0cyBzaGVldCBhdXRvRmlsdGVyIHRvIGEgUmFuZ2UuXHJcbiAgICAgKiBAcGFyYW0ge1JhbmdlfSByYW5nZSAtIFRoZSBhdXRvRmlsdGVyIHJhbmdlLlxyXG4gICAgICogQHJldHVybnMge1NoZWV0fSBUaGlzIHNoZWV0LlxyXG4gICAgICovXHJcbiAgICBhdXRvRmlsdGVyKHJhbmdlKSB7XHJcbiAgICAgICAgdGhpcy5fYXV0b0ZpbHRlciA9IHJhbmdlO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIHJvdyB3aXRoIHRoZSBnaXZlbiBudW1iZXIuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcm93TnVtYmVyIC0gVGhlIHJvdyBudW1iZXIuXHJcbiAgICAgKiBAcmV0dXJucyB7Um93fSBUaGUgcm93IHdpdGggdGhlIGdpdmVuIG51bWJlci5cclxuICAgICAqL1xyXG4gICAgcm93KHJvd051bWJlcikge1xyXG4gICAgICAgIGlmIChyb3dOdW1iZXIgPCAxKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgSW52YWxpZCByb3cgbnVtYmVyICR7cm93TnVtYmVyfS4gUmVtZW1iZXIgdGhhdCBzcHJlYWRzaGVldHMgdXNlIDEtYmFzZWQgaW5kZXhpbmcuYCk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLl9yb3dzW3Jvd051bWJlcl0pIHJldHVybiB0aGlzLl9yb3dzW3Jvd051bWJlcl07XHJcblxyXG4gICAgICAgIGNvbnN0IHJvd05vZGUgPSB7XHJcbiAgICAgICAgICAgIG5hbWU6ICdyb3cnLFxyXG4gICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XHJcbiAgICAgICAgICAgICAgICByOiByb3dOdW1iZXJcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgY2hpbGRyZW46IFtdXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgY29uc3Qgcm93ID0gbmV3IFJvdyh0aGlzLCByb3dOb2RlKTtcclxuICAgICAgICB0aGlzLl9yb3dzW3Jvd051bWJlcl0gPSByb3c7XHJcbiAgICAgICAgcmV0dXJuIHJvdztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldCB0aGUgdGFiIGNvbG9yLiAoU2VlIHN0eWxlIFtDb2xvcl0oI2NvbG9yKS4pXHJcbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfENvbG9yfSBUaGUgY29sb3Igb3IgdW5kZWZpbmVkIGlmIG5vdCBzZXQuXHJcbiAgICAgKi8vKipcclxuICAgICAqIFNldHMgdGhlIHRhYiBjb2xvci4gKFNlZSBzdHlsZSBbQ29sb3JdKCNjb2xvcikuKVxyXG4gICAgICogQHJldHVybnMge0NvbG9yfHN0cmluZ3xudW1iZXJ9IGNvbG9yIC0gQ29sb3Igb2YgdGhlIHRhYi4gSWYgc3RyaW5nLCB3aWxsIHNldCBhbiBSR0IgY29sb3IuIElmIG51bWJlciwgd2lsbCBzZXQgYSB0aGVtZSBjb2xvci5cclxuICAgICAqL1xyXG4gICAgdGFiQ29sb3IoKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBcmdIYW5kbGVyKFwiU2hlZXQudGFiQ29sb3JcIilcclxuICAgICAgICAgICAgLmNhc2UoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdGFiQ29sb3JOb2RlID0geG1scS5maW5kQ2hpbGQodGhpcy5fc2hlZXRQck5vZGUsIFwidGFiQ29sb3JcIik7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRhYkNvbG9yTm9kZSkgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IGNvbG9yID0ge307XHJcbiAgICAgICAgICAgICAgICBpZiAodGFiQ29sb3JOb2RlLmF0dHJpYnV0ZXMuaGFzT3duUHJvcGVydHkoJ3JnYicpKSBjb2xvci5yZ2IgPSB0YWJDb2xvck5vZGUuYXR0cmlidXRlcy5yZ2I7XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0YWJDb2xvck5vZGUuYXR0cmlidXRlcy5oYXNPd25Qcm9wZXJ0eSgndGhlbWUnKSkgY29sb3IudGhlbWUgPSB0YWJDb2xvck5vZGUuYXR0cmlidXRlcy50aGVtZTtcclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRhYkNvbG9yTm9kZS5hdHRyaWJ1dGVzLmhhc093blByb3BlcnR5KCdpbmRleGVkJykpIGNvbG9yLnJnYiA9IGNvbG9ySW5kZXhlc1t0YWJDb2xvck5vZGUuYXR0cmlidXRlcy5pbmRleGVkXTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodGFiQ29sb3JOb2RlLmF0dHJpYnV0ZXMuaGFzT3duUHJvcGVydHkoJ3RpbnQnKSkgY29sb3IudGludCA9IHRhYkNvbG9yTm9kZS5hdHRyaWJ1dGVzLnRpbnQ7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbG9yO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZShcInN0cmluZ1wiLCByZ2IgPT4gdGhpcy50YWJDb2xvcih7IHJnYiB9KSlcclxuICAgICAgICAgICAgLmNhc2UoXCJpbnRlZ2VyXCIsIHRoZW1lID0+IHRoaXMudGFiQ29sb3IoeyB0aGVtZSB9KSlcclxuICAgICAgICAgICAgLmNhc2UoXCJuaWxcIiwgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgeG1scS5yZW1vdmVDaGlsZCh0aGlzLl9zaGVldFByTm9kZSwgXCJ0YWJDb2xvclwiKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZShcIm9iamVjdFwiLCBjb2xvciA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB0YWJDb2xvck5vZGUgPSB4bWxxLmFwcGVuZENoaWxkSWZOb3RGb3VuZCh0aGlzLl9zaGVldFByTm9kZSwgXCJ0YWJDb2xvclwiKTtcclxuICAgICAgICAgICAgICAgIHhtbHEuc2V0QXR0cmlidXRlcyh0YWJDb2xvck5vZGUsIHtcclxuICAgICAgICAgICAgICAgICAgICByZ2I6IGNvbG9yLnJnYiAmJiBjb2xvci5yZ2IudG9VcHBlckNhc2UoKSxcclxuICAgICAgICAgICAgICAgICAgICBpbmRleGVkOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgIHRoZW1lOiBjb2xvci50aGVtZSxcclxuICAgICAgICAgICAgICAgICAgICB0aW50OiBjb2xvci50aW50XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmhhbmRsZShhcmd1bWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBhIHZhbHVlIGluZGljYXRpbmcgd2hldGhlciB0aGlzIHNoZWV0IGlzIHNlbGVjdGVkLlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgc2VsZWN0ZWQsIGZhbHNlIGlmIG5vdC5cclxuICAgICAqLy8qKlxyXG4gICAgICogU2V0cyB3aGV0aGVyIHRoaXMgc2hlZXQgaXMgc2VsZWN0ZWQuXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHNlbGVjdGVkIC0gVHJ1ZSB0byBzZWxlY3QsIGZhbHNlIHRvIGRlc2VsZWN0ZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7U2hlZXR9IFRoZSBzaGVldC5cclxuICAgICAqL1xyXG4gICAgdGFiU2VsZWN0ZWQoKSB7XHJcbiAgICAgICAgY29uc3Qgc2hlZXRWaWV3Tm9kZSA9IHRoaXMuX2dldE9yQ3JlYXRlU2hlZXRWaWV3Tm9kZSgpO1xyXG4gICAgICAgIHJldHVybiBuZXcgQXJnSGFuZGxlcignU2hlZXQudGFiU2VsZWN0ZWQnKVxyXG4gICAgICAgICAgICAuY2FzZSgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gc2hlZXRWaWV3Tm9kZS5hdHRyaWJ1dGVzLnRhYlNlbGVjdGVkID09PSAxO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnYm9vbGVhbicsIHNlbGVjdGVkID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZCkgc2hlZXRWaWV3Tm9kZS5hdHRyaWJ1dGVzLnRhYlNlbGVjdGVkID0gMTtcclxuICAgICAgICAgICAgICAgIGVsc2UgZGVsZXRlIHNoZWV0Vmlld05vZGUuYXR0cmlidXRlcy50YWJTZWxlY3RlZDtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuaGFuZGxlKGFyZ3VtZW50cyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXQgdGhlIHJhbmdlIG9mIGNlbGxzIGluIHRoZSBzaGVldCB0aGF0IGhhdmUgY29udGFpbmVkIGEgdmFsdWUgb3Igc3R5bGUgYXQgYW55IHBvaW50LiBVc2VmdWwgZm9yIGV4dHJhY3RpbmcgdGhlIGVudGlyZSBzaGVldCBjb250ZW50cy5cclxuICAgICAqIEByZXR1cm5zIHtSYW5nZXx1bmRlZmluZWR9IFRoZSB1c2VkIHJhbmdlIG9yIHVuZGVmaW5lZCBpZiBubyBjZWxscyBpbiB0aGUgc2hlZXQgYXJlIHVzZWQuXHJcbiAgICAgKi9cclxuICAgIHVzZWRSYW5nZSgpIHtcclxuICAgICAgICBjb25zdCBtaW5Sb3dOdW1iZXIgPSBfLmZpbmRJbmRleCh0aGlzLl9yb3dzKTtcclxuICAgICAgICBjb25zdCBtYXhSb3dOdW1iZXIgPSB0aGlzLl9yb3dzLmxlbmd0aCAtIDE7XHJcblxyXG4gICAgICAgIGxldCBtaW5Db2x1bW5OdW1iZXIgPSAwO1xyXG4gICAgICAgIGxldCBtYXhDb2x1bW5OdW1iZXIgPSAwO1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fcm93cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBjb25zdCByb3cgPSB0aGlzLl9yb3dzW2ldO1xyXG4gICAgICAgICAgICBpZiAoIXJvdykgY29udGludWU7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBtaW5Vc2VkQ29sdW1uTnVtYmVyID0gcm93Lm1pblVzZWRDb2x1bW5OdW1iZXIoKTtcclxuICAgICAgICAgICAgY29uc3QgbWF4VXNlZENvbHVtbk51bWJlciA9IHJvdy5tYXhVc2VkQ29sdW1uTnVtYmVyKCk7XHJcbiAgICAgICAgICAgIGlmIChtaW5Vc2VkQ29sdW1uTnVtYmVyID4gMCAmJiAoIW1pbkNvbHVtbk51bWJlciB8fCBtaW5Vc2VkQ29sdW1uTnVtYmVyIDwgbWluQ29sdW1uTnVtYmVyKSkgbWluQ29sdW1uTnVtYmVyID0gbWluVXNlZENvbHVtbk51bWJlcjtcclxuICAgICAgICAgICAgaWYgKG1heFVzZWRDb2x1bW5OdW1iZXIgPiAwICYmICghbWF4Q29sdW1uTnVtYmVyIHx8IG1heFVzZWRDb2x1bW5OdW1iZXIgPiBtYXhDb2x1bW5OdW1iZXIpKSBtYXhDb2x1bW5OdW1iZXIgPSBtYXhVc2VkQ29sdW1uTnVtYmVyO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gUmV0dXJuIHVuZGVmaW5lZCBpZiBub3RoaW5nIGluIHRoZSBzaGVldCBpcyB1c2VkLlxyXG4gICAgICAgIGlmIChtaW5Sb3dOdW1iZXIgPD0gMCB8fCBtaW5Db2x1bW5OdW1iZXIgPD0gMCB8fCBtYXhSb3dOdW1iZXIgPD0gMCB8fCBtYXhDb2x1bW5OdW1iZXIgPD0gMCkgcmV0dXJuO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5yYW5nZShtaW5Sb3dOdW1iZXIsIG1pbkNvbHVtbk51bWJlciwgbWF4Um93TnVtYmVyLCBtYXhDb2x1bW5OdW1iZXIpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgcGFyZW50IHdvcmtib29rLlxyXG4gICAgICogQHJldHVybnMge1dvcmtib29rfSBUaGUgcGFyZW50IHdvcmtib29rLlxyXG4gICAgICovXHJcbiAgICB3b3JrYm9vaygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fd29ya2Jvb2s7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIGFsbCBwYWdlIGJyZWFrcy5cclxuICAgICAqIEByZXR1cm5zIHt7fX0gdGhlIG9iamVjdCBob2xkcyBib3RoIHZlcnRpY2FsIGFuZCBob3Jpem9udGFsIFBhZ2VCcmVha3MuXHJcbiAgICAgKi9cclxuICAgIHBhZ2VCcmVha3MoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhZ2VCcmVha3M7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSB2ZXJ0aWNhbCBwYWdlIGJyZWFrcy5cclxuICAgICAqIEByZXR1cm5zIHtQYWdlQnJlYWtzfSB2ZXJ0aWNhbCBQYWdlQnJlYWtzLlxyXG4gICAgICovXHJcbiAgICB2ZXJ0aWNhbFBhZ2VCcmVha3MoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhZ2VCcmVha3MuY29sQnJlYWtzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgaG9yaXpvbnRhbCBwYWdlIGJyZWFrcy5cclxuICAgICAqIEByZXR1cm5zIHtQYWdlQnJlYWtzfSBob3Jpem9udGFsIFBhZ2VCcmVha3MuXHJcbiAgICAgKi9cclxuICAgIGhvcml6b250YWxQYWdlQnJlYWtzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9wYWdlQnJlYWtzLnJvd0JyZWFrcztcclxuICAgIH1cclxuXHJcbiAgICAvKiBJTlRFUk5BTCAqL1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2xlYXIgY2VsbHMgdGhhdCBhcmUgdXNpbmcgYSBnaXZlbiBzaGFyZWQgZm9ybXVsYSBJRC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzaGFyZWRGb3JtdWxhSWQgLSBUaGUgc2hhcmVkIGZvcm11bGEgSUQuXHJcbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gICAgICogQGlnbm9yZVxyXG4gICAgICovXHJcbiAgICBjbGVhckNlbGxzVXNpbmdTaGFyZWRGb3JtdWxhKHNoYXJlZEZvcm11bGFJZCkge1xyXG4gICAgICAgIHRoaXMuX3Jvd3MuZm9yRWFjaChyb3cgPT4ge1xyXG4gICAgICAgICAgICBpZiAoIXJvdykgcmV0dXJuO1xyXG4gICAgICAgICAgICByb3cuY2xlYXJDZWxsc1VzaW5nU2hhcmVkRm9ybXVsYShzaGFyZWRGb3JtdWxhSWQpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0IGFuIGV4aXN0aW5nIGNvbHVtbiBzdHlsZSBJRC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBjb2x1bW5OdW1iZXIgLSBUaGUgY29sdW1uIG51bWJlci5cclxuICAgICAqIEByZXR1cm5zIHt1bmRlZmluZWR8bnVtYmVyfSBUaGUgc3R5bGUgSUQuXHJcbiAgICAgKiBAaWdub3JlXHJcbiAgICAgKi9cclxuICAgIGV4aXN0aW5nQ29sdW1uU3R5bGVJZChjb2x1bW5OdW1iZXIpIHtcclxuICAgICAgICAvLyBUaGlzIHdpbGwgd29yayBhZnRlciBzZXR0aW5nIENvbHVtbi5zdHlsZSBiZWNhdXNlIENvbHVtbiB1cGRhdGVzIHRoZSBhdHRyaWJ1dGVzIGxpdmUuXHJcbiAgICAgICAgY29uc3QgY29sTm9kZSA9IHRoaXMuX2NvbE5vZGVzW2NvbHVtbk51bWJlcl07XHJcbiAgICAgICAgcmV0dXJuIGNvbE5vZGUgJiYgY29sTm9kZS5hdHRyaWJ1dGVzLnN0eWxlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbCBhIGNhbGxiYWNrIGZvciBlYWNoIGNvbHVtbiBudW1iZXIgdGhhdCBoYXMgYSBub2RlIGRlZmluZWQgZm9yIGl0LlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgLSBUaGUgY2FsbGJhY2suXHJcbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gICAgICogQGlnbm9yZVxyXG4gICAgICovXHJcbiAgICBmb3JFYWNoRXhpc3RpbmdDb2x1bW5OdW1iZXIoY2FsbGJhY2spIHtcclxuICAgICAgICBfLmZvckVhY2godGhpcy5fY29sTm9kZXMsIChub2RlLCBjb2x1bW5OdW1iZXIpID0+IHtcclxuICAgICAgICAgICAgaWYgKCFub2RlKSByZXR1cm47XHJcbiAgICAgICAgICAgIGNhbGxiYWNrKGNvbHVtbk51bWJlcik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsIGEgY2FsbGJhY2sgZm9yIGVhY2ggZXhpc3Rpbmcgcm93LlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgLSBUaGUgY2FsbGJhY2suXHJcbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gICAgICogQGlnbm9yZVxyXG4gICAgICovXHJcbiAgICBmb3JFYWNoRXhpc3RpbmdSb3coY2FsbGJhY2spIHtcclxuICAgICAgICBfLmZvckVhY2godGhpcy5fcm93cywgKHJvdywgcm93TnVtYmVyKSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChyb3cpIGNhbGxiYWNrKHJvdywgcm93TnVtYmVyKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXQgdGhlIGh5cGVybGluayBhdHRhY2hlZCB0byB0aGUgY2VsbCB3aXRoIHRoZSBnaXZlbiBhZGRyZXNzLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGFkZHJlc3MgLSBUaGUgYWRkcmVzcyBvZiB0aGUgaHlwZXJsaW5rZWQgY2VsbC5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8dW5kZWZpbmVkfSBUaGUgaHlwZXJsaW5rIG9yIHVuZGVmaW5lZCBpZiBub3Qgc2V0LlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXQgdGhlIGh5cGVybGluayBvbiB0aGUgY2VsbCB3aXRoIHRoZSBnaXZlbiBhZGRyZXNzLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGFkZHJlc3MgLSBUaGUgYWRkcmVzcyBvZiB0aGUgaHlwZXJsaW5rZWQgY2VsbC5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBoeXBlcmxpbmsgLSBUaGUgaHlwZXJsaW5rIHRvIHNldCBvciB1bmRlZmluZWQgdG8gY2xlYXIuXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtpbnRlcm5hbF0gLSBUaGUgZmxhZyB0byBmb3JjZSBoeXBlcmxpbmsgdG8gYmUgaW50ZXJuYWwuIElmIHRydWUsIHRoZW4gYXV0b2RldGVjdCBpcyBza2lwcGVkLlxyXG4gICAgICogQHJldHVybnMge1NoZWV0fSBUaGUgc2hlZXQuXHJcbiAgICAgKi8vKipcclxuICAgICAqIFNldCB0aGUgaHlwZXJsaW5rIG9uIHRoZSBjZWxsIHdpdGggdGhlIGdpdmVuIGFkZHJlc3MuIElmIG9wdHMgaXMgYSBDZWxsIGFuIGludGVybmFsIGh5cGVybGluayBpcyBhZGRlZC5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhZGRyZXNzIC0gVGhlIGFkZHJlc3Mgb2YgdGhlIGh5cGVybGlua2VkIGNlbGwuXHJcbiAgICAgKiBAcGFyYW0ge29iamVjdHxDZWxsfSBvcHRzIC0gT3B0aW9ucy5cclxuICAgICAqIEByZXR1cm5zIHtTaGVldH0gVGhlIHNoZWV0LlxyXG4gICAgICogQGlnbm9yZVxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXQgdGhlIGh5cGVybGluayBvbiB0aGUgY2VsbCB3aXRoIHRoZSBnaXZlbiBhZGRyZXNzIGFuZCBvcHRpb25zLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGFkZHJlc3MgLSBUaGUgYWRkcmVzcyBvZiB0aGUgaHlwZXJsaW5rZWQgY2VsbC5cclxuICAgICAqIEBwYXJhbSB7e318Q2VsbH0gb3B0cyAtIE9wdGlvbnMgb3IgQ2VsbC4gSWYgb3B0cyBpcyBhIENlbGwgdGhlbiBhbiBpbnRlcm5hbCBoeXBlcmxpbmsgaXMgYWRkZWQuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xDZWxsfSBbb3B0cy5oeXBlcmxpbmtdIC0gVGhlIGh5cGVybGluayB0byBzZXQsIGNhbiBiZSBhIENlbGwgb3IgYW4gaW50ZXJuYWwvZXh0ZXJuYWwgc3RyaW5nLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLnRvb2x0aXBdIC0gQWRkaXRpb25hbCB0ZXh0IHRvIGhlbHAgdGhlIHVzZXIgdW5kZXJzdGFuZCBtb3JlIGFib3V0IHRoZSBoeXBlcmxpbmsuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMuZW1haWxdIC0gRW1haWwgYWRkcmVzcywgaWdub3JlZCBpZiBvcHRzLmh5cGVybGluayBpcyBzZXQuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMuZW1haWxTdWJqZWN0XSAtIEVtYWlsIHN1YmplY3QsIGlnbm9yZWQgaWYgb3B0cy5oeXBlcmxpbmsgaXMgc2V0LlxyXG4gICAgICogQHJldHVybnMge1NoZWV0fSBUaGUgc2hlZXQuXHJcbiAgICAgKi9cclxuICAgIGh5cGVybGluaygpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEFyZ0hhbmRsZXIoJ1NoZWV0Lmh5cGVybGluaycpXHJcbiAgICAgICAgICAgIC5jYXNlKCdzdHJpbmcnLCBhZGRyZXNzID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGh5cGVybGlua05vZGUgPSB0aGlzLl9oeXBlcmxpbmtzW2FkZHJlc3NdO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFoeXBlcmxpbmtOb2RlKSByZXR1cm47XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZWxhdGlvbnNoaXAgPSB0aGlzLl9yZWxhdGlvbnNoaXBzLmZpbmRCeUlkKGh5cGVybGlua05vZGUuYXR0cmlidXRlc1sncjppZCddKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZWxhdGlvbnNoaXAgJiYgcmVsYXRpb25zaGlwLmF0dHJpYnV0ZXMuVGFyZ2V0O1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZShbJ3N0cmluZycsICduaWwnXSwgYWRkcmVzcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBkZWxldGUgcmVsYXRpb25zaGlwXHJcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5faHlwZXJsaW5rc1thZGRyZXNzXTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZShbJ3N0cmluZycsICdzdHJpbmcnXSwgKGFkZHJlc3MsIGh5cGVybGluaykgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaHlwZXJsaW5rKGFkZHJlc3MsIGh5cGVybGluaywgZmFsc2UpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZShbJ3N0cmluZycsICdzdHJpbmcnLCAnYm9vbGVhbiddLCAoYWRkcmVzcywgaHlwZXJsaW5rLCBpbnRlcm5hbCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaXNIeXBlcmxpbmtJbnRlcm5hbEFkZHJlc3MgPSBpbnRlcm5hbCB8fCBhZGRyZXNzQ29udmVydGVyLmZyb21BZGRyZXNzKGh5cGVybGluayk7XHJcbiAgICAgICAgICAgICAgICBsZXQgbm9kZUF0dHJpYnV0ZXM7XHJcbiAgICAgICAgICAgICAgICBpZiAoaXNIeXBlcmxpbmtJbnRlcm5hbEFkZHJlc3MpIHtcclxuICAgICAgICAgICAgICAgICAgICBub2RlQXR0cmlidXRlcyA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmOiBhZGRyZXNzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbjogaHlwZXJsaW5rLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5OiBoeXBlcmxpbmtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCByZWxhdGlvbnNoaXAgPSB0aGlzLl9yZWxhdGlvbnNoaXBzLmFkZChcImh5cGVybGlua1wiLCBoeXBlcmxpbmssIFwiRXh0ZXJuYWxcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgbm9kZUF0dHJpYnV0ZXMgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZjogYWRkcmVzcyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgJ3I6aWQnOiByZWxhdGlvbnNoaXAuYXR0cmlidXRlcy5JZFxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9oeXBlcmxpbmtzW2FkZHJlc3NdID0ge1xyXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICdoeXBlcmxpbmsnLFxyXG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IG5vZGVBdHRyaWJ1dGVzLFxyXG4gICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuOiBbXVxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZShbJ3N0cmluZycsICdvYmplY3QnXSwgKGFkZHJlc3MsIG9wdHMpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChvcHRzIGluc3RhbmNlb2YgQ2VsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNlbGwgPSBvcHRzO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGh5cGVybGluayA9IGNlbGwuYWRkcmVzcyh7IGluY2x1ZGVTaGVldE5hbWU6IHRydWUgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oeXBlcmxpbmsoYWRkcmVzcywgaHlwZXJsaW5rLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAob3B0cy5oeXBlcmxpbmspIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmh5cGVybGluayhhZGRyZXNzLCBvcHRzLmh5cGVybGluayk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG9wdHMuZW1haWwpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbWFpbCA9IG9wdHMuZW1haWw7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3ViamVjdCA9IG9wdHMuZW1haWxTdWJqZWN0IHx8ICcnO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaHlwZXJsaW5rKGFkZHJlc3MsIGVuY29kZVVSSShgbWFpbHRvOiR7ZW1haWx9P3N1YmplY3Q9JHtzdWJqZWN0fWApKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNvbnN0IGh5cGVybGlua05vZGUgPSB0aGlzLl9oeXBlcmxpbmtzW2FkZHJlc3NdO1xyXG4gICAgICAgICAgICAgICAgaWYgKGh5cGVybGlua05vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAob3B0cy50b29sdGlwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGh5cGVybGlua05vZGUuYXR0cmlidXRlcy50b29sdGlwID0gb3B0cy50b29sdGlwO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuaGFuZGxlKGFyZ3VtZW50cyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbmNyZW1lbnQgYW5kIHJldHVybiB0aGUgbWF4IHNoYXJlZCBmb3JtdWxhIElELlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVGhlIG5ldyBtYXggc2hhcmVkIGZvcm11bGEgSUQuXHJcbiAgICAgKiBAaWdub3JlXHJcbiAgICAgKi9cclxuICAgIGluY3JlbWVudE1heFNoYXJlZEZvcm11bGFJZCgpIHtcclxuICAgICAgICByZXR1cm4gKyt0aGlzLl9tYXhTaGFyZWRGb3JtdWxhSWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXQgYSB2YWx1ZSBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGNlbGxzIGluIHRoZSBnaXZlbiBhZGRyZXNzIGFyZSBtZXJnZWQuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYWRkcmVzcyAtIFRoZSBhZGRyZXNzIHRvIGNoZWNrLlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgbWVyZ2VkLCBmYWxzZSBpZiBub3QgbWVyZ2VkLlxyXG4gICAgICogQGlnbm9yZVxyXG4gICAgICovLyoqXHJcbiAgICAgKiBNZXJnZS91bm1lcmdlIGNlbGxzIGJ5IGFkZGluZy9yZW1vdmluZyBhIG1lcmdlQ2VsbCBlbnRyeS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhZGRyZXNzIC0gVGhlIGFkZHJlc3MgdG8gbWVyZ2UuXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IG1lcmdlZCAtIFRydWUgdG8gbWVyZ2UsIGZhbHNlIHRvIHVubWVyZ2UuXHJcbiAgICAgKiBAcmV0dXJucyB7U2hlZXR9IFRoZSBzaGVldC5cclxuICAgICAqIEBpZ25vcmVcclxuICAgICAqL1xyXG4gICAgbWVyZ2VkKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQXJnSGFuZGxlcignU2hlZXQubWVyZ2UnKVxyXG4gICAgICAgICAgICAuY2FzZSgnc3RyaW5nJywgYWRkcmVzcyA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbWVyZ2VDZWxscy5oYXNPd25Qcm9wZXJ0eShhZGRyZXNzKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoWydzdHJpbmcnLCAnKiddLCAoYWRkcmVzcywgbWVyZ2UpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChtZXJnZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX21lcmdlQ2VsbHNbYWRkcmVzc10gPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdtZXJnZUNlbGwnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7IHJlZjogYWRkcmVzcyB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbjogW11cclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5fbWVyZ2VDZWxsc1thZGRyZXNzXTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmhhbmRsZShhcmd1bWVudHMpO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgYSBPYmplY3Qgb3IgdW5kZWZpbmVkIG9mIHRoZSBjZWxscyBpbiB0aGUgZ2l2ZW4gYWRkcmVzcy5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhZGRyZXNzIC0gVGhlIGFkZHJlc3MgdG8gY2hlY2suXHJcbiAgICAgKiBAcmV0dXJucyB7b2JqZWN0fGJvb2xlYW59IE9iamVjdCBvciBmYWxzZSBpZiBub3Qgc2V0XHJcbiAgICAgKiBAaWdub3JlXHJcbiAgICAgKi8vKipcclxuICAgICAqIFJlbW92ZXMgZGF0YVZhbGlkYXRpb24gYXQgdGhlIGdpdmVuIGFkZHJlc3NcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhZGRyZXNzIC0gVGhlIGFkZHJlc3MgdG8gcmVtb3ZlLlxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBvYmogLSBmYWxzZSB0byBkZWxldGUuXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiByZW1vdmVkLlxyXG4gICAgICogQGlnbm9yZVxyXG4gICAgICovLyoqXHJcbiAgICAgKiBBZGQgZGF0YVZhbGlkYXRpb24gdG8gY2VsbHMgYXQgdGhlIGdpdmVuIGFkZHJlc3MgaWYgb2JqZWN0IG9yIHN0cmluZ1xyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGFkZHJlc3MgLSBUaGUgYWRkcmVzcyB0byBzZXQuXHJcbiAgICAgKiBAcGFyYW0ge29iamVjdHxzdHJpbmd9IG9iaiAtIE9iamVjdCBvciBTdHJpbmcgdG8gc2V0XHJcbiAgICAgKiBAcmV0dXJucyB7U2hlZXR9IFRoZSBzaGVldC5cclxuICAgICAqIEBpZ25vcmVcclxuICAgICAqL1xyXG4gICAgZGF0YVZhbGlkYXRpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBcmdIYW5kbGVyKCdTaGVldC5kYXRhVmFsaWRhdGlvbicpXHJcbiAgICAgICAgICAgIC5jYXNlKCdzdHJpbmcnLCBhZGRyZXNzID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9kYXRhVmFsaWRhdGlvbnNbYWRkcmVzc10pIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiB0aGlzLl9kYXRhVmFsaWRhdGlvbnNbYWRkcmVzc10uYXR0cmlidXRlcy50eXBlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhbGxvd0JsYW5rOiB0aGlzLl9kYXRhVmFsaWRhdGlvbnNbYWRkcmVzc10uYXR0cmlidXRlcy5hbGxvd0JsYW5rLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzaG93SW5wdXRNZXNzYWdlOiB0aGlzLl9kYXRhVmFsaWRhdGlvbnNbYWRkcmVzc10uYXR0cmlidXRlcy5zaG93SW5wdXRNZXNzYWdlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9tcHQ6IHRoaXMuX2RhdGFWYWxpZGF0aW9uc1thZGRyZXNzXS5hdHRyaWJ1dGVzLnByb21wdCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvbXB0VGl0bGU6IHRoaXMuX2RhdGFWYWxpZGF0aW9uc1thZGRyZXNzXS5hdHRyaWJ1dGVzLnByb21wdFRpdGxlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzaG93RXJyb3JNZXNzYWdlOiB0aGlzLl9kYXRhVmFsaWRhdGlvbnNbYWRkcmVzc10uYXR0cmlidXRlcy5zaG93RXJyb3JNZXNzYWdlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogdGhpcy5fZGF0YVZhbGlkYXRpb25zW2FkZHJlc3NdLmF0dHJpYnV0ZXMuZXJyb3IsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yVGl0bGU6IHRoaXMuX2RhdGFWYWxpZGF0aW9uc1thZGRyZXNzXS5hdHRyaWJ1dGVzLmVycm9yVGl0bGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdG9yOiB0aGlzLl9kYXRhVmFsaWRhdGlvbnNbYWRkcmVzc10uYXR0cmlidXRlcy5vcGVyYXRvcixcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybXVsYTE6IHRoaXMuX2RhdGFWYWxpZGF0aW9uc1thZGRyZXNzXS5jaGlsZHJlblswXS5jaGlsZHJlblswXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybXVsYTI6IHRoaXMuX2RhdGFWYWxpZGF0aW9uc1thZGRyZXNzXS5jaGlsZHJlblsxXSA/IHRoaXMuX2RhdGFWYWxpZGF0aW9uc1thZGRyZXNzXS5jaGlsZHJlblsxXS5jaGlsZHJlblswXSA6IHVuZGVmaW5lZFxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoWydzdHJpbmcnLCAnYm9vbGVhbiddLCAoYWRkcmVzcywgb2JqKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fZGF0YVZhbGlkYXRpb25zW2FkZHJlc3NdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9iaiA9PT0gZmFsc2UpIHJldHVybiBkZWxldGUgdGhpcy5fZGF0YVZhbGlkYXRpb25zW2FkZHJlc3NdO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKFsnc3RyaW5nJywgJyonXSwgKGFkZHJlc3MsIG9iaikgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmogPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZGF0YVZhbGlkYXRpb25zW2FkZHJlc3NdID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAnZGF0YVZhbGlkYXRpb24nLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnbGlzdCcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxvd0JsYW5rOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3dJbnB1dE1lc3NhZ2U6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvbXB0OiAnJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb21wdFRpdGxlOiAnJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3dFcnJvck1lc3NhZ2U6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3I6ICcnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JUaXRsZTogJycsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRvcjogJycsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcXJlZjogYWRkcmVzc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbjogW1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdmb3JtdWxhMScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXRycmlidXRlczoge30sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW46IFtvYmpdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdmb3JtdWxhMicsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXRycmlidXRlczoge30sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW46IFsnJ11cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgXVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBvYmogPT09ICdvYmplY3QnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZGF0YVZhbGlkYXRpb25zW2FkZHJlc3NdID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAnZGF0YVZhbGlkYXRpb24nLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBvYmoudHlwZSA/IG9iai50eXBlIDogJ2xpc3QnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsb3dCbGFuazogb2JqLmFsbG93QmxhbmssXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG93SW5wdXRNZXNzYWdlOiBvYmouc2hvd0lucHV0TWVzc2FnZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb21wdDogb2JqLnByb21wdCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb21wdFRpdGxlOiBvYmoucHJvbXB0VGl0bGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG93RXJyb3JNZXNzYWdlOiBvYmouc2hvd0Vycm9yTWVzc2FnZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yOiBvYmouZXJyb3IsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvclRpdGxlOiBvYmouZXJyb3JUaXRsZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdG9yOiBvYmoub3BlcmF0b3IsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcXJlZjogYWRkcmVzc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbjogW1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdmb3JtdWxhMScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXRycmlidXRlczoge30sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW46IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmZvcm11bGExXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAnZm9ybXVsYTInLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0cnJpYnV0ZXM6IHt9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuOiBbXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5mb3JtdWxhMlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgXVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmhhbmRsZShhcmd1bWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydCB0aGUgc2hlZXQgdG8gYSBjb2xsZWN0aW9uIG9mIFhNTCBvYmplY3RzLlxyXG4gICAgICogQHJldHVybnMge3t9fSBUaGUgWE1MIGZvcm1zLlxyXG4gICAgICogQGlnbm9yZVxyXG4gICAgICovXHJcbiAgICB0b1htbHMoKSB7XHJcbiAgICAgICAgLy8gU2hhbGxvdyBjbG9uZSB0aGUgbm9kZSBzbyB3ZSBkb24ndCBoYXZlIHRvIHJlbW92ZSB0aGVzZSBjaGlsZHJlbiBsYXRlciBpZiB0aGV5IGRvbid0IGJlbG9uZy5cclxuICAgICAgICBjb25zdCBub2RlID0gXy5jbG9uZSh0aGlzLl9ub2RlKTtcclxuICAgICAgICBub2RlLmNoaWxkcmVuID0gbm9kZS5jaGlsZHJlbi5zbGljZSgpO1xyXG5cclxuICAgICAgICAvLyBBZGQgdGhlIGNvbHVtbnMgaWYgbmVlZGVkLlxyXG4gICAgICAgIHRoaXMuX2NvbHNOb2RlLmNoaWxkcmVuID0gXy5maWx0ZXIodGhpcy5fY29sTm9kZXMsIChjb2xOb2RlLCBpKSA9PiB7XHJcbiAgICAgICAgICAgIC8vIENvbHVtbnMgc2hvdWxkIG9ubHkgYmUgcHJlc2VudCBpZiB0aGV5IGhhdmUgYXR0cmlidXRlcyBvdGhlciB0aGFuIG1pbi9tYXguXHJcbiAgICAgICAgICAgIHJldHVybiBjb2xOb2RlICYmIGkgPT09IGNvbE5vZGUuYXR0cmlidXRlcy5taW4gJiYgT2JqZWN0LmtleXMoY29sTm9kZS5hdHRyaWJ1dGVzKS5sZW5ndGggPiAyO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGlmICh0aGlzLl9jb2xzTm9kZS5jaGlsZHJlbi5sZW5ndGgpIHtcclxuICAgICAgICAgICAgeG1scS5pbnNlcnRJbk9yZGVyKG5vZGUsIHRoaXMuX2NvbHNOb2RlLCBub2RlT3JkZXIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQWRkIHRoZSBoeXBlcmxpbmtzIGlmIG5lZWRlZC5cclxuICAgICAgICB0aGlzLl9oeXBlcmxpbmtzTm9kZS5jaGlsZHJlbiA9IF8udmFsdWVzKHRoaXMuX2h5cGVybGlua3MpO1xyXG4gICAgICAgIGlmICh0aGlzLl9oeXBlcmxpbmtzTm9kZS5jaGlsZHJlbi5sZW5ndGgpIHtcclxuICAgICAgICAgICAgeG1scS5pbnNlcnRJbk9yZGVyKG5vZGUsIHRoaXMuX2h5cGVybGlua3NOb2RlLCBub2RlT3JkZXIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQWRkIHRoZSBwcmludE9wdGlvbnMgaWYgbmVlZGVkLlxyXG4gICAgICAgIGlmICh0aGlzLl9wcmludE9wdGlvbnNOb2RlKSB7XHJcbiAgICAgICAgICAgIGlmIChPYmplY3Qua2V5cyh0aGlzLl9wcmludE9wdGlvbnNOb2RlLmF0dHJpYnV0ZXMpLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgeG1scS5pbnNlcnRJbk9yZGVyKG5vZGUsIHRoaXMuX3ByaW50T3B0aW9uc05vZGUsIG5vZGVPcmRlcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEFkZCB0aGUgcGFnZU1hcmdpbnMgaWYgbmVlZGVkLlxyXG4gICAgICAgIGlmICh0aGlzLl9wYWdlTWFyZ2luc05vZGUgJiYgdGhpcy5fcGFnZU1hcmdpbnNQcmVzZXROYW1lKSB7XHJcbiAgICAgICAgICAgIC8vIENsb25lIHRvIHByZXNlcnZlIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoaXMgc2hlZXQuXHJcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkTm9kZSA9IF8uY2xvbmUodGhpcy5fcGFnZU1hcmdpbnNOb2RlKTtcclxuICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKHRoaXMuX3BhZ2VNYXJnaW5zTm9kZS5hdHRyaWJ1dGVzKS5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIC8vIEZpbGwgaW4gYW55IG1pc3NpbmcgYXR0cmlidXRlIHZhbHVlcyB3aXRoIHByZXNldHMuXHJcbiAgICAgICAgICAgICAgICBjaGlsZE5vZGUuYXR0cmlidXRlcyA9IF8uYXNzaWduKFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhZ2VNYXJnaW5zUHJlc2V0c1t0aGlzLl9wYWdlTWFyZ2luc1ByZXNldE5hbWVdLFxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhZ2VNYXJnaW5zTm9kZS5hdHRyaWJ1dGVzKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIE5vIG5lZWQgdG8gZmlsbCBpbiwgYWxsIGF0dHJpYnV0ZXMgaXMgY3VycmVudGx5IGVtcHR5LCBzaW1wbHkgcmVwbGFjZS5cclxuICAgICAgICAgICAgICAgIGNoaWxkTm9kZS5hdHRyaWJ1dGVzID0gdGhpcy5fcGFnZU1hcmdpbnNQcmVzZXRzW3RoaXMuX3BhZ2VNYXJnaW5zUHJlc2V0TmFtZV07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgeG1scS5pbnNlcnRJbk9yZGVyKG5vZGUsIGNoaWxkTm9kZSwgbm9kZU9yZGVyKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEFkZCB0aGUgbWVyZ2UgY2VsbHMgaWYgbmVlZGVkLlxyXG4gICAgICAgIHRoaXMuX21lcmdlQ2VsbHNOb2RlLmNoaWxkcmVuID0gXy52YWx1ZXModGhpcy5fbWVyZ2VDZWxscyk7XHJcbiAgICAgICAgaWYgKHRoaXMuX21lcmdlQ2VsbHNOb2RlLmNoaWxkcmVuLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB4bWxxLmluc2VydEluT3JkZXIobm9kZSwgdGhpcy5fbWVyZ2VDZWxsc05vZGUsIG5vZGVPcmRlcik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBBZGQgdGhlIERhdGFWYWxpZGF0aW9uIGNlbGxzIGlmIG5lZWRlZC5cclxuICAgICAgICB0aGlzLl9kYXRhVmFsaWRhdGlvbnNOb2RlLmNoaWxkcmVuID0gXy52YWx1ZXModGhpcy5fZGF0YVZhbGlkYXRpb25zKTtcclxuICAgICAgICBpZiAodGhpcy5fZGF0YVZhbGlkYXRpb25zTm9kZS5jaGlsZHJlbi5sZW5ndGgpIHtcclxuICAgICAgICAgICAgeG1scS5pbnNlcnRJbk9yZGVyKG5vZGUsIHRoaXMuX2RhdGFWYWxpZGF0aW9uc05vZGUsIG5vZGVPcmRlcik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5fYXV0b0ZpbHRlcikge1xyXG4gICAgICAgICAgICB4bWxxLmluc2VydEluT3JkZXIobm9kZSwge1xyXG4gICAgICAgICAgICAgICAgbmFtZTogXCJhdXRvRmlsdGVyXCIsXHJcbiAgICAgICAgICAgICAgICBjaGlsZHJlbjogW10sXHJcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVmOiB0aGlzLl9hdXRvRmlsdGVyLmFkZHJlc3MoKVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LCBub2RlT3JkZXIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQWRkIHRoZSBQYWdlQnJlYWtzIG5vZGVzIGlmIG5lZWRlZC5cclxuICAgICAgICBbJ2NvbEJyZWFrcycsICdyb3dCcmVha3MnXS5mb3JFYWNoKG5hbWUgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBicmVha3MgPSB0aGlzW2BfJHtuYW1lfU5vZGVgXTtcclxuICAgICAgICAgICAgaWYgKGJyZWFrcy5hdHRyaWJ1dGVzLmNvdW50KSB7XHJcbiAgICAgICAgICAgICAgICB4bWxxLmluc2VydEluT3JkZXIobm9kZSwgYnJlYWtzLCBub2RlT3JkZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIGlkOiB0aGlzLl9pZE5vZGUsXHJcbiAgICAgICAgICAgIHNoZWV0OiBub2RlLFxyXG4gICAgICAgICAgICByZWxhdGlvbnNoaXBzOiB0aGlzLl9yZWxhdGlvbnNoaXBzXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFVwZGF0ZSB0aGUgbWF4IHNoYXJlZCBmb3JtdWxhIElEIHRvIHRoZSBnaXZlbiB2YWx1ZSBpZiBncmVhdGVyIHRoYW4gY3VycmVudC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzaGFyZWRGb3JtdWxhSWQgLSBUaGUgbmV3IHNoYXJlZCBmb3JtdWxhIElELlxyXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICAgICAqIEBpZ25vcmVcclxuICAgICAqL1xyXG4gICAgdXBkYXRlTWF4U2hhcmVkRm9ybXVsYUlkKHNoYXJlZEZvcm11bGFJZCkge1xyXG4gICAgICAgIGlmIChzaGFyZWRGb3JtdWxhSWQgPiB0aGlzLl9tYXhTaGFyZWRGb3JtdWxhSWQpIHtcclxuICAgICAgICAgICAgdGhpcy5fbWF4U2hhcmVkRm9ybXVsYUlkID0gc2hhcmVkRm9ybXVsYUlkO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldCB0aGUgcHJpbnQgb3B0aW9uIGdpdmVuIGEgdmFsaWQgcHJpbnQgb3B0aW9uIGF0dHJpYnV0ZS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhdHRyaWJ1dGVOYW1lIC0gQXR0cmlidXRlIG5hbWUgb2YgdGhlIHByaW50T3B0aW9ucy5cclxuICAgICAqICAgZ3JpZExpbmVzIC0gVXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIGdyaWRMaW5lc1NldC4gSWYgYm90aCBncmlkTGluZXMgYW5kIGdyaWRsaW5lc1NldCBhcmUgdHJ1ZSwgdGhlbiBncmlkIGxpbmVzIHNoYWxsIHByaW50LiBPdGhlcndpc2UsIHRoZXkgc2hhbGwgbm90IChpLmUuLCBvbmUgb3IgYm90aCBoYXZlIGZhbHNlIHZhbHVlcykuXHJcbiAgICAgKiAgIGdyaWRMaW5lc1NldCAtIFVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCBncmlkTGluZXMuIElmIGJvdGggZ3JpZExpbmVzIGFuZCBncmlkTGluZXNTZXQgYXJlIHRydWUsIHRoZW4gZ3JpZCBsaW5lcyBzaGFsbCBwcmludC4gT3RoZXJ3aXNlLCB0aGV5IHNoYWxsIG5vdCAoaS5lLiwgb25lIG9yIGJvdGggaGF2ZSBmYWxzZSB2YWx1ZXMpLlxyXG4gICAgICogICBoZWFkaW5ncyAtIFByaW50IHJvdyBhbmQgY29sdW1uIGhlYWRpbmdzLlxyXG4gICAgICogICBob3Jpem9udGFsQ2VudGVyZWQgLSBDZW50ZXIgb24gcGFnZSBob3Jpem9udGFsbHkgd2hlbiBwcmludGluZy5cclxuICAgICAqICAgdmVydGljYWxDZW50ZXJlZCAtIENlbnRlciBvbiBwYWdlIHZlcnRpY2FsbHkgd2hlbiBwcmludGluZy5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXQgdGhlIHByaW50IG9wdGlvbiBnaXZlbiBhIHZhbGlkIHByaW50IG9wdGlvbiBhdHRyaWJ1dGUgYW5kIGEgdmFsdWUuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYXR0cmlidXRlTmFtZSAtIEF0dHJpYnV0ZSBuYW1lIG9mIHRoZSBwcmludE9wdGlvbnMuIFNlZSBnZXQgcHJpbnQgb3B0aW9uIGZvciBsaXN0IG9mIHZhbGlkIGF0dHJpYnV0ZXMuXHJcbiAgICAgKiBAcGFyYW0ge3VuZGVmaW5lZHxib29sZWFufSBhdHRyaWJ1dGVFbmFibGVkIC0gSWYgYHVuZGVmaW5lZGAgb3IgYGZhbHNlYCB0aGVuIHRoZSBhdHRyaWJ1dGUgaXMgcmVtb3ZlZCwgb3RoZXJ3aXNlIHRoZSBwcmludCBvcHRpb24gaXMgZW5hYmxlZC5cclxuICAgICAqIEByZXR1cm5zIHtTaGVldH0gVGhlIHNoZWV0LlxyXG4gICAgICovXHJcbiAgICBwcmludE9wdGlvbnMoKSB7XHJcbiAgICAgICAgY29uc3Qgc3VwcG9ydGVkQXR0cmlidXRlTmFtZXMgPSBbXHJcbiAgICAgICAgICAgICdncmlkTGluZXMnLCAnZ3JpZExpbmVzU2V0JywgJ2hlYWRpbmdzJywgJ2hvcml6b250YWxDZW50ZXJlZCcsICd2ZXJ0aWNhbENlbnRlcmVkJ107XHJcbiAgICAgICAgY29uc3QgY2hlY2tBdHRyaWJ1dGVOYW1lID0gdGhpcy5fZ2V0Q2hlY2tBdHRyaWJ1dGVOYW1lSGVscGVyKCdwcmludE9wdGlvbnMnLCBzdXBwb3J0ZWRBdHRyaWJ1dGVOYW1lcyk7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBcmdIYW5kbGVyKCdTaGVldC5wcmludE9wdGlvbnMnKVxyXG4gICAgICAgICAgICAuY2FzZShbJ3N0cmluZyddLCBhdHRyaWJ1dGVOYW1lID0+IHtcclxuICAgICAgICAgICAgICAgIGNoZWNrQXR0cmlidXRlTmFtZShhdHRyaWJ1dGVOYW1lKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9wcmludE9wdGlvbnNOb2RlLmF0dHJpYnV0ZXNbYXR0cmlidXRlTmFtZV0gPT09IDE7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKFsnc3RyaW5nJywgJ25pbCddLCBhdHRyaWJ1dGVOYW1lID0+IHtcclxuICAgICAgICAgICAgICAgIGNoZWNrQXR0cmlidXRlTmFtZShhdHRyaWJ1dGVOYW1lKTtcclxuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9wcmludE9wdGlvbnNOb2RlLmF0dHJpYnV0ZXNbYXR0cmlidXRlTmFtZV07XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoWydzdHJpbmcnLCAnYm9vbGVhbiddLCAoYXR0cmlidXRlTmFtZSwgYXR0cmlidXRlRW5hYmxlZCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY2hlY2tBdHRyaWJ1dGVOYW1lKGF0dHJpYnV0ZU5hbWUpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZUVuYWJsZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wcmludE9wdGlvbnNOb2RlLmF0dHJpYnV0ZXNbYXR0cmlidXRlTmFtZV0gPSAxO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wcmludE9wdGlvbnMoYXR0cmlidXRlTmFtZSwgdW5kZWZpbmVkKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmhhbmRsZShhcmd1bWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0IHRoZSBwcmludCBvcHRpb24gZm9yIHRoZSBncmlkTGluZXMgYXR0cmlidXRlIHZhbHVlLlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi8vKipcclxuICAgICAqIFNldCB0aGUgcHJpbnQgb3B0aW9uIGZvciB0aGUgZ3JpZExpbmVzIGF0dHJpYnV0ZSB2YWx1ZS5cclxuICAgICAqIEBwYXJhbSB7dW5kZWZpbmVkfGJvb2xlYW59IGVuYWJsZWQgLSBJZiBgdW5kZWZpbmVkYCBvciBgZmFsc2VgIHRoZW4gYXR0cmlidXRlIGlzIHJlbW92ZWQsIG90aGVyd2lzZSBncmlkTGluZXMgaXMgZW5hYmxlZC5cclxuICAgICAqIEByZXR1cm5zIHtTaGVldH0gVGhlIHNoZWV0LlxyXG4gICAgICovXHJcbiAgICBwcmludEdyaWRMaW5lcygpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEFyZ0hhbmRsZXIoJ1NoZWV0LmdyaWRMaW5lcycpXHJcbiAgICAgICAgICAgIC5jYXNlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnByaW50T3B0aW9ucygnZ3JpZExpbmVzJykgJiYgdGhpcy5wcmludE9wdGlvbnMoJ2dyaWRMaW5lc1NldCcpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZShbJ25pbCddLCAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnByaW50T3B0aW9ucygnZ3JpZExpbmVzJywgdW5kZWZpbmVkKTtcclxuICAgICAgICAgICAgICAgIHRoaXMucHJpbnRPcHRpb25zKCdncmlkTGluZXNTZXQnLCB1bmRlZmluZWQpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKFsnYm9vbGVhbiddLCBlbmFibGVkID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMucHJpbnRPcHRpb25zKCdncmlkTGluZXMnLCBlbmFibGVkKTtcclxuICAgICAgICAgICAgICAgIHRoaXMucHJpbnRPcHRpb25zKCdncmlkTGluZXNTZXQnLCBlbmFibGVkKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuaGFuZGxlKGFyZ3VtZW50cyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXQgdGhlIHBhZ2UgbWFyZ2luIGdpdmVuIGEgdmFsaWQgYXR0cmlidXRlIG5hbWUuXHJcbiAgICAgKiBJZiB0aGUgdmFsdWUgaXMgbm90IHlldCBkZWZpbmVkLCB0aGVuIGl0IHdpbGwgcmV0dXJuIHRoZSBjdXJyZW50IHByZXNldCB2YWx1ZS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhdHRyaWJ1dGVOYW1lIC0gQXR0cmlidXRlIG5hbWUgb2YgdGhlIHBhZ2VNYXJnaW5zLlxyXG4gICAgICogICAgIGxlZnQgLSBMZWZ0IFBhZ2UgTWFyZ2luIGluIGluY2hlcy5cclxuICAgICAqICAgICByaWdodCAtIFJpZ2h0IHBhZ2UgbWFyZ2luIGluIGluY2hlcy5cclxuICAgICAqICAgICB0b3AgLSBUb3AgUGFnZSBNYXJnaW4gaW4gaW5jaGVzLlxyXG4gICAgICogICAgIGJ1dHRvbSAtIEJvdHRvbSBQYWdlIE1hcmdpbiBpbiBpbmNoZXMuXHJcbiAgICAgKiAgICAgZm9vdGVyIC0gRm9vdGVyIFBhZ2UgTWFyZ2luIGluIGluY2hlcy5cclxuICAgICAqICAgICBoZWFkZXIgLSBIZWFkZXIgUGFnZSBNYXJnaW4gaW4gaW5jaGVzLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gdGhlIGF0dHJpYnV0ZSB2YWx1ZS5cclxuICAgICAqLy8qKlxyXG4gICAgICogU2V0IHRoZSBwYWdlIG1hcmdpbiAob3Igb3ZlcnJpZGUgdGhlIHByZXNldCkgZ2l2ZW4gYW4gYXR0cmlidXRlIG5hbWUgYW5kIGEgdmFsdWUuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYXR0cmlidXRlTmFtZSAtIEF0dHJpYnV0ZSBuYW1lIG9mIHRoZSBwYWdlTWFyZ2lucy4gU2VlIGdldCBwYWdlIG1hcmdpbiBmb3IgbGlzdCBvZiB2YWxpZCBhdHRyaWJ1dGVzLlxyXG4gICAgICogQHBhcmFtIHt1bmRlZmluZWR8bnVtYmVyfHN0cmluZ30gYXR0cmlidXRlU3RyaW5nVmFsdWUgLSBJZiBgdW5kZWZpbmVkYCB0aGVuIHNldCBiYWNrIHRvIHByZXNldCB2YWx1ZSwgb3RoZXJ3aXNlLCBzZXQgdGhlIGdpdmVuIGF0dHJpYnV0ZSB2YWx1ZS5cclxuICAgICAqIEByZXR1cm5zIHtTaGVldH0gVGhlIHNoZWV0LlxyXG4gICAgICovXHJcbiAgICBwYWdlTWFyZ2lucygpIHtcclxuICAgICAgICBpZiAodGhpcy5wYWdlTWFyZ2luc1ByZXNldCgpID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTaGVldC5wYWdlTWFyZ2luczogcHJlc2V0IGlzIHVuZGVmaW5lZC4nKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3Qgc3VwcG9ydGVkQXR0cmlidXRlTmFtZXMgPSBbXHJcbiAgICAgICAgICAgICdsZWZ0JywgJ3JpZ2h0JywgJ3RvcCcsICdib3R0b20nLCAnaGVhZGVyJywgJ2Zvb3RlciddO1xyXG4gICAgICAgIGNvbnN0IGNoZWNrQXR0cmlidXRlTmFtZSA9IHRoaXMuX2dldENoZWNrQXR0cmlidXRlTmFtZUhlbHBlcigncGFnZU1hcmdpbnMnLCBzdXBwb3J0ZWRBdHRyaWJ1dGVOYW1lcyk7XHJcbiAgICAgICAgY29uc3QgY2hlY2tSYW5nZSA9IHRoaXMuX2dldENoZWNrUmFuZ2VIZWxwZXIoJ3BhZ2VNYXJnaW5zJywgMCwgdW5kZWZpbmVkKTtcclxuICAgICAgICByZXR1cm4gbmV3IEFyZ0hhbmRsZXIoJ1NoZWV0LnBhZ2VNYXJnaW5zJylcclxuICAgICAgICAgICAgLmNhc2UoWydzdHJpbmcnXSwgYXR0cmlidXRlTmFtZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjaGVja0F0dHJpYnV0ZU5hbWUoYXR0cmlidXRlTmFtZSk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBhdHRyaWJ1dGVWYWx1ZSA9IHRoaXMuX3BhZ2VNYXJnaW5zTm9kZS5hdHRyaWJ1dGVzW2F0dHJpYnV0ZU5hbWVdO1xyXG4gICAgICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZVZhbHVlICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VGbG9hdChhdHRyaWJ1dGVWYWx1ZSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX3BhZ2VNYXJnaW5zUHJlc2V0TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUZsb2F0KHRoaXMuX3BhZ2VNYXJnaW5zUHJlc2V0c1t0aGlzLl9wYWdlTWFyZ2luc1ByZXNldE5hbWVdW2F0dHJpYnV0ZU5hbWVdKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoWydzdHJpbmcnLCAnbmlsJ10sIGF0dHJpYnV0ZU5hbWUgPT4ge1xyXG4gICAgICAgICAgICAgICAgY2hlY2tBdHRyaWJ1dGVOYW1lKGF0dHJpYnV0ZU5hbWUpO1xyXG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX3BhZ2VNYXJnaW5zTm9kZS5hdHRyaWJ1dGVzW2F0dHJpYnV0ZU5hbWVdO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKFsnc3RyaW5nJywgJ251bWJlciddLCAoYXR0cmlidXRlTmFtZSwgYXR0cmlidXRlTnVtYmVyVmFsdWUpID0+IHtcclxuICAgICAgICAgICAgICAgIGNoZWNrQXR0cmlidXRlTmFtZShhdHRyaWJ1dGVOYW1lKTtcclxuICAgICAgICAgICAgICAgIGNoZWNrUmFuZ2UoYXR0cmlidXRlTnVtYmVyVmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fcGFnZU1hcmdpbnNOb2RlLmF0dHJpYnV0ZXNbYXR0cmlidXRlTmFtZV0gPSBhdHRyaWJ1dGVOdW1iZXJWYWx1ZTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZShbJ3N0cmluZycsICdzdHJpbmcnXSwgKGF0dHJpYnV0ZU5hbWUsIGF0dHJpYnV0ZVN0cmluZ1ZhbHVlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYWdlTWFyZ2lucyhhdHRyaWJ1dGVOYW1lLCBwYXJzZUZsb2F0KGF0dHJpYnV0ZVN0cmluZ1ZhbHVlKSk7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5oYW5kbGUoYXJndW1lbnRzKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFBhZ2UgbWFyZ2lucyBwcmVzZXQgaXMgYSBzZXQgb2YgcGFnZSBtYXJnaW5zIGFzc29jaWF0ZWQgd2l0aCBhIG5hbWUuXHJcbiAgICAgKiBUaGUgcGFnZSBtYXJnaW4gcHJlc2V0IGFjdHMgYXMgYSBmYWxsYmFjayB3aGVuIG5vdCBleHBsaWNpdGx5IGRlZmluZWQgYnkgYFNoZWV0LnBhZ2VNYXJnaW5zYC5cclxuICAgICAqIElmIGEgc2hlZXQgYWxyZWFkeSBjb250YWlucyBwYWdlIG1hcmdpbnMsIGl0IGF0dGVtcHRzIHRvIGF1dG8tZGV0ZWN0LCBvdGhlcndpc2UgdGhleSBhcmUgZGVmaW5lZCBhcyB0aGUgdGVtcGxhdGUgcHJlc2V0LlxyXG4gICAgICogSWYgbm8gcGFnZSBtYXJnaW5zIGV4aXN0LCB0aGVuIHRoZSBwcmVzZXQgaXMgdW5kZWZpbmVkIGFuZCB3aWxsIG5vdCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IG9mIGBTaGVldC50b1htbHNgLlxyXG4gICAgICogQXZhaWxhYmxlIHByZXNldHMgaW5jbHVkZTogbm9ybWFsLCB3aWRlLCBuYXJyb3csIHRlbXBsYXRlLlxyXG4gICAgICpcclxuICAgICAqIEdldCB0aGUgcGFnZSBtYXJnaW5zIHByZXNldCBuYW1lLiBUaGUgcmVnaXN0ZXJlZCBuYW1lIG9mIGEgcHJlZGVmaW5lZCBzZXQgb2YgYXR0cmlidXRlcy5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBwcmVzZXQgbmFtZS5cclxuICAgICAqLy8qKlxyXG4gICAgICogU2V0IHRoZSBwYWdlIG1hcmdpbnMgcHJlc2V0IGJ5IG5hbWUsIGNsZWFyaW5nIGFueSBleGlzdGluZy90ZW1wb3JhcnkgYXR0cmlidXRlIHZhbHVlcy5cclxuICAgICAqIEBwYXJhbSB7dW5kZWZpbmVkfHN0cmluZ30gcHJlc2V0TmFtZSAtIFRoZSBwcmVzZXQgbmFtZS4gSWYgYHVuZGVmaW5lZGAsIHBhZ2UgbWFyZ2lucyB3aWxsIG5vdCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IG9mIGBTaGVldC50b1htbHNgLlxyXG4gICAgICogQHJldHVybnMge1NoZWV0fSBUaGUgc2hlZXQuXHJcbiAgICAgKi8vKipcclxuICAgICAqIFNldCBhIG5ldyBwYWdlIG1hcmdpbnMgcHJlc2V0IGJ5IG5hbWUgYW5kIGF0dHJpYnV0ZXMgb2JqZWN0LlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHByZXNldE5hbWUgLSBUaGUgcHJlc2V0IG5hbWUuXHJcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gcHJlc2V0QXR0cmlidXRlcyAtIFRoZSBwcmVzZXQgYXR0cmlidXRlcy5cclxuICAgICAqIEByZXR1cm5zIHtTaGVldH0gVGhlIHNoZWV0LlxyXG4gICAgICovXHJcbiAgICBwYWdlTWFyZ2luc1ByZXNldCgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEFyZ0hhbmRsZXIoJ1NoZWV0LnBhZ2VNYXJnaW5zUHJlc2V0JylcclxuICAgICAgICAgICAgLmNhc2UoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BhZ2VNYXJnaW5zUHJlc2V0TmFtZTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoWyduaWwnXSwgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBwcmVzZXQgb3ZlcnJpZGVzIGFuZCBleGNsdWRlIGZyb20gc2hlZXRcclxuICAgICAgICAgICAgICAgIHRoaXMuX3BhZ2VNYXJnaW5zUHJlc2V0TmFtZSA9IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgYWxsIHByZXNldCBvdmVycmlkZXNcclxuICAgICAgICAgICAgICAgIHRoaXMuX3BhZ2VNYXJnaW5zTm9kZS5hdHRyaWJ1dGVzID0ge307XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoWydzdHJpbmcnXSwgcHJlc2V0TmFtZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjaGVja1ByZXNldE5hbWUgPSB0aGlzLl9nZXRDaGVja0F0dHJpYnV0ZU5hbWVIZWxwZXIoXHJcbiAgICAgICAgICAgICAgICAgICAgJ3BhZ2VNYXJnaW5zUHJlc2V0JywgT2JqZWN0LmtleXModGhpcy5fcGFnZU1hcmdpbnNQcmVzZXRzKSk7XHJcbiAgICAgICAgICAgICAgICBjaGVja1ByZXNldE5hbWUocHJlc2V0TmFtZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gQ2hhbmdlIHRvIG5ldyBwcmVzZXRcclxuICAgICAgICAgICAgICAgIHRoaXMuX3BhZ2VNYXJnaW5zUHJlc2V0TmFtZSA9IHByZXNldE5hbWU7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBwcmVzZXQgb3ZlcnJpZGVzXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9wYWdlTWFyZ2luc05vZGUuYXR0cmlidXRlcyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKFsnc3RyaW5nJywgJ29iamVjdCddLCAocHJlc2V0TmFtZSwgcHJlc2V0QXR0cmlidXRlcykgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3BhZ2VNYXJnaW5zUHJlc2V0cy5oYXNPd25Qcm9wZXJ0eShwcmVzZXROYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU2hlZXQucGFnZU1hcmdpbnNQcmVzZXQ6IFRoZSBwcmVzZXQgJHtwcmVzZXROYW1lfSBhbHJlYWR5IGV4aXN0cyFgKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBWYWxpZGF0ZSBwcmVzZXQgYXR0cmlidXRlIGtleXMuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBwYWdlTWFyZ2luc0F0dHJpYnV0ZU5hbWVzID0gW1xyXG4gICAgICAgICAgICAgICAgICAgICdsZWZ0JywgJ3JpZ2h0JywgJ3RvcCcsICdib3R0b20nLCAnaGVhZGVyJywgJ2Zvb3RlciddO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaXNWYWxpZFByZXNldEF0dHJpYnV0ZUtleXMgPSBfLmlzRXF1YWwoXHJcbiAgICAgICAgICAgICAgICAgICAgXy5zb3J0QnkocGFnZU1hcmdpbnNBdHRyaWJ1dGVOYW1lcyksXHJcbiAgICAgICAgICAgICAgICAgICAgXy5zb3J0QnkoT2JqZWN0LmtleXMocHJlc2V0QXR0cmlidXRlcykpKTtcclxuICAgICAgICAgICAgICAgIGlmIChpc1ZhbGlkUHJlc2V0QXR0cmlidXRlS2V5cyA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFNoZWV0LnBhZ2VNYXJnaW5zUHJlc2V0OiBJbnZhbGlkIHByZXNldCBhdHRyaWJ1dGVzIGZvciBvbmUgb3Iga2V5KHMpISAtIFwiJHtPYmplY3Qua2V5cyhwcmVzZXRBdHRyaWJ1dGVzKX1cImApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIFZhbGlkYXRlIHByZXNldCBhdHRyaWJ1dGUgdmFsdWVzLlxyXG4gICAgICAgICAgICAgICAgXy5mb3JFYWNoKChhdHRyaWJ1dGVWYWx1ZSwgYXR0cmlidXRlTmFtZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGF0dHJpYnV0ZU51bWJlclZhbHVlID0gcGFyc2VGbG9hdChhdHRyaWJ1dGVWYWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF8uaXNOYU4oYXR0cmlidXRlTnVtYmVyVmFsdWUpIHx8IF8uaXNOdW1iZXIoYXR0cmlidXRlTnVtYmVyVmFsdWUpID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFNoZWV0LnBhZ2VNYXJnaW5zUHJlc2V0OiBJbnZhbGlkIHByZXNldCBhdHRyaWJ1dGUgdmFsdWUhIC0gXCIke2F0dHJpYnV0ZVZhbHVlfVwiYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gQ2hhbmdlIHRvIG5ldyBwcmVzZXRcclxuICAgICAgICAgICAgICAgIHRoaXMuX3BhZ2VNYXJnaW5zUHJlc2V0TmFtZSA9IHByZXNldE5hbWU7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBwcmVzZXQgb3ZlcnJpZGVzXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9wYWdlTWFyZ2luc05vZGUuYXR0cmlidXRlcyA9IHt9O1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIFJlZ2lzdGVyIHRoZSBwcmVzZXRcclxuICAgICAgICAgICAgICAgIHRoaXMuX3BhZ2VNYXJnaW5zUHJlc2V0c1twcmVzZXROYW1lXSA9IHByZXNldEF0dHJpYnV0ZXM7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmhhbmRsZShhcmd1bWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogaHR0cHM6Ly9kb2NzLm1pY3Jvc29mdC5jb20vZW4tdXMvZG90bmV0L2FwaS9kb2N1bWVudGZvcm1hdC5vcGVueG1sLnNwcmVhZHNoZWV0LnBhbmU/dmlldz1vcGVueG1sLTIuOC4xXHJcbiAgICAgKiBAdHlwZWRlZiB7T2JqZWN0fSBQYW5lT3B0aW9uc1xyXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IGFjdGl2ZVBhbmU9Ym90dG9tUmlnaHQgQWN0aXZlIFBhbmUuIFRoZSBwYW5lIHRoYXQgaXMgYWN0aXZlLlxyXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IHN0YXRlIFNwbGl0IFN0YXRlLiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgcGFuZSBoYXMgaG9yaXpvbnRhbCAvIHZlcnRpY2FsIHNwbGl0cyxcclxuICAgICAqIGFuZCB3aGV0aGVyIHRob3NlIHNwbGl0cyBhcmUgZnJvemVuLlxyXG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IHRvcExlZnRDZWxsIFRvcCBMZWZ0IFZpc2libGUgQ2VsbC4gTG9jYXRpb24gb2YgdGhlIHRvcCBsZWZ0IHZpc2libGUgY2VsbCBpbiB0aGUgYm90dG9tXHJcbiAgICAgKiByaWdodCBwYW5lICh3aGVuIGluIExlZnQtVG8tUmlnaHQgbW9kZSkuXHJcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0geFNwbGl0IChIb3Jpem9udGFsIFNwbGl0IFBvc2l0aW9uKSBIb3Jpem9udGFsIHBvc2l0aW9uIG9mIHRoZSBzcGxpdCwgaW4gMS8yMHRoIG9mIGEgcG9pbnQ7XHJcbiAgICAgKiAwICh6ZXJvKSBpZiBub25lLiBJZiB0aGUgcGFuZSBpcyBmcm96ZW4sIHRoaXMgdmFsdWUgaW5kaWNhdGVzIHRoZSBudW1iZXIgb2YgY29sdW1ucyB2aXNpYmxlIGluIHRoZSB0b3AgcGFuZS5cclxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB5U3BsaXQgKFZlcnRpY2FsIFNwbGl0IFBvc2l0aW9uKSBWZXJ0aWNhbCBwb3NpdGlvbiBvZiB0aGUgc3BsaXQsIGluIDEvMjB0aCBvZiBhIHBvaW50OyAwXHJcbiAgICAgKiAoemVybykgaWYgbm9uZS4gSWYgdGhlIHBhbmUgaXMgZnJvemVuLCB0aGlzIHZhbHVlIGluZGljYXRlcyB0aGUgbnVtYmVyIG9mIHJvd3MgdmlzaWJsZSBpbiB0aGUgbGVmdCBwYW5lLlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBHZXRzIHNoZWV0IHZpZXcgcGFuZSBvcHRpb25zXHJcbiAgICAgKiBAcmV0dXJuIHtQYW5lT3B0aW9uc30gc2hlZXQgdmlldyBwYW5lIG9wdGlvbnNcclxuICAgICAqLy8qKlxyXG4gICAgICogU2V0cyBzaGVldCB2aWV3IHBhbmUgb3B0aW9uc1xyXG4gICAgICogQHBhcmFtIHtQYW5lT3B0aW9uc3xudWxsfHVuZGVmaW5lZH0gcGFuZU9wdGlvbnMgc2hlZXQgdmlldyBwYW5lIG9wdGlvbnNcclxuICAgICAqIEByZXR1cm4ge1NoZWV0fSBUaGUgc2hlZXRcclxuICAgICAqL1xyXG4gICAgcGFuZXMoKSB7XHJcbiAgICAgICAgY29uc3Qgc3VwcG9ydGVkU3RhdGVzID0gWydzcGxpdCcsICdmcm96ZW4nLCAnZnJvemVuU3BsaXQnXTtcclxuICAgICAgICBjb25zdCBzdXBwb3J0ZWRBY3RpdmVQYW5lcyA9IFsnYm90dG9tTGVmdCcsICdib3R0b21SaWdodCcsICd0b3BMZWZ0JywgJ3RvcFJpZ2h0J107XHJcbiAgICAgICAgY29uc3QgY2hlY2tTdGF0ZU5hbWUgPSB0aGlzLl9nZXRDaGVja0F0dHJpYnV0ZU5hbWVIZWxwZXIoJ3BhbmUuc3RhdGUnLCBzdXBwb3J0ZWRTdGF0ZXMpO1xyXG4gICAgICAgIGNvbnN0IGNoZWNrQWN0aXZlUGFuZSA9IHRoaXMuX2dldENoZWNrQXR0cmlidXRlTmFtZUhlbHBlcigncGFuZS5hY3RpdmVQYW5lJywgc3VwcG9ydGVkQWN0aXZlUGFuZXMpO1xyXG4gICAgICAgIGNvbnN0IHNoZWV0Vmlld05vZGUgPSB0aGlzLl9nZXRPckNyZWF0ZVNoZWV0Vmlld05vZGUoKTtcclxuICAgICAgICBsZXQgcGFuZU5vZGUgPSB4bWxxLmZpbmRDaGlsZChzaGVldFZpZXdOb2RlLCAncGFuZScpO1xyXG4gICAgICAgIHJldHVybiBuZXcgQXJnSGFuZGxlcignU2hlZXQucGFuZScpXHJcbiAgICAgICAgICAgIC5jYXNlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChwYW5lTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IF8uY2xvbmVEZWVwKHBhbmVOb2RlLmF0dHJpYnV0ZXMpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghcmVzdWx0LnN0YXRlKSByZXN1bHQuc3RhdGUgPSAnc3BsaXQnO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKFsnbmlsJ10sICgpID0+IHtcclxuICAgICAgICAgICAgICAgIHhtbHEucmVtb3ZlQ2hpbGQoc2hlZXRWaWV3Tm9kZSwgJ3BhbmUnKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZShbJ29iamVjdCddLCBwYW5lQXR0cmlidXRlcyA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBhdHRyaWJ1dGVzID0gXy5hc3NpZ24oeyBhY3RpdmVQYW5lOiAnYm90dG9tUmlnaHQnIH0sIHBhbmVBdHRyaWJ1dGVzKTtcclxuICAgICAgICAgICAgICAgIGNoZWNrU3RhdGVOYW1lKGF0dHJpYnV0ZXMuc3RhdGUpO1xyXG4gICAgICAgICAgICAgICAgY2hlY2tBY3RpdmVQYW5lKGF0dHJpYnV0ZXMuYWN0aXZlUGFuZSk7XHJcbiAgICAgICAgICAgICAgICBpZiAocGFuZU5vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBwYW5lTm9kZS5hdHRyaWJ1dGVzID0gYXR0cmlidXRlcztcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcGFuZU5vZGUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IFwicGFuZVwiLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbjogW11cclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIHhtbHEuYXBwZW5kQ2hpbGQoc2hlZXRWaWV3Tm9kZSwgcGFuZU5vZGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5oYW5kbGUoYXJndW1lbnRzKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEZyZWV6ZXMgUGFuZXMgZm9yIHRoaXMgc2hlZXQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geFNwbGl0IHRoZSBudW1iZXIgb2YgY29sdW1ucyB2aXNpYmxlIGluIHRoZSB0b3AgcGFuZS4gMCAoemVybykgaWYgbm9uZS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5U3BsaXQgdGhlIG51bWJlciBvZiByb3dzIHZpc2libGUgaW4gdGhlIGxlZnQgcGFuZS4gMCAoemVybykgaWYgbm9uZS5cclxuICAgICAqIEByZXR1cm4ge1NoZWV0fSBUaGUgc2hlZXRcclxuICAgICAqLy8qKlxyXG4gICAgICogZnJlZXplcyBQYW5lcyBmb3IgdGhpcyBzaGVldC5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0b3BMZWZ0Q2VsbCBUb3AgTGVmdCBWaXNpYmxlIENlbGwuIExvY2F0aW9uIG9mIHRoZSB0b3AgbGVmdCB2aXNpYmxlIGNlbGwgaW4gdGhlIGJvdHRvbVxyXG4gICAgICogcmlnaHQgcGFuZSAod2hlbiBpbiBMZWZ0LVRvLVJpZ2h0IG1vZGUpLlxyXG4gICAgICogQHJldHVybiB7U2hlZXR9IFRoZSBzaGVldFxyXG4gICAgICovXHJcbiAgICBmcmVlemVQYW5lcygpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEFyZ0hhbmRsZXIoJ1NoZWV0LmZlZXplUGFuZXMnKVxyXG4gICAgICAgICAgICAuY2FzZShbJ2ludGVnZXInLCAnaW50ZWdlciddLCAoeFNwbGl0LCB5U3BsaXQpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHRvcExlZnRDZWxsID0gYWRkcmVzc0NvbnZlcnRlci5jb2x1bW5OdW1iZXJUb05hbWUoeFNwbGl0ICsgMSkgKyAoeVNwbGl0ICsgMSk7XHJcbiAgICAgICAgICAgICAgICBsZXQgYWN0aXZlUGFuZSA9IHhTcGxpdCA9PT0gMCA/ICdib3R0b21MZWZ0JyA6ICdib3R0b21SaWdodCc7XHJcbiAgICAgICAgICAgICAgICBhY3RpdmVQYW5lID0geVNwbGl0ID09PSAwID8gJ3RvcFJpZ2h0JyA6IGFjdGl2ZVBhbmU7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wYW5lcyh7IHN0YXRlOiAnZnJvemVuJywgdG9wTGVmdENlbGwsIHhTcGxpdCwgeVNwbGl0LCBhY3RpdmVQYW5lIH0pO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZShbJ3N0cmluZyddLCB0b3BMZWZ0Q2VsbCA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZWYgPSBhZGRyZXNzQ29udmVydGVyLmZyb21BZGRyZXNzKHRvcExlZnRDZWxsKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHhTcGxpdCA9IHJlZi5jb2x1bW5OdW1iZXIgLSAxLCB5U3BsaXQgPSByZWYucm93TnVtYmVyIC0gMTtcclxuICAgICAgICAgICAgICAgIGxldCBhY3RpdmVQYW5lID0geFNwbGl0ID09PSAwID8gJ2JvdHRvbUxlZnQnIDogJ2JvdHRvbVJpZ2h0JztcclxuICAgICAgICAgICAgICAgIGFjdGl2ZVBhbmUgPSB5U3BsaXQgPT09IDAgPyAndG9wUmlnaHQnIDogYWN0aXZlUGFuZTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBhbmVzKHsgc3RhdGU6ICdmcm96ZW4nLCB0b3BMZWZ0Q2VsbCwgeFNwbGl0LCB5U3BsaXQsIGFjdGl2ZVBhbmUgfSk7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5oYW5kbGUoYXJndW1lbnRzKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNwbGl0cyBQYW5lcyBmb3IgdGhpcyBzaGVldC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB4U3BsaXQgKEhvcml6b250YWwgU3BsaXQgUG9zaXRpb24pIEhvcml6b250YWwgcG9zaXRpb24gb2YgdGhlIHNwbGl0LFxyXG4gICAgICogaW4gMS8yMHRoIG9mIGEgcG9pbnQ7IDAgKHplcm8pIGlmIG5vbmUuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0geVNwbGl0IChWZXJ0aWNhbCBTcGxpdCBQb3NpdGlvbikgVlZlcnRpY2FsIHBvc2l0aW9uIG9mIHRoZSBzcGxpdCxcclxuICAgICAqIGluIDEvMjB0aCBvZiBhIHBvaW50OyAwICh6ZXJvKSBpZiBub25lLlxyXG4gICAgICogQHJldHVybiB7U2hlZXR9IFRoZSBzaGVldFxyXG4gICAgICovXHJcbiAgICBzcGxpdFBhbmVzKHhTcGxpdCwgeVNwbGl0KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucGFuZXMoeyBzdGF0ZTogJ3NwbGl0JywgeFNwbGl0LCB5U3BsaXQgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiByZXNldHMgdG8gZGVmYXVsdCBzaGVldCB2aWV3IHBhbmVzLlxyXG4gICAgICogQHJldHVybiB7U2hlZXR9IFRoZSBzaGVldFxyXG4gICAgICovXHJcbiAgICByZXNldFBhbmVzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnBhbmVzKG51bGwpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qIFBSSVZBVEUgKi9cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldCBhIGhlbHBlciBmdW5jdGlvbiB0byBjaGVjayB0aGF0IHRoZSBhdHRyaWJ1dGUgbmFtZSBwcm92aWRlZCBpcyBzdXBwb3J0ZWQuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZnVuY3Rpb25OYW1lIC0gTmFtZSBvZiB0aGUgcGFyZW50IGZ1bmN0aW9uLlxyXG4gICAgICogQHBhcmFtIHthcnJheX0gc3VwcG9ydGVkQXR0cmlidXRlTmFtZXMgLSBBcnJheSBvZiBzdXBwb3J0ZWQgYXR0cmlidXRlIG5hbWUgc3RyaW5ncy5cclxuICAgICAqIEByZXR1cm5zIHtmdW5jdGlvbn0gVGhlIGhlbHBlciBmdW5jdGlvbiwgd2hpY2ggdGFrZXMgYW4gYXR0cmlidXRlIG5hbWUuIElmIHRoZSBhcnJheSBvZiBzdXBwb3J0ZWQgYXR0cmlidXRlIG5hbWVzIGRvZXMgbm90IGNvbnRhaW4gdGhlIGdpdmVuIGF0dHJpYnV0ZSBuYW1lLCB0aGVuIGFuIEVycm9yIGlzIHRocm93bi5cclxuICAgICAqIEBpZ25vcmVcclxuICAgICAqL1xyXG4gICAgX2dldENoZWNrQXR0cmlidXRlTmFtZUhlbHBlcihmdW5jdGlvbk5hbWUsIHN1cHBvcnRlZEF0dHJpYnV0ZU5hbWVzKSB7XHJcbiAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZU5hbWUgPT4ge1xyXG4gICAgICAgICAgICBpZiAoIV8uaW5jbHVkZXMoc3VwcG9ydGVkQXR0cmlidXRlTmFtZXMsIGF0dHJpYnV0ZU5hbWUpKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFNoZWV0LiR7ZnVuY3Rpb25OYW1lfTogXCIke2F0dHJpYnV0ZU5hbWV9XCIgaXMgbm90IHN1cHBvcnRlZC5gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXQgYSBoZWxwZXIgZnVuY3Rpb24gdG8gY2hlY2sgdGhhdCB0aGUgdmFsdWUgaXMgb2YgdGhlIGV4cGVjdGVkIHR5cGUuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZnVuY3Rpb25OYW1lIC0gTmFtZSBvZiB0aGUgcGFyZW50IGZ1bmN0aW9uLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlVHlwZSAtIEEgc3RyaW5nIHByb2R1Y2VkIGJ5IHR5cGVvZi5cclxuICAgICAqIEByZXR1cm5zIHtmdW5jdGlvbn0gVGhlIGhlbHBlciBmdW5jdGlvbiwgd2hpY2ggdGFrZXMgYSB2YWx1ZS4gSWYgdGhlIHZhbHVlIHR5cGUgaXMgbm90IGV4cGVjdGVkLCBhIFR5cGVFcnJvciBpcyB0aHJvd24uXHJcbiAgICAgKiBAaWdub3JlXHJcbiAgICAgKi9cclxuICAgIF9nZXRDaGVja1R5cGVIZWxwZXIoZnVuY3Rpb25OYW1lLCB2YWx1ZVR5cGUpIHtcclxuICAgICAgICByZXR1cm4gdmFsdWUgPT4ge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSB2YWx1ZVR5cGUpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYFNoZWV0LiR7ZnVuY3Rpb25OYW1lfTogaW52YWxpZCB0eXBlIC0gdmFsdWUgbXVzdCBiZSBvZiB0eXBlICR7dmFsdWVUeXBlfS5gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXQgYSBoZWxwZXIgZnVuY3Rpb24gdG8gY2hlY2sgdGhhdCB0aGUgdmFsdWUgaXMgd2l0aGluIHRoZSBleHBlY3RlZCByYW5nZS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBmdW5jdGlvbk5hbWUgLSBOYW1lIG9mIHRoZSBwYXJlbnQgZnVuY3Rpb24uXHJcbiAgICAgKiBAcGFyYW0ge3VuZGVmaW5lZHxudW1iZXJ9IHZhbHVlTWluIC0gVGhlIG1pbmltdW0gdmFsdWUgb2YgdGhlIHJhbmdlLiBUaGlzIHZhbHVlIGlzIHJhbmdlLWluY2x1c2l2ZS5cclxuICAgICAqIEBwYXJhbSB7dW5kZWZpbmVkfG51bWJlcn0gdmFsdWVNYXggLSBUaGUgbWF4aW11bSB2YWx1ZSBvZiB0aGUgcmFuZ2UuIFRoaXMgdmFsdWUgaXMgcmFuZ2UtZXhjbHVzaXZlLlxyXG4gICAgICogQHJldHVybnMge2Z1bmN0aW9ufSBUaGUgaGVscGVyIGZ1bmN0aW9uLCB3aGljaCB0YWtlcyBhIHZhbHVlLiBJZiB0aGUgdmFsdWUgdHlwZSBpcyBub3QgJ251bWJlcicsIGEgVHlwZUVycm9yIGlzIHRocm93bi4gSWYgdGhlIHZhbHVlIGlzIG5vdCB3aXRoaW4gdGhlIHJhbmdlLCBhIFJhbmdlRXJyb3IgaXMgdGhyb3duLlxyXG4gICAgICogQGlnbm9yZVxyXG4gICAgICovXHJcbiAgICBfZ2V0Q2hlY2tSYW5nZUhlbHBlcihmdW5jdGlvbk5hbWUsIHZhbHVlTWluLCB2YWx1ZU1heCkge1xyXG4gICAgICAgIGNvbnN0IGNoZWNrVHlwZSA9IHRoaXMuX2dldENoZWNrVHlwZUhlbHBlcihmdW5jdGlvbk5hbWUsICdudW1iZXInKTtcclxuICAgICAgICByZXR1cm4gdmFsdWUgPT4ge1xyXG4gICAgICAgICAgICBjaGVja1R5cGUodmFsdWUpO1xyXG4gICAgICAgICAgICBpZiAodmFsdWVNaW4gIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlIDwgdmFsdWVNaW4pIHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgU2hlZXQuJHtmdW5jdGlvbk5hbWV9OiB2YWx1ZSB0b28gc21hbGwgLSB2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAke3ZhbHVlTWlufS5gKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodmFsdWVNYXggIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlTWF4IDw9IHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYFNoZWV0LiR7ZnVuY3Rpb25OYW1lfTogdmFsdWUgdG9vIGxhcmdlIC0gdmFsdWUgbXVzdCBiZSBsZXNzIHRoYW4gJHt2YWx1ZU1heH0uYCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0IHRoZSBzaGVldCB2aWV3IG5vZGUgaWYgaXQgZXhpc3RzIG9yIGNyZWF0ZSBpdCBpZiBpdCBkb2Vzbid0LlxyXG4gICAgICogQHJldHVybnMge3t9fSBUaGUgc2hlZXQgdmlldyBub2RlLlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgX2dldE9yQ3JlYXRlU2hlZXRWaWV3Tm9kZSgpIHtcclxuICAgICAgICBsZXQgc2hlZXRWaWV3c05vZGUgPSB4bWxxLmZpbmRDaGlsZCh0aGlzLl9ub2RlLCBcInNoZWV0Vmlld3NcIik7XHJcbiAgICAgICAgaWYgKCFzaGVldFZpZXdzTm9kZSkge1xyXG4gICAgICAgICAgICBzaGVldFZpZXdzTm9kZSA9IHtcclxuICAgICAgICAgICAgICAgIG5hbWU6IFwic2hlZXRWaWV3c1wiLFxyXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlczoge30sXHJcbiAgICAgICAgICAgICAgICBjaGlsZHJlbjogW3tcclxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBcInNoZWV0Vmlld1wiLFxyXG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgd29ya2Jvb2tWaWV3SWQ6IDBcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuOiBbXVxyXG4gICAgICAgICAgICAgICAgfV1cclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIHhtbHEuaW5zZXJ0SW5PcmRlcih0aGlzLl9ub2RlLCBzaGVldFZpZXdzTm9kZSwgbm9kZU9yZGVyKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB4bWxxLmZpbmRDaGlsZChzaGVldFZpZXdzTm9kZSwgXCJzaGVldFZpZXdcIik7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbml0aWFsaXplcyB0aGUgc2hlZXQuXHJcbiAgICAgKiBAcGFyYW0ge1dvcmtib29rfSB3b3JrYm9vayAtIFRoZSBwYXJlbnQgd29ya2Jvb2suXHJcbiAgICAgKiBAcGFyYW0ge3t9fSBpZE5vZGUgLSBUaGUgc2hlZXQgSUQgbm9kZSAoZnJvbSB0aGUgcGFyZW50IHdvcmtib29rKS5cclxuICAgICAqIEBwYXJhbSB7e319IG5vZGUgLSBUaGUgc2hlZXQgbm9kZS5cclxuICAgICAqIEBwYXJhbSB7e319IFtyZWxhdGlvbnNoaXBzTm9kZV0gLSBUaGUgb3B0aW9uYWwgc2hlZXQgcmVsYXRpb25zaGlwcyBub2RlLlxyXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIF9pbml0KHdvcmtib29rLCBpZE5vZGUsIG5vZGUsIHJlbGF0aW9uc2hpcHNOb2RlKSB7XHJcbiAgICAgICAgaWYgKCFub2RlKSB7XHJcbiAgICAgICAgICAgIG5vZGUgPSB7XHJcbiAgICAgICAgICAgICAgICBuYW1lOiBcIndvcmtzaGVldFwiLFxyXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlczoge1xyXG4gICAgICAgICAgICAgICAgICAgIHhtbG5zOiBcImh0dHA6Ly9zY2hlbWFzLm9wZW54bWxmb3JtYXRzLm9yZy9zcHJlYWRzaGVldG1sLzIwMDYvbWFpblwiLFxyXG4gICAgICAgICAgICAgICAgICAgICd4bWxuczpyJzogXCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvb2ZmaWNlRG9jdW1lbnQvMjAwNi9yZWxhdGlvbnNoaXBzXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgJ3htbG5zOm1jJzogXCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvbWFya3VwLWNvbXBhdGliaWxpdHkvMjAwNlwiLFxyXG4gICAgICAgICAgICAgICAgICAgICdtYzpJZ25vcmFibGUnOiBcIngxNGFjXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgJ3htbG5zOngxNGFjJzogXCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL29mZmljZS9zcHJlYWRzaGVldG1sLzIwMDkvOS9hY1wiXHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgY2hpbGRyZW46IFt7XHJcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJzaGVldERhdGFcIixcclxuICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7fSxcclxuICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbjogW11cclxuICAgICAgICAgICAgICAgIH1dXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl93b3JrYm9vayA9IHdvcmtib29rO1xyXG4gICAgICAgIHRoaXMuX2lkTm9kZSA9IGlkTm9kZTtcclxuICAgICAgICB0aGlzLl9ub2RlID0gbm9kZTtcclxuICAgICAgICB0aGlzLl9tYXhTaGFyZWRGb3JtdWxhSWQgPSAtMTtcclxuICAgICAgICB0aGlzLl9tZXJnZUNlbGxzID0ge307XHJcbiAgICAgICAgdGhpcy5fZGF0YVZhbGlkYXRpb25zID0ge307XHJcbiAgICAgICAgdGhpcy5faHlwZXJsaW5rcyA9IHt9O1xyXG4gICAgICAgIHRoaXMuX2F1dG9GaWx0ZXIgPSBudWxsO1xyXG5cclxuICAgICAgICAvLyBDcmVhdGUgdGhlIHJlbGF0aW9uc2hpcHMuXHJcbiAgICAgICAgdGhpcy5fcmVsYXRpb25zaGlwcyA9IG5ldyBSZWxhdGlvbnNoaXBzKHJlbGF0aW9uc2hpcHNOb2RlKTtcclxuXHJcbiAgICAgICAgLy8gRGVsZXRlIHRoZSBvcHRpb25hbCBkaW1lbnNpb24gbm9kZVxyXG4gICAgICAgIHhtbHEucmVtb3ZlQ2hpbGQodGhpcy5fbm9kZSwgXCJkaW1lbnNpb25cIik7XHJcblxyXG4gICAgICAgIC8vIENyZWF0ZSB0aGUgcm93cy5cclxuICAgICAgICB0aGlzLl9yb3dzID0gW107XHJcbiAgICAgICAgdGhpcy5fc2hlZXREYXRhTm9kZSA9IHhtbHEuZmluZENoaWxkKHRoaXMuX25vZGUsIFwic2hlZXREYXRhXCIpO1xyXG4gICAgICAgIHRoaXMuX3NoZWV0RGF0YU5vZGUuY2hpbGRyZW4uZm9yRWFjaChyb3dOb2RlID0+IHtcclxuICAgICAgICAgICAgY29uc3Qgcm93ID0gbmV3IFJvdyh0aGlzLCByb3dOb2RlKTtcclxuICAgICAgICAgICAgdGhpcy5fcm93c1tyb3cucm93TnVtYmVyKCldID0gcm93O1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuX3NoZWV0RGF0YU5vZGUuY2hpbGRyZW4gPSB0aGlzLl9yb3dzO1xyXG5cclxuICAgICAgICAvLyBDcmVhdGUgdGhlIGNvbHVtbnMgbm9kZS5cclxuICAgICAgICB0aGlzLl9jb2x1bW5zID0gW107XHJcbiAgICAgICAgdGhpcy5fY29sc05vZGUgPSB4bWxxLmZpbmRDaGlsZCh0aGlzLl9ub2RlLCBcImNvbHNcIik7XHJcbiAgICAgICAgaWYgKHRoaXMuX2NvbHNOb2RlKSB7XHJcbiAgICAgICAgICAgIHhtbHEucmVtb3ZlQ2hpbGQodGhpcy5fbm9kZSwgdGhpcy5fY29sc05vZGUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvbHNOb2RlID0geyBuYW1lOiAnY29scycsIGF0dHJpYnV0ZXM6IHt9LCBjaGlsZHJlbjogW10gfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIENhY2hlIHRoZSBjb2wgbm9kZXMuXHJcbiAgICAgICAgdGhpcy5fY29sTm9kZXMgPSBbXTtcclxuICAgICAgICBfLmZvckVhY2godGhpcy5fY29sc05vZGUuY2hpbGRyZW4sIGNvbE5vZGUgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBtaW4gPSBjb2xOb2RlLmF0dHJpYnV0ZXMubWluO1xyXG4gICAgICAgICAgICBjb25zdCBtYXggPSBjb2xOb2RlLmF0dHJpYnV0ZXMubWF4O1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gbWluOyBpIDw9IG1heDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9jb2xOb2Rlc1tpXSA9IGNvbE5vZGU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgLy8gQ3JlYXRlIHRoZSBzaGVldCBwcm9wZXJ0aWVzIG5vZGUuXHJcbiAgICAgICAgdGhpcy5fc2hlZXRQck5vZGUgPSB4bWxxLmZpbmRDaGlsZCh0aGlzLl9ub2RlLCBcInNoZWV0UHJcIik7XHJcbiAgICAgICAgaWYgKCF0aGlzLl9zaGVldFByTm9kZSkge1xyXG4gICAgICAgICAgICB0aGlzLl9zaGVldFByTm9kZSA9IHsgbmFtZTogJ3NoZWV0UHInLCBhdHRyaWJ1dGVzOiB7fSwgY2hpbGRyZW46IFtdIH07XHJcbiAgICAgICAgICAgIHhtbHEuaW5zZXJ0SW5PcmRlcih0aGlzLl9ub2RlLCB0aGlzLl9zaGVldFByTm9kZSwgbm9kZU9yZGVyKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIENyZWF0ZSB0aGUgbWVyZ2UgY2VsbHMuXHJcbiAgICAgICAgdGhpcy5fbWVyZ2VDZWxsc05vZGUgPSB4bWxxLmZpbmRDaGlsZCh0aGlzLl9ub2RlLCBcIm1lcmdlQ2VsbHNcIik7XHJcbiAgICAgICAgaWYgKHRoaXMuX21lcmdlQ2VsbHNOb2RlKSB7XHJcbiAgICAgICAgICAgIHhtbHEucmVtb3ZlQ2hpbGQodGhpcy5fbm9kZSwgdGhpcy5fbWVyZ2VDZWxsc05vZGUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuX21lcmdlQ2VsbHNOb2RlID0geyBuYW1lOiAnbWVyZ2VDZWxscycsIGF0dHJpYnV0ZXM6IHt9LCBjaGlsZHJlbjogW10gfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IG1lcmdlQ2VsbE5vZGVzID0gdGhpcy5fbWVyZ2VDZWxsc05vZGUuY2hpbGRyZW47XHJcbiAgICAgICAgdGhpcy5fbWVyZ2VDZWxsc05vZGUuY2hpbGRyZW4gPSBbXTtcclxuICAgICAgICBtZXJnZUNlbGxOb2Rlcy5mb3JFYWNoKG1lcmdlQ2VsbE5vZGUgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9tZXJnZUNlbGxzW21lcmdlQ2VsbE5vZGUuYXR0cmlidXRlcy5yZWZdID0gbWVyZ2VDZWxsTm9kZTtcclxuICAgICAgICB9KTtcclxuXHJcblxyXG4gICAgICAgIC8vIENyZWF0ZSB0aGUgRGF0YVZhbGlkYXRpb25zLlxyXG4gICAgICAgIHRoaXMuX2RhdGFWYWxpZGF0aW9uc05vZGUgPSB4bWxxLmZpbmRDaGlsZCh0aGlzLl9ub2RlLCBcImRhdGFWYWxpZGF0aW9uc1wiKTtcclxuICAgICAgICBpZiAodGhpcy5fZGF0YVZhbGlkYXRpb25zTm9kZSkge1xyXG4gICAgICAgICAgICB4bWxxLnJlbW92ZUNoaWxkKHRoaXMuX25vZGUsIHRoaXMuX2RhdGFWYWxpZGF0aW9uc05vZGUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2RhdGFWYWxpZGF0aW9uc05vZGUgPSB7IG5hbWU6ICdkYXRhVmFsaWRhdGlvbnMnLCBhdHRyaWJ1dGVzOiB7fSwgY2hpbGRyZW46IFtdIH07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBkYXRhVmFsaWRhdGlvbk5vZGVzID0gdGhpcy5fZGF0YVZhbGlkYXRpb25zTm9kZS5jaGlsZHJlbjtcclxuICAgICAgICB0aGlzLl9kYXRhVmFsaWRhdGlvbnNOb2RlLmNoaWxkcmVuID0gW107XHJcbiAgICAgICAgZGF0YVZhbGlkYXRpb25Ob2Rlcy5mb3JFYWNoKGRhdGFWYWxpZGF0aW9uTm9kZSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX2RhdGFWYWxpZGF0aW9uc1tkYXRhVmFsaWRhdGlvbk5vZGUuYXR0cmlidXRlcy5zcXJlZl0gPSBkYXRhVmFsaWRhdGlvbk5vZGU7XHJcbiAgICAgICAgfSk7XHJcblxyXG5cclxuICAgICAgICAvLyBDcmVhdGUgdGhlIGh5cGVybGlua3MuXHJcbiAgICAgICAgdGhpcy5faHlwZXJsaW5rc05vZGUgPSB4bWxxLmZpbmRDaGlsZCh0aGlzLl9ub2RlLCBcImh5cGVybGlua3NcIik7XHJcbiAgICAgICAgaWYgKHRoaXMuX2h5cGVybGlua3NOb2RlKSB7XHJcbiAgICAgICAgICAgIHhtbHEucmVtb3ZlQ2hpbGQodGhpcy5fbm9kZSwgdGhpcy5faHlwZXJsaW5rc05vZGUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2h5cGVybGlua3NOb2RlID0geyBuYW1lOiAnaHlwZXJsaW5rcycsIGF0dHJpYnV0ZXM6IHt9LCBjaGlsZHJlbjogW10gfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGh5cGVybGlua05vZGVzID0gdGhpcy5faHlwZXJsaW5rc05vZGUuY2hpbGRyZW47XHJcbiAgICAgICAgdGhpcy5faHlwZXJsaW5rc05vZGUuY2hpbGRyZW4gPSBbXTtcclxuICAgICAgICBoeXBlcmxpbmtOb2Rlcy5mb3JFYWNoKGh5cGVybGlua05vZGUgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9oeXBlcmxpbmtzW2h5cGVybGlua05vZGUuYXR0cmlidXRlcy5yZWZdID0gaHlwZXJsaW5rTm9kZTtcclxuICAgICAgICB9KTtcclxuXHJcblxyXG4gICAgICAgIC8vIENyZWF0ZSB0aGUgcHJpbnRPcHRpb25zLlxyXG4gICAgICAgIHRoaXMuX3ByaW50T3B0aW9uc05vZGUgPSB4bWxxLmZpbmRDaGlsZCh0aGlzLl9ub2RlLCBcInByaW50T3B0aW9uc1wiKTtcclxuICAgICAgICBpZiAodGhpcy5fcHJpbnRPcHRpb25zTm9kZSkge1xyXG4gICAgICAgICAgICB4bWxxLnJlbW92ZUNoaWxkKHRoaXMuX25vZGUsIHRoaXMuX3ByaW50T3B0aW9uc05vZGUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3ByaW50T3B0aW9uc05vZGUgPSB7IG5hbWU6ICdwcmludE9wdGlvbnMnLCBhdHRyaWJ1dGVzOiB7fSwgY2hpbGRyZW46IFtdIH07XHJcbiAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgLy8gQ3JlYXRlIHRoZSBwYWdlTWFyZ2lucy5cclxuICAgICAgICB0aGlzLl9wYWdlTWFyZ2luc1ByZXNldHMgPSB7XHJcbiAgICAgICAgICAgIG5vcm1hbDoge1xyXG4gICAgICAgICAgICAgICAgbGVmdDogMC43LFxyXG4gICAgICAgICAgICAgICAgcmlnaHQ6IDAuNyxcclxuICAgICAgICAgICAgICAgIHRvcDogMC43NSxcclxuICAgICAgICAgICAgICAgIGJvdHRvbTogMC43NSxcclxuICAgICAgICAgICAgICAgIGhlYWRlcjogMC4zLFxyXG4gICAgICAgICAgICAgICAgZm9vdGVyOiAwLjNcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgd2lkZToge1xyXG4gICAgICAgICAgICAgICAgbGVmdDogMSxcclxuICAgICAgICAgICAgICAgIHJpZ2h0OiAxLFxyXG4gICAgICAgICAgICAgICAgdG9wOiAxLFxyXG4gICAgICAgICAgICAgICAgYm90dG9tOiAxLFxyXG4gICAgICAgICAgICAgICAgaGVhZGVyOiAwLjUsXHJcbiAgICAgICAgICAgICAgICBmb290ZXI6IDAuNVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBuYXJyb3c6IHtcclxuICAgICAgICAgICAgICAgIGxlZnQ6IDAuMjUsXHJcbiAgICAgICAgICAgICAgICByaWdodDogMC4yNSxcclxuICAgICAgICAgICAgICAgIHRvcDogMC43NSxcclxuICAgICAgICAgICAgICAgIGJvdHRvbTogMC43NSxcclxuICAgICAgICAgICAgICAgIGhlYWRlcjogMC4zLFxyXG4gICAgICAgICAgICAgICAgZm9vdGVyOiAwLjNcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgdGhpcy5fcGFnZU1hcmdpbnNOb2RlID0geG1scS5maW5kQ2hpbGQodGhpcy5fbm9kZSwgXCJwYWdlTWFyZ2luc1wiKTtcclxuICAgICAgICBpZiAodGhpcy5fcGFnZU1hcmdpbnNOb2RlKSB7XHJcbiAgICAgICAgICAgIC8vIFNoZWV0IGhhcyBwYWdlIG1hcmdpbnMsIGFzc3VtZSBwcmVzZXQgaXMgdGVtcGxhdGUuXHJcbiAgICAgICAgICAgIHRoaXMuX3BhZ2VNYXJnaW5zUHJlc2V0TmFtZSA9ICd0ZW1wbGF0ZSc7XHJcblxyXG4gICAgICAgICAgICAvLyBTZWFyY2ggZm9yIGEgcHJlc2V0IHRoYXQgbWF0Y2hlcyBleGlzdGluZyBhdHRyaWJ1dGVzLlxyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHByZXNldE5hbWUgaW4gdGhpcy5fcGFnZU1hcmdpbnNQcmVzZXRzKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoXy5pc0VxdWFsKHRoaXMuX3BhZ2VNYXJnaW5zTm9kZS5hdHRyaWJ1dGVzLCB0aGlzLl9wYWdlTWFyZ2luc1ByZXNldHNbcHJlc2V0TmFtZV0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFnZU1hcmdpbnNQcmVzZXROYW1lID0gcHJlc2V0TmFtZTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gSWYgdGVtcGxhdGUgcHJlc2V0LCB0aGVuIHJlZ2lzdGVyIGFzIHRlbXBsYXRlIHByZXNldCwgYW5kIGNsZWFyIGF0dHJpYnV0ZXMuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9wYWdlTWFyZ2luc1ByZXNldE5hbWUgPT09ICd0ZW1wbGF0ZScpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3BhZ2VNYXJnaW5zUHJlc2V0cy50ZW1wbGF0ZSA9IHRoaXMuX3BhZ2VNYXJnaW5zTm9kZS5hdHRyaWJ1dGVzO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fcGFnZU1hcmdpbnNOb2RlLmF0dHJpYnV0ZXMgPSB7fTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgeG1scS5yZW1vdmVDaGlsZCh0aGlzLl9ub2RlLCB0aGlzLl9wYWdlTWFyZ2luc05vZGUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIFNoZWV0IGhhcyBubyBwYWdlIG1hcmdpbnMsIHRoZSBwcmVzZXQgYXNzaWdubWVudCBpcyB0aGVyZWZvcmUgdW5kZWZpbmVkLlxyXG4gICAgICAgICAgICB0aGlzLl9wYWdlTWFyZ2luc1ByZXNldE5hbWUgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgIHRoaXMuX3BhZ2VNYXJnaW5zTm9kZSA9IHsgbmFtZTogJ3BhZ2VNYXJnaW5zJywgYXR0cmlidXRlczoge30sIGNoaWxkcmVuOiBbXSB9O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQ3JlYXRlIHRoZSBwYWdlQnJlYWtzXHJcbiAgICAgICAgWydjb2xCcmVha3MnLCAncm93QnJlYWtzJ10uZm9yRWFjaChuYW1lID0+IHtcclxuICAgICAgICAgICAgdGhpc1tgXyR7bmFtZX1Ob2RlYF0gPSB4bWxxLmZpbmRDaGlsZCh0aGlzLl9ub2RlLCBuYW1lKTtcclxuICAgICAgICAgICAgaWYgKHRoaXNbYF8ke25hbWV9Tm9kZWBdKSB7XHJcbiAgICAgICAgICAgICAgICB4bWxxLnJlbW92ZUNoaWxkKHRoaXMuX25vZGUsIHRoaXNbYF8ke25hbWV9Tm9kZWBdKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXNbYF8ke25hbWV9Tm9kZWBdID0ge1xyXG4gICAgICAgICAgICAgICAgICAgIG5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW46IFtdLFxyXG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY291bnQ6IDAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hbnVhbEJyZWFrQ291bnQ6IDBcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5fcGFnZUJyZWFrcyA9IHtcclxuICAgICAgICAgICAgY29sQnJlYWtzOiBuZXcgUGFnZUJyZWFrcyh0aGlzLl9jb2xCcmVha3NOb2RlKSxcclxuICAgICAgICAgICAgcm93QnJlYWtzOiBuZXcgUGFnZUJyZWFrcyh0aGlzLl9yb3dCcmVha3NOb2RlKVxyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gU2hlZXQ7XHJcblxyXG4vKlxyXG54bC93b3JrYm9vay54bWxcclxuXHJcbjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIlVURi04XCIgc3RhbmRhbG9uZT1cInllc1wiPz5cclxuPHdvcmtzaGVldCAuLi4+XHJcbiAgICAuLi5cclxuXHJcbiAgICA8cHJpbnRPcHRpb25zIGhlYWRpbmdzPVwiMVwiIGdyaWRMaW5lcz1cIjFcIiAvPlxyXG4gICAgPHBhZ2VNYXJnaW5zIGxlZnQ9XCIwLjdcIiByaWdodD1cIjAuN1wiIHRvcD1cIjAuNzVcIiBib3R0b209XCIwLjc1XCIgaGVhZGVyPVwiMC4zXCIgZm9vdGVyPVwiMC4zXCIgLz5cclxuICAgIDxwYWdlU2V0dXAgb3JpZW50YXRpb249XCJwb3J0cmFpdFwiIGhvcml6b250YWxEcGk9XCIwXCIgdmVydGljYWxEcGk9XCIwXCIgLz5cclxuPC93b3Jrc2hlZXQ+XHJcbi8vICovXHJcbiIsIlwidXNlIHN0cmljdFwiO1xyXG5cclxuLyogZXNsaW50IGNhbWVsY2FzZTpvZmYgKi9cclxuXHJcbmNvbnN0IEFyZ0hhbmRsZXIgPSByZXF1aXJlKFwiLi9BcmdIYW5kbGVyXCIpO1xyXG5jb25zdCBfID0gcmVxdWlyZShcImxvZGFzaFwiKTtcclxuY29uc3QgeG1scSA9IHJlcXVpcmUoXCIuL3htbHFcIik7XHJcbmNvbnN0IGNvbG9ySW5kZXhlcyA9IHJlcXVpcmUoXCIuL2NvbG9ySW5kZXhlc1wiKTtcclxuXHJcbi8qKlxyXG4gKiBBIHN0eWxlLlxyXG4gKiBAaWdub3JlXHJcbiAqL1xyXG5jbGFzcyBTdHlsZSB7XHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgX1N0eWxlLlxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKiBAcGFyYW0ge1N0eWxlU2hlZXR9IHN0eWxlU2hlZXQgLSBUaGUgc3R5bGVTaGVldC5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpZCAtIFRoZSBzdHlsZSBJRC5cclxuICAgICAqIEBwYXJhbSB7e319IHhmTm9kZSAtIFRoZSB4ZiBub2RlLlxyXG4gICAgICogQHBhcmFtIHt7fX0gZm9udE5vZGUgLSBUaGUgZm9udCBub2RlLlxyXG4gICAgICogQHBhcmFtIHt7fX0gZmlsbE5vZGUgLSBUaGUgZmlsbCBub2RlLlxyXG4gICAgICogQHBhcmFtIHt7fX0gYm9yZGVyTm9kZSAtIFRoZSBib3JkZXIgbm9kZS5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3Ioc3R5bGVTaGVldCwgaWQsIHhmTm9kZSwgZm9udE5vZGUsIGZpbGxOb2RlLCBib3JkZXJOb2RlKSB7XHJcbiAgICAgICAgdGhpcy5fc3R5bGVTaGVldCA9IHN0eWxlU2hlZXQ7XHJcbiAgICAgICAgdGhpcy5faWQgPSBpZDtcclxuICAgICAgICB0aGlzLl94Zk5vZGUgPSB4Zk5vZGU7XHJcbiAgICAgICAgdGhpcy5fZm9udE5vZGUgPSBmb250Tm9kZTtcclxuICAgICAgICB0aGlzLl9maWxsTm9kZSA9IGZpbGxOb2RlO1xyXG4gICAgICAgIHRoaXMuX2JvcmRlck5vZGUgPSBib3JkZXJOb2RlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgc3R5bGUgSUQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgSUQuXHJcbiAgICAgKi9cclxuICAgIGlkKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9pZDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgb3Igc2V0cyBhIHN0eWxlLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgc3R5bGUgbmFtZS5cclxuICAgICAqIEBwYXJhbSB7Kn0gW3ZhbHVlXSAtIFRoZSB2YWx1ZSB0byBzZXQuXHJcbiAgICAgKiBAcmV0dXJucyB7KnxTdHlsZX0gVGhlIHZhbHVlIGlmIGdldHRpbmcgb3IgdGhlIHN0eWxlIGlmIHNldHRpbmcuXHJcbiAgICAgKi9cclxuICAgIHN0eWxlKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQXJnSGFuZGxlcihcIl9TdHlsZS5zdHlsZVwiKVxyXG4gICAgICAgICAgICAuY2FzZSgnc3RyaW5nJywgbmFtZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBnZXR0ZXJOYW1lID0gYF9nZXRfJHtuYW1lfWA7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXNbZ2V0dGVyTmFtZV0pIHRocm93IG5ldyBFcnJvcihgX1N0eWxlLnN0eWxlOiAnJHtuYW1lfScgaXMgbm90IGEgdmFsaWQgc3R5bGVgKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzW2dldHRlck5hbWVdKCk7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKFsnc3RyaW5nJywgJyonXSwgKG5hbWUsIHZhbHVlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBzZXR0ZXJOYW1lID0gYF9zZXRfJHtuYW1lfWA7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXNbc2V0dGVyTmFtZV0pIHRocm93IG5ldyBFcnJvcihgX1N0eWxlLnN0eWxlOiAnJHtuYW1lfScgaXMgbm90IGEgdmFsaWQgc3R5bGVgKTtcclxuICAgICAgICAgICAgICAgIHRoaXNbc2V0dGVyTmFtZV0odmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5oYW5kbGUoYXJndW1lbnRzKTtcclxuICAgIH1cclxuXHJcbiAgICBfZ2V0Q29sb3Iobm9kZSwgbmFtZSkge1xyXG4gICAgICAgIGNvbnN0IGNoaWxkID0geG1scS5maW5kQ2hpbGQobm9kZSwgbmFtZSk7XHJcbiAgICAgICAgaWYgKCFjaGlsZCB8fCAhY2hpbGQuYXR0cmlidXRlcykgcmV0dXJuO1xyXG5cclxuICAgICAgICBjb25zdCBjb2xvciA9IHt9O1xyXG4gICAgICAgIGlmIChjaGlsZC5hdHRyaWJ1dGVzLmhhc093blByb3BlcnR5KCdyZ2InKSkgY29sb3IucmdiID0gY2hpbGQuYXR0cmlidXRlcy5yZ2I7XHJcbiAgICAgICAgZWxzZSBpZiAoY2hpbGQuYXR0cmlidXRlcy5oYXNPd25Qcm9wZXJ0eSgndGhlbWUnKSkgY29sb3IudGhlbWUgPSBjaGlsZC5hdHRyaWJ1dGVzLnRoZW1lO1xyXG4gICAgICAgIGVsc2UgaWYgKGNoaWxkLmF0dHJpYnV0ZXMuaGFzT3duUHJvcGVydHkoJ2luZGV4ZWQnKSkgY29sb3IucmdiID0gY29sb3JJbmRleGVzW2NoaWxkLmF0dHJpYnV0ZXMuaW5kZXhlZF07XHJcblxyXG4gICAgICAgIGlmIChjaGlsZC5hdHRyaWJ1dGVzLmhhc093blByb3BlcnR5KCd0aW50JykpIGNvbG9yLnRpbnQgPSBjaGlsZC5hdHRyaWJ1dGVzLnRpbnQ7XHJcblxyXG4gICAgICAgIGlmIChfLmlzRW1wdHkoY29sb3IpKSByZXR1cm47XHJcblxyXG4gICAgICAgIHJldHVybiBjb2xvcjtcclxuICAgIH1cclxuXHJcbiAgICBfc2V0Q29sb3Iobm9kZSwgbmFtZSwgY29sb3IpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGNvbG9yID09PSBcInN0cmluZ1wiKSBjb2xvciA9IHsgcmdiOiBjb2xvciB9O1xyXG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBjb2xvciA9PT0gXCJudW1iZXJcIikgY29sb3IgPSB7IHRoZW1lOiBjb2xvciB9O1xyXG5cclxuICAgICAgICB4bWxxLnNldENoaWxkQXR0cmlidXRlcyhub2RlLCBuYW1lLCB7XHJcbiAgICAgICAgICAgIHJnYjogY29sb3IgJiYgY29sb3IucmdiICYmIGNvbG9yLnJnYi50b1VwcGVyQ2FzZSgpLFxyXG4gICAgICAgICAgICBpbmRleGVkOiBudWxsLFxyXG4gICAgICAgICAgICB0aGVtZTogY29sb3IgJiYgY29sb3IudGhlbWUsXHJcbiAgICAgICAgICAgIHRpbnQ6IGNvbG9yICYmIGNvbG9yLnRpbnRcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgeG1scS5yZW1vdmVDaGlsZElmRW1wdHkobm9kZSwgJ2NvbG9yJyk7XHJcbiAgICB9XHJcblxyXG4gICAgX2dldF9ib2xkKCkge1xyXG4gICAgICAgIHJldHVybiB4bWxxLmhhc0NoaWxkKHRoaXMuX2ZvbnROb2RlLCAnYicpO1xyXG4gICAgfVxyXG5cclxuICAgIF9zZXRfYm9sZChib2xkKSB7XHJcbiAgICAgICAgaWYgKGJvbGQpIHhtbHEuYXBwZW5kQ2hpbGRJZk5vdEZvdW5kKHRoaXMuX2ZvbnROb2RlLCBcImJcIik7XHJcbiAgICAgICAgZWxzZSB4bWxxLnJlbW92ZUNoaWxkKHRoaXMuX2ZvbnROb2RlLCAnYicpO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRfaXRhbGljKCkge1xyXG4gICAgICAgIHJldHVybiB4bWxxLmhhc0NoaWxkKHRoaXMuX2ZvbnROb2RlLCAnaScpO1xyXG4gICAgfVxyXG5cclxuICAgIF9zZXRfaXRhbGljKGl0YWxpYykge1xyXG4gICAgICAgIGlmIChpdGFsaWMpIHhtbHEuYXBwZW5kQ2hpbGRJZk5vdEZvdW5kKHRoaXMuX2ZvbnROb2RlLCBcImlcIik7XHJcbiAgICAgICAgZWxzZSB4bWxxLnJlbW92ZUNoaWxkKHRoaXMuX2ZvbnROb2RlLCAnaScpO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRfdW5kZXJsaW5lKCkge1xyXG4gICAgICAgIGNvbnN0IHVOb2RlID0geG1scS5maW5kQ2hpbGQodGhpcy5fZm9udE5vZGUsICd1Jyk7XHJcbiAgICAgICAgcmV0dXJuIHVOb2RlID8gdU5vZGUuYXR0cmlidXRlcy52YWwgfHwgdHJ1ZSA6IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIF9zZXRfdW5kZXJsaW5lKHVuZGVybGluZSkge1xyXG4gICAgICAgIGlmICh1bmRlcmxpbmUpIHtcclxuICAgICAgICAgICAgY29uc3QgdU5vZGUgPSB4bWxxLmFwcGVuZENoaWxkSWZOb3RGb3VuZCh0aGlzLl9mb250Tm9kZSwgXCJ1XCIpO1xyXG4gICAgICAgICAgICBjb25zdCB2YWwgPSB0eXBlb2YgdW5kZXJsaW5lID09PSAnc3RyaW5nJyA/IHVuZGVybGluZSA6IG51bGw7XHJcbiAgICAgICAgICAgIHhtbHEuc2V0QXR0cmlidXRlcyh1Tm9kZSwgeyB2YWwgfSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgeG1scS5yZW1vdmVDaGlsZCh0aGlzLl9mb250Tm9kZSwgJ3UnKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgX2dldF9zdHJpa2V0aHJvdWdoKCkge1xyXG4gICAgICAgIHJldHVybiB4bWxxLmhhc0NoaWxkKHRoaXMuX2ZvbnROb2RlLCAnc3RyaWtlJyk7XHJcbiAgICB9XHJcblxyXG4gICAgX3NldF9zdHJpa2V0aHJvdWdoKHN0cmlrZXRocm91Z2gpIHtcclxuICAgICAgICBpZiAoc3RyaWtldGhyb3VnaCkgeG1scS5hcHBlbmRDaGlsZElmTm90Rm91bmQodGhpcy5fZm9udE5vZGUsIFwic3RyaWtlXCIpO1xyXG4gICAgICAgIGVsc2UgeG1scS5yZW1vdmVDaGlsZCh0aGlzLl9mb250Tm9kZSwgJ3N0cmlrZScpO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRGb250VmVydGljYWxBbGlnbm1lbnQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHhtbHEuZ2V0Q2hpbGRBdHRyaWJ1dGUodGhpcy5fZm9udE5vZGUsICd2ZXJ0QWxpZ24nLCBcInZhbFwiKTtcclxuICAgIH1cclxuXHJcbiAgICBfc2V0Rm9udFZlcnRpY2FsQWxpZ25tZW50KGFsaWdubWVudCkge1xyXG4gICAgICAgIHhtbHEuc2V0Q2hpbGRBdHRyaWJ1dGVzKHRoaXMuX2ZvbnROb2RlLCAndmVydEFsaWduJywgeyB2YWw6IGFsaWdubWVudCB9KTtcclxuICAgICAgICB4bWxxLnJlbW92ZUNoaWxkSWZFbXB0eSh0aGlzLl9mb250Tm9kZSwgJ3ZlcnRBbGlnbicpO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRfc3Vic2NyaXB0KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRGb250VmVydGljYWxBbGlnbm1lbnQoKSA9PT0gXCJzdWJzY3JpcHRcIjtcclxuICAgIH1cclxuXHJcbiAgICBfc2V0X3N1YnNjcmlwdChzdWJzY3JpcHQpIHtcclxuICAgICAgICB0aGlzLl9zZXRGb250VmVydGljYWxBbGlnbm1lbnQoc3Vic2NyaXB0ID8gXCJzdWJzY3JpcHRcIiA6IG51bGwpO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRfc3VwZXJzY3JpcHQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldEZvbnRWZXJ0aWNhbEFsaWdubWVudCgpID09PSBcInN1cGVyc2NyaXB0XCI7XHJcbiAgICB9XHJcblxyXG4gICAgX3NldF9zdXBlcnNjcmlwdChzdXBlcnNjcmlwdCkge1xyXG4gICAgICAgIHRoaXMuX3NldEZvbnRWZXJ0aWNhbEFsaWdubWVudChzdXBlcnNjcmlwdCA/IFwic3VwZXJzY3JpcHRcIiA6IG51bGwpO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRfZm9udFNpemUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHhtbHEuZ2V0Q2hpbGRBdHRyaWJ1dGUodGhpcy5fZm9udE5vZGUsICdzeicsIFwidmFsXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIF9zZXRfZm9udFNpemUoc2l6ZSkge1xyXG4gICAgICAgIHhtbHEuc2V0Q2hpbGRBdHRyaWJ1dGVzKHRoaXMuX2ZvbnROb2RlLCAnc3onLCB7IHZhbDogc2l6ZSB9KTtcclxuICAgICAgICB4bWxxLnJlbW92ZUNoaWxkSWZFbXB0eSh0aGlzLl9mb250Tm9kZSwgJ3N6Jyk7XHJcbiAgICB9XHJcblxyXG4gICAgX2dldF9mb250RmFtaWx5KCkge1xyXG4gICAgICAgIHJldHVybiB4bWxxLmdldENoaWxkQXR0cmlidXRlKHRoaXMuX2ZvbnROb2RlLCAnbmFtZScsIFwidmFsXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIF9zZXRfZm9udEZhbWlseShmYW1pbHkpIHtcclxuICAgICAgICB4bWxxLnNldENoaWxkQXR0cmlidXRlcyh0aGlzLl9mb250Tm9kZSwgJ25hbWUnLCB7IHZhbDogZmFtaWx5IH0pO1xyXG4gICAgICAgIHhtbHEucmVtb3ZlQ2hpbGRJZkVtcHR5KHRoaXMuX2ZvbnROb2RlLCAnbmFtZScpO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRfZm9udEdlbmVyaWNGYW1pbHkoKSB7XHJcbiAgICAgICAgcmV0dXJuIHhtbHEuZ2V0Q2hpbGRBdHRyaWJ1dGUodGhpcy5fZm9udE5vZGUsICdmYW1pbHknLCBcInZhbFwiKTtcclxuICAgIH1cclxuXHJcbiAgICBfc2V0X2ZvbnRHZW5lcmljRmFtaWx5KGdlbmVyaWNGYW1pbHkpIHtcclxuICAgICAgICB4bWxxLnNldENoaWxkQXR0cmlidXRlcyh0aGlzLl9mb250Tm9kZSwgJ2ZhbWlseScsIHsgdmFsOiBnZW5lcmljRmFtaWx5IH0pO1xyXG4gICAgICAgIHhtbHEucmVtb3ZlQ2hpbGRJZkVtcHR5KHRoaXMuX2ZvbnROb2RlLCAnZmFtaWx5Jyk7XHJcbiAgICB9XHJcblxyXG4gICAgX2dldF9mb250Q29sb3IoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldENvbG9yKHRoaXMuX2ZvbnROb2RlLCBcImNvbG9yXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIF9zZXRfZm9udENvbG9yKGNvbG9yKSB7XHJcbiAgICAgICAgdGhpcy5fc2V0Q29sb3IodGhpcy5fZm9udE5vZGUsIFwiY29sb3JcIiwgY29sb3IpO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRfZm9udFNjaGVtZSgpIHtcclxuICAgICAgICAvLyBjYW4gYmUgJ21pbm9yJywgJ21ham9yJywgJ25vbmUnXHJcbiAgICAgICAgcmV0dXJuIHhtbHEuZ2V0Q2hpbGRBdHRyaWJ1dGUodGhpcy5fZm9udE5vZGUsICdzY2hlbWUnLCBcInZhbFwiKTtcclxuICAgIH1cclxuXHJcbiAgICBfc2V0X2ZvbnRTY2hlbWUoc2NoZW1lKSB7XHJcbiAgICAgICAgeG1scS5zZXRDaGlsZEF0dHJpYnV0ZXModGhpcy5fZm9udE5vZGUsICdzY2hlbWUnLCB7IHZhbDogc2NoZW1lIH0pO1xyXG4gICAgICAgIHhtbHEucmVtb3ZlQ2hpbGRJZkVtcHR5KHRoaXMuX2ZvbnROb2RlLCAnc2NoZW1lJyk7XHJcbiAgICB9XHJcblxyXG4gICAgX2dldF9ob3Jpem9udGFsQWxpZ25tZW50KCkge1xyXG4gICAgICAgIHJldHVybiB4bWxxLmdldENoaWxkQXR0cmlidXRlKHRoaXMuX3hmTm9kZSwgJ2FsaWdubWVudCcsIFwiaG9yaXpvbnRhbFwiKTtcclxuICAgIH1cclxuXHJcbiAgICBfc2V0X2hvcml6b250YWxBbGlnbm1lbnQoYWxpZ25tZW50KSB7XHJcbiAgICAgICAgeG1scS5zZXRDaGlsZEF0dHJpYnV0ZXModGhpcy5feGZOb2RlLCAnYWxpZ25tZW50JywgeyBob3Jpem9udGFsOiBhbGlnbm1lbnQgfSk7XHJcbiAgICAgICAgeG1scS5yZW1vdmVDaGlsZElmRW1wdHkodGhpcy5feGZOb2RlLCAnYWxpZ25tZW50Jyk7XHJcbiAgICB9XHJcblxyXG4gICAgX2dldF9qdXN0aWZ5TGFzdExpbmUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHhtbHEuZ2V0Q2hpbGRBdHRyaWJ1dGUodGhpcy5feGZOb2RlLCAnYWxpZ25tZW50JywgXCJqdXN0aWZ5TGFzdExpbmVcIikgPT09IDE7XHJcbiAgICB9XHJcblxyXG4gICAgX3NldF9qdXN0aWZ5TGFzdExpbmUoanVzdGlmeUxhc3RMaW5lKSB7XHJcbiAgICAgICAgeG1scS5zZXRDaGlsZEF0dHJpYnV0ZXModGhpcy5feGZOb2RlLCAnYWxpZ25tZW50JywgeyBqdXN0aWZ5TGFzdExpbmU6IGp1c3RpZnlMYXN0TGluZSA/IDEgOiBudWxsIH0pO1xyXG4gICAgICAgIHhtbHEucmVtb3ZlQ2hpbGRJZkVtcHR5KHRoaXMuX3hmTm9kZSwgJ2FsaWdubWVudCcpO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRfaW5kZW50KCkge1xyXG4gICAgICAgIHJldHVybiB4bWxxLmdldENoaWxkQXR0cmlidXRlKHRoaXMuX3hmTm9kZSwgJ2FsaWdubWVudCcsIFwiaW5kZW50XCIpO1xyXG4gICAgfVxyXG5cclxuICAgIF9zZXRfaW5kZW50KGluZGVudCkge1xyXG4gICAgICAgIHhtbHEuc2V0Q2hpbGRBdHRyaWJ1dGVzKHRoaXMuX3hmTm9kZSwgJ2FsaWdubWVudCcsIHsgaW5kZW50IH0pO1xyXG4gICAgICAgIHhtbHEucmVtb3ZlQ2hpbGRJZkVtcHR5KHRoaXMuX3hmTm9kZSwgJ2FsaWdubWVudCcpO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRfdmVydGljYWxBbGlnbm1lbnQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHhtbHEuZ2V0Q2hpbGRBdHRyaWJ1dGUodGhpcy5feGZOb2RlLCAnYWxpZ25tZW50JywgXCJ2ZXJ0aWNhbFwiKTtcclxuICAgIH1cclxuXHJcbiAgICBfc2V0X3ZlcnRpY2FsQWxpZ25tZW50KGFsaWdubWVudCkge1xyXG4gICAgICAgIHhtbHEuc2V0Q2hpbGRBdHRyaWJ1dGVzKHRoaXMuX3hmTm9kZSwgJ2FsaWdubWVudCcsIHsgdmVydGljYWw6IGFsaWdubWVudCB9KTtcclxuICAgICAgICB4bWxxLnJlbW92ZUNoaWxkSWZFbXB0eSh0aGlzLl94Zk5vZGUsICdhbGlnbm1lbnQnKTtcclxuICAgIH1cclxuXHJcbiAgICBfZ2V0X3dyYXBUZXh0KCkge1xyXG4gICAgICAgIHJldHVybiB4bWxxLmdldENoaWxkQXR0cmlidXRlKHRoaXMuX3hmTm9kZSwgJ2FsaWdubWVudCcsIFwid3JhcFRleHRcIikgPT09IDE7XHJcbiAgICB9XHJcblxyXG4gICAgX3NldF93cmFwVGV4dCh3cmFwVGV4dCkge1xyXG4gICAgICAgIHhtbHEuc2V0Q2hpbGRBdHRyaWJ1dGVzKHRoaXMuX3hmTm9kZSwgJ2FsaWdubWVudCcsIHsgd3JhcFRleHQ6IHdyYXBUZXh0ID8gMSA6IG51bGwgfSk7XHJcbiAgICAgICAgeG1scS5yZW1vdmVDaGlsZElmRW1wdHkodGhpcy5feGZOb2RlLCAnYWxpZ25tZW50Jyk7XHJcbiAgICB9XHJcblxyXG4gICAgX2dldF9zaHJpbmtUb0ZpdCgpIHtcclxuICAgICAgICByZXR1cm4geG1scS5nZXRDaGlsZEF0dHJpYnV0ZSh0aGlzLl94Zk5vZGUsICdhbGlnbm1lbnQnLCBcInNocmlua1RvRml0XCIpID09PSAxO1xyXG4gICAgfVxyXG5cclxuICAgIF9zZXRfc2hyaW5rVG9GaXQoc2hyaW5rVG9GaXQpIHtcclxuICAgICAgICB4bWxxLnNldENoaWxkQXR0cmlidXRlcyh0aGlzLl94Zk5vZGUsICdhbGlnbm1lbnQnLCB7IHNocmlua1RvRml0OiBzaHJpbmtUb0ZpdCA/IDEgOiBudWxsIH0pO1xyXG4gICAgICAgIHhtbHEucmVtb3ZlQ2hpbGRJZkVtcHR5KHRoaXMuX3hmTm9kZSwgJ2FsaWdubWVudCcpO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRfdGV4dERpcmVjdGlvbigpIHtcclxuICAgICAgICBjb25zdCByZWFkaW5nT3JkZXIgPSB4bWxxLmdldENoaWxkQXR0cmlidXRlKHRoaXMuX3hmTm9kZSwgJ2FsaWdubWVudCcsIFwicmVhZGluZ09yZGVyXCIpO1xyXG4gICAgICAgIGlmIChyZWFkaW5nT3JkZXIgPT09IDEpIHJldHVybiBcImxlZnQtdG8tcmlnaHRcIjtcclxuICAgICAgICBpZiAocmVhZGluZ09yZGVyID09PSAyKSByZXR1cm4gXCJyaWdodC10by1sZWZ0XCI7XHJcbiAgICAgICAgcmV0dXJuIHJlYWRpbmdPcmRlcjtcclxuICAgIH1cclxuXHJcbiAgICBfc2V0X3RleHREaXJlY3Rpb24odGV4dERpcmVjdGlvbikge1xyXG4gICAgICAgIGxldCByZWFkaW5nT3JkZXI7XHJcbiAgICAgICAgaWYgKHRleHREaXJlY3Rpb24gPT09IFwibGVmdC10by1yaWdodFwiKSByZWFkaW5nT3JkZXIgPSAxO1xyXG4gICAgICAgIGVsc2UgaWYgKHRleHREaXJlY3Rpb24gPT09IFwicmlnaHQtdG8tbGVmdFwiKSByZWFkaW5nT3JkZXIgPSAyO1xyXG4gICAgICAgIHhtbHEuc2V0Q2hpbGRBdHRyaWJ1dGVzKHRoaXMuX3hmTm9kZSwgJ2FsaWdubWVudCcsIHsgcmVhZGluZ09yZGVyIH0pO1xyXG4gICAgICAgIHhtbHEucmVtb3ZlQ2hpbGRJZkVtcHR5KHRoaXMuX3hmTm9kZSwgJ2FsaWdubWVudCcpO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRUZXh0Um90YXRpb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIHhtbHEuZ2V0Q2hpbGRBdHRyaWJ1dGUodGhpcy5feGZOb2RlLCAnYWxpZ25tZW50JywgXCJ0ZXh0Um90YXRpb25cIik7XHJcbiAgICB9XHJcblxyXG4gICAgX3NldFRleHRSb3RhdGlvbih0ZXh0Um90YXRpb24pIHtcclxuICAgICAgICB4bWxxLnNldENoaWxkQXR0cmlidXRlcyh0aGlzLl94Zk5vZGUsICdhbGlnbm1lbnQnLCB7IHRleHRSb3RhdGlvbiB9KTtcclxuICAgICAgICB4bWxxLnJlbW92ZUNoaWxkSWZFbXB0eSh0aGlzLl94Zk5vZGUsICdhbGlnbm1lbnQnKTtcclxuICAgIH1cclxuXHJcbiAgICBfZ2V0X3RleHRSb3RhdGlvbigpIHtcclxuICAgICAgICBsZXQgdGV4dFJvdGF0aW9uID0gdGhpcy5fZ2V0VGV4dFJvdGF0aW9uKCk7XHJcblxyXG4gICAgICAgIC8vIE5lZ2F0aXZlIGFuZ2xlcyBpbiBFeGNlbCBjb3JyZXNwb25kIHRvIHZhbHVlcyA+IDkwIGluIE9PWE1MLlxyXG4gICAgICAgIGlmICh0ZXh0Um90YXRpb24gPiA5MCkgdGV4dFJvdGF0aW9uID0gOTAgLSB0ZXh0Um90YXRpb247XHJcbiAgICAgICAgcmV0dXJuIHRleHRSb3RhdGlvbjtcclxuICAgIH1cclxuXHJcbiAgICBfc2V0X3RleHRSb3RhdGlvbih0ZXh0Um90YXRpb24pIHtcclxuICAgICAgICAvLyBOZWdhdGl2ZSBhbmdsZXMgaW4gRXhjZWwgY29ycmVzcG9uZCB0byB2YWx1ZXMgPiA5MCBpbiBPT1hNTC5cclxuICAgICAgICBpZiAodGV4dFJvdGF0aW9uIDwgMCkgdGV4dFJvdGF0aW9uID0gOTAgLSB0ZXh0Um90YXRpb247XHJcbiAgICAgICAgdGhpcy5fc2V0VGV4dFJvdGF0aW9uKHRleHRSb3RhdGlvbik7XHJcbiAgICB9XHJcblxyXG4gICAgX2dldF9hbmdsZVRleHRDb3VudGVyY2xvY2t3aXNlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRUZXh0Um90YXRpb24oKSA9PT0gNDU7XHJcbiAgICB9XHJcblxyXG4gICAgX3NldF9hbmdsZVRleHRDb3VudGVyY2xvY2t3aXNlKHZhbHVlKSB7XHJcbiAgICAgICAgdGhpcy5fc2V0VGV4dFJvdGF0aW9uKHZhbHVlID8gNDUgOiBudWxsKTtcclxuICAgIH1cclxuXHJcbiAgICBfZ2V0X2FuZ2xlVGV4dENsb2Nrd2lzZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0VGV4dFJvdGF0aW9uKCkgPT09IDEzNTtcclxuICAgIH1cclxuXHJcbiAgICBfc2V0X2FuZ2xlVGV4dENsb2Nrd2lzZSh2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuX3NldFRleHRSb3RhdGlvbih2YWx1ZSA/IDEzNSA6IG51bGwpO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRfcm90YXRlVGV4dFVwKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRUZXh0Um90YXRpb24oKSA9PT0gOTA7XHJcbiAgICB9XHJcblxyXG4gICAgX3NldF9yb3RhdGVUZXh0VXAodmFsdWUpIHtcclxuICAgICAgICB0aGlzLl9zZXRUZXh0Um90YXRpb24odmFsdWUgPyA5MCA6IG51bGwpO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRfcm90YXRlVGV4dERvd24oKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldFRleHRSb3RhdGlvbigpID09PSAxODA7XHJcbiAgICB9XHJcblxyXG4gICAgX3NldF9yb3RhdGVUZXh0RG93bih2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuX3NldFRleHRSb3RhdGlvbih2YWx1ZSA/IDE4MCA6IG51bGwpO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRfdmVydGljYWxUZXh0KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRUZXh0Um90YXRpb24oKSA9PT0gMjU1O1xyXG4gICAgfVxyXG5cclxuICAgIF9zZXRfdmVydGljYWxUZXh0KHZhbHVlKSB7XHJcbiAgICAgICAgdGhpcy5fc2V0VGV4dFJvdGF0aW9uKHZhbHVlID8gMjU1IDogbnVsbCk7XHJcbiAgICB9XHJcblxyXG4gICAgX2dldF9maWxsKCkge1xyXG4gICAgICAgIGNvbnN0IHBhdHRlcm5GaWxsTm9kZSA9IHhtbHEuZmluZENoaWxkKHRoaXMuX2ZpbGxOb2RlLCAncGF0dGVybkZpbGwnKTsvLyBqcS5nZXQodGhpcy5fZmlsbE5vZGUsIFwicGF0dGVybkZpbGxbMF1cIik7XHJcbiAgICAgICAgY29uc3QgZ3JhZGllbnRGaWxsTm9kZSA9IHhtbHEuZmluZENoaWxkKHRoaXMuX2ZpbGxOb2RlLCAnZ3JhZGllbnRGaWxsJyk7Ly8ganEuZ2V0KHRoaXMuX2ZpbGxOb2RlLCBcImdyYWRpZW50RmlsbFswXVwiKTtcclxuICAgICAgICBjb25zdCBwYXR0ZXJuVHlwZSA9IHBhdHRlcm5GaWxsTm9kZSAmJiBwYXR0ZXJuRmlsbE5vZGUuYXR0cmlidXRlcy5wYXR0ZXJuVHlwZTsvLyBqcS5nZXQocGF0dGVybkZpbGxOb2RlLCBcIiQucGF0dGVyblR5cGVcIik7XHJcblxyXG4gICAgICAgIGlmIChwYXR0ZXJuVHlwZSA9PT0gXCJzb2xpZFwiKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiBcInNvbGlkXCIsXHJcbiAgICAgICAgICAgICAgICBjb2xvcjogdGhpcy5fZ2V0Q29sb3IocGF0dGVybkZpbGxOb2RlLCBcImZnQ29sb3JcIilcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChwYXR0ZXJuVHlwZSkge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogXCJwYXR0ZXJuXCIsXHJcbiAgICAgICAgICAgICAgICBwYXR0ZXJuOiBwYXR0ZXJuVHlwZSxcclxuICAgICAgICAgICAgICAgIGZvcmVncm91bmQ6IHRoaXMuX2dldENvbG9yKHBhdHRlcm5GaWxsTm9kZSwgXCJmZ0NvbG9yXCIpLFxyXG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZDogdGhpcy5fZ2V0Q29sb3IocGF0dGVybkZpbGxOb2RlLCBcImJnQ29sb3JcIilcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChncmFkaWVudEZpbGxOb2RlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGdyYWRpZW50VHlwZSA9IGdyYWRpZW50RmlsbE5vZGUuYXR0cmlidXRlcy50eXBlIHx8IFwibGluZWFyXCI7XHJcbiAgICAgICAgICAgIGNvbnN0IGZpbGwgPSB7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiBcImdyYWRpZW50XCIsXHJcbiAgICAgICAgICAgICAgICBncmFkaWVudFR5cGUsXHJcbiAgICAgICAgICAgICAgICBzdG9wczogXy5tYXAoZ3JhZGllbnRGaWxsTm9kZS5jaGlsZHJlbiwgc3RvcCA9PiAoe1xyXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiBzdG9wLmF0dHJpYnV0ZXMucG9zaXRpb24sXHJcbiAgICAgICAgICAgICAgICAgICAgY29sb3I6IHRoaXMuX2dldENvbG9yKHN0b3AsIFwiY29sb3JcIilcclxuICAgICAgICAgICAgICAgIH0pKVxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgaWYgKGdyYWRpZW50VHlwZSA9PT0gXCJsaW5lYXJcIikge1xyXG4gICAgICAgICAgICAgICAgZmlsbC5hbmdsZSA9IGdyYWRpZW50RmlsbE5vZGUuYXR0cmlidXRlcy5kZWdyZWU7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBmaWxsLmxlZnQgPSBncmFkaWVudEZpbGxOb2RlLmF0dHJpYnV0ZXMubGVmdDtcclxuICAgICAgICAgICAgICAgIGZpbGwucmlnaHQgPSBncmFkaWVudEZpbGxOb2RlLmF0dHJpYnV0ZXMucmlnaHQ7XHJcbiAgICAgICAgICAgICAgICBmaWxsLnRvcCA9IGdyYWRpZW50RmlsbE5vZGUuYXR0cmlidXRlcy50b3A7XHJcbiAgICAgICAgICAgICAgICBmaWxsLmJvdHRvbSA9IGdyYWRpZW50RmlsbE5vZGUuYXR0cmlidXRlcy5ib3R0b207XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBmaWxsO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfc2V0X2ZpbGwoZmlsbCkge1xyXG4gICAgICAgIHRoaXMuX2ZpbGxOb2RlLmNoaWxkcmVuID0gW107XHJcblxyXG4gICAgICAgIC8vIE5vIGZpbGxcclxuICAgICAgICBpZiAoXy5pc05pbChmaWxsKSkgcmV0dXJuO1xyXG5cclxuICAgICAgICAvLyBQYXR0ZXJuIGZpbGxcclxuICAgICAgICBpZiAoZmlsbC50eXBlID09PSBcInBhdHRlcm5cIikge1xyXG4gICAgICAgICAgICBjb25zdCBwYXR0ZXJuRmlsbCA9IHtcclxuICAgICAgICAgICAgICAgIG5hbWU6ICdwYXR0ZXJuRmlsbCcsXHJcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7IHBhdHRlcm5UeXBlOiBmaWxsLnBhdHRlcm4gfSxcclxuICAgICAgICAgICAgICAgIGNoaWxkcmVuOiBbXVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB0aGlzLl9maWxsTm9kZS5jaGlsZHJlbi5wdXNoKHBhdHRlcm5GaWxsKTtcclxuICAgICAgICAgICAgdGhpcy5fc2V0Q29sb3IocGF0dGVybkZpbGwsIFwiZmdDb2xvclwiLCBmaWxsLmZvcmVncm91bmQpO1xyXG4gICAgICAgICAgICB0aGlzLl9zZXRDb2xvcihwYXR0ZXJuRmlsbCwgXCJiZ0NvbG9yXCIsIGZpbGwuYmFja2dyb3VuZCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEdyYWRpZW50IGZpbGxcclxuICAgICAgICBpZiAoZmlsbC50eXBlID09PSBcImdyYWRpZW50XCIpIHtcclxuICAgICAgICAgICAgY29uc3QgZ3JhZGllbnRGaWxsID0geyBuYW1lOiAnZ3JhZGllbnRGaWxsJywgYXR0cmlidXRlczoge30sIGNoaWxkcmVuOiBbXSB9O1xyXG4gICAgICAgICAgICB0aGlzLl9maWxsTm9kZS5jaGlsZHJlbi5wdXNoKGdyYWRpZW50RmlsbCk7XHJcbiAgICAgICAgICAgIHhtbHEuc2V0QXR0cmlidXRlcyhncmFkaWVudEZpbGwsIHtcclxuICAgICAgICAgICAgICAgIHR5cGU6IGZpbGwuZ3JhZGllbnRUeXBlID09PSBcInBhdGhcIiA/IFwicGF0aFwiIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICAgICAgbGVmdDogZmlsbC5sZWZ0LFxyXG4gICAgICAgICAgICAgICAgcmlnaHQ6IGZpbGwucmlnaHQsXHJcbiAgICAgICAgICAgICAgICB0b3A6IGZpbGwudG9wLFxyXG4gICAgICAgICAgICAgICAgYm90dG9tOiBmaWxsLmJvdHRvbSxcclxuICAgICAgICAgICAgICAgIGRlZ3JlZTogZmlsbC5hbmdsZVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIF8uZm9yRWFjaChmaWxsLnN0b3BzLCAoZmlsbFN0b3AsIGkpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHN0b3AgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJ3N0b3AnLFxyXG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHsgcG9zaXRpb246IGZpbGxTdG9wLnBvc2l0aW9uIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW46IFtdXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgZ3JhZGllbnRGaWxsLmNoaWxkcmVuLnB1c2goc3RvcCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXRDb2xvcihzdG9wLCAnY29sb3InLCBmaWxsU3RvcC5jb2xvcik7XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gU29saWQgZmlsbCAocmVhbGx5IGEgcGF0dGVybiBmaWxsIHdpdGggYSBzb2xpZCBwYXR0ZXJuIHR5cGUpLlxyXG4gICAgICAgIGlmICghXy5pc09iamVjdChmaWxsKSkgZmlsbCA9IHsgdHlwZTogXCJzb2xpZFwiLCBjb2xvcjogZmlsbCB9O1xyXG4gICAgICAgIGVsc2UgaWYgKGZpbGwuaGFzT3duUHJvcGVydHkoJ3JnYicpIHx8IGZpbGwuaGFzT3duUHJvcGVydHkoXCJ0aGVtZVwiKSkgZmlsbCA9IHsgY29sb3I6IGZpbGwgfTtcclxuXHJcbiAgICAgICAgY29uc3QgcGF0dGVybkZpbGwgPSB7XHJcbiAgICAgICAgICAgIG5hbWU6ICdwYXR0ZXJuRmlsbCcsXHJcbiAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHsgcGF0dGVyblR5cGU6ICdzb2xpZCcgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgdGhpcy5fZmlsbE5vZGUuY2hpbGRyZW4ucHVzaChwYXR0ZXJuRmlsbCk7XHJcbiAgICAgICAgdGhpcy5fc2V0Q29sb3IocGF0dGVybkZpbGwsIFwiZmdDb2xvclwiLCBmaWxsLmNvbG9yKTtcclxuICAgIH1cclxuXHJcbiAgICBfZ2V0Qm9yZGVyKCkge1xyXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHt9O1xyXG4gICAgICAgIFtcImxlZnRcIiwgXCJyaWdodFwiLCBcInRvcFwiLCBcImJvdHRvbVwiLCBcImRpYWdvbmFsXCJdLmZvckVhY2goc2lkZSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHNpZGVOb2RlID0geG1scS5maW5kQ2hpbGQodGhpcy5fYm9yZGVyTm9kZSwgc2lkZSk7XHJcbiAgICAgICAgICAgIGNvbnN0IHNpZGVSZXN1bHQgPSB7fTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHN0eWxlID0geG1scS5nZXRDaGlsZEF0dHJpYnV0ZSh0aGlzLl9ib3JkZXJOb2RlLCBzaWRlLCAnc3R5bGUnKTtcclxuICAgICAgICAgICAgaWYgKHN0eWxlKSBzaWRlUmVzdWx0LnN0eWxlID0gc3R5bGU7XHJcbiAgICAgICAgICAgIGNvbnN0IGNvbG9yID0gdGhpcy5fZ2V0Q29sb3Ioc2lkZU5vZGUsICdjb2xvcicpO1xyXG4gICAgICAgICAgICBpZiAoY29sb3IpIHNpZGVSZXN1bHQuY29sb3IgPSBjb2xvcjtcclxuXHJcbiAgICAgICAgICAgIGlmIChzaWRlID09PSBcImRpYWdvbmFsXCIpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHVwID0gdGhpcy5fYm9yZGVyTm9kZS5hdHRyaWJ1dGVzLmRpYWdvbmFsVXA7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBkb3duID0gdGhpcy5fYm9yZGVyTm9kZS5hdHRyaWJ1dGVzLmRpYWdvbmFsRG93bjtcclxuICAgICAgICAgICAgICAgIGxldCBkaXJlY3Rpb247XHJcbiAgICAgICAgICAgICAgICBpZiAodXAgJiYgZG93bikgZGlyZWN0aW9uID0gXCJib3RoXCI7XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh1cCkgZGlyZWN0aW9uID0gXCJ1cFwiO1xyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoZG93bikgZGlyZWN0aW9uID0gXCJkb3duXCI7XHJcbiAgICAgICAgICAgICAgICBpZiAoZGlyZWN0aW9uKSBzaWRlUmVzdWx0LmRpcmVjdGlvbiA9IGRpcmVjdGlvbjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCFfLmlzRW1wdHkoc2lkZVJlc3VsdCkpIHJlc3VsdFtzaWRlXSA9IHNpZGVSZXN1bHQ7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9XHJcblxyXG4gICAgX3NldEJvcmRlcihzZXR0aW5ncykge1xyXG4gICAgICAgIF8uZm9yT3duKHNldHRpbmdzLCAoc2V0dGluZywgc2lkZSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHNldHRpbmcgPT09IFwiYm9vbGVhblwiKSB7XHJcbiAgICAgICAgICAgICAgICBzZXR0aW5nID0geyBzdHlsZTogc2V0dGluZyA/IFwidGhpblwiIDogbnVsbCB9O1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXR0aW5nID09PSBcInN0cmluZ1wiKSB7XHJcbiAgICAgICAgICAgICAgICBzZXR0aW5nID0geyBzdHlsZTogc2V0dGluZyB9O1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHNldHRpbmcgPT09IG51bGwgfHwgc2V0dGluZyA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICBzZXR0aW5nID0geyBzdHlsZTogbnVsbCwgY29sb3I6IG51bGwsIGRpcmVjdGlvbjogbnVsbCB9O1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoc2V0dGluZy5oYXNPd25Qcm9wZXJ0eShcInN0eWxlXCIpKSB7XHJcbiAgICAgICAgICAgICAgICB4bWxxLnNldENoaWxkQXR0cmlidXRlcyh0aGlzLl9ib3JkZXJOb2RlLCBzaWRlLCB7IHN0eWxlOiBzZXR0aW5nLnN0eWxlIH0pO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoc2V0dGluZy5oYXNPd25Qcm9wZXJ0eShcImNvbG9yXCIpKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBzaWRlTm9kZSA9IHhtbHEuZmluZENoaWxkKHRoaXMuX2JvcmRlck5vZGUsIHNpZGUpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fc2V0Q29sb3Ioc2lkZU5vZGUsIFwiY29sb3JcIiwgc2V0dGluZy5jb2xvcik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChzaWRlID09PSBcImRpYWdvbmFsXCIpIHtcclxuICAgICAgICAgICAgICAgIHhtbHEuc2V0QXR0cmlidXRlcyh0aGlzLl9ib3JkZXJOb2RlLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGlhZ29uYWxVcDogc2V0dGluZy5kaXJlY3Rpb24gPT09IFwidXBcIiB8fCBzZXR0aW5nLmRpcmVjdGlvbiA9PT0gXCJib3RoXCIgPyAxIDogbnVsbCxcclxuICAgICAgICAgICAgICAgICAgICBkaWFnb25hbERvd246IHNldHRpbmcuZGlyZWN0aW9uID09PSBcImRvd25cIiB8fCBzZXR0aW5nLmRpcmVjdGlvbiA9PT0gXCJib3RoXCIgPyAxIDogbnVsbFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBfZ2V0X2JvcmRlcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Qm9yZGVyKCk7XHJcbiAgICB9XHJcblxyXG4gICAgX3NldF9ib3JkZXIoc2V0dGluZ3MpIHtcclxuICAgICAgICBpZiAoXy5pc09iamVjdChzZXR0aW5ncykgJiYgIXNldHRpbmdzLmhhc093blByb3BlcnR5KFwic3R5bGVcIikgJiYgIXNldHRpbmdzLmhhc093blByb3BlcnR5KFwiY29sb3JcIikpIHtcclxuICAgICAgICAgICAgc2V0dGluZ3MgPSBfLmRlZmF1bHRzKHNldHRpbmdzLCB7XHJcbiAgICAgICAgICAgICAgICBsZWZ0OiBudWxsLFxyXG4gICAgICAgICAgICAgICAgcmlnaHQ6IG51bGwsXHJcbiAgICAgICAgICAgICAgICB0b3A6IG51bGwsXHJcbiAgICAgICAgICAgICAgICBib3R0b206IG51bGwsXHJcbiAgICAgICAgICAgICAgICBkaWFnb25hbDogbnVsbFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgdGhpcy5fc2V0Qm9yZGVyKHNldHRpbmdzKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9zZXRCb3JkZXIoe1xyXG4gICAgICAgICAgICAgICAgbGVmdDogc2V0dGluZ3MsXHJcbiAgICAgICAgICAgICAgICByaWdodDogc2V0dGluZ3MsXHJcbiAgICAgICAgICAgICAgICB0b3A6IHNldHRpbmdzLFxyXG4gICAgICAgICAgICAgICAgYm90dG9tOiBzZXR0aW5nc1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgX2dldF9ib3JkZXJDb2xvcigpIHtcclxuICAgICAgICByZXR1cm4gXy5tYXBWYWx1ZXModGhpcy5fZ2V0Qm9yZGVyKCksIHZhbHVlID0+IHZhbHVlLmNvbG9yKTtcclxuICAgIH1cclxuXHJcbiAgICBfc2V0X2JvcmRlckNvbG9yKGNvbG9yKSB7XHJcbiAgICAgICAgaWYgKF8uaXNPYmplY3QoY29sb3IpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3NldEJvcmRlcihfLm1hcFZhbHVlcyhjb2xvciwgY29sb3IgPT4gKHsgY29sb3IgfSkpKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9zZXRCb3JkZXIoe1xyXG4gICAgICAgICAgICAgICAgbGVmdDogeyBjb2xvciB9LFxyXG4gICAgICAgICAgICAgICAgcmlnaHQ6IHsgY29sb3IgfSxcclxuICAgICAgICAgICAgICAgIHRvcDogeyBjb2xvciB9LFxyXG4gICAgICAgICAgICAgICAgYm90dG9tOiB7IGNvbG9yIH0sXHJcbiAgICAgICAgICAgICAgICBkaWFnb25hbDogeyBjb2xvciB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfZ2V0X2JvcmRlclN0eWxlKCkge1xyXG4gICAgICAgIHJldHVybiBfLm1hcFZhbHVlcyh0aGlzLl9nZXRCb3JkZXIoKSwgdmFsdWUgPT4gdmFsdWUuc3R5bGUpO1xyXG4gICAgfVxyXG5cclxuICAgIF9zZXRfYm9yZGVyU3R5bGUoc3R5bGUpIHtcclxuICAgICAgICBpZiAoXy5pc09iamVjdChzdHlsZSkpIHtcclxuICAgICAgICAgICAgdGhpcy5fc2V0Qm9yZGVyKF8ubWFwVmFsdWVzKHN0eWxlLCBzdHlsZSA9PiAoeyBzdHlsZSB9KSkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3NldEJvcmRlcih7XHJcbiAgICAgICAgICAgICAgICBsZWZ0OiB7IHN0eWxlIH0sXHJcbiAgICAgICAgICAgICAgICByaWdodDogeyBzdHlsZSB9LFxyXG4gICAgICAgICAgICAgICAgdG9wOiB7IHN0eWxlIH0sXHJcbiAgICAgICAgICAgICAgICBib3R0b206IHsgc3R5bGUgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgX2dldF9kaWFnb25hbEJvcmRlckRpcmVjdGlvbigpIHtcclxuICAgICAgICBjb25zdCBib3JkZXIgPSB0aGlzLl9nZXRCb3JkZXIoKS5kaWFnb25hbDtcclxuICAgICAgICByZXR1cm4gYm9yZGVyICYmIGJvcmRlci5kaXJlY3Rpb247XHJcbiAgICB9XHJcblxyXG4gICAgX3NldF9kaWFnb25hbEJvcmRlckRpcmVjdGlvbihkaXJlY3Rpb24pIHtcclxuICAgICAgICB0aGlzLl9zZXRCb3JkZXIoeyBkaWFnb25hbDogeyBkaXJlY3Rpb24gfSB9KTtcclxuICAgIH1cclxuXHJcbiAgICBfZ2V0X251bWJlckZvcm1hdCgpIHtcclxuICAgICAgICBjb25zdCBudW1GbXRJZCA9IHRoaXMuX3hmTm9kZS5hdHRyaWJ1dGVzLm51bUZtdElkIHx8IDA7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0eWxlU2hlZXQuZ2V0TnVtYmVyRm9ybWF0Q29kZShudW1GbXRJZCk7XHJcbiAgICB9XHJcblxyXG4gICAgX3NldF9udW1iZXJGb3JtYXQoZm9ybWF0Q29kZSkge1xyXG4gICAgICAgIHRoaXMuX3hmTm9kZS5hdHRyaWJ1dGVzLm51bUZtdElkID0gdGhpcy5fc3R5bGVTaGVldC5nZXROdW1iZXJGb3JtYXRJZChmb3JtYXRDb2RlKTtcclxuICAgIH1cclxufVxyXG5cclxuW1wibGVmdFwiLCBcInJpZ2h0XCIsIFwidG9wXCIsIFwiYm90dG9tXCIsIFwiZGlhZ29uYWxcIl0uZm9yRWFjaChzaWRlID0+IHtcclxuICAgIFN0eWxlLnByb3RvdHlwZVtgX2dldF8ke3NpZGV9Qm9yZGVyYF0gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldEJvcmRlcigpW3NpZGVdO1xyXG4gICAgfTtcclxuXHJcbiAgICBTdHlsZS5wcm90b3R5cGVbYF9zZXRfJHtzaWRlfUJvcmRlcmBdID0gZnVuY3Rpb24gKHNldHRpbmdzKSB7XHJcbiAgICAgICAgdGhpcy5fc2V0Qm9yZGVyKHsgW3NpZGVdOiBzZXR0aW5ncyB9KTtcclxuICAgIH07XHJcblxyXG4gICAgU3R5bGUucHJvdG90eXBlW2BfZ2V0XyR7c2lkZX1Cb3JkZXJDb2xvcmBdID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGNvbnN0IGJvcmRlciA9IHRoaXMuX2dldEJvcmRlcigpW3NpZGVdO1xyXG4gICAgICAgIHJldHVybiBib3JkZXIgJiYgYm9yZGVyLmNvbG9yO1xyXG4gICAgfTtcclxuXHJcbiAgICBTdHlsZS5wcm90b3R5cGVbYF9zZXRfJHtzaWRlfUJvcmRlckNvbG9yYF0gPSBmdW5jdGlvbiAoY29sb3IpIHtcclxuICAgICAgICB0aGlzLl9zZXRCb3JkZXIoeyBbc2lkZV06IHsgY29sb3IgfSB9KTtcclxuICAgIH07XHJcblxyXG4gICAgU3R5bGUucHJvdG90eXBlW2BfZ2V0XyR7c2lkZX1Cb3JkZXJTdHlsZWBdID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGNvbnN0IGJvcmRlciA9IHRoaXMuX2dldEJvcmRlcigpW3NpZGVdO1xyXG4gICAgICAgIHJldHVybiBib3JkZXIgJiYgYm9yZGVyLnN0eWxlO1xyXG4gICAgfTtcclxuXHJcbiAgICBTdHlsZS5wcm90b3R5cGVbYF9zZXRfJHtzaWRlfUJvcmRlclN0eWxlYF0gPSBmdW5jdGlvbiAoc3R5bGUpIHtcclxuICAgICAgICB0aGlzLl9zZXRCb3JkZXIoeyBbc2lkZV06IHsgc3R5bGUgfSB9KTtcclxuICAgIH07XHJcbn0pO1xyXG5cclxuLy8gSUUgZG9lc24ndCBzdXBwb3J0IGZ1bmN0aW9uIG5hbWVzIHNvIGV4cGxpY2l0bHkgc2V0IGl0LlxyXG5pZiAoIVN0eWxlLm5hbWUpIFN0eWxlLm5hbWUgPSBcIlN0eWxlXCI7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IFN0eWxlO1xyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxuXHJcbmNvbnN0IF8gPSByZXF1aXJlKFwibG9kYXNoXCIpO1xyXG5jb25zdCB4bWxxID0gcmVxdWlyZShcIi4veG1scVwiKTtcclxuY29uc3QgU3R5bGUgPSByZXF1aXJlKFwiLi9TdHlsZVwiKTtcclxuXHJcbi8qKlxyXG4gKiBTdGFuZGFyZCBudW1iZXIgZm9ybWF0IGNvZGVzXHJcbiAqIFRha2VuIGZyb20gaHR0cDovL3BvbHltYXRocHJvZ3JhbW1lci5jb20vMjAxMS8wMi8xNS9idWlsdC1pbi1zdHlsZXMtZm9yLWV4Y2VsLW9wZW4teG1sL1xyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuY29uc3QgU1RBTkRBUkRfQ09ERVMgPSB7XHJcbiAgICAwOiAnR2VuZXJhbCcsXHJcbiAgICAxOiAnMCcsXHJcbiAgICAyOiAnMC4wMCcsXHJcbiAgICAzOiAnIywjIzAnLFxyXG4gICAgNDogJyMsIyMwLjAwJyxcclxuICAgIDk6ICcwJScsXHJcbiAgICAxMDogJzAuMDAlJyxcclxuICAgIDExOiAnMC4wMEUrMDAnLFxyXG4gICAgMTI6ICcjID8vPycsXHJcbiAgICAxMzogJyMgPz8vPz8nLFxyXG4gICAgMTQ6ICdtbS1kZC15eScsXHJcbiAgICAxNTogJ2QtbW1tLXl5JyxcclxuICAgIDE2OiAnZC1tbW0nLFxyXG4gICAgMTc6ICdtbW0teXknLFxyXG4gICAgMTg6ICdoOm1tIEFNL1BNJyxcclxuICAgIDE5OiAnaDptbTpzcyBBTS9QTScsXHJcbiAgICAyMDogJ2g6bW0nLFxyXG4gICAgMjE6ICdoOm1tOnNzJyxcclxuICAgIDIyOiAnbS9kL3l5IGg6bW0nLFxyXG4gICAgMzc6ICcjLCMjMCA7KCMsIyMwKScsXHJcbiAgICAzODogJyMsIyMwIDtbUmVkXSgjLCMjMCknLFxyXG4gICAgMzk6ICcjLCMjMC4wMDsoIywjIzAuMDApJyxcclxuICAgIDQwOiAnIywjIzAuMDA7W1JlZF0oIywjIzAuMDApJyxcclxuICAgIDQ1OiAnbW06c3MnLFxyXG4gICAgNDY6ICdbaF06bW06c3MnLFxyXG4gICAgNDc6ICdtbXNzLjAnLFxyXG4gICAgNDg6ICcjIzAuMEUrMCcsXHJcbiAgICA0OTogJ0AnXHJcbn07XHJcblxyXG4vKipcclxuICogVGhlIHN0YXJ0aW5nIElEIGZvciBjdXN0b20gbnVtYmVyIGZvcm1hdHMuIFRoZSBmaXJzdCAxNjMgaW5kZXhlcyBhcmUgcmVzZXJ2ZWQuXHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5jb25zdCBTVEFSVElOR19DVVNUT01fTlVNQkVSX0ZPUk1BVF9JRCA9IDE2NDtcclxuXHJcbi8qKlxyXG4gKiBBIHN0eWxlIHNoZWV0LlxyXG4gKiBAaWdub3JlXHJcbiAqL1xyXG5jbGFzcyBTdHlsZVNoZWV0IHtcclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBfU3R5bGVTaGVldC5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBub2RlIC0gVGhlIHN0eWxlIHNoZWV0IG5vZGVcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3Iobm9kZSkge1xyXG4gICAgICAgIHRoaXMuX2luaXQobm9kZSk7XHJcbiAgICAgICAgdGhpcy5fY2FjaGVOdW1iZXJGb3JtYXRzKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGUgYSBzdHlsZS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc291cmNlSWRdIC0gVGhlIHNvdXJjZSBzdHlsZSBJRCB0byBjb3B5LCBpZiBwcm92aWRlZC5cclxuICAgICAqIEByZXR1cm5zIHtTdHlsZX0gVGhlIHN0eWxlLlxyXG4gICAgICovXHJcbiAgICBjcmVhdGVTdHlsZShzb3VyY2VJZCkge1xyXG4gICAgICAgIGxldCBmb250Tm9kZSwgZmlsbE5vZGUsIGJvcmRlck5vZGUsIHhmTm9kZTtcclxuICAgICAgICBpZiAoc291cmNlSWQgPj0gMCkge1xyXG4gICAgICAgICAgICBjb25zdCBzb3VyY2VYZk5vZGUgPSB0aGlzLl9jZWxsWGZzTm9kZS5jaGlsZHJlbltzb3VyY2VJZF07XHJcbiAgICAgICAgICAgIHhmTm9kZSA9IF8uY2xvbmVEZWVwKHNvdXJjZVhmTm9kZSk7XHJcblxyXG4gICAgICAgICAgICBpZiAoc291cmNlWGZOb2RlLmF0dHJpYnV0ZXMuYXBwbHlGb250KSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBmb250SWQgPSBzb3VyY2VYZk5vZGUuYXR0cmlidXRlcy5mb250SWQ7XHJcbiAgICAgICAgICAgICAgICBmb250Tm9kZSA9IF8uY2xvbmVEZWVwKHRoaXMuX2ZvbnRzTm9kZS5jaGlsZHJlbltmb250SWRdKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHNvdXJjZVhmTm9kZS5hdHRyaWJ1dGVzLmFwcGx5RmlsbCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZmlsbElkID0gc291cmNlWGZOb2RlLmF0dHJpYnV0ZXMuZmlsbElkO1xyXG4gICAgICAgICAgICAgICAgZmlsbE5vZGUgPSBfLmNsb25lRGVlcCh0aGlzLl9maWxsc05vZGUuY2hpbGRyZW5bZmlsbElkXSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChzb3VyY2VYZk5vZGUuYXR0cmlidXRlcy5hcHBseUJvcmRlcikge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgYm9yZGVySWQgPSBzb3VyY2VYZk5vZGUuYXR0cmlidXRlcy5ib3JkZXJJZDtcclxuICAgICAgICAgICAgICAgIGJvcmRlck5vZGUgPSBfLmNsb25lRGVlcCh0aGlzLl9ib3JkZXJzTm9kZS5jaGlsZHJlbltib3JkZXJJZF0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIWZvbnROb2RlKSBmb250Tm9kZSA9IHsgbmFtZTogXCJmb250XCIsIGF0dHJpYnV0ZXM6IHt9LCBjaGlsZHJlbjogW10gfTtcclxuICAgICAgICB0aGlzLl9mb250c05vZGUuY2hpbGRyZW4ucHVzaChmb250Tm9kZSk7XHJcblxyXG4gICAgICAgIGlmICghZmlsbE5vZGUpIGZpbGxOb2RlID0geyBuYW1lOiBcImZpbGxcIiwgYXR0cmlidXRlczoge30sIGNoaWxkcmVuOiBbXSB9O1xyXG4gICAgICAgIHRoaXMuX2ZpbGxzTm9kZS5jaGlsZHJlbi5wdXNoKGZpbGxOb2RlKTtcclxuXHJcbiAgICAgICAgLy8gVGhlIGJvcmRlciBzaWRlcyBtdXN0IGJlIGluIG9yZGVyXHJcbiAgICAgICAgaWYgKCFib3JkZXJOb2RlKSBib3JkZXJOb2RlID0geyBuYW1lOiBcImJvcmRlclwiLCBhdHRyaWJ1dGVzOiB7fSwgY2hpbGRyZW46IFtdIH07XHJcbiAgICAgICAgYm9yZGVyTm9kZS5jaGlsZHJlbiA9IFtcclxuICAgICAgICAgICAgeG1scS5maW5kQ2hpbGQoYm9yZGVyTm9kZSwgXCJsZWZ0XCIpIHx8IHsgbmFtZTogXCJsZWZ0XCIsIGF0dHJpYnV0ZXM6IHt9LCBjaGlsZHJlbjogW10gfSxcclxuICAgICAgICAgICAgeG1scS5maW5kQ2hpbGQoYm9yZGVyTm9kZSwgXCJyaWdodFwiKSB8fCB7IG5hbWU6IFwicmlnaHRcIiwgYXR0cmlidXRlczoge30sIGNoaWxkcmVuOiBbXSB9LFxyXG4gICAgICAgICAgICB4bWxxLmZpbmRDaGlsZChib3JkZXJOb2RlLCBcInRvcFwiKSB8fCB7IG5hbWU6IFwidG9wXCIsIGF0dHJpYnV0ZXM6IHt9LCBjaGlsZHJlbjogW10gfSxcclxuICAgICAgICAgICAgeG1scS5maW5kQ2hpbGQoYm9yZGVyTm9kZSwgXCJib3R0b21cIikgfHwgeyBuYW1lOiBcImJvdHRvbVwiLCBhdHRyaWJ1dGVzOiB7fSwgY2hpbGRyZW46IFtdIH0sXHJcbiAgICAgICAgICAgIHhtbHEuZmluZENoaWxkKGJvcmRlck5vZGUsIFwiZGlhZ29uYWxcIikgfHwgeyBuYW1lOiBcImRpYWdvbmFsXCIsIGF0dHJpYnV0ZXM6IHt9LCBjaGlsZHJlbjogW10gfVxyXG4gICAgICAgIF07XHJcbiAgICAgICAgdGhpcy5fYm9yZGVyc05vZGUuY2hpbGRyZW4ucHVzaChib3JkZXJOb2RlKTtcclxuXHJcbiAgICAgICAgaWYgKCF4Zk5vZGUpIHhmTm9kZSA9IHsgbmFtZTogXCJ4ZlwiLCBhdHRyaWJ1dGVzOiB7fSwgY2hpbGRyZW46IFtdIH07XHJcbiAgICAgICAgXy5hc3NpZ24oeGZOb2RlLmF0dHJpYnV0ZXMsIHtcclxuICAgICAgICAgICAgZm9udElkOiB0aGlzLl9mb250c05vZGUuY2hpbGRyZW4ubGVuZ3RoIC0gMSxcclxuICAgICAgICAgICAgZmlsbElkOiB0aGlzLl9maWxsc05vZGUuY2hpbGRyZW4ubGVuZ3RoIC0gMSxcclxuICAgICAgICAgICAgYm9yZGVySWQ6IHRoaXMuX2JvcmRlcnNOb2RlLmNoaWxkcmVuLmxlbmd0aCAtIDEsXHJcbiAgICAgICAgICAgIGFwcGx5Rm9udDogMSxcclxuICAgICAgICAgICAgYXBwbHlGaWxsOiAxLFxyXG4gICAgICAgICAgICBhcHBseUJvcmRlcjogMVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLl9jZWxsWGZzTm9kZS5jaGlsZHJlbi5wdXNoKHhmTm9kZSk7XHJcblxyXG4gICAgICAgIHJldHVybiBuZXcgU3R5bGUodGhpcywgdGhpcy5fY2VsbFhmc05vZGUuY2hpbGRyZW4ubGVuZ3RoIC0gMSwgeGZOb2RlLCBmb250Tm9kZSwgZmlsbE5vZGUsIGJvcmRlck5vZGUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0IHRoZSBudW1iZXIgZm9ybWF0IGNvZGUgZm9yIGEgZ2l2ZW4gSUQuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gaWQgLSBUaGUgbnVtYmVyIGZvcm1hdCBJRC5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBmb3JtYXQgY29kZS5cclxuICAgICAqL1xyXG4gICAgZ2V0TnVtYmVyRm9ybWF0Q29kZShpZCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9udW1iZXJGb3JtYXRDb2Rlc0J5SWRbaWRdO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0IHRoZSBudXVtYmVyIGZvcm1hdCBJRCBmb3IgYSBnaXZlbiBjb2RlLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNvZGUgLSBUaGUgZm9ybWF0IGNvZGUuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgbnVtYmVyIGZvcm1hdCBJRC5cclxuICAgICAqL1xyXG4gICAgZ2V0TnVtYmVyRm9ybWF0SWQoY29kZSkge1xyXG4gICAgICAgIGxldCBpZCA9IHRoaXMuX251bWJlckZvcm1hdElkc0J5Q29kZVtjb2RlXTtcclxuICAgICAgICBpZiAoaWQgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBpZCA9IHRoaXMuX25leHROdW1Gb3JtYXRJZCsrO1xyXG4gICAgICAgICAgICB0aGlzLl9udW1iZXJGb3JtYXRDb2Rlc0J5SWRbaWRdID0gY29kZTtcclxuICAgICAgICAgICAgdGhpcy5fbnVtYmVyRm9ybWF0SWRzQnlDb2RlW2NvZGVdID0gaWQ7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9udW1GbXRzTm9kZS5jaGlsZHJlbi5wdXNoKHtcclxuICAgICAgICAgICAgICAgIG5hbWU6ICdudW1GbXQnLFxyXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlczoge1xyXG4gICAgICAgICAgICAgICAgICAgIG51bUZtdElkOiBpZCxcclxuICAgICAgICAgICAgICAgICAgICBmb3JtYXRDb2RlOiBjb2RlXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGlkO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydCB0aGUgc3R5bGUgc2hlZXQgdG8gYW4gWE1MIG9iamVjdC5cclxuICAgICAqIEByZXR1cm5zIHt7fX0gVGhlIFhNTCBmb3JtLlxyXG4gICAgICogQGlnbm9yZVxyXG4gICAgICovXHJcbiAgICB0b1htbCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbm9kZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENhY2hlIHRoZSBudW1iZXIgZm9ybWF0IGNvZGVzXHJcbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgX2NhY2hlTnVtYmVyRm9ybWF0cygpIHtcclxuICAgICAgICAvLyBMb2FkIHRoZSBzdGFuZGFyZCBudW1iZXIgZm9ybWF0IGNvZGVzIGludG8gdGhlIGNhY2hlcy5cclxuICAgICAgICB0aGlzLl9udW1iZXJGb3JtYXRDb2Rlc0J5SWQgPSB7fTtcclxuICAgICAgICB0aGlzLl9udW1iZXJGb3JtYXRJZHNCeUNvZGUgPSB7fTtcclxuICAgICAgICBmb3IgKGNvbnN0IGlkIGluIFNUQU5EQVJEX0NPREVTKSB7XHJcbiAgICAgICAgICAgIGlmICghU1RBTkRBUkRfQ09ERVMuaGFzT3duUHJvcGVydHkoaWQpKSBjb250aW51ZTtcclxuICAgICAgICAgICAgY29uc3QgY29kZSA9IFNUQU5EQVJEX0NPREVTW2lkXTtcclxuICAgICAgICAgICAgdGhpcy5fbnVtYmVyRm9ybWF0Q29kZXNCeUlkW2lkXSA9IGNvZGU7XHJcbiAgICAgICAgICAgIHRoaXMuX251bWJlckZvcm1hdElkc0J5Q29kZVtjb2RlXSA9IHBhcnNlSW50KGlkKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFNldCB0aGUgbmV4dCBudW1iZXIgZm9ybWF0IGNvZGUuXHJcbiAgICAgICAgdGhpcy5fbmV4dE51bUZvcm1hdElkID0gU1RBUlRJTkdfQ1VTVE9NX05VTUJFUl9GT1JNQVRfSUQ7XHJcblxyXG4gICAgICAgIC8vIElmIHRoZXJlIGFyZSBjdXN0b20gbnVtYmVyIGZvcm1hdHMsIGNhY2hlIHRoZW0gYWxsIGFuZCB1cGRhdGUgdGhlIG5leHQgbnVtIGFzIG5lZWRlZC5cclxuICAgICAgICB0aGlzLl9udW1GbXRzTm9kZS5jaGlsZHJlbi5mb3JFYWNoKG5vZGUgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBpZCA9IG5vZGUuYXR0cmlidXRlcy5udW1GbXRJZDtcclxuICAgICAgICAgICAgY29uc3QgY29kZSA9IG5vZGUuYXR0cmlidXRlcy5mb3JtYXRDb2RlO1xyXG4gICAgICAgICAgICB0aGlzLl9udW1iZXJGb3JtYXRDb2Rlc0J5SWRbaWRdID0gY29kZTtcclxuICAgICAgICAgICAgdGhpcy5fbnVtYmVyRm9ybWF0SWRzQnlDb2RlW2NvZGVdID0gaWQ7XHJcbiAgICAgICAgICAgIGlmIChpZCA+PSB0aGlzLl9uZXh0TnVtRm9ybWF0SWQpIHRoaXMuX25leHROdW1Gb3JtYXRJZCA9IGlkICsgMTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEluaXRpYWxpemUgdGhlIHN0eWxlIHNoZWV0IG5vZGUuXHJcbiAgICAgKiBAcGFyYW0ge3t9fSBbbm9kZV0gLSBUaGUgbm9kZVxyXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIF9pbml0KG5vZGUpIHtcclxuICAgICAgICB0aGlzLl9ub2RlID0gbm9kZTtcclxuXHJcbiAgICAgICAgLy8gQ2FjaGUgdGhlIHJlZnMgdG8gdGhlIGNvbGxlY3Rpb25zLlxyXG4gICAgICAgIHRoaXMuX251bUZtdHNOb2RlID0geG1scS5maW5kQ2hpbGQodGhpcy5fbm9kZSwgXCJudW1GbXRzXCIpO1xyXG4gICAgICAgIHRoaXMuX2ZvbnRzTm9kZSA9IHhtbHEuZmluZENoaWxkKHRoaXMuX25vZGUsIFwiZm9udHNcIik7XHJcbiAgICAgICAgdGhpcy5fZmlsbHNOb2RlID0geG1scS5maW5kQ2hpbGQodGhpcy5fbm9kZSwgXCJmaWxsc1wiKTtcclxuICAgICAgICB0aGlzLl9ib3JkZXJzTm9kZSA9IHhtbHEuZmluZENoaWxkKHRoaXMuX25vZGUsIFwiYm9yZGVyc1wiKTtcclxuICAgICAgICB0aGlzLl9jZWxsWGZzTm9kZSA9IHhtbHEuZmluZENoaWxkKHRoaXMuX25vZGUsIFwiY2VsbFhmc1wiKTtcclxuXHJcbiAgICAgICAgaWYgKCF0aGlzLl9udW1GbXRzTm9kZSkge1xyXG4gICAgICAgICAgICB0aGlzLl9udW1GbXRzTm9kZSA9IHtcclxuICAgICAgICAgICAgICAgIG5hbWU6IFwibnVtRm10c1wiLFxyXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlczoge30sXHJcbiAgICAgICAgICAgICAgICBjaGlsZHJlbjogW11cclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIC8vIE51bWJlciBmb3JtYXRzIG5lZWQgdG8gYmUgYmVmb3JlIHRoZSBvdGhlcnMuXHJcbiAgICAgICAgICAgIHhtbHEuaW5zZXJ0QmVmb3JlKHRoaXMuX25vZGUsIHRoaXMuX251bUZtdHNOb2RlLCB0aGlzLl9mb250c05vZGUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gUmVtb3ZlIHRoZSBvcHRpb25hbCBjb3VudHMgc28gd2UgZG9uJ3QgaGF2ZSB0byBrZWVwIHRoZW0gdXAgdG8gZGF0ZS5cclxuICAgICAgICBkZWxldGUgdGhpcy5fbnVtRm10c05vZGUuYXR0cmlidXRlcy5jb3VudDtcclxuICAgICAgICBkZWxldGUgdGhpcy5fZm9udHNOb2RlLmF0dHJpYnV0ZXMuY291bnQ7XHJcbiAgICAgICAgZGVsZXRlIHRoaXMuX2ZpbGxzTm9kZS5hdHRyaWJ1dGVzLmNvdW50O1xyXG4gICAgICAgIGRlbGV0ZSB0aGlzLl9ib3JkZXJzTm9kZS5hdHRyaWJ1dGVzLmNvdW50O1xyXG4gICAgICAgIGRlbGV0ZSB0aGlzLl9jZWxsWGZzTm9kZS5hdHRyaWJ1dGVzLmNvdW50O1xyXG4gICAgfVxyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IFN0eWxlU2hlZXQ7XHJcblxyXG4vKlxyXG54bC9zdHlsZXMueG1sXHJcblxyXG48P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJVVEYtOFwiIHN0YW5kYWxvbmU9XCJ5ZXNcIj8+XHJcbjxzdHlsZVNoZWV0IHhtbG5zPVwiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL3NwcmVhZHNoZWV0bWwvMjAwNi9tYWluXCIgeG1sbnM6bWM9XCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvbWFya3VwLWNvbXBhdGliaWxpdHkvMjAwNlwiIG1jOklnbm9yYWJsZT1cIngxNGFjIHgxNnIyXCIgeG1sbnM6eDE0YWM9XCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL29mZmljZS9zcHJlYWRzaGVldG1sLzIwMDkvOS9hY1wiIHhtbG5zOngxNnIyPVwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9vZmZpY2Uvc3ByZWFkc2hlZXRtbC8yMDE1LzAyL21haW5cIj5cclxuICAgIDxudW1GbXRzIGNvdW50PVwiMVwiPlxyXG4gICAgICAgIDxudW1GbXQgbnVtRm10SWQ9XCIxNjRcIiBmb3JtYXRDb2RlPVwiIywjIzBfKTtbUmVkXVxcKCMsIyMwXFwpXFwpXCIvPlxyXG4gICAgPC9udW1GbXRzPlxyXG4gICAgPGZvbnRzIGNvdW50PVwiMVwiIHgxNGFjOmtub3duRm9udHM9XCIxXCI+XHJcbiAgICAgICAgPGZvbnQ+XHJcbiAgICAgICAgICAgIDxzeiB2YWw9XCIxMVwiLz5cclxuICAgICAgICAgICAgPGNvbG9yIHRoZW1lPVwiMVwiLz5cclxuICAgICAgICAgICAgPG5hbWUgdmFsPVwiQ2FsaWJyaVwiLz5cclxuICAgICAgICAgICAgPGZhbWlseSB2YWw9XCIyXCIvPlxyXG4gICAgICAgICAgICA8c2NoZW1lIHZhbD1cIm1pbm9yXCIvPlxyXG4gICAgICAgIDwvZm9udD5cclxuICAgIDwvZm9udHM+XHJcbiAgICA8ZmlsbHMgY291bnQ9XCIxMVwiPlxyXG4gICAgICAgIDxmaWxsPlxyXG4gICAgICAgICAgICA8cGF0dGVybkZpbGwgcGF0dGVyblR5cGU9XCJub25lXCIvPlxyXG4gICAgICAgIDwvZmlsbD5cclxuICAgICAgICA8ZmlsbD5cclxuICAgICAgICAgICAgPHBhdHRlcm5GaWxsIHBhdHRlcm5UeXBlPVwiZ3JheTEyNVwiLz5cclxuICAgICAgICA8L2ZpbGw+XHJcbiAgICAgICAgPGZpbGw+XHJcbiAgICAgICAgICAgIDxwYXR0ZXJuRmlsbCBwYXR0ZXJuVHlwZT1cInNvbGlkXCI+XHJcbiAgICAgICAgICAgICAgICA8ZmdDb2xvciByZ2I9XCJGRkMwMDAwMFwiLz5cclxuICAgICAgICAgICAgICAgIDxiZ0NvbG9yIGluZGV4ZWQ9XCI2NFwiLz5cclxuICAgICAgICAgICAgPC9wYXR0ZXJuRmlsbD5cclxuICAgICAgICA8L2ZpbGw+XHJcbiAgICAgICAgPGZpbGw+XHJcbiAgICAgICAgICAgIDxwYXR0ZXJuRmlsbCBwYXR0ZXJuVHlwZT1cImxpZ2h0RG93blwiPlxyXG4gICAgICAgICAgICAgICAgPGZnQ29sb3IgdGhlbWU9XCI0XCIvPlxyXG4gICAgICAgICAgICAgICAgPGJnQ29sb3IgcmdiPVwiRkZDMDAwMDBcIi8+XHJcbiAgICAgICAgICAgIDwvcGF0dGVybkZpbGw+XHJcbiAgICAgICAgPC9maWxsPlxyXG4gICAgICAgIDxmaWxsPlxyXG4gICAgICAgICAgICA8Z3JhZGllbnRGaWxsIGRlZ3JlZT1cIjkwXCI+XHJcbiAgICAgICAgICAgICAgICA8c3RvcCBwb3NpdGlvbj1cIjBcIj5cclxuICAgICAgICAgICAgICAgICAgICA8Y29sb3IgdGhlbWU9XCIwXCIvPlxyXG4gICAgICAgICAgICAgICAgPC9zdG9wPlxyXG4gICAgICAgICAgICAgICAgPHN0b3AgcG9zaXRpb249XCIxXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGNvbG9yIHRoZW1lPVwiNFwiLz5cclxuICAgICAgICAgICAgICAgIDwvc3RvcD5cclxuICAgICAgICAgICAgPC9ncmFkaWVudEZpbGw+XHJcbiAgICAgICAgPC9maWxsPlxyXG4gICAgICAgIDxmaWxsPlxyXG4gICAgICAgICAgICA8Z3JhZGllbnRGaWxsPlxyXG4gICAgICAgICAgICAgICAgPHN0b3AgcG9zaXRpb249XCIwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGNvbG9yIHRoZW1lPVwiMFwiLz5cclxuICAgICAgICAgICAgICAgIDwvc3RvcD5cclxuICAgICAgICAgICAgICAgIDxzdG9wIHBvc2l0aW9uPVwiMVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxjb2xvciB0aGVtZT1cIjRcIi8+XHJcbiAgICAgICAgICAgICAgICA8L3N0b3A+XHJcbiAgICAgICAgICAgIDwvZ3JhZGllbnRGaWxsPlxyXG4gICAgICAgIDwvZmlsbD5cclxuICAgICAgICA8ZmlsbD5cclxuICAgICAgICAgICAgPGdyYWRpZW50RmlsbCBkZWdyZWU9XCI0NVwiPlxyXG4gICAgICAgICAgICAgICAgPHN0b3AgcG9zaXRpb249XCIwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGNvbG9yIHRoZW1lPVwiMFwiLz5cclxuICAgICAgICAgICAgICAgIDwvc3RvcD5cclxuICAgICAgICAgICAgICAgIDxzdG9wIHBvc2l0aW9uPVwiMVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxjb2xvciB0aGVtZT1cIjRcIi8+XHJcbiAgICAgICAgICAgICAgICA8L3N0b3A+XHJcbiAgICAgICAgICAgIDwvZ3JhZGllbnRGaWxsPlxyXG4gICAgICAgIDwvZmlsbD5cclxuICAgICAgICA8ZmlsbD5cclxuICAgICAgICAgICAgPGdyYWRpZW50RmlsbCBkZWdyZWU9XCIxMzVcIj5cclxuICAgICAgICAgICAgICAgIDxzdG9wIHBvc2l0aW9uPVwiMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxjb2xvciB0aGVtZT1cIjBcIi8+XHJcbiAgICAgICAgICAgICAgICA8L3N0b3A+XHJcbiAgICAgICAgICAgICAgICA8c3RvcCBwb3NpdGlvbj1cIjFcIj5cclxuICAgICAgICAgICAgICAgICAgICA8Y29sb3IgdGhlbWU9XCI0XCIvPlxyXG4gICAgICAgICAgICAgICAgPC9zdG9wPlxyXG4gICAgICAgICAgICA8L2dyYWRpZW50RmlsbD5cclxuICAgICAgICA8L2ZpbGw+XHJcbiAgICAgICAgPGZpbGw+XHJcbiAgICAgICAgICAgIDxncmFkaWVudEZpbGwgdHlwZT1cInBhdGhcIj5cclxuICAgICAgICAgICAgICAgIDxzdG9wIHBvc2l0aW9uPVwiMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxjb2xvciB0aGVtZT1cIjBcIi8+XHJcbiAgICAgICAgICAgICAgICA8L3N0b3A+XHJcbiAgICAgICAgICAgICAgICA8c3RvcCBwb3NpdGlvbj1cIjFcIj5cclxuICAgICAgICAgICAgICAgICAgICA8Y29sb3IgdGhlbWU9XCI0XCIvPlxyXG4gICAgICAgICAgICAgICAgPC9zdG9wPlxyXG4gICAgICAgICAgICA8L2dyYWRpZW50RmlsbD5cclxuICAgICAgICA8L2ZpbGw+XHJcbiAgICAgICAgPGZpbGw+XHJcbiAgICAgICAgICAgIDxncmFkaWVudEZpbGwgdHlwZT1cInBhdGhcIiBsZWZ0PVwiMC41XCIgcmlnaHQ9XCIwLjVcIiB0b3A9XCIwLjVcIiBib3R0b209XCIwLjVcIj5cclxuICAgICAgICAgICAgICAgIDxzdG9wIHBvc2l0aW9uPVwiMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxjb2xvciB0aGVtZT1cIjBcIi8+XHJcbiAgICAgICAgICAgICAgICA8L3N0b3A+XHJcbiAgICAgICAgICAgICAgICA8c3RvcCBwb3NpdGlvbj1cIjFcIj5cclxuICAgICAgICAgICAgICAgICAgICA8Y29sb3IgdGhlbWU9XCI0XCIvPlxyXG4gICAgICAgICAgICAgICAgPC9zdG9wPlxyXG4gICAgICAgICAgICA8L2dyYWRpZW50RmlsbD5cclxuICAgICAgICA8L2ZpbGw+XHJcbiAgICAgICAgPGZpbGw+XHJcbiAgICAgICAgICAgIDxncmFkaWVudEZpbGwgZGVncmVlPVwiMjcwXCI+XHJcbiAgICAgICAgICAgICAgICA8c3RvcCBwb3NpdGlvbj1cIjBcIj5cclxuICAgICAgICAgICAgICAgICAgICA8Y29sb3IgdGhlbWU9XCIwXCIvPlxyXG4gICAgICAgICAgICAgICAgPC9zdG9wPlxyXG4gICAgICAgICAgICAgICAgPHN0b3AgcG9zaXRpb249XCIxXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGNvbG9yIHRoZW1lPVwiNFwiLz5cclxuICAgICAgICAgICAgICAgIDwvc3RvcD5cclxuICAgICAgICAgICAgPC9ncmFkaWVudEZpbGw+XHJcbiAgICAgICAgPC9maWxsPlxyXG4gICAgPC9maWxscz5cclxuICAgIDxib3JkZXJzIGNvdW50PVwiMTBcIj5cclxuICAgICAgICA8Ym9yZGVyPlxyXG4gICAgICAgICAgICA8bGVmdC8+XHJcbiAgICAgICAgICAgIDxyaWdodC8+XHJcbiAgICAgICAgICAgIDx0b3AvPlxyXG4gICAgICAgICAgICA8Ym90dG9tLz5cclxuICAgICAgICAgICAgPGRpYWdvbmFsLz5cclxuICAgICAgICA8L2JvcmRlcj5cclxuICAgICAgICA8Ym9yZGVyIGRpYWdvbmFsRG93bj1cIjFcIj5cclxuICAgICAgICAgICAgPGxlZnQvPlxyXG4gICAgICAgICAgICA8cmlnaHQvPlxyXG4gICAgICAgICAgICA8dG9wLz5cclxuICAgICAgICAgICAgPGJvdHRvbS8+XHJcbiAgICAgICAgICAgIDxkaWFnb25hbCBzdHlsZT1cImhhaXJcIj5cclxuICAgICAgICAgICAgICAgIDxjb2xvciBhdXRvPVwiMVwiLz5cclxuICAgICAgICAgICAgPC9kaWFnb25hbD5cclxuICAgICAgICA8L2JvcmRlcj5cclxuICAgICAgICA8Ym9yZGVyIGRpYWdvbmFsRG93bj1cIjFcIj5cclxuICAgICAgICAgICAgPGxlZnQvPlxyXG4gICAgICAgICAgICA8cmlnaHQvPlxyXG4gICAgICAgICAgICA8dG9wLz5cclxuICAgICAgICAgICAgPGJvdHRvbS8+XHJcbiAgICAgICAgICAgIDxkaWFnb25hbCBzdHlsZT1cImRvdHRlZFwiPlxyXG4gICAgICAgICAgICAgICAgPGNvbG9yIGF1dG89XCIxXCIvPlxyXG4gICAgICAgICAgICA8L2RpYWdvbmFsPlxyXG4gICAgICAgIDwvYm9yZGVyPlxyXG4gICAgICAgIDxib3JkZXIgZGlhZ29uYWxEb3duPVwiMVwiPlxyXG4gICAgICAgICAgICA8bGVmdC8+XHJcbiAgICAgICAgICAgIDxyaWdodC8+XHJcbiAgICAgICAgICAgIDx0b3AvPlxyXG4gICAgICAgICAgICA8Ym90dG9tLz5cclxuICAgICAgICAgICAgPGRpYWdvbmFsIHN0eWxlPVwiZGFzaERvdERvdFwiPlxyXG4gICAgICAgICAgICAgICAgPGNvbG9yIGF1dG89XCIxXCIvPlxyXG4gICAgICAgICAgICA8L2RpYWdvbmFsPlxyXG4gICAgICAgIDwvYm9yZGVyPlxyXG4gICAgICAgIDxib3JkZXIgZGlhZ29uYWxEb3duPVwiMVwiPlxyXG4gICAgICAgICAgICA8bGVmdC8+XHJcbiAgICAgICAgICAgIDxyaWdodC8+XHJcbiAgICAgICAgICAgIDx0b3AvPlxyXG4gICAgICAgICAgICA8Ym90dG9tLz5cclxuICAgICAgICAgICAgPGRpYWdvbmFsIHN0eWxlPVwiZGFzaERvdFwiPlxyXG4gICAgICAgICAgICAgICAgPGNvbG9yIGF1dG89XCIxXCIvPlxyXG4gICAgICAgICAgICA8L2RpYWdvbmFsPlxyXG4gICAgICAgIDwvYm9yZGVyPlxyXG4gICAgICAgIDxib3JkZXIgZGlhZ29uYWxEb3duPVwiMVwiPlxyXG4gICAgICAgICAgICA8bGVmdC8+XHJcbiAgICAgICAgICAgIDxyaWdodC8+XHJcbiAgICAgICAgICAgIDx0b3AvPlxyXG4gICAgICAgICAgICA8Ym90dG9tLz5cclxuICAgICAgICAgICAgPGRpYWdvbmFsIHN0eWxlPVwiZGFzaGVkXCI+XHJcbiAgICAgICAgICAgICAgICA8Y29sb3IgYXV0bz1cIjFcIi8+XHJcbiAgICAgICAgICAgIDwvZGlhZ29uYWw+XHJcbiAgICAgICAgPC9ib3JkZXI+XHJcbiAgICAgICAgPGJvcmRlciBkaWFnb25hbFVwPVwiMVwiPlxyXG4gICAgICAgICAgICA8bGVmdC8+XHJcbiAgICAgICAgICAgIDxyaWdodC8+XHJcbiAgICAgICAgICAgIDx0b3AvPlxyXG4gICAgICAgICAgICA8Ym90dG9tLz5cclxuICAgICAgICAgICAgPGRpYWdvbmFsIHN0eWxlPVwibWVkaXVtRGFzaERvdERvdFwiPlxyXG4gICAgICAgICAgICAgICAgPGNvbG9yIGF1dG89XCIxXCIvPlxyXG4gICAgICAgICAgICA8L2RpYWdvbmFsPlxyXG4gICAgICAgIDwvYm9yZGVyPlxyXG4gICAgICAgIDxib3JkZXIgZGlhZ29uYWxVcD1cIjFcIj5cclxuICAgICAgICAgICAgPGxlZnQvPlxyXG4gICAgICAgICAgICA8cmlnaHQvPlxyXG4gICAgICAgICAgICA8dG9wLz5cclxuICAgICAgICAgICAgPGJvdHRvbS8+XHJcbiAgICAgICAgICAgIDxkaWFnb25hbCBzdHlsZT1cInNsYW50RGFzaERvdFwiPlxyXG4gICAgICAgICAgICAgICAgPGNvbG9yIGF1dG89XCIxXCIvPlxyXG4gICAgICAgICAgICA8L2RpYWdvbmFsPlxyXG4gICAgICAgIDwvYm9yZGVyPlxyXG4gICAgICAgIDxib3JkZXIgZGlhZ29uYWxVcD1cIjFcIj5cclxuICAgICAgICAgICAgPGxlZnQvPlxyXG4gICAgICAgICAgICA8cmlnaHQvPlxyXG4gICAgICAgICAgICA8dG9wLz5cclxuICAgICAgICAgICAgPGJvdHRvbS8+XHJcbiAgICAgICAgICAgIDxkaWFnb25hbCBzdHlsZT1cIm1lZGl1bURhc2hEb3RcIj5cclxuICAgICAgICAgICAgICAgIDxjb2xvciBhdXRvPVwiMVwiLz5cclxuICAgICAgICAgICAgPC9kaWFnb25hbD5cclxuICAgICAgICA8L2JvcmRlcj5cclxuICAgICAgICA8Ym9yZGVyIGRpYWdvbmFsVXA9XCIxXCI+XHJcbiAgICAgICAgICAgIDxsZWZ0Lz5cclxuICAgICAgICAgICAgPHJpZ2h0Lz5cclxuICAgICAgICAgICAgPHRvcC8+XHJcbiAgICAgICAgICAgIDxib3R0b20vPlxyXG4gICAgICAgICAgICA8ZGlhZ29uYWwgc3R5bGU9XCJtZWRpdW1EYXNoZWRcIj5cclxuICAgICAgICAgICAgICAgIDxjb2xvciBhdXRvPVwiMVwiLz5cclxuICAgICAgICAgICAgPC9kaWFnb25hbD5cclxuICAgICAgICA8L2JvcmRlcj5cclxuICAgIDwvYm9yZGVycz5cclxuICAgIDxjZWxsU3R5bGVYZnMgY291bnQ9XCIxXCI+XHJcbiAgICAgICAgPHhmIG51bUZtdElkPVwiMFwiIGZvbnRJZD1cIjBcIiBmaWxsSWQ9XCIwXCIgYm9yZGVySWQ9XCIwXCIvPlxyXG4gICAgPC9jZWxsU3R5bGVYZnM+XHJcbiAgICA8Y2VsbFhmcyBjb3VudD1cIjE5XCI+XHJcbiAgICAgICAgPHhmIG51bUZtdElkPVwiMFwiIGZvbnRJZD1cIjBcIiBmaWxsSWQ9XCIwXCIgYm9yZGVySWQ9XCIwXCIgeGZJZD1cIjBcIi8+XHJcbiAgICAgICAgPHhmIG51bUZtdElkPVwiMFwiIGZvbnRJZD1cIjBcIiBmaWxsSWQ9XCIwXCIgYm9yZGVySWQ9XCIxXCIgeGZJZD1cIjBcIiBhcHBseUJvcmRlcj1cIjFcIi8+XHJcbiAgICAgICAgPHhmIG51bUZtdElkPVwiMFwiIGZvbnRJZD1cIjBcIiBmaWxsSWQ9XCIwXCIgYm9yZGVySWQ9XCIyXCIgeGZJZD1cIjBcIiBhcHBseUJvcmRlcj1cIjFcIi8+XHJcbiAgICAgICAgPHhmIG51bUZtdElkPVwiMFwiIGZvbnRJZD1cIjBcIiBmaWxsSWQ9XCIwXCIgYm9yZGVySWQ9XCIzXCIgeGZJZD1cIjBcIiBhcHBseUJvcmRlcj1cIjFcIi8+XHJcbiAgICAgICAgPHhmIG51bUZtdElkPVwiMFwiIGZvbnRJZD1cIjBcIiBmaWxsSWQ9XCIwXCIgYm9yZGVySWQ9XCI0XCIgeGZJZD1cIjBcIiBhcHBseUJvcmRlcj1cIjFcIi8+XHJcbiAgICAgICAgPHhmIG51bUZtdElkPVwiMFwiIGZvbnRJZD1cIjBcIiBmaWxsSWQ9XCIwXCIgYm9yZGVySWQ9XCI1XCIgeGZJZD1cIjBcIiBhcHBseUJvcmRlcj1cIjFcIi8+XHJcbiAgICAgICAgPHhmIG51bUZtdElkPVwiMFwiIGZvbnRJZD1cIjBcIiBmaWxsSWQ9XCIwXCIgYm9yZGVySWQ9XCI2XCIgeGZJZD1cIjBcIiBhcHBseUJvcmRlcj1cIjFcIi8+XHJcbiAgICAgICAgPHhmIG51bUZtdElkPVwiMFwiIGZvbnRJZD1cIjBcIiBmaWxsSWQ9XCIwXCIgYm9yZGVySWQ9XCI3XCIgeGZJZD1cIjBcIiBhcHBseUJvcmRlcj1cIjFcIi8+XHJcbiAgICAgICAgPHhmIG51bUZtdElkPVwiMFwiIGZvbnRJZD1cIjBcIiBmaWxsSWQ9XCIwXCIgYm9yZGVySWQ9XCI4XCIgeGZJZD1cIjBcIiBhcHBseUJvcmRlcj1cIjFcIi8+XHJcbiAgICAgICAgPHhmIG51bUZtdElkPVwiMFwiIGZvbnRJZD1cIjBcIiBmaWxsSWQ9XCIwXCIgYm9yZGVySWQ9XCI5XCIgeGZJZD1cIjBcIiBhcHBseUJvcmRlcj1cIjFcIi8+XHJcbiAgICAgICAgPHhmIG51bUZtdElkPVwiMFwiIGZvbnRJZD1cIjBcIiBmaWxsSWQ9XCIyXCIgYm9yZGVySWQ9XCIwXCIgeGZJZD1cIjBcIiBhcHBseUZpbGw9XCIxXCIgYXBwbHlCb3JkZXI9XCIxXCIvPlxyXG4gICAgICAgIDx4ZiBudW1GbXRJZD1cIjBcIiBmb250SWQ9XCIwXCIgZmlsbElkPVwiM1wiIGJvcmRlcklkPVwiMFwiIHhmSWQ9XCIwXCIgYXBwbHlGaWxsPVwiMVwiLz5cclxuICAgICAgICA8eGYgbnVtRm10SWQ9XCIwXCIgZm9udElkPVwiMFwiIGZpbGxJZD1cIjRcIiBib3JkZXJJZD1cIjBcIiB4ZklkPVwiMFwiIGFwcGx5RmlsbD1cIjFcIi8+XHJcbiAgICAgICAgPHhmIG51bUZtdElkPVwiMFwiIGZvbnRJZD1cIjBcIiBmaWxsSWQ9XCI1XCIgYm9yZGVySWQ9XCIwXCIgeGZJZD1cIjBcIiBhcHBseUZpbGw9XCIxXCIvPlxyXG4gICAgICAgIDx4ZiBudW1GbXRJZD1cIjBcIiBmb250SWQ9XCIwXCIgZmlsbElkPVwiNlwiIGJvcmRlcklkPVwiMFwiIHhmSWQ9XCIwXCIgYXBwbHlGaWxsPVwiMVwiLz5cclxuICAgICAgICA8eGYgbnVtRm10SWQ9XCIwXCIgZm9udElkPVwiMFwiIGZpbGxJZD1cIjdcIiBib3JkZXJJZD1cIjBcIiB4ZklkPVwiMFwiIGFwcGx5RmlsbD1cIjFcIi8+XHJcbiAgICAgICAgPHhmIG51bUZtdElkPVwiMFwiIGZvbnRJZD1cIjBcIiBmaWxsSWQ9XCI4XCIgYm9yZGVySWQ9XCIwXCIgeGZJZD1cIjBcIiBhcHBseUZpbGw9XCIxXCIvPlxyXG4gICAgICAgIDx4ZiBudW1GbXRJZD1cIjBcIiBmb250SWQ9XCIwXCIgZmlsbElkPVwiOVwiIGJvcmRlcklkPVwiMFwiIHhmSWQ9XCIwXCIgYXBwbHlGaWxsPVwiMVwiLz5cclxuICAgICAgICA8eGYgbnVtRm10SWQ9XCIwXCIgZm9udElkPVwiMFwiIGZpbGxJZD1cIjEwXCIgYm9yZGVySWQ9XCIwXCIgeGZJZD1cIjBcIiBhcHBseUZpbGw9XCIxXCIvPlxyXG4gICAgPC9jZWxsWGZzPlxyXG4gICAgPGNlbGxTdHlsZXMgY291bnQ9XCIxXCI+XHJcbiAgICAgICAgPGNlbGxTdHlsZSBuYW1lPVwiTm9ybWFsXCIgeGZJZD1cIjBcIiBidWlsdGluSWQ9XCIwXCIvPlxyXG4gICAgPC9jZWxsU3R5bGVzPlxyXG4gICAgPGR4ZnMgY291bnQ9XCIwXCIvPlxyXG4gICAgPHRhYmxlU3R5bGVzIGNvdW50PVwiMFwiIGRlZmF1bHRUYWJsZVN0eWxlPVwiVGFibGVTdHlsZU1lZGl1bTJcIiBkZWZhdWx0UGl2b3RTdHlsZT1cIlBpdm90U3R5bGVMaWdodDE2XCIvPlxyXG4gICAgPGV4dExzdD5cclxuICAgICAgICA8ZXh0IHVyaT1cIntFQjc5REVGMi04MEI4LTQzZTUtOTVCRC01NENCRERGOTAyMEN9XCIgeG1sbnM6eDE0PVwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9vZmZpY2Uvc3ByZWFkc2hlZXRtbC8yMDA5LzkvbWFpblwiPlxyXG4gICAgICAgICAgICA8eDE0OnNsaWNlclN0eWxlcyBkZWZhdWx0U2xpY2VyU3R5bGU9XCJTbGljZXJTdHlsZUxpZ2h0MVwiLz5cclxuICAgICAgICA8L2V4dD5cclxuICAgICAgICA8ZXh0IHVyaT1cIns5MjYwQTUxMC1GMzAxLTQ2YTgtODYzNS1GNTEyRDY0QkU1RjV9XCIgeG1sbnM6eDE1PVwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9vZmZpY2Uvc3ByZWFkc2hlZXRtbC8yMDEwLzExL21haW5cIj5cclxuICAgICAgICAgICAgPHgxNTp0aW1lbGluZVN0eWxlcyBkZWZhdWx0VGltZWxpbmVTdHlsZT1cIlRpbWVTbGljZXJTdHlsZUxpZ2h0MVwiLz5cclxuICAgICAgICA8L2V4dD5cclxuICAgIDwvZXh0THN0PlxyXG48L3N0eWxlU2hlZXQ+XHJcbiovXHJcbiIsIlwidXNlIHN0cmljdFwiO1xyXG5cclxuY29uc3QgXyA9IHJlcXVpcmUoXCJsb2Rhc2hcIik7XHJcbmNvbnN0IGZzID0gcmVxdWlyZShcImZzXCIpO1xyXG5jb25zdCBKU1ppcCA9IHJlcXVpcmUoJ2pzemlwJyk7XHJcblxyXG5jb25zdCBleHRlcm5hbHMgPSByZXF1aXJlKFwiLi9leHRlcm5hbHNcIik7XHJcbmNvbnN0IHJlZ2V4aWZ5ID0gcmVxdWlyZShcIi4vcmVnZXhpZnlcIik7XHJcbmNvbnN0IGJsYW5rID0gcmVxdWlyZShcIi4vYmxhbmtcIikoKTtcclxuY29uc3QgeG1scSA9IHJlcXVpcmUoXCIuL3htbHFcIik7XHJcbmNvbnN0IFNoZWV0ID0gcmVxdWlyZShcIi4vU2hlZXRcIik7XHJcbmNvbnN0IENvbnRlbnRUeXBlcyA9IHJlcXVpcmUoXCIuL0NvbnRlbnRUeXBlc1wiKTtcclxuY29uc3QgQXBwUHJvcGVydGllcyA9IHJlcXVpcmUoXCIuL0FwcFByb3BlcnRpZXNcIik7XHJcbmNvbnN0IENvcmVQcm9wZXJ0aWVzID0gcmVxdWlyZShcIi4vQ29yZVByb3BlcnRpZXNcIik7XHJcbmNvbnN0IFJlbGF0aW9uc2hpcHMgPSByZXF1aXJlKFwiLi9SZWxhdGlvbnNoaXBzXCIpO1xyXG5jb25zdCBTaGFyZWRTdHJpbmdzID0gcmVxdWlyZShcIi4vU2hhcmVkU3RyaW5nc1wiKTtcclxuY29uc3QgU3R5bGVTaGVldCA9IHJlcXVpcmUoXCIuL1N0eWxlU2hlZXRcIik7XHJcbmNvbnN0IEVuY3J5cHRvciA9IHJlcXVpcmUoXCIuL0VuY3J5cHRvclwiKTtcclxuY29uc3QgWG1sUGFyc2VyID0gcmVxdWlyZShcIi4vWG1sUGFyc2VyXCIpO1xyXG5jb25zdCBYbWxCdWlsZGVyID0gcmVxdWlyZShcIi4vWG1sQnVpbGRlclwiKTtcclxuY29uc3QgQXJnSGFuZGxlciA9IHJlcXVpcmUoXCIuL0FyZ0hhbmRsZXJcIik7XHJcbmNvbnN0IGFkZHJlc3NDb252ZXJ0ZXIgPSByZXF1aXJlKFwiLi9hZGRyZXNzQ29udmVydGVyXCIpO1xyXG5cclxuLy8gT3B0aW9ucyBmb3IgYWRkaW5nIGZpbGVzIHRvIHppcC4gRG8gbm90IGNyZWF0ZSBmb2xkZXJzIGFuZCB1c2UgYSBmaXhlZCB0aW1lIGF0IGVwb2NoLlxyXG4vLyBUaGUgZGVmYXVsdCBKU1ppcCBiZWhhdmlvciB1c2VzIGN1cnJlbnQgdGltZSwgd2hpY2ggY2F1c2VzIGlkZW50aWFsIHdvcmtib29rcyB0byBiZSBkaWZmZXJlbnQgZWFjaCB0aW1lLlxyXG5jb25zdCB6aXBGaWxlT3B0cyA9IHtcclxuICAgIGRhdGU6IG5ldyBEYXRlKDApLFxyXG4gICAgY3JlYXRlRm9sZGVyczogZmFsc2VcclxufTtcclxuXHJcbi8vIEluaXRpYWxpemUgdGhlIHBhcnNlciBhbmQgYnVpbGRlci5cclxuY29uc3QgeG1sUGFyc2VyID0gbmV3IFhtbFBhcnNlcigpO1xyXG5jb25zdCB4bWxCdWlsZGVyID0gbmV3IFhtbEJ1aWxkZXIoKTtcclxuXHJcbi8vIEluaXRpYWxpemUgdGhlIGVuY3J5cHRvciBpZiBwcmVzZW50IChjYW4gYmUgZXhjbHVkZWQgaW4gYnJvd3NlciBidWlsZCkuXHJcbmNvbnN0IGVuY3J5cHRvciA9IHR5cGVvZiBFbmNyeXB0b3IgPT09IFwiZnVuY3Rpb25cIiAmJiBuZXcgRW5jcnlwdG9yKCk7XHJcblxyXG4vLyBDaGFyYWN0ZXJzIG5vdCBhbGxvd2VkIGluIHNoZWV0IG5hbWVzLlxyXG5jb25zdCBiYWRTaGVldE5hbWVDaGFycyA9IFsnXFxcXCcsICcvJywgJyonLCAnWycsICddJywgJzonLCAnPyddO1xyXG5cclxuLy8gRXhjZWwgbGltaXRzIHNoZWV0IG5hbWVzIHRvIDMxIGNoYXJzLlxyXG5jb25zdCBtYXhTaGVldE5hbWVMZW5ndGggPSAzMTtcclxuXHJcbi8vIE9yZGVyIG9mIHRoZSBub2RlcyBhcyBkZWZpbmVkIGJ5IHRoZSBzcGVjLlxyXG5jb25zdCBub2RlT3JkZXIgPSBbXHJcbiAgICBcImZpbGVWZXJzaW9uXCIsIFwiZmlsZVNoYXJpbmdcIiwgXCJ3b3JrYm9va1ByXCIsIFwid29ya2Jvb2tQcm90ZWN0aW9uXCIsIFwiYm9va1ZpZXdzXCIsIFwic2hlZXRzXCIsIFwiZnVuY3Rpb25Hcm91cHNcIixcclxuICAgIFwiZXh0ZXJuYWxSZWZlcmVuY2VzXCIsIFwiZGVmaW5lZE5hbWVzXCIsIFwiY2FsY1ByXCIsIFwib2xlU2l6ZVwiLCBcImN1c3RvbVdvcmtib29rVmlld3NcIiwgXCJwaXZvdENhY2hlc1wiLCBcInNtYXJ0VGFnUHJcIixcclxuICAgIFwic21hcnRUYWdUeXBlc1wiLCBcIndlYlB1Ymxpc2hpbmdcIiwgXCJmaWxlUmVjb3ZlcnlQclwiLCBcIndlYlB1Ymxpc2hPYmplY3RzXCIsIFwiZXh0THN0XCJcclxuXTtcclxuXHJcbi8qKlxyXG4gKiBBIHdvcmtib29rLlxyXG4gKi9cclxuY2xhc3MgV29ya2Jvb2sge1xyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGUgYSBuZXcgYmxhbmsgd29ya2Jvb2suXHJcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZS48V29ya2Jvb2s+fSBUaGUgd29ya2Jvb2suXHJcbiAgICAgKiBAaWdub3JlXHJcbiAgICAgKi9cclxuICAgIHN0YXRpYyBmcm9tQmxhbmtBc3luYygpIHtcclxuICAgICAgICByZXR1cm4gV29ya2Jvb2suZnJvbURhdGFBc3luYyhibGFuayk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBMb2FkcyBhIHdvcmtib29rIGZyb20gYSBkYXRhIG9iamVjdC4gKFN1cHBvcnRzIGFueSBzdXBwb3J0ZWQgW0pTWmlwIGRhdGEgdHlwZXNde0BsaW5rIGh0dHBzOi8vc3R1ay5naXRodWIuaW8vanN6aXAvZG9jdW1lbnRhdGlvbi9hcGlfanN6aXAvbG9hZF9hc3luYy5odG1sfS4pXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xBcnJheS48bnVtYmVyPnxBcnJheUJ1ZmZlcnxVaW50OEFycmF5fEJ1ZmZlcnxCbG9ifFByb21pc2UuPCo+fSBkYXRhIC0gVGhlIGRhdGEgdG8gbG9hZC5cclxuICAgICAqIEBwYXJhbSB7e319IFtvcHRzXSAtIE9wdGlvbnNcclxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlLjxXb3JrYm9vaz59IFRoZSB3b3JrYm9vay5cclxuICAgICAqIEBpZ25vcmVcclxuICAgICAqL1xyXG4gICAgc3RhdGljIGZyb21EYXRhQXN5bmMoZGF0YSwgb3B0cykge1xyXG4gICAgICAgIHJldHVybiBuZXcgV29ya2Jvb2soKS5faW5pdEFzeW5jKGRhdGEsIG9wdHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTG9hZHMgYSB3b3JrYm9vayBmcm9tIGZpbGUuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aCAtIFRoZSBwYXRoIHRvIHRoZSB3b3JrYm9vay5cclxuICAgICAqIEBwYXJhbSB7e319IFtvcHRzXSAtIE9wdGlvbnNcclxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlLjxXb3JrYm9vaz59IFRoZSB3b3JrYm9vay5cclxuICAgICAqIEBpZ25vcmVcclxuICAgICAqL1xyXG4gICAgc3RhdGljIGZyb21GaWxlQXN5bmMocGF0aCwgb3B0cykge1xyXG4gICAgICAgIGlmIChwcm9jZXNzLmJyb3dzZXIpIHRocm93IG5ldyBFcnJvcihcIldvcmtib29rLmZyb21GaWxlQXN5bmMgaXMgbm90IHN1cHBvcnRlZCBpbiB0aGUgYnJvd3NlclwiKTtcclxuICAgICAgICByZXR1cm4gbmV3IGV4dGVybmFscy5Qcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICAgICAgZnMucmVhZEZpbGUocGF0aCwgKGVyciwgZGF0YSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGVycikgcmV0dXJuIHJlamVjdChlcnIpO1xyXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShkYXRhKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSkudGhlbihkYXRhID0+IFdvcmtib29rLmZyb21EYXRhQXN5bmMoZGF0YSwgb3B0cykpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0IHRoZSBhY3RpdmUgc2hlZXQgaW4gdGhlIHdvcmtib29rLlxyXG4gICAgICogQHJldHVybnMge1NoZWV0fSBUaGUgYWN0aXZlIHNoZWV0LlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXQgdGhlIGFjdGl2ZSBzaGVldCBpbiB0aGUgd29ya2Jvb2suXHJcbiAgICAgKiBAcGFyYW0ge1NoZWV0fHN0cmluZ3xudW1iZXJ9IHNoZWV0IC0gVGhlIHNoZWV0IG9yIG5hbWUgb2Ygc2hlZXQgb3IgaW5kZXggb2Ygc2hlZXQgdG8gYWN0aXZhdGUuIFRoZSBzaGVldCBtdXN0IG5vdCBiZSBoaWRkZW4uXHJcbiAgICAgKiBAcmV0dXJucyB7V29ya2Jvb2t9IFRoZSB3b3JrYm9vay5cclxuICAgICAqL1xyXG4gICAgYWN0aXZlU2hlZXQoKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBcmdIYW5kbGVyKCdXb3JrYm9vay5hY3RpdmVTaGVldCcpXHJcbiAgICAgICAgICAgIC5jYXNlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9hY3RpdmVTaGVldDtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoJyonLCBzaGVldCA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIHNoZWV0IGZyb20gbmFtZS9pbmRleCBpZiBuZWVkZWQuXHJcbiAgICAgICAgICAgICAgICBpZiAoIShzaGVldCBpbnN0YW5jZW9mIFNoZWV0KSkgc2hlZXQgPSB0aGlzLnNoZWV0KHNoZWV0KTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB0aGUgc2hlZXQgaXMgaGlkZGVuLlxyXG4gICAgICAgICAgICAgICAgaWYgKHNoZWV0LmhpZGRlbigpKSB0aHJvdyBuZXcgRXJyb3IoXCJZb3UgbWF5IG5vdCBhY3RpdmF0ZSBhIGhpZGRlbiBzaGVldC5cIik7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gRGVzZWxlY3QgYWxsIHNoZWV0cyBleGNlcHQgdGhlIGFjdGl2ZSBvbmUgKG1pcnJvcmluZyB5aW5nIEV4Y2VsIGJlaGF2aW9yKS5cclxuICAgICAgICAgICAgICAgIF8uZm9yRWFjaCh0aGlzLl9zaGVldHMsIGN1cnJlbnQgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnQudGFiU2VsZWN0ZWQoY3VycmVudCA9PT0gc2hlZXQpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5fYWN0aXZlU2hlZXQgPSBzaGVldDtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmhhbmRsZShhcmd1bWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWRkIGEgbmV3IHNoZWV0IHRvIHRoZSB3b3JrYm9vay5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHNoZWV0LiBNdXN0IGJlIHVuaXF1ZSwgbGVzcyB0aGFuIDMxIGNoYXJhY3RlcnMsIGFuZCBtYXkgbm90IGNvbnRhaW4gdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBcXCAvICogWyBdIDogP1xyXG4gICAgICogQHBhcmFtIHtudW1iZXJ8c3RyaW5nfFNoZWV0fSBbaW5kZXhPckJlZm9yZVNoZWV0XSBUaGUgaW5kZXggdG8gbW92ZSB0aGUgc2hlZXQgdG8gb3IgdGhlIHNoZWV0IChvciBuYW1lIG9mIHNoZWV0KSB0byBtb3ZlIHRoaXMgc2hlZXQgYmVmb3JlLiBPbWl0IHRoaXMgYXJndW1lbnQgdG8gbW92ZSB0byB0aGUgZW5kIG9mIHRoZSB3b3JrYm9vay5cclxuICAgICAqIEByZXR1cm5zIHtTaGVldH0gVGhlIG5ldyBzaGVldC5cclxuICAgICAqL1xyXG4gICAgYWRkU2hlZXQobmFtZSwgaW5kZXhPckJlZm9yZVNoZWV0KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZFNoZWV0KG5hbWUsIGluZGV4T3JCZWZvcmVTaGVldCk7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBhIGRlZmluZWQgbmFtZSBzY29wZWQgdG8gdGhlIHdvcmtib29rLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgZGVmaW5lZCBuYW1lLlxyXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZHxzdHJpbmd8Q2VsbHxSYW5nZXxSb3d8Q29sdW1ufSBXaGF0IHRoZSBkZWZpbmVkIG5hbWUgcmVmZXJzIHRvIG9yIHVuZGVmaW5lZCBpZiBub3QgZm91bmQuIFdpbGwgcmV0dXJuIHRoZSBzdHJpbmcgZm9ybXVsYSBpZiBub3QgYSBSb3csIENvbHVtbiwgQ2VsbCwgb3IgUmFuZ2UuXHJcbiAgICAgKi8vKipcclxuICAgICAqIFNldCBhIGRlZmluZWQgbmFtZSBzY29wZWQgdG8gdGhlIHdvcmtib29rLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgZGVmaW5lZCBuYW1lLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd8Q2VsbHxSYW5nZXxSb3d8Q29sdW1ufSByZWZlcnNUbyAtIFdoYXQgdGhlIG5hbWUgcmVmZXJzIHRvLlxyXG4gICAgICogQHJldHVybnMge1dvcmtib29rfSBUaGUgd29ya2Jvb2suXHJcbiAgICAgKi9cclxuICAgIGRlZmluZWROYW1lKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQXJnSGFuZGxlcihcIldvcmtib29rLmRlZmluZWROYW1lXCIpXHJcbiAgICAgICAgICAgIC5jYXNlKCdzdHJpbmcnLCBuYW1lID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNjb3BlZERlZmluZWROYW1lKHVuZGVmaW5lZCwgbmFtZSk7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKFsnc3RyaW5nJywgJyonXSwgKG5hbWUsIHJlZmVyc1RvKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNjb3BlZERlZmluZWROYW1lKHVuZGVmaW5lZCwgbmFtZSwgcmVmZXJzVG8pO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5oYW5kbGUoYXJndW1lbnRzKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIERlbGV0ZSBhIHNoZWV0IGZyb20gdGhlIHdvcmtib29rLlxyXG4gICAgICogQHBhcmFtIHtTaGVldHxzdHJpbmd8bnVtYmVyfSBzaGVldCAtIFRoZSBzaGVldCBvciBuYW1lIG9mIHNoZWV0IG9yIGluZGV4IG9mIHNoZWV0IHRvIG1vdmUuXHJcbiAgICAgKiBAcmV0dXJucyB7V29ya2Jvb2t9IFRoZSB3b3JrYm9vay5cclxuICAgICAqL1xyXG4gICAgZGVsZXRlU2hlZXQoc2hlZXQpIHtcclxuICAgICAgICAvLyBHZXQgdGhlIHNoZWV0IHRvIG1vdmUuXHJcbiAgICAgICAgaWYgKCEoc2hlZXQgaW5zdGFuY2VvZiBTaGVldCkpIHtcclxuICAgICAgICAgICAgc2hlZXQgPSB0aGlzLnNoZWV0KHNoZWV0KTtcclxuICAgICAgICAgICAgaWYgKCFzaGVldCkgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBtb3ZlIHNoZWV0IHJlZmVyZW5jZS5cIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBNYWtlIHN1cmUgd2UgYXJlIG5vdCBkZWxldGluZyB0aGUgb25seSB2aXNpYmxlIHNoZWV0LlxyXG4gICAgICAgIGNvbnN0IHZpc2libGVTaGVldHMgPSBfLmZpbHRlcih0aGlzLl9zaGVldHMsIHNoZWV0ID0+ICFzaGVldC5oaWRkZW4oKSk7XHJcbiAgICAgICAgaWYgKHZpc2libGVTaGVldHMubGVuZ3RoID09PSAxICYmIHZpc2libGVTaGVldHNbMF0gPT09IHNoZWV0KSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgc2hlZXQgbWF5IG5vdCBiZSBkZWxldGVkIGFzIGEgd29ya2Jvb2sgbXVzdCBjb250YWluIGF0IGxlYXN0IG9uZSB2aXNpYmxlIHNoZWV0LlwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFJlbW92ZSB0aGUgc2hlZXQuXHJcbiAgICAgICAgbGV0IGluZGV4ID0gdGhpcy5fc2hlZXRzLmluZGV4T2Yoc2hlZXQpO1xyXG4gICAgICAgIHRoaXMuX3NoZWV0cy5zcGxpY2UoaW5kZXgsIDEpO1xyXG5cclxuICAgICAgICAvLyBTZXQgdGhlIG5ldyBhY3RpdmUgc2hlZXQuXHJcbiAgICAgICAgaWYgKHNoZWV0ID09PSB0aGlzLmFjdGl2ZVNoZWV0KCkpIHtcclxuICAgICAgICAgICAgaWYgKGluZGV4ID49IHRoaXMuX3NoZWV0cy5sZW5ndGgpIGluZGV4LS07XHJcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlU2hlZXQoaW5kZXgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaW5kIHRoZSBnaXZlbiBwYXR0ZXJuIGluIHRoZSB3b3JrYm9vayBhbmQgb3B0aW9uYWxseSByZXBsYWNlIGl0LlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd8UmVnRXhwfSBwYXR0ZXJuIC0gVGhlIHBhdHRlcm4gdG8gbG9vayBmb3IuIFByb3ZpZGluZyBhIHN0cmluZyB3aWxsIHJlc3VsdCBpbiBhIGNhc2UtaW5zZW5zaXRpdmUgc3Vic3RyaW5nIHNlYXJjaC4gVXNlIGEgUmVnRXhwIGZvciBtb3JlIHNvcGhpc3RpY2F0ZWQgc2VhcmNoZXMuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xmdW5jdGlvbn0gW3JlcGxhY2VtZW50XSAtIFRoZSB0ZXh0IHRvIHJlcGxhY2Ugb3IgYSBTdHJpbmcucmVwbGFjZSBjYWxsYmFjayBmdW5jdGlvbi4gSWYgcGF0dGVybiBpcyBhIHN0cmluZywgYWxsIG9jY3VycmVuY2VzIG9mIHRoZSBwYXR0ZXJuIGluIGVhY2ggY2VsbCB3aWxsIGJlIHJlcGxhY2VkLlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IEEgZmxhZyBpbmRpY2F0aW5nIGlmIHRoZSBwYXR0ZXJuIHdhcyBmb3VuZC5cclxuICAgICAqL1xyXG4gICAgZmluZChwYXR0ZXJuLCByZXBsYWNlbWVudCkge1xyXG4gICAgICAgIHBhdHRlcm4gPSByZWdleGlmeShwYXR0ZXJuKTtcclxuXHJcbiAgICAgICAgbGV0IG1hdGNoZXMgPSBbXTtcclxuICAgICAgICB0aGlzLl9zaGVldHMuZm9yRWFjaChzaGVldCA9PiB7XHJcbiAgICAgICAgICAgIG1hdGNoZXMgPSBtYXRjaGVzLmNvbmNhdChzaGVldC5maW5kKHBhdHRlcm4sIHJlcGxhY2VtZW50KSk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBtYXRjaGVzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTW92ZSBhIHNoZWV0IHRvIGEgbmV3IHBvc2l0aW9uLlxyXG4gICAgICogQHBhcmFtIHtTaGVldHxzdHJpbmd8bnVtYmVyfSBzaGVldCAtIFRoZSBzaGVldCBvciBuYW1lIG9mIHNoZWV0IG9yIGluZGV4IG9mIHNoZWV0IHRvIG1vdmUuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcnxzdHJpbmd8U2hlZXR9IFtpbmRleE9yQmVmb3JlU2hlZXRdIFRoZSBpbmRleCB0byBtb3ZlIHRoZSBzaGVldCB0byBvciB0aGUgc2hlZXQgKG9yIG5hbWUgb2Ygc2hlZXQpIHRvIG1vdmUgdGhpcyBzaGVldCBiZWZvcmUuIE9taXQgdGhpcyBhcmd1bWVudCB0byBtb3ZlIHRvIHRoZSBlbmQgb2YgdGhlIHdvcmtib29rLlxyXG4gICAgICogQHJldHVybnMge1dvcmtib29rfSBUaGUgd29ya2Jvb2suXHJcbiAgICAgKi9cclxuICAgIG1vdmVTaGVldChzaGVldCwgaW5kZXhPckJlZm9yZVNoZWV0KSB7XHJcbiAgICAgICAgLy8gR2V0IHRoZSBzaGVldCB0byBtb3ZlLlxyXG4gICAgICAgIGlmICghKHNoZWV0IGluc3RhbmNlb2YgU2hlZXQpKSB7XHJcbiAgICAgICAgICAgIHNoZWV0ID0gdGhpcy5zaGVldChzaGVldCk7XHJcbiAgICAgICAgICAgIGlmICghc2hlZXQpIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgbW92ZSBzaGVldCByZWZlcmVuY2UuXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gR2V0IHRoZSB0by9mcm9tIGluZGV4ZXMuXHJcbiAgICAgICAgY29uc3QgZnJvbSA9IHRoaXMuX3NoZWV0cy5pbmRleE9mKHNoZWV0KTtcclxuICAgICAgICBsZXQgdG87XHJcbiAgICAgICAgaWYgKF8uaXNOaWwoaW5kZXhPckJlZm9yZVNoZWV0KSkge1xyXG4gICAgICAgICAgICB0byA9IHRoaXMuX3NoZWV0cy5sZW5ndGggLSAxO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoXy5pc0ludGVnZXIoaW5kZXhPckJlZm9yZVNoZWV0KSkge1xyXG4gICAgICAgICAgICB0byA9IGluZGV4T3JCZWZvcmVTaGVldDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAoIShpbmRleE9yQmVmb3JlU2hlZXQgaW5zdGFuY2VvZiBTaGVldCkpIHtcclxuICAgICAgICAgICAgICAgIGluZGV4T3JCZWZvcmVTaGVldCA9IHRoaXMuc2hlZXQoaW5kZXhPckJlZm9yZVNoZWV0KTtcclxuICAgICAgICAgICAgICAgIGlmICghaW5kZXhPckJlZm9yZVNoZWV0KSB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGJlZm9yZSBzaGVldCByZWZlcmVuY2UuXCIpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0byA9IHRoaXMuX3NoZWV0cy5pbmRleE9mKGluZGV4T3JCZWZvcmVTaGVldCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBJbnNlcnQgdGhlIHNoZWV0IGF0IHRoZSBhcHByb3ByaWF0ZSBwbGFjZS5cclxuICAgICAgICB0aGlzLl9zaGVldHMuc3BsaWNlKHRvLCAwLCB0aGlzLl9zaGVldHMuc3BsaWNlKGZyb20sIDEpWzBdKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZW5lcmF0ZXMgdGhlIHdvcmtib29rIG91dHB1dC5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZV0gLSBUaGUgdHlwZSBvZiB0aGUgZGF0YSB0byByZXR1cm46IGJhc2U2NCwgYmluYXJ5c3RyaW5nLCB1aW50OGFycmF5LCBhcnJheWJ1ZmZlciwgYmxvYiwgbm9kZWJ1ZmZlci4gRGVmYXVsdHMgdG8gJ25vZGVidWZmZXInIGluIE5vZGUuanMgYW5kICdibG9iJyBpbiBicm93c2Vycy5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd8VWludDhBcnJheXxBcnJheUJ1ZmZlcnxCbG9ifEJ1ZmZlcn0gVGhlIGRhdGEuXHJcbiAgICAgKi8vKipcclxuICAgICAqIEdlbmVyYXRlcyB0aGUgd29ya2Jvb2sgb3V0cHV0LlxyXG4gICAgICogQHBhcmFtIHt7fX0gW29wdHNdIE9wdGlvbnNcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy50eXBlXSAtIFRoZSB0eXBlIG9mIHRoZSBkYXRhIHRvIHJldHVybjogYmFzZTY0LCBiaW5hcnlzdHJpbmcsIHVpbnQ4YXJyYXksIGFycmF5YnVmZmVyLCBibG9iLCBub2RlYnVmZmVyLiBEZWZhdWx0cyB0byAnbm9kZWJ1ZmZlcicgaW4gTm9kZS5qcyBhbmQgJ2Jsb2InIGluIGJyb3dzZXJzLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLnBhc3N3b3JkXSAtIFRoZSBwYXNzd29yZCB0byB1c2UgdG8gZW5jcnlwdCB0aGUgd29ya2Jvb2suXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfFVpbnQ4QXJyYXl8QXJyYXlCdWZmZXJ8QmxvYnxCdWZmZXJ9IFRoZSBkYXRhLlxyXG4gICAgICovXHJcbiAgICBvdXRwdXRBc3luYyhvcHRzKSB7XHJcbiAgICAgICAgb3B0cyA9IG9wdHMgfHwge307XHJcbiAgICAgICAgaWYgKHR5cGVvZiBvcHRzID09PSAnc3RyaW5nJykgb3B0cyA9IHsgdHlwZTogb3B0cyB9O1xyXG5cclxuICAgICAgICB0aGlzLl9zZXRTaGVldFJlZnMoKTtcclxuXHJcbiAgICAgICAgbGV0IGRlZmluZWROYW1lc05vZGUgPSB4bWxxLmZpbmRDaGlsZCh0aGlzLl9ub2RlLCBcImRlZmluZWROYW1lc1wiKTtcclxuXHJcbiAgICAgICAgdGhpcy5fc2hlZXRzLmZvckVhY2goKHNoZWV0LCBpKSA9PiB7XHJcbiAgICAgICAgICAgIGlmICghc2hlZXQuX2F1dG9GaWx0ZXIpIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgIGlmICghZGVmaW5lZE5hbWVzTm9kZSkge1xyXG4gICAgICAgICAgICAgICAgZGVmaW5lZE5hbWVzTm9kZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICBuYW1lOiBcImRlZmluZWROYW1lc1wiLFxyXG4gICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHt9LFxyXG4gICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuOiBbXVxyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICB4bWxxLmluc2VydEluT3JkZXIodGhpcy5fbm9kZSwgZGVmaW5lZE5hbWVzTm9kZSwgbm9kZU9yZGVyKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgeG1scS5hcHBlbmRDaGlsZChkZWZpbmVkTmFtZXNOb2RlLCB7XHJcbiAgICAgICAgICAgICAgICBuYW1lOiBcImRlZmluZWROYW1lXCIsXHJcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJfeGxubS5fRmlsdGVyRGF0YWJhc2VcIixcclxuICAgICAgICAgICAgICAgICAgICBsb2NhbFNoZWV0SWQ6IGksXHJcbiAgICAgICAgICAgICAgICAgICAgaGlkZGVuOiBcIjFcIlxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGNoaWxkcmVuOiBbc2hlZXQuX2F1dG9GaWx0ZXIuYWRkcmVzcyh7IGluY2x1ZGVTaGVldE5hbWU6IHRydWUsIGFuY2hvcmVkOiB0cnVlIH0pXVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5fc2hlZXRzTm9kZS5jaGlsZHJlbiA9IFtdO1xyXG4gICAgICAgIHRoaXMuX3NoZWV0cy5mb3JFYWNoKChzaGVldCwgaSkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBzaGVldFBhdGggPSBgeGwvd29ya3NoZWV0cy9zaGVldCR7aSArIDF9LnhtbGA7XHJcbiAgICAgICAgICAgIGNvbnN0IHNoZWV0UmVsc1BhdGggPSBgeGwvd29ya3NoZWV0cy9fcmVscy9zaGVldCR7aSArIDF9LnhtbC5yZWxzYDtcclxuICAgICAgICAgICAgY29uc3Qgc2hlZXRYbWxzID0gc2hlZXQudG9YbWxzKCk7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlbGF0aW9uc2hpcCA9IHRoaXMuX3JlbGF0aW9uc2hpcHMuZmluZEJ5SWQoc2hlZXRYbWxzLmlkLmF0dHJpYnV0ZXNbJ3I6aWQnXSk7XHJcbiAgICAgICAgICAgIHJlbGF0aW9uc2hpcC5hdHRyaWJ1dGVzLlRhcmdldCA9IGB3b3Jrc2hlZXRzL3NoZWV0JHtpICsgMX0ueG1sYDtcclxuICAgICAgICAgICAgdGhpcy5fc2hlZXRzTm9kZS5jaGlsZHJlbi5wdXNoKHNoZWV0WG1scy5pZCk7XHJcbiAgICAgICAgICAgIHRoaXMuX3ppcC5maWxlKHNoZWV0UGF0aCwgeG1sQnVpbGRlci5idWlsZChzaGVldFhtbHMuc2hlZXQpLCB6aXBGaWxlT3B0cyk7XHJcblxyXG4gICAgICAgICAgICBjb25zdCByZWxhdGlvbnNoaXBzWG1sID0geG1sQnVpbGRlci5idWlsZChzaGVldFhtbHMucmVsYXRpb25zaGlwcyk7XHJcbiAgICAgICAgICAgIGlmIChyZWxhdGlvbnNoaXBzWG1sKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl96aXAuZmlsZShzaGVldFJlbHNQYXRoLCByZWxhdGlvbnNoaXBzWG1sLCB6aXBGaWxlT3B0cyk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl96aXAucmVtb3ZlKHNoZWV0UmVsc1BhdGgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIC8vIFNldCB0aGUgYXBwIHNlY3VyaXR5IHRvIHRydWUgaWYgYSBwYXNzd29yZCBpcyBzZXQsIGZhbHNlIGlmIG5vdC5cclxuICAgICAgICAvLyB0aGlzLl9hcHBQcm9wZXJ0aWVzLmlzU2VjdXJlKCEhb3B0cy5wYXNzd29yZCk7XHJcblxyXG4gICAgICAgIC8vIENvbnZlcnQgdGhlIHZhcmlvdXMgY29tcG9uZW50cyB0byBYTUwgc3RyaW5ncyBhbmQgYWRkIHRoZW0gdG8gdGhlIHppcC5cclxuICAgICAgICB0aGlzLl96aXAuZmlsZShcIltDb250ZW50X1R5cGVzXS54bWxcIiwgeG1sQnVpbGRlci5idWlsZCh0aGlzLl9jb250ZW50VHlwZXMpLCB6aXBGaWxlT3B0cyk7XHJcbiAgICAgICAgdGhpcy5femlwLmZpbGUoXCJkb2NQcm9wcy9hcHAueG1sXCIsIHhtbEJ1aWxkZXIuYnVpbGQodGhpcy5fYXBwUHJvcGVydGllcyksIHppcEZpbGVPcHRzKTtcclxuICAgICAgICB0aGlzLl96aXAuZmlsZShcImRvY1Byb3BzL2NvcmUueG1sXCIsIHhtbEJ1aWxkZXIuYnVpbGQodGhpcy5fY29yZVByb3BlcnRpZXMpLCB6aXBGaWxlT3B0cyk7XHJcbiAgICAgICAgdGhpcy5femlwLmZpbGUoXCJ4bC9fcmVscy93b3JrYm9vay54bWwucmVsc1wiLCB4bWxCdWlsZGVyLmJ1aWxkKHRoaXMuX3JlbGF0aW9uc2hpcHMpLCB6aXBGaWxlT3B0cyk7XHJcbiAgICAgICAgdGhpcy5femlwLmZpbGUoXCJ4bC9zaGFyZWRTdHJpbmdzLnhtbFwiLCB4bWxCdWlsZGVyLmJ1aWxkKHRoaXMuX3NoYXJlZFN0cmluZ3MpLCB6aXBGaWxlT3B0cyk7XHJcbiAgICAgICAgdGhpcy5femlwLmZpbGUoXCJ4bC9zdHlsZXMueG1sXCIsIHhtbEJ1aWxkZXIuYnVpbGQodGhpcy5fc3R5bGVTaGVldCksIHppcEZpbGVPcHRzKTtcclxuICAgICAgICB0aGlzLl96aXAuZmlsZShcInhsL3dvcmtib29rLnhtbFwiLCB4bWxCdWlsZGVyLmJ1aWxkKHRoaXMuX25vZGUpLCB6aXBGaWxlT3B0cyk7XHJcblxyXG4gICAgICAgIC8vIEdlbmVyYXRlIHRoZSB6aXAuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ppcC5nZW5lcmF0ZUFzeW5jKHtcclxuICAgICAgICAgICAgdHlwZTogXCJub2RlYnVmZmVyXCIsXHJcbiAgICAgICAgICAgIGNvbXByZXNzaW9uOiBcIkRFRkxBVEVcIlxyXG4gICAgICAgIH0pLnRoZW4ob3V0cHV0ID0+IHtcclxuICAgICAgICAgICAgLy8gSWYgYSBwYXNzd29yZCBpcyBzZXQsIGVuY3J5cHQgdGhlIHdvcmtib29rLlxyXG4gICAgICAgICAgICBpZiAob3B0cy5wYXNzd29yZCkgb3V0cHV0ID0gZW5jcnlwdG9yLmVuY3J5cHQob3V0cHV0LCBvcHRzLnBhc3N3b3JkKTtcclxuXHJcbiAgICAgICAgICAgIC8vIENvbnZlcnQgYW5kIHJldHVyblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY29udmVydEJ1ZmZlclRvT3V0cHV0KG91dHB1dCwgb3B0cy50eXBlKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIHNoZWV0IHdpdGggdGhlIHByb3ZpZGVkIG5hbWUgb3IgaW5kZXggKDAtYmFzZWQpLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBzaGVldE5hbWVPckluZGV4IC0gVGhlIHNoZWV0IG5hbWUgb3IgaW5kZXguXHJcbiAgICAgKiBAcmV0dXJucyB7U2hlZXR8dW5kZWZpbmVkfSBUaGUgc2hlZXQgb3IgdW5kZWZpbmVkIGlmIG5vdCBmb3VuZC5cclxuICAgICAqL1xyXG4gICAgc2hlZXQoc2hlZXROYW1lT3JJbmRleCkge1xyXG4gICAgICAgIGlmIChfLmlzSW50ZWdlcihzaGVldE5hbWVPckluZGV4KSkgcmV0dXJuIHRoaXMuX3NoZWV0c1tzaGVldE5hbWVPckluZGV4XTtcclxuICAgICAgICByZXR1cm4gXy5maW5kKHRoaXMuX3NoZWV0cywgc2hlZXQgPT4gc2hlZXQubmFtZSgpID09PSBzaGVldE5hbWVPckluZGV4KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldCBhbiBhcnJheSBvZiBhbGwgdGhlIHNoZWV0cyBpbiB0aGUgd29ya2Jvb2suXHJcbiAgICAgKiBAcmV0dXJucyB7QXJyYXkuPFNoZWV0Pn0gVGhlIHNoZWV0cy5cclxuICAgICAqL1xyXG4gICAgc2hlZXRzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaGVldHMuc2xpY2UoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgYW4gaW5kaXZpZHVhbCBwcm9wZXJ0eS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5LlxyXG4gICAgICogQHJldHVybnMgeyp9IFRoZSBwcm9wZXJ0eS5cclxuICAgICAqLy8qKlxyXG4gICAgICogR2V0cyBtdWx0aXBsZSBwcm9wZXJ0aWVzLlxyXG4gICAgICogQHBhcmFtIHtBcnJheS48c3RyaW5nPn0gbmFtZXMgLSBUaGUgbmFtZXMgb2YgdGhlIHByb3BlcnRpZXMuXHJcbiAgICAgKiBAcmV0dXJucyB7b2JqZWN0LjxzdHJpbmcsICo+fSBPYmplY3Qgd2hvc2Uga2V5cyBhcmUgdGhlIHByb3BlcnR5IG5hbWVzIGFuZCB2YWx1ZXMgYXJlIHRoZSBwcm9wZXJ0aWVzLlxyXG4gICAgICovLyoqXHJcbiAgICAgKiBTZXRzIGFuIGluZGl2aWR1YWwgcHJvcGVydHkuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eS5cclxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gc2V0LlxyXG4gICAgICogQHJldHVybnMge1dvcmtib29rfSBUaGUgd29ya2Jvb2suXHJcbiAgICAgKi8vKipcclxuICAgICAqIFNldHMgbXVsdGlwbGUgcHJvcGVydGllcy5cclxuICAgICAqIEBwYXJhbSB7b2JqZWN0LjxzdHJpbmcsICo+fSBwcm9wZXJ0aWVzIC0gT2JqZWN0IHdob3NlIGtleXMgYXJlIHRoZSBwcm9wZXJ0eSBuYW1lcyBhbmQgdmFsdWVzIGFyZSB0aGUgdmFsdWVzIHRvIHNldC5cclxuICAgICAqIEByZXR1cm5zIHtXb3JrYm9va30gVGhlIHdvcmtib29rLlxyXG4gICAgICovXHJcbiAgICBwcm9wZXJ0eSgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEFyZ0hhbmRsZXIoXCJXb3JrYm9vay5wcm9wZXJ0eVwiKVxyXG4gICAgICAgICAgICAuY2FzZSgnc3RyaW5nJywgbmFtZSA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBHZXQgc2luZ2xlIHZhbHVlXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fY29yZVByb3BlcnRpZXMuZ2V0KG5hbWUpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZSgnYXJyYXknLCBuYW1lcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBHZXQgbGlzdCBvZiB2YWx1ZXNcclxuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlcyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgbmFtZXMuZm9yRWFjaChuYW1lID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXNbbmFtZV0gPSB0aGlzLl9jb3JlUHJvcGVydGllcy5nZXQobmFtZSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuY2FzZShbJ3N0cmluZycsICcqJ10sIChuYW1lLCB2YWx1ZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gU2V0IGEgc2luZ2xlIHZhbHVlIGZvciBhbGwgY2VsbHMgdG8gYSBzaW5nbGUgdmFsdWVcclxuICAgICAgICAgICAgICAgIHRoaXMuX2NvcmVQcm9wZXJ0aWVzLnNldChuYW1lLCB2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoJ29iamVjdCcsIG5hbWVWYWx1ZXMgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gT2JqZWN0IG9mIGtleSB2YWx1ZSBwYWlycyB0byBzZXRcclxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgbmFtZSBpbiBuYW1lVmFsdWVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFuYW1lVmFsdWVzLmhhc093blByb3BlcnR5KG5hbWUpKSBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IG5hbWVWYWx1ZXNbbmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fY29yZVByb3BlcnRpZXMuc2V0KG5hbWUsIHZhbHVlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmhhbmRsZShhcmd1bWVudHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0IGFjY2VzcyB0byBjb3JlIHByb3BlcnRpZXMgb2JqZWN0XHJcbiAgICAgKiBAcmV0dXJucyB7Q29yZVByb3BlcnRpZXN9IFRoZSBjb3JlIHByb3BlcnRpZXMuXHJcbiAgICAgKi9cclxuICAgIHByb3BlcnRpZXMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvcmVQcm9wZXJ0aWVzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogV3JpdGUgdGhlIHdvcmtib29rIHRvIGZpbGUuIChOb3Qgc3VwcG9ydGVkIGluIGJyb3dzZXJzLilcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gVGhlIHBhdGggb2YgdGhlIGZpbGUgdG8gd3JpdGUuXHJcbiAgICAgKiBAcGFyYW0ge3t9fSBbb3B0c10gLSBPcHRpb25zXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMucGFzc3dvcmRdIC0gVGhlIHBhc3N3b3JkIHRvIGVuY3J5cHQgdGhlIHdvcmtib29rLlxyXG4gICAgICogQHJldHVybnMge1Byb21pc2UuPHVuZGVmaW5lZD59IEEgcHJvbWlzZS5cclxuICAgICAqL1xyXG4gICAgdG9GaWxlQXN5bmMocGF0aCwgb3B0cykge1xyXG4gICAgICAgIGlmIChwcm9jZXNzLmJyb3dzZXIpIHRocm93IG5ldyBFcnJvcihcIldvcmtib29rLnRvRmlsZUFzeW5jIGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhlIGJyb3dzZXIuXCIpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLm91dHB1dEFzeW5jKG9wdHMpXHJcbiAgICAgICAgICAgIC50aGVuKGRhdGEgPT4gbmV3IGV4dGVybmFscy5Qcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICAgICAgICAgIGZzLndyaXRlRmlsZShwYXRoLCBkYXRhLCBlcnIgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnIpIHJldHVybiByZWplY3QoZXJyKTtcclxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBhIHNjb3BlZCBkZWZpbmVkIG5hbWUuXHJcbiAgICAgKiBAcGFyYW0ge1NoZWV0fSBzaGVldFNjb3BlIC0gVGhlIHNoZWV0IHRoZSBuYW1lIGlzIHNjb3BlZCB0by4gVXNlIHVuZGVmaW5lZCBmb3Igd29ya2Jvb2sgc2NvcGUuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIFRoZSBkZWZpbmVkIG5hbWUuXHJcbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfENlbGx8UmFuZ2V8Um93fENvbHVtbn0gV2hhdCB0aGUgZGVmaW5lZCBuYW1lIHJlZmVycyB0by5cclxuICAgICAqIEBpZ25vcmVcclxuICAgICAqLy8qKlxyXG4gICAgICogU2V0cyBhIHNjb3BlZCBkZWZpbmVkIG5hbWUuXHJcbiAgICAgKiBAcGFyYW0ge1NoZWV0fSBzaGVldFNjb3BlIC0gVGhlIHNoZWV0IHRoZSBuYW1lIGlzIHNjb3BlZCB0by4gVXNlIHVuZGVmaW5lZCBmb3Igd29ya2Jvb2sgc2NvcGUuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIFRoZSBkZWZpbmVkIG5hbWUuXHJcbiAgICAgKiBAcGFyYW0ge3VuZGVmaW5lZHxDZWxsfFJhbmdlfFJvd3xDb2x1bW59IHJlZmVyc1RvIC0gV2hhdCB0aGUgZGVmaW5lZCBuYW1lIHJlZmVycyB0by5cclxuICAgICAqIEByZXR1cm5zIHtXb3JrYm9va30gVGhlIHdvcmtib29rLlxyXG4gICAgICogQGlnbm9yZVxyXG4gICAgICovXHJcbiAgICBzY29wZWREZWZpbmVkTmFtZShzaGVldFNjb3BlLCBuYW1lLCByZWZlcnNUbykge1xyXG4gICAgICAgIGxldCBkZWZpbmVkTmFtZXNOb2RlID0geG1scS5maW5kQ2hpbGQodGhpcy5fbm9kZSwgXCJkZWZpbmVkTmFtZXNcIik7XHJcbiAgICAgICAgbGV0IGRlZmluZWROYW1lTm9kZSA9IGRlZmluZWROYW1lc05vZGUgJiYgXy5maW5kKGRlZmluZWROYW1lc05vZGUuY2hpbGRyZW4sIG5vZGUgPT4gbm9kZS5hdHRyaWJ1dGVzLm5hbWUgPT09IG5hbWUgJiYgbm9kZS5sb2NhbFNoZWV0ID09PSBzaGVldFNjb3BlKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBBcmdIYW5kbGVyKCdXb3JrYm9vay5zY29wZWREZWZpbmVkTmFtZScpXHJcbiAgICAgICAgICAgIC5jYXNlKFsnKicsICdzdHJpbmcnXSwgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBhZGRyZXNzIGZyb20gdGhlIGRlZmluZWROYW1lcyBub2RlLlxyXG4gICAgICAgICAgICAgICAgY29uc3QgcmVmZXJzVG8gPSBkZWZpbmVkTmFtZU5vZGUgJiYgZGVmaW5lZE5hbWVOb2RlLmNoaWxkcmVuWzBdO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFyZWZlcnNUbykgcmV0dXJuIHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBUcnkgdG8gcGFyc2UgdGhlIGFkZHJlc3MuXHJcbiAgICAgICAgICAgICAgICBjb25zdCByZWYgPSBhZGRyZXNzQ29udmVydGVyLmZyb21BZGRyZXNzKHJlZmVyc1RvKTtcclxuICAgICAgICAgICAgICAgIGlmICghcmVmKSByZXR1cm4gcmVmZXJzVG87XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gTG9hZCB0aGUgYXBwcm9wcmlhdGUgc2VsZWN0aW9uIHR5cGUuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBzaGVldCA9IHRoaXMuc2hlZXQocmVmLnNoZWV0TmFtZSk7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVmLnR5cGUgPT09ICdjZWxsJykgcmV0dXJuIHNoZWV0LmNlbGwocmVmLnJvd051bWJlciwgcmVmLmNvbHVtbk51bWJlcik7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVmLnR5cGUgPT09ICdyYW5nZScpIHJldHVybiBzaGVldC5yYW5nZShyZWYuc3RhcnRSb3dOdW1iZXIsIHJlZi5zdGFydENvbHVtbk51bWJlciwgcmVmLmVuZFJvd051bWJlciwgcmVmLmVuZENvbHVtbk51bWJlcik7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVmLnR5cGUgPT09ICdyb3cnKSByZXR1cm4gc2hlZXQucm93KHJlZi5yb3dOdW1iZXIpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlZi50eXBlID09PSAnY29sdW1uJykgcmV0dXJuIHNoZWV0LmNvbHVtbihyZWYuY29sdW1uTnVtYmVyKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZWZlcnNUbztcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhc2UoWycqJywgJ3N0cmluZycsICduaWwnXSwgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGRlZmluZWROYW1lTm9kZSkgeG1scS5yZW1vdmVDaGlsZChkZWZpbmVkTmFtZXNOb2RlLCBkZWZpbmVkTmFtZU5vZGUpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGRlZmluZWROYW1lc05vZGUgJiYgIWRlZmluZWROYW1lc05vZGUuY2hpbGRyZW4ubGVuZ3RoKSB4bWxxLnJlbW92ZUNoaWxkKHRoaXMuX25vZGUsIGRlZmluZWROYW1lc05vZGUpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC5jYXNlKFsnKicsICdzdHJpbmcnLCAnKiddLCAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHJlZmVyc1RvICE9PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlZmVyc1RvID0gcmVmZXJzVG8uYWRkcmVzcyh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGluY2x1ZGVTaGVldE5hbWU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFuY2hvcmVkOiB0cnVlXHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCFkZWZpbmVkTmFtZXNOb2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVmaW5lZE5hbWVzTm9kZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogXCJkZWZpbmVkTmFtZXNcIixcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlczoge30sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuOiBbXVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHhtbHEuaW5zZXJ0SW5PcmRlcih0aGlzLl9ub2RlLCBkZWZpbmVkTmFtZXNOb2RlLCBub2RlT3JkZXIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmICghZGVmaW5lZE5hbWVOb2RlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVmaW5lZE5hbWVOb2RlID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBcImRlZmluZWROYW1lXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHsgbmFtZSB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbjogW3JlZmVyc1RvXVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzaGVldFNjb3BlKSBkZWZpbmVkTmFtZU5vZGUubG9jYWxTaGVldCA9IHNoZWV0U2NvcGU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHhtbHEuYXBwZW5kQ2hpbGQoZGVmaW5lZE5hbWVzTm9kZSwgZGVmaW5lZE5hbWVOb2RlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBkZWZpbmVkTmFtZU5vZGUuY2hpbGRyZW4gPSBbcmVmZXJzVG9dO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAuaGFuZGxlKGFyZ3VtZW50cyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXQgdGhlIHNoYXJlZCBzdHJpbmdzIHRhYmxlLlxyXG4gICAgICogQHJldHVybnMge1NoYXJlZFN0cmluZ3N9IFRoZSBzaGFyZWQgc3RyaW5ncyB0YWJsZS5cclxuICAgICAqIEBpZ25vcmVcclxuICAgICAqL1xyXG4gICAgc2hhcmVkU3RyaW5ncygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2hhcmVkU3RyaW5ncztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldCB0aGUgc3R5bGUgc2hlZXQuXHJcbiAgICAgKiBAcmV0dXJucyB7U3R5bGVTaGVldH0gVGhlIHN0eWxlIHNoZWV0LlxyXG4gICAgICogQGlnbm9yZVxyXG4gICAgICovXHJcbiAgICBzdHlsZVNoZWV0KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zdHlsZVNoZWV0O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWRkIGEgbmV3IHNoZWV0IHRvIHRoZSB3b3JrYm9vay5cclxuICAgICAqIFxyXG4gICAgICogKipXQVJOOioqIHRoaXMgZnVuY3Rpb24gaGFzIGxpbWl0czogIGlmIHlvdSBjbG9uZSBhIHNoZWV0IHdpdGggc29tZSBpbWFnZXMgb3Igb3RoZXIgdGhpbmdzIGxpbmsgb3V0c2lkZSB0aGUgU2hlZXQgb2JqZWN0LCB0aGVzZSB0aGluZ3MgaW4gdGhlIGNsb25lZCBzaGVldCB3aWxsIGJlIGxvY2tlZCB3aGVuIHlvdSBvcGVuIGluIE1TIEV4Y2VsIGFwcC5cclxuICAgICAqIEBwYXJhbSB7U2hlZXR9IGZyb20gLSBUaGUgc2hlZXQgdG8gYmUgY2xvbmVkLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgbmV3IHNoZWV0LiBNdXN0IGJlIHVuaXF1ZSwgbGVzcyB0aGFuIDMxIGNoYXJhY3RlcnMsIGFuZCBtYXkgbm90IGNvbnRhaW4gdGhlIGZvbGxvd2luZyBjaGFyYWN0ZXJzOiBcXCAvICogWyBdIDogP1xyXG4gICAgICogQHBhcmFtIHtudW1iZXJ8c3RyaW5nfFNoZWV0fSBbaW5kZXhPckJlZm9yZVNoZWV0XSBUaGUgaW5kZXggdG8gbW92ZSB0aGUgc2hlZXQgdG8gb3IgdGhlIHNoZWV0IChvciBuYW1lIG9mIHNoZWV0KSB0byBtb3ZlIHRoaXMgc2hlZXQgYmVmb3JlLiBPbWl0IHRoaXMgYXJndW1lbnQgdG8gbW92ZSB0byB0aGUgZW5kIG9mIHRoZSB3b3JrYm9vay5cclxuICAgICAqIEByZXR1cm5zIHtTaGVldH0gVGhlIG5ldyBzaGVldC5cclxuICAgICAqL1xyXG4gICAgY2xvbmVTaGVldChmcm9tLCBuYW1lLCBpbmRleE9yQmVmb3JlU2hlZXQpIHtcclxuICAgICAgICBpZiAoIWZyb20gfHwgIShmcm9tIGluc3RhbmNlb2YgU2hlZXQpKSB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGNsb25lIGZyb20uXCIpO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fYWRkU2hlZXQobmFtZSwgaW5kZXhPckJlZm9yZVNoZWV0LCAoKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNsb25lWG1sID0gbm9kZSA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbm9kZSBoYXMgYSB0b1htbCBtZXRob2QsIGNhbGwgaXQuXHJcbiAgICAgICAgICAgICAgICBpZiAobm9kZSAmJiBfLmlzRnVuY3Rpb24obm9kZS50b1htbCkpIG5vZGUgPSBub2RlLnRvWG1sKCk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG5vZGUgPT09ICdvYmplY3QnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUubmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBub2RlLm5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7fSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuOiBbXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgXy5mb3JPd24obm9kZS5hdHRyaWJ1dGVzLCAodmFsdWUsIG5hbWUpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5hdHRyaWJ1dGVzW25hbWVdID0gdmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pOyBcclxuICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNobGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlLmNoaWxkcmVuKSB7IFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5jaGlsZHJlbi5mb3JFYWNoKGNoaWxkID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGxkID0gY2xvbmVYbWwoY2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZCAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuY2hpbGRyZW4ucHVzaChjaGxkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobm9kZSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBub2RlO1xyXG4gICAgICAgICAgICAgICAgfSBcclxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgLy8gY2xvbmUgU2hlZXROb2RlICYgcmVsYXRpb25zaGlwTm9kZSBmcm9tIHNvdXJjZVxyXG4gICAgICAgICAgICBjb25zdCBmcm9tWG1sID0gZnJvbS50b1htbHMoKTtcclxuICAgICAgICAgICAgY29uc3Qgc2hlZXROb2RlID0gY2xvbmVYbWwoZnJvbVhtbC5zaGVldCk7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlbGF0aW9uc2hpcE5vZGUgPSBjbG9uZVhtbChmcm9tWG1sLnJlbGF0aW9uc2hpcHMpO1xyXG4gICAgICAgICAgICByZXR1cm4geyBzaGVldE5vZGUsIHJlbGF0aW9uc2hpcE5vZGUgfTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFkZCBhIG5ldyBzaGVldCB0byB0aGUgd29ya2Jvb2suXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBzaGVldC4gTXVzdCBiZSB1bmlxdWUsIGxlc3MgdGhhbiAzMSBjaGFyYWN0ZXJzLCBhbmQgbWF5IG5vdCBjb250YWluIHRoZSBmb2xsb3dpbmcgY2hhcmFjdGVyczogXFwgLyAqIFsgXSA6ID9cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfHN0cmluZ3xTaGVldH0gW2luZGV4T3JCZWZvcmVTaGVldF0gVGhlIGluZGV4IHRvIG1vdmUgdGhlIHNoZWV0IHRvIG9yIHRoZSBzaGVldCAob3IgbmFtZSBvZiBzaGVldCkgdG8gbW92ZSB0aGlzIHNoZWV0IGJlZm9yZS4gT21pdCB0aGlzIGFyZ3VtZW50IHRvIG1vdmUgdG8gdGhlIGVuZCBvZiB0aGUgd29ya2Jvb2suXHJcbiAgICAgKiBAcGFyYW0ge2NhbGxiYWNrfSBbZ2V0VGVtcGxhdGVOb2Rlc10gb3B0aW9uYWwgY2FsbGJhY2sgZnVuY3Rpb24gZm9yIHRlbXBsYXRlIG5vZGVzXHJcbiAgICAgKiBAcmV0dXJucyB7U2hlZXR9IFRoZSBuZXcgc2hlZXQuXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICBfYWRkU2hlZXQobmFtZSwgaW5kZXhPckJlZm9yZVNoZWV0LCBnZXRUZW1wbGF0ZU5vZGVzKSB7XHJcbiAgICAgICAgLy8gVmFsaWRhdGUgdGhlIHNoZWV0IG5hbWUuXHJcbiAgICAgICAgaWYgKCFuYW1lIHx8IHR5cGVvZiBuYW1lICE9PSBcInN0cmluZ1wiKSB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHNoZWV0IG5hbWUuXCIpO1xyXG4gICAgICAgIGlmIChfLnNvbWUoYmFkU2hlZXROYW1lQ2hhcnMsIGNoYXIgPT4gbmFtZS5pbmRleE9mKGNoYXIpID49IDApKSB0aHJvdyBuZXcgRXJyb3IoYFNoZWV0IG5hbWUgbWF5IG5vdCBjb250YWluIGFueSBvZiB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnM6ICR7YmFkU2hlZXROYW1lQ2hhcnMuam9pbihcIiBcIil9YCk7XHJcbiAgICAgICAgaWYgKG5hbWUubGVuZ3RoID4gbWF4U2hlZXROYW1lTGVuZ3RoKSB0aHJvdyBuZXcgRXJyb3IoYFNoZWV0IG5hbWUgbWF5IG5vdCBiZSBncmVhdGVyIHRoYW4gJHttYXhTaGVldE5hbWVMZW5ndGh9IGNoYXJhY3RlcnMuYCk7XHJcbiAgICAgICAgaWYgKHRoaXMuc2hlZXQobmFtZSkpIHRocm93IG5ldyBFcnJvcihgU2hlZXQgd2l0aCBuYW1lIFwiJHtuYW1lfVwiIGFscmVhZHkgZXhpc3RzLmApO1xyXG5cclxuICAgICAgICAvLyBHZXQgdGhlIGRlc3RpbmF0aW9uIGluZGV4IG9mIG5ldyBzaGVldC5cclxuICAgICAgICBsZXQgaW5kZXg7XHJcbiAgICAgICAgaWYgKF8uaXNOaWwoaW5kZXhPckJlZm9yZVNoZWV0KSkge1xyXG4gICAgICAgICAgICBpbmRleCA9IHRoaXMuX3NoZWV0cy5sZW5ndGg7XHJcbiAgICAgICAgfSBlbHNlIGlmIChfLmlzSW50ZWdlcihpbmRleE9yQmVmb3JlU2hlZXQpKSB7XHJcbiAgICAgICAgICAgIGluZGV4ID0gaW5kZXhPckJlZm9yZVNoZWV0O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGlmICghKGluZGV4T3JCZWZvcmVTaGVldCBpbnN0YW5jZW9mIFNoZWV0KSkge1xyXG4gICAgICAgICAgICAgICAgaW5kZXhPckJlZm9yZVNoZWV0ID0gdGhpcy5zaGVldChpbmRleE9yQmVmb3JlU2hlZXQpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFpbmRleE9yQmVmb3JlU2hlZXQpIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgYmVmb3JlIHNoZWV0IHJlZmVyZW5jZS5cIik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGluZGV4ID0gdGhpcy5fc2hlZXRzLmluZGV4T2YoaW5kZXhPckJlZm9yZVNoZWV0KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIEFkZCBhIG5ldyByZWxhdGlvbnNoaXAgZm9yIHRoZSBuZXcgc2hlZXQgYW5kIGNyZWF0ZSB0aGUgbmV3IHNoZWV0IElEIG5vZGUuXHJcbiAgICAgICAgY29uc3QgcmVsYXRpb25zaGlwID0gdGhpcy5fcmVsYXRpb25zaGlwcy5hZGQoXCJ3b3Jrc2hlZXRcIik7IC8vIExlYXZlIHRhcmdldCBibGFuayBhcyBpdCB3aWxsIGJlIGZpbGxlZCBsYXRlci5cclxuICAgICAgICBjb25zdCBzaGVldElkTm9kZSA9IHtcclxuICAgICAgICAgICAgbmFtZTogXCJzaGVldFwiLFxyXG4gICAgICAgICAgICBhdHRyaWJ1dGVzOiB7XHJcbiAgICAgICAgICAgICAgICBuYW1lLFxyXG4gICAgICAgICAgICAgICAgc2hlZXRJZDogKyt0aGlzLl9tYXhTaGVldElkLFxyXG4gICAgICAgICAgICAgICAgJ3I6aWQnOiByZWxhdGlvbnNoaXAuYXR0cmlidXRlcy5JZFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBjaGlsZHJlbjogW11cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvLyBDcmVhdGUgdGhlIG5ldyBzaGVldC5cclxuICAgICAgICBsZXQgc2hlZXQ7XHJcbiAgICAgICAgaWYgKGdldFRlbXBsYXRlTm9kZXMpIHtcclxuICAgICAgICAgICAgY29uc3QgeyBzaGVldE5vZGUsIHJlbGF0aW9uc2hpcE5vZGUgfSA9IGdldFRlbXBsYXRlTm9kZXMoKTtcclxuICAgICAgICAgICAgc2hlZXQgPSBuZXcgU2hlZXQodGhpcywgc2hlZXRJZE5vZGUsIHNoZWV0Tm9kZSwgcmVsYXRpb25zaGlwTm9kZSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgc2hlZXQgPSBuZXcgU2hlZXQodGhpcywgc2hlZXRJZE5vZGUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gSW5zZXJ0IHRoZSBzaGVldCBhdCB0aGUgYXBwcm9wcmlhdGUgaW5kZXguXHJcbiAgICAgICAgdGhpcy5fc2hlZXRzLnNwbGljZShpbmRleCwgMCwgc2hlZXQpO1xyXG5cclxuICAgICAgICByZXR1cm4gc2hlZXQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbml0aWFsaXplIHRoZSB3b3JrYm9vay4gKFRoaXMgaXMgc2VwYXJhdGVkIGZyb20gdGhlIGNvbnN0cnVjdG9yIHRvIGVhc2UgdGVzdGluZy4pXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xBcnJheUJ1ZmZlcnxVaW50OEFycmF5fEJ1ZmZlcnxCbG9ifSBkYXRhIC0gVGhlIGRhdGEgdG8gbG9hZC5cclxuICAgICAqIEBwYXJhbSB7e319IFtvcHRzXSAtIE9wdGlvbnNcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdHMuYmFzZTY0PWZhbHNlXSAtIE5vIHVzZWQgdW5sZXNzIGlucHV0IGlzIGEgc3RyaW5nLiBUcnVlIGlmIHRoZSBpbnB1dCBzdHJpbmcgaXMgYmFzZTY0IGVuY29kZWQsIGZhbHNlIGZvciBiaW5hcnkuXHJcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZS48V29ya2Jvb2s+fSBUaGUgd29ya2Jvb2suXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICBfaW5pdEFzeW5jKGRhdGEsIG9wdHMpIHtcclxuICAgICAgICBvcHRzID0gb3B0cyB8fCB7fTtcclxuXHJcbiAgICAgICAgdGhpcy5fbWF4U2hlZXRJZCA9IDA7XHJcbiAgICAgICAgdGhpcy5fc2hlZXRzID0gW107XHJcblxyXG4gICAgICAgIHJldHVybiBleHRlcm5hbHMuUHJvbWlzZS5yZXNvbHZlKClcclxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHRoZSBpbnB1dCBpcyBhIEJ1ZmZlclxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnZlcnRJbnB1dFRvQnVmZmVyQXN5bmMoZGF0YSwgb3B0cy5iYXNlNjQpXHJcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oYnVmZmVyID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGJ1ZmZlcjtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFvcHRzLnBhc3N3b3JkKSByZXR1cm47XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZW5jcnlwdG9yLmRlY3J5cHRBc3luYyhkYXRhLCBvcHRzLnBhc3N3b3JkKVxyXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKGRlY3J5cHRlZCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZWNyeXB0ZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIC50aGVuKCgpID0+IEpTWmlwLmxvYWRBc3luYyhkYXRhKSlcclxuICAgICAgICAgICAgLnRoZW4oemlwID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3ppcCA9IHppcDtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9wYXJzZU5vZGVzQXN5bmMoW1xyXG4gICAgICAgICAgICAgICAgICAgIFwiW0NvbnRlbnRfVHlwZXNdLnhtbFwiLFxyXG4gICAgICAgICAgICAgICAgICAgIFwiZG9jUHJvcHMvYXBwLnhtbFwiLFxyXG4gICAgICAgICAgICAgICAgICAgIFwiZG9jUHJvcHMvY29yZS54bWxcIixcclxuICAgICAgICAgICAgICAgICAgICBcInhsL19yZWxzL3dvcmtib29rLnhtbC5yZWxzXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgXCJ4bC9zaGFyZWRTdHJpbmdzLnhtbFwiLFxyXG4gICAgICAgICAgICAgICAgICAgIFwieGwvc3R5bGVzLnhtbFwiLFxyXG4gICAgICAgICAgICAgICAgICAgIFwieGwvd29ya2Jvb2sueG1sXCJcclxuICAgICAgICAgICAgICAgIF0pO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAudGhlbihub2RlcyA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjb250ZW50VHlwZXNOb2RlID0gbm9kZXNbMF07XHJcbiAgICAgICAgICAgICAgICBjb25zdCBhcHBQcm9wZXJ0aWVzTm9kZSA9IG5vZGVzWzFdO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgY29yZVByb3BlcnRpZXNOb2RlID0gbm9kZXNbMl07XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZWxhdGlvbnNoaXBzTm9kZSA9IG5vZGVzWzNdO1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc2hhcmVkU3RyaW5nc05vZGUgPSBub2Rlc1s0XTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHN0eWxlU2hlZXROb2RlID0gbm9kZXNbNV07XHJcbiAgICAgICAgICAgICAgICBjb25zdCB3b3JrYm9va05vZGUgPSBub2Rlc1s2XTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBMb2FkIHRoZSB2YXJpb3VzIGNvbXBvbmVudHMuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9jb250ZW50VHlwZXMgPSBuZXcgQ29udGVudFR5cGVzKGNvbnRlbnRUeXBlc05vZGUpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fYXBwUHJvcGVydGllcyA9IG5ldyBBcHBQcm9wZXJ0aWVzKGFwcFByb3BlcnRpZXNOb2RlKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2NvcmVQcm9wZXJ0aWVzID0gbmV3IENvcmVQcm9wZXJ0aWVzKGNvcmVQcm9wZXJ0aWVzTm9kZSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9yZWxhdGlvbnNoaXBzID0gbmV3IFJlbGF0aW9uc2hpcHMocmVsYXRpb25zaGlwc05vZGUpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fc2hhcmVkU3RyaW5ncyA9IG5ldyBTaGFyZWRTdHJpbmdzKHNoYXJlZFN0cmluZ3NOb2RlKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3N0eWxlU2hlZXQgPSBuZXcgU3R5bGVTaGVldChzdHlsZVNoZWV0Tm9kZSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9ub2RlID0gd29ya2Jvb2tOb2RlO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vIEFkZCB0aGUgc2hhcmVkIHN0cmluZ3MgcmVsYXRpb25zaGlwIGlmIGl0IGRvZXNuJ3QgZXhpc3QuXHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX3JlbGF0aW9uc2hpcHMuZmluZEJ5VHlwZShcInNoYXJlZFN0cmluZ3NcIikpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZWxhdGlvbnNoaXBzLmFkZChcInNoYXJlZFN0cmluZ3NcIiwgXCJzaGFyZWRTdHJpbmdzLnhtbFwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBBZGQgdGhlIHNoYXJlZCBzdHJpbmcgY29udGVudCB0eXBlIGlmIGl0IGRvZXNuJ3QgZXhpc3QuXHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX2NvbnRlbnRUeXBlcy5maW5kQnlQYXJ0TmFtZShcIi94bC9zaGFyZWRTdHJpbmdzLnhtbFwiKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2NvbnRlbnRUeXBlcy5hZGQoXCIveGwvc2hhcmVkU3RyaW5ncy54bWxcIiwgXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5zaGFyZWRTdHJpbmdzK3htbFwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBLaWxsIHRoZSBjYWxjIGNoYWluLiBJdCdzIG5vdCByZXF1aXJlZCBhbmQgdGhlIHdvcmtib29rIHdpbGwgY29ycnVwdCB1bmxlc3Mgd2Uga2VlcCBpdCB1cCB0byBkYXRlLlxyXG4gICAgICAgICAgICAgICAgdGhpcy5femlwLnJlbW92ZShcInhsL2NhbGNDaGFpbi54bWxcIik7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gTG9hZCBlYWNoIHNoZWV0LlxyXG4gICAgICAgICAgICAgICAgdGhpcy5fc2hlZXRzTm9kZSA9IHhtbHEuZmluZENoaWxkKHRoaXMuX25vZGUsIFwic2hlZXRzXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGV4dGVybmFscy5Qcm9taXNlLmFsbChfLm1hcCh0aGlzLl9zaGVldHNOb2RlLmNoaWxkcmVuLCAoc2hlZXRJZE5vZGUsIGkpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2hlZXRJZE5vZGUuYXR0cmlidXRlcy5zaGVldElkID4gdGhpcy5fbWF4U2hlZXRJZCkgdGhpcy5fbWF4U2hlZXRJZCA9IHNoZWV0SWROb2RlLmF0dHJpYnV0ZXMuc2hlZXRJZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnNlTm9kZXNBc3luYyhbYHhsL3dvcmtzaGVldHMvc2hlZXQke2kgKyAxfS54bWxgLCBgeGwvd29ya3NoZWV0cy9fcmVscy9zaGVldCR7aSArIDF9LnhtbC5yZWxzYF0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKG5vZGVzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNoZWV0Tm9kZSA9IG5vZGVzWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2hlZXRSZWxhdGlvbnNoaXBzTm9kZSA9IG5vZGVzWzFdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluc2VydCBhdCBwb3NpdGlvbiBpIGFzIHRoZSBwcm9taXNlcyB3aWxsIHJlc29sdmUgYXQgZGlmZmVyZW50IHRpbWVzLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2hlZXRzW2ldID0gbmV3IFNoZWV0KHRoaXMsIHNoZWV0SWROb2RlLCBzaGVldE5vZGUsIHNoZWV0UmVsYXRpb25zaGlwc05vZGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5fcGFyc2VTaGVldFJlZnMoKSlcclxuICAgICAgICAgICAgLnRoZW4oKCkgPT4gdGhpcyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBQYXJzZSBmaWxlcyBvdXQgb2YgemlwIGludG8gWE1MIG5vZGUgb2JqZWN0cy5cclxuICAgICAqIEBwYXJhbSB7QXJyYXkuPHN0cmluZz59IG5hbWVzIC0gVGhlIGZpbGUgbmFtZXMgdG8gcGFyc2UuXHJcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZS48QXJyYXkuPHt9Pj59IEFuIGFycmF5IG9mIHRoZSBwYXJzZWQgb2JqZWN0cy5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIF9wYXJzZU5vZGVzQXN5bmMobmFtZXMpIHtcclxuICAgICAgICByZXR1cm4gZXh0ZXJuYWxzLlByb21pc2UuYWxsKF8ubWFwKG5hbWVzLCBuYW1lID0+IHRoaXMuX3ppcC5maWxlKG5hbWUpKSlcclxuICAgICAgICAgICAgLnRoZW4oZmlsZXMgPT4gZXh0ZXJuYWxzLlByb21pc2UuYWxsKF8ubWFwKGZpbGVzLCBmaWxlID0+IGZpbGUgJiYgZmlsZS5hc3luYyhcInN0cmluZ1wiKSkpKVxyXG4gICAgICAgICAgICAudGhlbih0ZXh0cyA9PiBleHRlcm5hbHMuUHJvbWlzZS5hbGwoXy5tYXAodGV4dHMsIHRleHQgPT4gdGV4dCAmJiB4bWxQYXJzZXIucGFyc2VBc3luYyh0ZXh0KSkpKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFBhcnNlIHRoZSBzaGVldCByZWZlcmVuY2VzIG91dCBzbyB3ZSBjYW4gcmVvcmRlciBmcmVlbHkuXHJcbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgX3BhcnNlU2hlZXRSZWZzKCkge1xyXG4gICAgICAgIC8vIFBhcnNlIHRoZSBhY3RpdmUgc2hlZXQuXHJcbiAgICAgICAgY29uc3QgYm9va1ZpZXdzTm9kZSA9IHhtbHEuZmluZENoaWxkKHRoaXMuX25vZGUsIFwiYm9va1ZpZXdzXCIpO1xyXG4gICAgICAgIGNvbnN0IHdvcmtib29rVmlld05vZGUgPSBib29rVmlld3NOb2RlICYmIHhtbHEuZmluZENoaWxkKGJvb2tWaWV3c05vZGUsIFwid29ya2Jvb2tWaWV3XCIpO1xyXG4gICAgICAgIGNvbnN0IGFjdGl2ZVRhYklkID0gd29ya2Jvb2tWaWV3Tm9kZSAmJiB3b3JrYm9va1ZpZXdOb2RlLmF0dHJpYnV0ZXMuYWN0aXZlVGFiIHx8IDA7XHJcbiAgICAgICAgdGhpcy5fYWN0aXZlU2hlZXQgPSB0aGlzLl9zaGVldHNbYWN0aXZlVGFiSWRdO1xyXG5cclxuICAgICAgICAvLyBTZXQgdGhlIGxvY2F0aW9uIHNoZWV0IG9uIHRoZSBkZWZpbmVkIG5hbWUgbm9kZXMuIFRoZSBkZWZpbmVkIG5hbWUgc2hvdWxkIHBvaW50IHRvIHRoZSBpbmRleCBvZiB0aGUgc2hlZXRcclxuICAgICAgICAvLyBidXQgcmVvcmRlcmluZyBzaGVldHMgbWVzc2VzIHRoaXMgdXAuIFNvIHN0b3JlIGl0IG9uIHRoZSBub2RlIGFuZCB3ZSdsbCB1cGRhdGUgdGhlIGluZGV4IG9uIFhNTCBidWlsZC5cclxuICAgICAgICBjb25zdCBkZWZpbmVkTmFtZXNOb2RlID0geG1scS5maW5kQ2hpbGQodGhpcy5fbm9kZSwgXCJkZWZpbmVkTmFtZXNcIik7XHJcbiAgICAgICAgaWYgKGRlZmluZWROYW1lc05vZGUpIHtcclxuICAgICAgICAgICAgXy5mb3JFYWNoKGRlZmluZWROYW1lc05vZGUuY2hpbGRyZW4sIGRlZmluZWROYW1lTm9kZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZGVmaW5lZE5hbWVOb2RlLmF0dHJpYnV0ZXMuaGFzT3duUHJvcGVydHkoXCJsb2NhbFNoZWV0SWRcIikpIHtcclxuICAgICAgICAgICAgICAgICAgICBkZWZpbmVkTmFtZU5vZGUubG9jYWxTaGVldCA9IHRoaXMuX3NoZWV0c1tkZWZpbmVkTmFtZU5vZGUuYXR0cmlidXRlcy5sb2NhbFNoZWV0SWRdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZXQgdGhlIHByb3BlciBzaGVldCByZWZlcmVuY2VzIGluIHRoZSBYTUwuXHJcbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgX3NldFNoZWV0UmVmcygpIHtcclxuICAgICAgICAvLyBTZXQgdGhlIGFjdGl2ZSBzaGVldC5cclxuICAgICAgICBsZXQgYm9va1ZpZXdzTm9kZSA9IHhtbHEuZmluZENoaWxkKHRoaXMuX25vZGUsIFwiYm9va1ZpZXdzXCIpO1xyXG4gICAgICAgIGlmICghYm9va1ZpZXdzTm9kZSkge1xyXG4gICAgICAgICAgICBib29rVmlld3NOb2RlID0geyBuYW1lOiAnYm9va1ZpZXdzJywgYXR0cmlidXRlczoge30sIGNoaWxkcmVuOiBbXSB9O1xyXG4gICAgICAgICAgICB4bWxxLmluc2VydEluT3JkZXIodGhpcy5fbm9kZSwgYm9va1ZpZXdzTm9kZSwgbm9kZU9yZGVyKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCB3b3JrYm9va1ZpZXdOb2RlID0geG1scS5maW5kQ2hpbGQoYm9va1ZpZXdzTm9kZSwgXCJ3b3JrYm9va1ZpZXdcIik7XHJcbiAgICAgICAgaWYgKCF3b3JrYm9va1ZpZXdOb2RlKSB7XHJcbiAgICAgICAgICAgIHdvcmtib29rVmlld05vZGUgPSB7IG5hbWU6ICd3b3JrYm9va1ZpZXcnLCBhdHRyaWJ1dGVzOiB7fSwgY2hpbGRyZW46IFtdIH07XHJcbiAgICAgICAgICAgIHhtbHEuYXBwZW5kQ2hpbGQoYm9va1ZpZXdzTm9kZSwgd29ya2Jvb2tWaWV3Tm9kZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB3b3JrYm9va1ZpZXdOb2RlLmF0dHJpYnV0ZXMuYWN0aXZlVGFiID0gdGhpcy5fc2hlZXRzLmluZGV4T2YodGhpcy5fYWN0aXZlU2hlZXQpO1xyXG5cclxuICAgICAgICAvLyBTZXQgdGhlIGRlZmluZWQgbmFtZXMgbG9jYWwgc2hlZXQgaW5kZXhlcy5cclxuICAgICAgICBjb25zdCBkZWZpbmVkTmFtZXNOb2RlID0geG1scS5maW5kQ2hpbGQodGhpcy5fbm9kZSwgXCJkZWZpbmVkTmFtZXNcIik7XHJcbiAgICAgICAgaWYgKGRlZmluZWROYW1lc05vZGUpIHtcclxuICAgICAgICAgICAgXy5mb3JFYWNoKGRlZmluZWROYW1lc05vZGUuY2hpbGRyZW4sIGRlZmluZWROYW1lTm9kZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZGVmaW5lZE5hbWVOb2RlLmxvY2FsU2hlZXQpIHtcclxuICAgICAgICAgICAgICAgICAgICBkZWZpbmVkTmFtZU5vZGUuYXR0cmlidXRlcy5sb2NhbFNoZWV0SWQgPSB0aGlzLl9zaGVldHMuaW5kZXhPZihkZWZpbmVkTmFtZU5vZGUubG9jYWxTaGVldCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnQgYnVmZmVyIHRvIGRlc2lyZWQgb3V0cHV0IGZvcm1hdFxyXG4gICAgICogQHBhcmFtIHtCdWZmZXJ9IGJ1ZmZlciAtIFRoZSBidWZmZXJcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIC0gVGhlIHR5cGUgdG8gY29udmVydCB0bzogYnVmZmVyL25vZGVidWZmZXIsIGJsb2IsIGJhc2U2NCwgYmluYXJ5c3RyaW5nLCB1aW50OGFycmF5LCBhcnJheWJ1ZmZlclxyXG4gICAgICogQHJldHVybnMge0J1ZmZlcnxCbG9ifHN0cmluZ3xVaW50OEFycmF5fEFycmF5QnVmZmVyfSBUaGUgb3V0cHV0XHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICBfY29udmVydEJ1ZmZlclRvT3V0cHV0KGJ1ZmZlciwgdHlwZSkge1xyXG4gICAgICAgIGlmICghdHlwZSkgdHlwZSA9IHByb2Nlc3MuYnJvd3NlciA/IFwiYmxvYlwiIDogXCJub2RlYnVmZmVyXCI7XHJcblxyXG4gICAgICAgIGlmICh0eXBlID09PSBcImJ1ZmZlclwiIHx8IHR5cGUgPT09IFwibm9kZWJ1ZmZlclwiKSByZXR1cm4gYnVmZmVyO1xyXG4gICAgICAgIGlmIChwcm9jZXNzLmJyb3dzZXIgJiYgdHlwZSA9PT0gXCJibG9iXCIpIHJldHVybiBuZXcgQmxvYihbYnVmZmVyXSwgeyB0eXBlOiBXb3JrYm9vay5NSU1FX1RZUEUgfSk7XHJcbiAgICAgICAgaWYgKHR5cGUgPT09IFwiYmFzZTY0XCIpIHJldHVybiBidWZmZXIudG9TdHJpbmcoXCJiYXNlNjRcIik7XHJcbiAgICAgICAgaWYgKHR5cGUgPT09IFwiYmluYXJ5c3RyaW5nXCIpIHJldHVybiBidWZmZXIudG9TdHJpbmcoXCJ1dGY4XCIpO1xyXG4gICAgICAgIGlmICh0eXBlID09PSBcInVpbnQ4YXJyYXlcIikgcmV0dXJuIG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XHJcbiAgICAgICAgaWYgKHR5cGUgPT09IFwiYXJyYXlidWZmZXJcIikgcmV0dXJuIG5ldyBVaW50OEFycmF5KGJ1ZmZlcikuYnVmZmVyO1xyXG5cclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE91dHB1dCB0eXBlICcke3R5cGV9JyBub3Qgc3VwcG9ydGVkLmApO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydCBpbnB1dCB0byBidWZmZXJcclxuICAgICAqIEBwYXJhbSB7QnVmZmVyfEJsb2J8c3RyaW5nfFVpbnQ4QXJyYXl8QXJyYXlCdWZmZXJ9IGlucHV0IC0gVGhlIGlucHV0XHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtiYXNlNjQ9ZmFsc2VdIC0gT25seSBhcHBsaWVzIGlmIGlucHV0IGlzIGEgc3RyaW5nLiBJZiB0cnVlLCB0aGUgc3RyaW5nIGlzIGJhc2U2NCBlbmNvZGVkLCBmYWxzZSBmb3IgYmluYXJ5XHJcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZS48QnVmZmVyPn0gVGhlIGJ1ZmZlci5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIF9jb252ZXJ0SW5wdXRUb0J1ZmZlckFzeW5jKGlucHV0LCBiYXNlNjQpIHtcclxuICAgICAgICByZXR1cm4gZXh0ZXJuYWxzLlByb21pc2UucmVzb2x2ZSgpXHJcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChCdWZmZXIuaXNCdWZmZXIoaW5wdXQpKSByZXR1cm4gaW5wdXQ7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHByb2Nlc3MuYnJvd3NlciAmJiBpbnB1dCBpbnN0YW5jZW9mIEJsb2IpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IGV4dGVybmFscy5Qcm9taXNlKHJlc29sdmUgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaWxlUmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVJlYWRlci5vbmxvYWQgPSBldmVudCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKEJ1ZmZlci5mcm9tKGV2ZW50LnRhcmdldC5yZXN1bHQpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmlsZVJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcihpbnB1dCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBpbnB1dCA9PT0gXCJzdHJpbmdcIiAmJiBiYXNlNjQpIHJldHVybiBCdWZmZXIuZnJvbShpbnB1dCwgXCJiYXNlNjRcIik7XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGlucHV0ID09PSBcInN0cmluZ1wiICYmICFiYXNlNjQpIHJldHVybiBCdWZmZXIuZnJvbShpbnB1dCwgXCJ1dGY4XCIpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGlucHV0IGluc3RhbmNlb2YgVWludDhBcnJheSB8fCBpbnB1dCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSByZXR1cm4gQnVmZmVyLmZyb20oaW5wdXQpO1xyXG5cclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW5wdXQgdHlwZSB1bmtub3duLmApO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFRoZSBYTFNYIG1pbWUgdHlwZS5cclxuICogQHR5cGUge3N0cmluZ31cclxuICogQGlnbm9yZVxyXG4gKi9cclxuV29ya2Jvb2suTUlNRV9UWVBFID0gXCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5zaGVldFwiO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBXb3JrYm9vaztcclxuXHJcbi8qXHJcbnhsL3dvcmtib29rLnhtbFxyXG5cclxuPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVRGLThcIiBzdGFuZGFsb25lPVwieWVzXCI/PlxyXG48d29ya2Jvb2sgeG1sbnM9XCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvc3ByZWFkc2hlZXRtbC8yMDA2L21haW5cIiB4bWxuczpyPVwiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL29mZmljZURvY3VtZW50LzIwMDYvcmVsYXRpb25zaGlwc1wiIHhtbG5zOm1jPVwiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL21hcmt1cC1jb21wYXRpYmlsaXR5LzIwMDZcIiBtYzpJZ25vcmFibGU9XCJ4MTVcIiB4bWxuczp4MTU9XCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL29mZmljZS9zcHJlYWRzaGVldG1sLzIwMTAvMTEvbWFpblwiPlxyXG5cdDxmaWxlVmVyc2lvbiBhcHBOYW1lPVwieGxcIiBsYXN0RWRpdGVkPVwiN1wiIGxvd2VzdEVkaXRlZD1cIjdcIiBydXBCdWlsZD1cIjE2OTI1XCIvPlxyXG5cdDx3b3JrYm9va1ByIGRlZmF1bHRUaGVtZVZlcnNpb249XCIxNjQwMTFcIi8+XHJcblx0PG1jOkFsdGVybmF0ZUNvbnRlbnQgeG1sbnM6bWM9XCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvbWFya3VwLWNvbXBhdGliaWxpdHkvMjAwNlwiPlxyXG5cdFx0PG1jOkNob2ljZSBSZXF1aXJlcz1cIngxNVwiPlxyXG5cdFx0XHQ8eDE1YWM6YWJzUGF0aCB1cmw9XCJcXHBhdGhcXHRvXFxmaWxlXCIgeG1sbnM6eDE1YWM9XCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL29mZmljZS9zcHJlYWRzaGVldG1sLzIwMTAvMTEvYWNcIi8+XHJcblx0XHQ8L21jOkNob2ljZT5cclxuXHQ8L21jOkFsdGVybmF0ZUNvbnRlbnQ+XHJcblx0PGJvb2tWaWV3cz5cclxuXHRcdDx3b3JrYm9va1ZpZXcgeFdpbmRvdz1cIjM3MjBcIiB5V2luZG93PVwiMFwiIHdpbmRvd1dpZHRoPVwiMjc4NzBcIiB3aW5kb3dIZWlnaHQ9XCIxMjc5NVwiLz5cclxuXHQ8L2Jvb2tWaWV3cz5cclxuXHQ8c2hlZXRzPlxyXG5cdFx0PHNoZWV0IG5hbWU9XCJTaGVldDFcIiBzaGVldElkPVwiMVwiIHI6aWQ9XCJySWQxXCIvPlxyXG5cdDwvc2hlZXRzPlxyXG5cdDxjYWxjUHIgY2FsY0lkPVwiMTcxMDI3XCIvPlxyXG5cdDxleHRMc3Q+XHJcblx0XHQ8ZXh0IHVyaT1cInsxNDBBNzA5NC0wRTM1LTQ4OTItODQzMi1DNEQyRTU3RURFQjV9XCIgeG1sbnM6eDE1PVwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9vZmZpY2Uvc3ByZWFkc2hlZXRtbC8yMDEwLzExL21haW5cIj5cclxuXHRcdFx0PHgxNTp3b3JrYm9va1ByIGNoYXJ0VHJhY2tpbmdSZWZCYXNlPVwiMVwiLz5cclxuXHRcdDwvZXh0PlxyXG5cdDwvZXh0THN0PlxyXG48L3dvcmtib29rPlxyXG4vLyAqL1xyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxuXHJcbmNvbnN0IGV4dGVybmFscyA9IHJlcXVpcmUoXCIuL2V4dGVybmFsc1wiKTtcclxuY29uc3QgV29ya2Jvb2sgPSByZXF1aXJlKFwiLi9Xb3JrYm9va1wiKTtcclxuY29uc3QgRm9ybXVsYUVycm9yID0gcmVxdWlyZShcIi4vRm9ybXVsYUVycm9yXCIpO1xyXG5jb25zdCBkYXRlQ29udmVydGVyID0gcmVxdWlyZShcIi4vZGF0ZUNvbnZlcnRlclwiKTtcclxuY29uc3QgUmljaFRleHQgPSByZXF1aXJlKFwiLi9SaWNoVGV4dFwiKTtcclxuXHJcbi8qKlxyXG4gKiB4bHN4LXBvdWxhdGUgbmFtZXNwYWNlLlxyXG4gKiBAbmFtZXNwYWNlXHJcbiAqL1xyXG5jbGFzcyBYbHN4UG9wdWxhdGUge1xyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0IGEgZGF0ZSB0byBhIG51bWJlciBmb3IgRXhjZWwuXHJcbiAgICAgKiBAcGFyYW0ge0RhdGV9IGRhdGUgLSBUaGUgZGF0ZS5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFRoZSBudW1iZXIuXHJcbiAgICAgKi9cclxuICAgIHN0YXRpYyBkYXRlVG9OdW1iZXIoZGF0ZSkge1xyXG4gICAgICAgIHJldHVybiBkYXRlQ29udmVydGVyLmRhdGVUb051bWJlcihkYXRlKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZSBhIG5ldyBibGFuayB3b3JrYm9vay5cclxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlLjxXb3JrYm9vaz59IFRoZSB3b3JrYm9vay5cclxuICAgICAqL1xyXG4gICAgc3RhdGljIGZyb21CbGFua0FzeW5jKCkge1xyXG4gICAgICAgIHJldHVybiBXb3JrYm9vay5mcm9tQmxhbmtBc3luYygpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogTG9hZHMgYSB3b3JrYm9vayBmcm9tIGEgZGF0YSBvYmplY3QuIChTdXBwb3J0cyBhbnkgc3VwcG9ydGVkIFtKU1ppcCBkYXRhIHR5cGVzXXtAbGluayBodHRwczovL3N0dWsuZ2l0aHViLmlvL2pzemlwL2RvY3VtZW50YXRpb24vYXBpX2pzemlwL2xvYWRfYXN5bmMuaHRtbH0uKVxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd8QXJyYXkuPG51bWJlcj58QXJyYXlCdWZmZXJ8VWludDhBcnJheXxCdWZmZXJ8QmxvYnxQcm9taXNlLjwqPn0gZGF0YSAtIFRoZSBkYXRhIHRvIGxvYWQuXHJcbiAgICAgKiBAcGFyYW0ge3t9fSBbb3B0c10gLSBPcHRpb25zXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdHMucGFzc3dvcmRdIC0gVGhlIHBhc3N3b3JkIHRvIGRlY3J5cHQgdGhlIHdvcmtib29rLlxyXG4gICAgICogQHJldHVybnMge1Byb21pc2UuPFdvcmtib29rPn0gVGhlIHdvcmtib29rLlxyXG4gICAgICovXHJcbiAgICBzdGF0aWMgZnJvbURhdGFBc3luYyhkYXRhLCBvcHRzKSB7XHJcbiAgICAgICAgcmV0dXJuIFdvcmtib29rLmZyb21EYXRhQXN5bmMoZGF0YSwgb3B0cyk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBMb2FkcyBhIHdvcmtib29rIGZyb20gZmlsZS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gVGhlIHBhdGggdG8gdGhlIHdvcmtib29rLlxyXG4gICAgICogQHBhcmFtIHt7fX0gW29wdHNdIC0gT3B0aW9uc1xyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLnBhc3N3b3JkXSAtIFRoZSBwYXNzd29yZCB0byBkZWNyeXB0IHRoZSB3b3JrYm9vay5cclxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlLjxXb3JrYm9vaz59IFRoZSB3b3JrYm9vay5cclxuICAgICAqL1xyXG4gICAgc3RhdGljIGZyb21GaWxlQXN5bmMocGF0aCwgb3B0cykge1xyXG4gICAgICAgIHJldHVybiBXb3JrYm9vay5mcm9tRmlsZUFzeW5jKHBhdGgsIG9wdHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydCBhbiBFeGNlbCBudW1iZXIgdG8gYSBkYXRlLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG51bWJlciAtIFRoZSBudW1iZXIuXHJcbiAgICAgKiBAcmV0dXJucyB7RGF0ZX0gVGhlIGRhdGUuXHJcbiAgICAgKi9cclxuICAgIHN0YXRpYyBudW1iZXJUb0RhdGUobnVtYmVyKSB7XHJcbiAgICAgICAgcmV0dXJuIGRhdGVDb252ZXJ0ZXIubnVtYmVyVG9EYXRlKG51bWJlcik7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgUHJvbWlzZSBsaWJyYXJ5LlxyXG4gICAgICogQHR5cGUge1Byb21pc2V9XHJcbiAgICAgKi9cclxuICAgIHN0YXRpYyBnZXQgUHJvbWlzZSgpIHtcclxuICAgICAgICByZXR1cm4gZXh0ZXJuYWxzLlByb21pc2U7XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgc2V0IFByb21pc2UoUHJvbWlzZSkge1xyXG4gICAgICAgIGV4dGVybmFscy5Qcm9taXNlID0gUHJvbWlzZTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFRoZSBYTFNYIG1pbWUgdHlwZS5cclxuICogQHR5cGUge3N0cmluZ31cclxuICovXHJcblhsc3hQb3B1bGF0ZS5NSU1FX1RZUEUgPSBXb3JrYm9vay5NSU1FX1RZUEU7XHJcblxyXG4vKipcclxuICogRm9ybXVsYSBlcnJvciBjbGFzcy5cclxuICogQHR5cGUge0Zvcm11bGFFcnJvcn1cclxuICovXHJcblhsc3hQb3B1bGF0ZS5Gb3JtdWxhRXJyb3IgPSBGb3JtdWxhRXJyb3I7XHJcblxyXG4vKipcclxuICogUmljaFRleHRzIGNsYXNzXHJcbiAqIEB0eXBlIHtSaWNoVGV4dH1cclxuICovXHJcblhsc3hQb3B1bGF0ZS5SaWNoVGV4dCA9IFJpY2hUZXh0O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBYbHN4UG9wdWxhdGU7XHJcbiIsIlwidXNlIHN0cmljdFwiO1xyXG5cclxuY29uc3QgXyA9IHJlcXVpcmUoXCJsb2Rhc2hcIik7XHJcblxyXG5jb25zdCBYTUxfREVDTEFSQVRJT04gPSBgPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVRGLThcIiBzdGFuZGFsb25lPVwieWVzXCI/PmA7XHJcblxyXG4vKipcclxuICogWE1MIGRvY3VtZW50IGJ1aWxkZXIuXHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5jbGFzcyBYbWxCdWlsZGVyIHtcclxuICAgIC8qKlxyXG4gICAgICogQnVpbGQgYW4gWE1MIHN0cmluZyBmcm9tIHRoZSBKU09OIG9iamVjdC5cclxuICAgICAqIEBwYXJhbSB7e319IG5vZGUgLSBUaGUgbm9kZS5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBYTUwgdGV4dC5cclxuICAgICAqL1xyXG4gICAgYnVpbGQobm9kZSkge1xyXG4gICAgICAgIHRoaXMuX2kgPSAwO1xyXG4gICAgICAgIGNvbnN0IHhtbCA9IHRoaXMuX2J1aWxkKG5vZGUsICcnKTtcclxuICAgICAgICBpZiAoeG1sID09PSAnJykgcmV0dXJuO1xyXG4gICAgICAgIHJldHVybiBYTUxfREVDTEFSQVRJT04gKyB4bWw7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBCdWlsZCB0aGUgWE1MIHN0cmluZy4gKFRoaXMgaXMgdGhlIGludGVybmFsIHJlY3Vyc2l2ZSBtZXRob2QuKVxyXG4gICAgICogQHBhcmFtIHt7fX0gbm9kZSAtIFRoZSBub2RlLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHhtbCAtIFRoZSBpbml0aWFsIFhNTCBkb2Mgc3RyaW5nLlxyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGdlbmVyYXRlZCBYTUwgZWxlbWVudC5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIF9idWlsZChub2RlLCB4bWwpIHtcclxuICAgICAgICAvLyBGb3IgQ1BVIHBlcmZvcm1hbmNlLCBKUyBlbmdpbmVzIGRvbid0IHRydWx5IGNvbmNhdGVuYXRlIHN0cmluZ3M7IHRoZXkgY3JlYXRlIGEgdHJlZSBvZiBwb2ludGVycyB0b1xyXG4gICAgICAgIC8vIHRoZSB2YXJpb3VzIGNvbmNhdGVuYXRlZCBzdHJpbmdzLiBUaGUgZG93bnNpZGUgb2YgdGhpcyBpcyB0aGF0IGl0IGNvbnN1bWVzIGEgbG90IG9mIG1lbW9yeSwgd2hpY2hcclxuICAgICAgICAvLyB3aWxsIGNhdXNlIHByb2JsZW1zIHdpdGggbGFyZ2Ugd29ya2Jvb2tzLiBTbyBwZXJpb2RpY2FsbHksIHdlIGdyYWIgYSBjaGFyYWN0ZXIgZnJvbSB0aGUgeG1sLCB3aGljaFxyXG4gICAgICAgIC8vIGNhdXNlcyB0aGUgSlMgZW5naW5lIHRvIGZsYXR0ZW4gdGhlIHRyZWUgaW50byBhIHNpbmdsZSBzdHJpbmcuIERvIHRoaXMgdG9vIG9mdGVuIGFuZCBDUFUgdGFrZXMgYSBoaXQuXHJcbiAgICAgICAgLy8gVG9vIGZyZXF1ZW50bHkgYW5kIG1lbW9yeSB0YWtlcyBhIGhpdC4gRXZlcnkgMTAwayBub2RlcyBzZWVtcyB0byBiZSBhIGdvb2QgYmFsYW5jZS5cclxuICAgICAgICBpZiAodGhpcy5faSsrICUgMTAwMDAwMCA9PT0gMCkge1xyXG4gICAgICAgICAgICB0aGlzLl9jID0geG1sWzBdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gSWYgdGhlIG5vZGUgaGFzIGEgdG9YbWwgbWV0aG9kLCBjYWxsIGl0LlxyXG4gICAgICAgIGlmIChub2RlICYmIF8uaXNGdW5jdGlvbihub2RlLnRvWG1sKSkgbm9kZSA9IG5vZGUudG9YbWwoKTtcclxuXHJcbiAgICAgICAgaWYgKF8uaXNPYmplY3Qobm9kZSkpIHtcclxuICAgICAgICAgICAgLy8gSWYgdGhlIG5vZGUgaXMgYW4gb2JqZWN0LCB0aGVuIGl0IG1hcHMgdG8gYW4gZWxlbWVudC4gQ2hlY2sgaWYgaXQgaGFzIGEgbmFtZS5cclxuICAgICAgICAgICAgaWYgKCFub2RlLm5hbWUpIHRocm93IG5ldyBFcnJvcihgWE1MIG5vZGUgZG9lcyBub3QgaGF2ZSBuYW1lOiAke0pTT04uc3RyaW5naWZ5KG5vZGUpfWApO1xyXG5cclxuICAgICAgICAgICAgLy8gQWRkIHRoZSBvcGVuaW5nIHRhZy5cclxuICAgICAgICAgICAgeG1sICs9IGA8JHtub2RlLm5hbWV9YDtcclxuXHJcbiAgICAgICAgICAgIC8vIEFkZCBhbnkgbm9kZSBhdHRyaWJ1dGVzXHJcbiAgICAgICAgICAgIF8uZm9yT3duKG5vZGUuYXR0cmlidXRlcywgKHZhbHVlLCBuYW1lKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB4bWwgKz0gYCAke25hbWV9PVwiJHt0aGlzLl9lc2NhcGVTdHJpbmcodmFsdWUsIHRydWUpfVwiYDtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICBpZiAoXy5pc0VtcHR5KG5vZGUuY2hpbGRyZW4pKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBTZWxmLWNsb3NlIHRoZSB0YWcgaWYgbm8gY2hpbGRyZW4uXHJcbiAgICAgICAgICAgICAgICB4bWwgKz0gXCIvPlwiO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgeG1sICs9IFwiPlwiO1xyXG4gICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAvLyBSZWN1cnNpdmVseSBhZGQgYW55IGNoaWxkcmVuLlxyXG4gICAgICAgICAgICAgICAgXy5mb3JFYWNoKG5vZGUuY2hpbGRyZW4sIGNoaWxkID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBBZGQgdGhlIGNoaWxkcmVuIHRvIHRoZSBYTUwuXHJcbiAgICAgICAgICAgICAgICAgICAgeG1sID0gdGhpcy5fYnVpbGQoY2hpbGQsIHhtbCk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBDbG9zZSB0aGUgdGFnLlxyXG4gICAgICAgICAgICAgICAgeG1sICs9IGA8LyR7bm9kZS5uYW1lfT5gO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIGlmICghXy5pc05pbChub2RlKSkge1xyXG4gICAgICAgICAgICAvLyBJdCBub3QgYW4gb2JqZWN0LCB0aGlzIHNob3VsZCBiZSBhIHRleHQgbm9kZS4gSnVzdCBhZGQgaXQuXHJcbiAgICAgICAgICAgIHhtbCArPSB0aGlzLl9lc2NhcGVTdHJpbmcobm9kZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBSZXR1cm4gdGhlIHVwZGF0ZWQgWE1MIGVsZW1lbnQuXHJcbiAgICAgICAgcmV0dXJuIHhtbDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEVzY2FwZSBhIHN0cmluZyBmb3IgdXNlIGluIFhNTCBieSByZXBsYWNpbmcgJiwgXCIsICcsIDwsIGFuZCA+LlxyXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBlc2NhcGUuXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0F0dHJpYnV0ZV0gLSBBIGZsYWcgaW5kaWNhdGluZyBpZiB0aGlzIGlzIGFuIGF0dHJpYnV0ZS5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBlc2NhcGVkIHN0cmluZy5cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIF9lc2NhcGVTdHJpbmcodmFsdWUsIGlzQXR0cmlidXRlKSB7XHJcbiAgICAgICAgaWYgKF8uaXNOaWwodmFsdWUpKSByZXR1cm4gdmFsdWU7XHJcbiAgICAgICAgdmFsdWUgPSB2YWx1ZS50b1N0cmluZygpXHJcbiAgICAgICAgICAgIC5yZXBsYWNlKC8mL2csIFwiJmFtcDtcIikgLy8gRXNjYXBlICcmJyBmaXJzdCBhcyB0aGUgb3RoZXIgZXNjYXBlcyBhZGQgdGhlbS5cclxuICAgICAgICAgICAgLnJlcGxhY2UoLzwvZywgXCImbHQ7XCIpXHJcbiAgICAgICAgICAgIC5yZXBsYWNlKC8+L2csIFwiJmd0O1wiKTtcclxuXHJcbiAgICAgICAgaWYgKGlzQXR0cmlidXRlKSB7XHJcbiAgICAgICAgICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZSgvXCIvZywgXCImcXVvdDtcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gWG1sQnVpbGRlcjtcclxuIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG5jb25zdCBzYXggPSByZXF1aXJlKFwic2F4XCIpO1xyXG5jb25zdCBleHRlcm5hbHMgPSByZXF1aXJlKFwiLi9leHRlcm5hbHNcIik7XHJcblxyXG4vLyBSZWdleCB0byBjaGVjayBpZiBzdHJpbmcgaXMgYWxsIHdoaXRlc3BhY2UuXHJcbmNvbnN0IGFsbFdoaXRlc3BhY2VSZWdleCA9IC9eXFxzKyQvO1xyXG5cclxuLyoqXHJcbiAqIFhNTCBwYXJzZXIuXHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5jbGFzcyBYbWxQYXJzZXIge1xyXG4gICAgLyoqXHJcbiAgICAgKiBQYXJzZSB0aGUgWE1MIHRleHQgaW50byBhIEpTT04gb2JqZWN0LlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHhtbFRleHQgLSBUaGUgWE1MIHRleHQuXHJcbiAgICAgKiBAcmV0dXJucyB7e319IFRoZSBKU09OIG9iamVjdC5cclxuICAgICAqL1xyXG4gICAgcGFyc2VBc3luYyh4bWxUZXh0KSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBleHRlcm5hbHMuUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgIC8vIENyZWF0ZSB0aGUgU0FYIHBhcnNlci5cclxuICAgICAgICAgICAgY29uc3QgcGFyc2VyID0gc2F4LnBhcnNlcih0cnVlKTtcclxuXHJcbiAgICAgICAgICAgIC8vIFBhcnNlZCBpcyB0aGUgZnVsbCBwYXJzZWQgb2JqZWN0LiBDdXJyZW50IGlzIHRoZSBjdXJyZW50IG5vZGUgYmVpbmcgcGFyc2VkLiBTdGFjayBpcyB0aGUgY3VycmVudCBzdGFjayBvZlxyXG4gICAgICAgICAgICAvLyBub2RlcyBsZWFkaW5nIHRvIHRoZSBjdXJyZW50IG9uZS5cclxuICAgICAgICAgICAgbGV0IHBhcnNlZCwgY3VycmVudDtcclxuICAgICAgICAgICAgY29uc3Qgc3RhY2sgPSBbXTtcclxuXHJcbiAgICAgICAgICAgIC8vIE9uIGVycm9yOiBSZWplY3QgdGhlIHByb21pc2UuXHJcbiAgICAgICAgICAgIHBhcnNlci5vbmVycm9yID0gcmVqZWN0O1xyXG5cclxuICAgICAgICAgICAgLy8gT24gdGV4dCBub2RlczogSWYgaXQgaXMgYWxsIHdoaXRlc3BhY2UsIGRvIG5vdGhpbmcuIE90aGVyd2lzZSwgdHJ5IHRvIGNvbnZlcnQgdG8gYSBudW1iZXIgYW5kIGFkZCBhcyBhIGNoaWxkLlxyXG4gICAgICAgICAgICBwYXJzZXIub250ZXh0ID0gdGV4dCA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYWxsV2hpdGVzcGFjZVJlZ2V4LnRlc3QodGV4dCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudCAmJiBjdXJyZW50LmF0dHJpYnV0ZXNbJ3htbDpzcGFjZSddID09PSAncHJlc2VydmUnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnQuY2hpbGRyZW4ucHVzaCh0ZXh0KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnQuY2hpbGRyZW4ucHVzaCh0aGlzLl9jb3ZlcnRUb051bWJlcklmTnVtYmVyKHRleHQpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIC8vIE9uIG9wZW4gdGFnIHN0YXJ0OiBDcmVhdGUgYSBjaGlsZCBlbGVtZW50LiBJZiB0aGlzIGlzIHRoZSByb290IGVsZW1lbnQsIHNldCBpdCBhcyBwYXJzZWQuIE90aGVyd2lzZSwgYWRkXHJcbiAgICAgICAgICAgIC8vIGl0IGFzIGEgY2hpbGQgdG8gdGhlIGN1cnJlbnQgbm9kZS5cclxuICAgICAgICAgICAgcGFyc2VyLm9ub3BlbnRhZ3N0YXJ0ID0gbm9kZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjaGlsZCA9IHsgbmFtZTogbm9kZS5uYW1lLCBhdHRyaWJ1dGVzOiB7fSwgY2hpbGRyZW46IFtdIH07XHJcbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnQuY2hpbGRyZW4ucHVzaChjaGlsZCk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHBhcnNlZCA9IGNoaWxkO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHN0YWNrLnB1c2goY2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgY3VycmVudCA9IGNoaWxkO1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgLy8gT24gY2xvc2UgdGFnOiBQb3AgdGhlIHN0YWNrLlxyXG4gICAgICAgICAgICBwYXJzZXIub25jbG9zZXRhZyA9IG5vZGUgPT4ge1xyXG4gICAgICAgICAgICAgICAgc3RhY2sucG9wKCk7XHJcbiAgICAgICAgICAgICAgICBjdXJyZW50ID0gc3RhY2tbc3RhY2subGVuZ3RoIC0gMV07XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAvLyBPbiBhdHRyaWJ1dGU6IFRyeSB0byBjb252ZXJ0IHRoZSB2YWx1ZSB0byBhIG51bWJlciBhbmQgYWRkIHRvIHRoZSBjdXJyZW50IG5vZGUuXHJcbiAgICAgICAgICAgIHBhcnNlci5vbmF0dHJpYnV0ZSA9IGF0dHJpYnV0ZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjdXJyZW50LmF0dHJpYnV0ZXNbYXR0cmlidXRlLm5hbWVdID0gdGhpcy5fY292ZXJ0VG9OdW1iZXJJZk51bWJlcihhdHRyaWJ1dGUudmFsdWUpO1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgLy8gT24gZW5kOiBSZXNvbHZlIHRoZSBwcm9taXNlLlxyXG4gICAgICAgICAgICBwYXJzZXIub25lbmQgPSAoKSA9PiByZXNvbHZlKHBhcnNlZCk7XHJcblxyXG4gICAgICAgICAgICAvLyBTdGFydCBwYXJzaW5nIHRoZSB0ZXh0LlxyXG4gICAgICAgICAgICBwYXJzZXIud3JpdGUoeG1sVGV4dCkuY2xvc2UoKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnQgdGhlIHN0cmluZyB0byBhIG51bWJlciBpZiBpdCBsb29rcyBsaWtlIG9uZS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgLSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bWJlcn0gVGhlIG51bWJlciBpZiBjb252ZXJ0ZWQgb3IgdGhlIHN0cmluZyBpZiBub3QuXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICBfY292ZXJ0VG9OdW1iZXJJZk51bWJlcihzdHIpIHtcclxuICAgICAgICBjb25zdCBudW0gPSBOdW1iZXIoc3RyKTtcclxuICAgICAgICByZXR1cm4gbnVtLnRvU3RyaW5nKCkgPT09IHN0ciA/IG51bSA6IHN0cjtcclxuICAgIH1cclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBYbWxQYXJzZXI7XHJcbiIsIlwidXNlIHN0cmljdFwiO1xyXG5cclxuLy8gVjggZG9lc24ndCBzdXBwb3J0IG9wdGltaXphdGlvbiBmb3IgY29tcG91bmQgYXNzaWdubWVudCBvZiBsZXQgdmFyaWFibGVzLlxyXG4vLyBUaGVzZSBtZXRob2RzIGdldCBjYWxsZWQgYSBsb3Qgc28gZGlzYWJsZSB0aGUgcnVsZSB0byBhbGxvdyBWOCBvcG10aW1pemF0aW9uLlxyXG4vKiBlc2xpbnQtZGlzYWJsZSBvcGVyYXRvci1hc3NpZ25tZW50ICovXHJcblxyXG5jb25zdCBfID0gcmVxdWlyZShcImxvZGFzaFwiKTtcclxuY29uc3QgQUREUkVTU19SRUdFWCA9IC9eKD86Jz8oLis/KSc/ISk/KD86KFxcJCk/KFtBLVpdKykoXFwkKT8oXFxkKykoPzo6KFxcJCk/KFtBLVpdKykoXFwkKT8oXFxkKykpP3woXFwkKT8oW0EtWl0rKTooXFwkKT8oW0EtWl0rKXwoXFwkKT8oXFxkKyk6KFxcJCk/KFxcZCspKSQvO1xyXG5cclxuLyoqXHJcbiAqIEFkZHJlc3MgY29udmVydGVyLlxyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxubW9kdWxlLmV4cG9ydHMgPSB7XHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnQgYSBjb2x1bW4gbmFtZSB0byBhIG51bWJlci5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gVGhlIGNvbHVtbiBuYW1lLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVGhlIG51bWJlci5cclxuICAgICAqL1xyXG4gICAgY29sdW1uTmFtZVRvTnVtYmVyKG5hbWUpIHtcclxuICAgICAgICBpZiAoIW5hbWUgfHwgdHlwZW9mIG5hbWUgIT09IFwic3RyaW5nXCIpIHJldHVybjtcclxuXHJcbiAgICAgICAgbmFtZSA9IG5hbWUudG9VcHBlckNhc2UoKTtcclxuICAgICAgICBsZXQgc3VtID0gMDtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5hbWUubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgc3VtID0gc3VtICogMjY7XHJcbiAgICAgICAgICAgIHN1bSA9IHN1bSArIChuYW1lW2ldLmNoYXJDb2RlQXQoMCkgLSAnQScuY2hhckNvZGVBdCgwKSArIDEpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHN1bTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0IGEgY29sdW1uIG51bWJlciB0byBhIG5hbWUuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbnVtYmVyIC0gVGhlIGNvbHVtbiBudW1iZXIuXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgbmFtZS5cclxuICAgICAqL1xyXG4gICAgY29sdW1uTnVtYmVyVG9OYW1lKG51bWJlcikge1xyXG4gICAgICAgIGxldCBkaXZpZGVuZCA9IG51bWJlcjtcclxuICAgICAgICBsZXQgbmFtZSA9ICcnO1xyXG4gICAgICAgIGxldCBtb2R1bG8gPSAwO1xyXG5cclxuICAgICAgICB3aGlsZSAoZGl2aWRlbmQgPiAwKSB7XHJcbiAgICAgICAgICAgIG1vZHVsbyA9IChkaXZpZGVuZCAtIDEpICUgMjY7XHJcbiAgICAgICAgICAgIG5hbWUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKCdBJy5jaGFyQ29kZUF0KDApICsgbW9kdWxvKSArIG5hbWU7XHJcbiAgICAgICAgICAgIGRpdmlkZW5kID0gTWF0aC5mbG9vcigoZGl2aWRlbmQgLSBtb2R1bG8pIC8gMjYpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG5hbWU7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydCBhbiBhZGRyZXNzIHRvIGEgcmVmZXJlbmNlIG9iamVjdC5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhZGRyZXNzIC0gVGhlIGFkZHJlc3MuXHJcbiAgICAgKiBAcmV0dXJucyB7e319IFRoZSByZWZlcmVuY2Ugb2JqZWN0LlxyXG4gICAgICovXHJcbiAgICBmcm9tQWRkcmVzcyhhZGRyZXNzKSB7XHJcbiAgICAgICAgY29uc3QgbWF0Y2ggPSBhZGRyZXNzLm1hdGNoKEFERFJFU1NfUkVHRVgpO1xyXG4gICAgICAgIGlmICghbWF0Y2gpIHJldHVybjtcclxuICAgICAgICBjb25zdCByZWYgPSB7fTtcclxuXHJcbiAgICAgICAgaWYgKG1hdGNoWzFdKSByZWYuc2hlZXROYW1lID0gbWF0Y2hbMV0ucmVwbGFjZSgvJycvZywgXCInXCIpO1xyXG4gICAgICAgIGlmIChtYXRjaFszXSAmJiBtYXRjaFs3XSkge1xyXG4gICAgICAgICAgICByZWYudHlwZSA9ICdyYW5nZSc7XHJcbiAgICAgICAgICAgIHJlZi5zdGFydENvbHVtbkFuY2hvcmVkID0gISFtYXRjaFsyXTtcclxuICAgICAgICAgICAgcmVmLnN0YXJ0Q29sdW1uTmFtZSA9IG1hdGNoWzNdO1xyXG4gICAgICAgICAgICByZWYuc3RhcnRDb2x1bW5OdW1iZXIgPSB0aGlzLmNvbHVtbk5hbWVUb051bWJlcihyZWYuc3RhcnRDb2x1bW5OYW1lKTtcclxuICAgICAgICAgICAgcmVmLnN0YXJ0Um93QW5jaG9yZWQgPSAhIW1hdGNoWzRdO1xyXG4gICAgICAgICAgICByZWYuc3RhcnRSb3dOdW1iZXIgPSBwYXJzZUludChtYXRjaFs1XSk7XHJcbiAgICAgICAgICAgIHJlZi5lbmRDb2x1bW5BbmNob3JlZCA9ICEhbWF0Y2hbNl07XHJcbiAgICAgICAgICAgIHJlZi5lbmRDb2x1bW5OYW1lID0gbWF0Y2hbN107XHJcbiAgICAgICAgICAgIHJlZi5lbmRDb2x1bW5OdW1iZXIgPSB0aGlzLmNvbHVtbk5hbWVUb051bWJlcihyZWYuZW5kQ29sdW1uTmFtZSk7XHJcbiAgICAgICAgICAgIHJlZi5lbmRSb3dBbmNob3JlZCA9ICEhbWF0Y2hbOF07XHJcbiAgICAgICAgICAgIHJlZi5lbmRSb3dOdW1iZXIgPSBwYXJzZUludChtYXRjaFs5XSk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChtYXRjaFszXSkge1xyXG4gICAgICAgICAgICByZWYudHlwZSA9ICdjZWxsJztcclxuICAgICAgICAgICAgcmVmLmNvbHVtbkFuY2hvcmVkID0gISFtYXRjaFsyXTtcclxuICAgICAgICAgICAgcmVmLmNvbHVtbk5hbWUgPSBtYXRjaFszXTtcclxuICAgICAgICAgICAgcmVmLmNvbHVtbk51bWJlciA9IHRoaXMuY29sdW1uTmFtZVRvTnVtYmVyKHJlZi5jb2x1bW5OYW1lKTtcclxuICAgICAgICAgICAgcmVmLnJvd0FuY2hvcmVkID0gISFtYXRjaFs0XTtcclxuICAgICAgICAgICAgcmVmLnJvd051bWJlciA9IHBhcnNlSW50KG1hdGNoWzVdKTtcclxuICAgICAgICB9IGVsc2UgaWYgKG1hdGNoWzExXSAmJiBtYXRjaFsxMV0gIT09IG1hdGNoWzEzXSkge1xyXG4gICAgICAgICAgICByZWYudHlwZSA9ICdjb2x1bW5SYW5nZSc7XHJcbiAgICAgICAgICAgIHJlZi5zdGFydENvbHVtbkFuY2hvcmVkID0gISFtYXRjaFsxMF07XHJcbiAgICAgICAgICAgIHJlZi5zdGFydENvbHVtbk5hbWUgPSBtYXRjaFsxMV07XHJcbiAgICAgICAgICAgIHJlZi5zdGFydENvbHVtbk51bWJlciA9IHRoaXMuY29sdW1uTmFtZVRvTnVtYmVyKHJlZi5zdGFydENvbHVtbk5hbWUpO1xyXG4gICAgICAgICAgICByZWYuZW5kQ29sdW1uQW5jaG9yZWQgPSAhIW1hdGNoWzEyXTtcclxuICAgICAgICAgICAgcmVmLmVuZENvbHVtbk5hbWUgPSBtYXRjaFsxM107XHJcbiAgICAgICAgICAgIHJlZi5lbmRDb2x1bW5OdW1iZXIgPSB0aGlzLmNvbHVtbk5hbWVUb051bWJlcihyZWYuZW5kQ29sdW1uTmFtZSk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChtYXRjaFsxMV0pIHtcclxuICAgICAgICAgICAgcmVmLnR5cGUgPSAnY29sdW1uJztcclxuICAgICAgICAgICAgcmVmLmNvbHVtbkFuY2hvcmVkID0gISFtYXRjaFsxMF07XHJcbiAgICAgICAgICAgIHJlZi5jb2x1bW5OYW1lID0gbWF0Y2hbMTFdO1xyXG4gICAgICAgICAgICByZWYuY29sdW1uTnVtYmVyID0gdGhpcy5jb2x1bW5OYW1lVG9OdW1iZXIocmVmLmNvbHVtbk5hbWUpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAobWF0Y2hbMTVdICYmIG1hdGNoWzE1XSAhPT0gbWF0Y2hbMTddKSB7XHJcbiAgICAgICAgICAgIHJlZi50eXBlID0gJ3Jvd1JhbmdlJztcclxuICAgICAgICAgICAgcmVmLnN0YXJ0Um93QW5jaG9yZWQgPSAhIW1hdGNoWzE0XTtcclxuICAgICAgICAgICAgcmVmLnN0YXJ0Um93TnVtYmVyID0gcGFyc2VJbnQobWF0Y2hbMTVdKTtcclxuICAgICAgICAgICAgcmVmLmVuZFJvd0FuY2hvcmVkID0gISFtYXRjaFsxNl07XHJcbiAgICAgICAgICAgIHJlZi5lbmRSb3dOdW1iZXIgPSBwYXJzZUludChtYXRjaFsxN10pO1xyXG4gICAgICAgIH0gZWxzZSBpZiAobWF0Y2hbMTVdKSB7XHJcbiAgICAgICAgICAgIHJlZi50eXBlID0gJ3Jvdyc7XHJcbiAgICAgICAgICAgIHJlZi5yb3dBbmNob3JlZCA9ICEhbWF0Y2hbMTRdO1xyXG4gICAgICAgICAgICByZWYucm93TnVtYmVyID0gcGFyc2VJbnQobWF0Y2hbMTVdKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiByZWY7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydCBhIHJlZmVyZW5jZSBvYmplY3QgdG8gYW4gYWRkcmVzcy5cclxuICAgICAqIEBwYXJhbSB7e319IHJlZiAtIFRoZSByZWZlcmVuY2Ugb2JqZWN0LlxyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGFkZHJlc3MuXHJcbiAgICAgKi9cclxuICAgIHRvQWRkcmVzcyhyZWYpIHtcclxuICAgICAgICBsZXQgYSwgYjtcclxuICAgICAgICBjb25zdCBzaGVldE5hbWUgPSByZWYuc2hlZXROYW1lO1xyXG5cclxuICAgICAgICBpZiAocmVmLnR5cGUgPT09ICdjZWxsJykge1xyXG4gICAgICAgICAgICBhID0ge1xyXG4gICAgICAgICAgICAgICAgY29sdW1uTmFtZTogcmVmLmNvbHVtbk5hbWUsXHJcbiAgICAgICAgICAgICAgICBjb2x1bW5OdW1iZXI6IHJlZi5jb2x1bW5OdW1iZXIsXHJcbiAgICAgICAgICAgICAgICBjb2x1bW5BbmNob3JlZDogcmVmLmNvbHVtbkFuY2hvcmVkLFxyXG4gICAgICAgICAgICAgICAgcm93TnVtYmVyOiByZWYucm93TnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgcm93QW5jaG9yZWQ6IHJlZi5yb3dBbmNob3JlZFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH0gZWxzZSBpZiAocmVmLnR5cGUgPT09ICdyYW5nZScpIHtcclxuICAgICAgICAgICAgYSA9IHtcclxuICAgICAgICAgICAgICAgIGNvbHVtbk5hbWU6IHJlZi5zdGFydENvbHVtbk5hbWUsXHJcbiAgICAgICAgICAgICAgICBjb2x1bW5OdW1iZXI6IHJlZi5zdGFydENvbHVtbk51bWJlcixcclxuICAgICAgICAgICAgICAgIGNvbHVtbkFuY2hvcmVkOiByZWYuc3RhcnRDb2x1bW5BbmNob3JlZCxcclxuICAgICAgICAgICAgICAgIHJvd051bWJlcjogcmVmLnN0YXJ0Um93TnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgcm93QW5jaG9yZWQ6IHJlZi5zdGFydFJvd0FuY2hvcmVkXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIGIgPSB7XHJcbiAgICAgICAgICAgICAgICBjb2x1bW5OYW1lOiByZWYuZW5kQ29sdW1uTmFtZSxcclxuICAgICAgICAgICAgICAgIGNvbHVtbk51bWJlcjogcmVmLmVuZENvbHVtbk51bWJlcixcclxuICAgICAgICAgICAgICAgIGNvbHVtbkFuY2hvcmVkOiByZWYuZW5kQ29sdW1uQW5jaG9yZWQsXHJcbiAgICAgICAgICAgICAgICByb3dOdW1iZXI6IHJlZi5lbmRSb3dOdW1iZXIsXHJcbiAgICAgICAgICAgICAgICByb3dBbmNob3JlZDogcmVmLmVuZFJvd0FuY2hvcmVkXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfSBlbHNlIGlmIChyZWYudHlwZSA9PT0gJ2NvbHVtbicpIHtcclxuICAgICAgICAgICAgYSA9IGIgPSB7XHJcbiAgICAgICAgICAgICAgICBjb2x1bW5OYW1lOiByZWYuY29sdW1uTmFtZSxcclxuICAgICAgICAgICAgICAgIGNvbHVtbk51bWJlcjogcmVmLmNvbHVtbk51bWJlcixcclxuICAgICAgICAgICAgICAgIGNvbHVtbkFuY2hvcmVkOiByZWYuY29sdW1uQW5jaG9yZWRcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9IGVsc2UgaWYgKHJlZi50eXBlID09PSAncm93Jykge1xyXG4gICAgICAgICAgICBhID0gYiA9IHtcclxuICAgICAgICAgICAgICAgIHJvd051bWJlcjogcmVmLnJvd051bWJlcixcclxuICAgICAgICAgICAgICAgIHJvd0FuY2hvcmVkOiByZWYucm93QW5jaG9yZWRcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9IGVsc2UgaWYgKHJlZi50eXBlID09PSAnY29sdW1uUmFuZ2UnKSB7XHJcbiAgICAgICAgICAgIGEgPSB7XHJcbiAgICAgICAgICAgICAgICBjb2x1bW5OYW1lOiByZWYuc3RhcnRDb2x1bW5OYW1lLFxyXG4gICAgICAgICAgICAgICAgY29sdW1uTnVtYmVyOiByZWYuc3RhcnRDb2x1bW5OdW1iZXIsXHJcbiAgICAgICAgICAgICAgICBjb2x1bW5BbmNob3JlZDogcmVmLnN0YXJ0Q29sdW1uQW5jaG9yZWRcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgYiA9IHtcclxuICAgICAgICAgICAgICAgIGNvbHVtbk5hbWU6IHJlZi5lbmRDb2x1bW5OYW1lLFxyXG4gICAgICAgICAgICAgICAgY29sdW1uTnVtYmVyOiByZWYuZW5kQ29sdW1uTnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgY29sdW1uQW5jaG9yZWQ6IHJlZi5lbmRDb2x1bW5BbmNob3JlZFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH0gZWxzZSBpZiAocmVmLnR5cGUgPT09ICdyb3dSYW5nZScpIHtcclxuICAgICAgICAgICAgYSA9IHtcclxuICAgICAgICAgICAgICAgIHJvd051bWJlcjogcmVmLnN0YXJ0Um93TnVtYmVyLFxyXG4gICAgICAgICAgICAgICAgcm93QW5jaG9yZWQ6IHJlZi5zdGFydFJvd0FuY2hvcmVkXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIGIgPSB7XHJcbiAgICAgICAgICAgICAgICByb3dOdW1iZXI6IHJlZi5lbmRSb3dOdW1iZXIsXHJcbiAgICAgICAgICAgICAgICByb3dBbmNob3JlZDogcmVmLmVuZFJvd0FuY2hvcmVkXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsZXQgYWRkcmVzcyA9ICcnO1xyXG4gICAgICAgIGlmIChzaGVldE5hbWUpIGFkZHJlc3MgPSBgJHthZGRyZXNzfScke3NoZWV0TmFtZS5yZXBsYWNlKC8nL2csIFwiJydcIil9JyFgO1xyXG4gICAgICAgIGlmIChhLmNvbHVtbkFuY2hvcmVkKSBhZGRyZXNzID0gYCR7YWRkcmVzc30kYDtcclxuICAgICAgICBpZiAoYS5jb2x1bW5OYW1lKSBhZGRyZXNzID0gYWRkcmVzcyArIGEuY29sdW1uTmFtZTtcclxuICAgICAgICBlbHNlIGlmIChhLmNvbHVtbk51bWJlcikgYWRkcmVzcyA9IGFkZHJlc3MgKyB0aGlzLmNvbHVtbk51bWJlclRvTmFtZShhLmNvbHVtbk51bWJlcik7XHJcbiAgICAgICAgaWYgKGEucm93QW5jaG9yZWQpIGFkZHJlc3MgPSBgJHthZGRyZXNzfSRgO1xyXG4gICAgICAgIGlmIChhLnJvd051bWJlcikgYWRkcmVzcyA9IGFkZHJlc3MgKyBhLnJvd051bWJlcjtcclxuXHJcbiAgICAgICAgaWYgKGIpIHtcclxuICAgICAgICAgICAgYWRkcmVzcyA9IGAke2FkZHJlc3N9OmA7XHJcbiAgICAgICAgICAgIGlmIChiLmNvbHVtbkFuY2hvcmVkKSBhZGRyZXNzID0gYCR7YWRkcmVzc30kYDtcclxuICAgICAgICAgICAgaWYgKGIuY29sdW1uTmFtZSkgYWRkcmVzcyA9IGFkZHJlc3MgKyBiLmNvbHVtbk5hbWU7XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGIuY29sdW1uTnVtYmVyKSBhZGRyZXNzID0gYWRkcmVzcyArIHRoaXMuY29sdW1uTnVtYmVyVG9OYW1lKGIuY29sdW1uTnVtYmVyKTtcclxuICAgICAgICAgICAgaWYgKGIucm93QW5jaG9yZWQpIGFkZHJlc3MgPSBgJHthZGRyZXNzfSRgO1xyXG4gICAgICAgICAgICBpZiAoYi5yb3dOdW1iZXIpIGFkZHJlc3MgPSBhZGRyZXNzICsgYi5yb3dOdW1iZXI7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gYWRkcmVzcztcclxuICAgIH1cclxufTtcclxuIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG4vLyBFeHBvcnQgYXMgYSBmdW5jdGlvbiBhcyBwcm94eXF1aXJlaWZ5IGhhcyB0cm91YmxlIHdpdGggY29uc3RhbnQgZXhwb3J0cy5cclxubW9kdWxlLmV4cG9ydHMgPSAoKSA9PiBCdWZmZXIuZnJvbShcIlVFc0RCQlFBQUFBSUFBQUFJUUMxVlRBajdBQUFBRXdDQUFBTEFBQUFYM0psYkhNdkxuSmxiSE9Oa3MxT3d6QU1nTzlJdkVQaysrcHVTQWlocGJzZ3BOMFFLZzlnRXZkSGJlTW9DZEM5UGVHQW9OSVlQY2F4UDMrMnZEL00wNmplT2NSZW5JWnRVWUppWjhUMnJ0WHdVajl1N2tERlJNN1NLSTQxbkRqQ29icSsyai96U0NrWHhhNzNVV1dLaXhxNmxQdzlZalFkVHhRTDhlenlUeU5ob3BTZm9VVlBacUNXY1ZlV3R4aCtNNkJhTU5YUmFnaEhld09xUG5sZXc1YW02UTAvaUhtYjJLVXpMWkRueE02eTNmaVE2MFBxOHpTcXB0QnkwbURGUE9Wd1JQSyt5R2pBODBhNzlVWi9UNHNUSjdLVUNJMEV2dXp6bFhGSmFMdGU2UDhWTFROK2JPWVJQeVFNcnlMRHR3c3VicUQ2QkZCTEF3UVVBQUFBQ0FBQUFDRUEza0VXMlhzQkFBQVJBd0FBRUFBQUFHUnZZMUJ5YjNCekwyRndjQzU0Yld5ZGtrRlA0ekFRaGU5SS9JZklkK29FbGhXcUhDTlVRQndXYmFVV09CdG4wbGc0dHVVWm9wWmZqNU9xSVYzMnhPM056TlBMbHhtTDYyMXJzdzRpR3U5S1ZzeHlsb0hUdmpKdVU3S245ZjNaRmN1UWxLdVU5UTVLdGdOazEvTDBSQ3lqRHhESkFHWXB3bUhKR3FJdzV4eDFBNjNDV1JxN05LbDliQldsTW02NHIydWo0ZGJyOXhZYzhmTTgvODFoUytBcXFNN0NHTWoyaWZPT2ZocGFlZDN6NGZONkYxS2VGRGNoV0tNVnBiK1VqMFpIajc2bTdHNnJ3UW8rSFlvVXRBTDlIZzN0WkM3NHRCUXJyU3dzVXJDc2xVVVEvS3NoSGtEMVMxc3FFMUdLanVZZGFQSXhRL09SMW5iT3NsZUYwT09VckZQUktFZHNiOXNYZzdZQktjb1hIOSt3QVNBVWZHd09jdXFkYXZOTEZvTWhpV01qSDBHU1BrWmNHN0tBZit1bGl2UWY0bUpLUERDd0NlT3E1eXUrOFIyKzlFLzJ3cmRCdWJSQVBxby94cjNoVTFqN1cwVndXT2R4VTZ3YUZhRktGeGpYUFRiRVErS0t0dmN2R3VVMlVCMDgzd2Y5OFovM0wxd1dsN1A4SXMrSG14OTZnbis5WmZrSlVFc0RCQlFBQUFBSUFPZWhka2MrcUdXdzFRQUFBRzBCQUFBUkFBQUFaRzlqVUhKdmNITXZZMjl5WlM1NGJXeHRrRTFMdzBBUWh1OUMvMFBZZXpLSkJaR1FwRGRQQ2tJVnZBNjdZN3FZL1dCbk5PMi83elpvRk94eGVKOTVtSG03M2RGTnhSY2x0c0gzcXFscVZaRFh3VmcvOXVyMTVhRzhWd1VMZW9OVDhOU3JFN0hhRFp1YlRzZFdoMFRQS1VSS1lvbUxiUExjNnRpcmcwaHNBVmdmeUNGWG1mQTVmQS9Kb2VReGpSQlJmK0JJY0Z2WGQrQkkwS0FnWElSbFhJM3FXMm4wcW95ZmFWb0VSZ05ONU1nTFExTTE4TXNLSmNkWEY1YmtEK21zbkNKZFJYL0NsVDZ5WGNGNW5xdDV1NkQ1L2diZW5oNzN5NnVsOVpldU5LbWhnMzhGRFdkUVN3TUVGQUFBQUFBQTJhRjJSd0FBQUFBQUFBQUFBQUFBQUFrQUFBQjRiQzlmY21Wc2N5OVFTd01FRkFBQUFBZ0FBQUFoQUkySDJuRGFBQUFBTFFJQUFCb0FBQUI0YkM5ZmNtVnNjeTkzYjNKclltOXZheTU0Yld3dWNtVnNjNjJSM1lyQ01CQ0Y3eGYySGNMY2I5TldXR1F4OVVZV2VpdjFBVUk2L2NFMkNabFp0Vzl2WE1FZkVQSENxK0ZNbU8rY3lTeVdoM0VRT3d6VU82c2dTMUlRYUkycmU5c3EyRlMvWDNNUXhOcldlbkFXRlV4SXNDdytQeFpySERUSEllcDZUeUpTTENub21QMlBsR1E2SERVbHpxT05MNDBMbytZb1F5dTlObHZkb3N6VDlGdUdXd1lVZDB4UjFncENXYzlBVkpQSFY5aXVhWHFESzJmK1JyVDh3RUlTVDBOY1FGUTZ0TWdLempxSkhKQ1A3Zk4zMm5PY3hhdjd2enczczJjWnNuZG0yTHV3cFE2UnJ6a3VyZmhCcDNJSkkrK09YQndCVUVzREJCUUFBQUFJQUFBQUlRRGVJL0xUYmdJQUFMRUZBQUFOQUFBQWVHd3ZjM1I1YkdWekxuaHRiS1dVWFd2Yk1CU0c3d2Y3RDBMM3JtdzN6cEpndXl4TkRZVnVESnJCYmhWYlRrVDFZU1NsU3piMjMzdGtPN0ZEeHpiV0s1M3o2dWc1cno3czlPWWdCWHBteG5LdE1oeGRoUmd4VmVxS3EyMkd2NjZMWUlhUmRWUlZWR2pGTW54a0Z0L2s3OStsMWgwRmU5d3g1aEFnbE0zd3pybG1RWWd0ZDB4U2U2VWJwbUNtMWtaU0I2blpFdHNZUml2ckYwbEI0akNjRWttNXdoMWhJY3QvZ1VocW52Wk5VR3JaVU1jM1hIQjNiRmtZeVhKeHYxWGEwSTBBcTRkb1Fzc1R1MDFlNFNVdmpiYTZkbGVBSTdxdWVjbGV1NXlUT1FGU250WmFPWXRLdlZjT3pnclFIcnA0VXZxN0t2eVVGN3VxUExVLzBETVZvRVNZNUdtcGhUYklRVmZtaTBCUlZMS3U0cFlLdmpIY2l6V1ZYQnc3T2ZaQ2E3U3ZreHkyNWtYU2RXZ0hDNHU0RUdkWE1lNkVQSVhUY2N5b0FoTFV4K3RqQSswVlhHU0hhZXYrVXIwMTlCakZ5V2hCTzBEZmpUWVZQSnpoUEU1U25ncFdPMWhnK0hiblI2Y2I0aWVkZzFQTzA0clRyVlpVZU9ScFJSOEF0bVJDUFBySDlhMitZQjlxcFBheWtPNit5akE4VTcvN1V3aUcrckREZElubmoya2QrODFZZEtnditXZDAyK2lDZmxhUnYrOE1mL1lQV1F3SXRObHo0Ymo2aldGZ1ZvZkJhenZyL011KzdBS01pdFYwTDl6NlBKbmhJZjdFS3I2WDhibnFDMy9XcnE4YTRnZC9VOUhVOTJBSDkyQmRPNks5NFJuK2ViZjhNRi9kRlhFd0M1ZXpZSExOa21DZUxGZEJNcmxkcmxiRlBJekQyMStqRCswTm4xbjdPNEJMaVNZTEs2REs5SnZ0elQ4T1dvWkhTV2UvUFQrd1BmWStqNmZoeHlRS2crSTZqSUxKbE02QzJmUTZDWW9raWxmVHlmSXVLWktSOStUL3ZFY2hpYUxCZkxKd1hETEJGYnUwdng2cmNFbVEvbUVUNUhRVFpQalg1aTlRU3dNRUZBQUFBQUFBMmFGMlJ3QUFBQUFBQUFBQUFBQUFBQWtBQUFCNGJDOTBhR1Z0WlM5UVN3TUVGQUFBQUFnQUFBQWhBSXVDYmxqMUJRQUFqaG9BQUJNQUFBQjRiQzkwYUdWdFpTOTBhR1Z0WlRFdWVHMXM3VmxQanhzMUZMOGo4UjJzdWFmemZ5WlpOVnNsazZTRjdyWlZkMXZVb3pOeE1tNDg0MmpzN0c1VVZVTHRFUWtKVVJBWEpHNGNFRkNwbGJpVVQ3TlFCRVhxVjhEanlSOVA0dENGYnFXQ21rakorUG4zbm45KzcvblpNM1B4MGtsS3dCSEtHYVpaMDdBdldBWkFXVXdIT0JzMWpWdUh2VnJkQUl6RGJBQUp6VkRUbUNGbVhOcDkvNzJMY0ljbktFVkE2R2RzQnphTmhQUEpqbW15V0lnaHUwQW5LQk45UTVxbmtJdG1QaklIT1R3V2RsTmlPcFlWbUNuRW1RRXltQXF6MTRkREhDTndXSmcwZGhmR3UwVDhaSndWZ3Bqa0I3RWNVZFdRMk1IWUx2N1lqRVVrQjBlUU5BMHh6b0FlSDZJVGJnQUNHUmNkVGNPU0g4UGN2V2d1bFFqZm9xdm85ZVJucmpkWEdJd2RxWmVQK2t0RnovTzlvTFcwNzVUMk4zSGRzQnQwZzZVOUNZQnhMR1pxYjJEOWRxUGQ4ZWRZQlZSZWFteDN3bzVyVi9DS2ZYY0QzL0tMYndYdnJ2RGVCcjdYaTFZK1ZFRGxwYS94U2VoRVhnWHZyL0RCQmo2MFdoMHZyT0FsS0NFNEcyK2dMVDl3bzhWc2w1QWhKVmUwOElidjlVSm5EbCtoVENXN1N2Mk1iOHUxRk42bGVVOEFaSEFoeHhuZ3N3a2F3bGpnSWtod1A4ZGdENDhTa1hnVG1GRW14SlpqOVN4WC9CWmZUMTVKajhBZEJCWHRVaFN6RFZIQkI3QTR4eFBlTkQ0VVZnMEY4dkxaOXkrZlBRRXZuejArZmZEMDlNRlBwdzhmbmo3NFVhTjRCV1lqVmZIRnQ1LzkrZlhINEk4bjM3eDQ5SVVlejFUOHJ6OTg4c3ZQbit1QlhBVSsvL0x4YjA4ZlAvL3EwOSsvZTZTQnQzTFlWK0dIT0VVTVhFUEg0Q1pOeGR3MEE2QisvczgwRGhPSUt4b3dFVWdOc011VEN2RGFEQklkcm8ycXpydWRpeUtoQTE2ZTNxMXdQVWp5S2NjYTROVWtyUUQzS1NWdG1tdW5jN1VZUzUzT05CdnBCOCtuS3U0bWhFZTZzYU8xMEhhbkU1SHRXR2N5U2xDRjVnMGlvZzFIS0VNY0ZIMTBqSkJHN1E3R0ZiL3U0emluakE0NXVJTkJHMkt0U3c1eG4rdVZydUJVeEdXbUl5aENYZkhOL20zUXBrUm52b09PcWtpeElDRFJtVVNrNHNiTGNNcGhxbVVNVTZJaTl5QlBkQ1FQWm5sY2NUampJdElqUkNqb0RoQmpPcDNyK2F4Qzk2b29MdnF3NzVOWldrWG1ISTkxeUQxSXFZcnMwSEdVd0hTaTVZeXpSTVYrd01ZaVJTRzRRYm1XQksydWtLSXQ0Z0N6cmVHK2pWRWwzSzllMXJkRVhkVW5TTkV6elhWTEF0SHFlcHlSSVVUU3VMbFd6Vk9jdmJLMHJ4VjEvMTFSMXhmMVZvNjFTMnU5bEcvRC9RY0xlQWRPc3h0SXJCa045RjM5ZmxlLy8vZjFlOXRhUHYrcXZTclVacW1vbk4zVHJVZjNJU2JrZ004STJtT3l4RE14dlVGUENHVkRLaTN2RkNhSnVKd1BWOEdOY2lpdlFVNzVSNWduQndtY2lHRnNPY0tJelUyUEdKaFFKallKWTZ2dG9vTk0wMzA2S0tXMnZiZzVGUXFRcitSaWsxbkl4WmJFUzJrUXJ1N0NsdVpsYThSVUFyNDBlbllTeW1CVkVxNkdST2llallSdG5SZUxob1pGM2Y0N0ZxWVNGYkgrQUN5ZWEvaGV5VWprR3lSb1VNU3AxRjlFOTl3anZjMloxV2s3bXVrMXZMTTUrUXlScnBCUTBxMUtRa25EQkE3UXV2aWNZOTFZaGJSQ3o5SFNDT3R2SXRibVptMGdXYlVGanNXYWMzMWhKb2FUcGpFVXgwTnhtVTZFUFZiVVRVaEdXZE9JK2R6Ui82YXlUSExHTzVBbEpVeDJsZk5QTVVjNUlEZ1Z1YTZHZ1dRcmJyWVRXbTh2dVliMTlubk9YQTh5R2c1UnpMZElWazNSVnhyUjlyNG11R2pRcVNCOWtBeU9RWjlNODV0UU9Nb1A3Y0tCQTh6NDBwc0RuQ3ZKdmZMaVdybWFMOFhLUTdQVkVvVmtrc0Q1anFJVzh4SXVyNWQwbEhsSXB1dXpxcmJuayttUGV1ZXg2NzVhcWVoUWl1YVdEU1RjV3NYZTNDYXZzSEwxckh4dHJXdlVsMUw5THZINkc0SkNyYTZuNXVxcFdWdW9uZU9CUUJrdTJPSzM1UjV4M3J2QmV0YWF5cmxTdGpiZVR0RCtYWkg1SFhGY25STE9KRlYwSXU0Um9zVno1YklTU09taXVweHdNTTF4MDdobitTMHZjdnlvWnRYOWJzMXpQYXRXOTF0dXJlWDdydDMxYmF2VGR1NExwL0FrdGYxeTdKNjRueUd6K2NzWEtkOTRBWk11anRrWFlwcWFWSjZEVGFrc1g4RFl6dllYTUFBTHo5d0xuRjdEYmJTRFdzTnQ5V3BlcDEydk5hS2dYZXNFVWRqcGRTSy8zdWpkTjhDUkJIc3ROL0tDYnIwVzJGRlU4d0tyb0Y5djFFTFBjVnBlMktwM3ZkYjl1YS9GekJmL0MvZEtYcnQvQVZCTEF3UVVBQUFBQ0FBQUFDRUFmRHp1d3k0Q0FBQ2JCQUFBRHdBQUFIaHNMM2R2Y210aWIyOXJMbmh0YksyVVRZK2JNQkNHNzVYNkg1RHZoSTlBTjBFaHE4MUgxVWpWYXJYTjdsNXljY3dRM0JpYjJxWkpWUFcvZDRDU3BzMWxLKzBGajgzNDRaMTNiQ2EzeDFJNDMwRWJybVJLZ29GUEhKQk1aVnp1VXZLMC91aU9pR01zbFJrVlNrSktUbURJN2ZUOXU4bEI2ZjFXcWIyREFHbFNVbGhiSlo1bldBRWxOUU5WZ2NRM3VkSWx0VGpWTzg5VUdtaG1DZ0JiQ2kvMC9ROWVTYmtrSFNIUnIyR29QT2NNRm9yVkpVamJRVFFJYWxHK0tYaGxlbHJKWG9NcnFkN1hsY3RVV1NGaXl3VzNweFpLbkpJbHE1MVVtbTRGbG4wTTRwNk00Ulc2NUV3cm8zSTdRTlJ2a1ZmMUJyNFhCRjNKMDBuT0JUeDN0anUwcXU1cDJYeEZFRWRRWTVjWnQ1Q2xCR1VJZFlDL0ZuUmR6V291Y0JKRVVlZ1RiM3B1eFlOMk1zaHBMZXdhWmZWNFRJeUhZUmcybVZqVW5iQ2dKYlV3VjlLaWgyL2tWOHVlRndvTGR4N2hXODAxbU02MjZRU2ZsQ1YwYXg2b0xaeGFpNVRNazgyVFFYMmI3S3NxcEZGeU0xY1piSTdDSE4xS1ZUVjJGRGFDYnpjWHJ0TnJpZi9oTzJXTkFkNVpaUmYvNjhaMDBoajV6T0ZnL3ZqYVRKM2pDNWVaT3FSa1BNUTdjdXBuR0IvYThJVm50a2hKT1BSdnptdWZnTzhLaXczd2gxMm52QXQ2SzdBZkhka2VnQzlOSE9DTmE4WlYwMk5zZU1JeDBLc3NhQW45TmtZRnc0WTNRNXNZaDNIUVpzRFJmamEySGRGcm5wSWZRZVRmM2ZqanlQV1h3OWlOUnVQUUhVWEQwSjFIaTNBWjN5d1h5MW44ODIyUE4xS1NpMlBKQ3FydFdsTzJ4Ly9LSStRemFxQXByaWtJZFhiUFZyWFg3NXIrQWxCTEF3UVVBQUFBQUFEWm9YWkhBQUFBQUFBQUFBQUFBQUFBRGdBQUFIaHNMM2R2Y210emFHVmxkSE12VUVzREJCUUFBQUFJQUFBQUlRRG1WYWpqWFFFQUFJUUNBQUFZQUFBQWVHd3ZkMjl5YTNOb1pXVjBjeTl6YUdWbGRERXVlRzFzalpKUGF3SXhFTVh2aFg2SGtMdEdiVzJydUVwQnBCNEtwZi91MmV6c2JqREpMTWxZOWR0M2RxMVM4T0p0WGliejQ3MUpab3U5ZCtJSFlySVlNam5zRDZTQVlMQ3dvY3JrMStlcTl5UkZJaDBLN1RCQUpnK1E1R0orZXpQYllkeWtHb0FFRTBMS1pFM1VUSlZLcGdhdlV4OGJDTndwTVhwTkxHT2xVaE5CRjkyUWQybzBHRHdvcjIyUVI4STBYc1BBc3JRR2xtaTJIZ0lkSVJHY0p2YWZhdHVrRTgyYmEzQmV4ODIyNlJuMERTTnk2eXdkT3FnVTNrelhWY0NvYzhlNTk4TjdiVTdzVGx6Z3ZUVVJFNWJVWjl5ZjBjdk1FelZSVEpyUENzc0oycldMQ0dVbW40ZFN6V2ZkeFc4THUvU3ZGcVR6RDNCZ0NBcCtJeW5hM2VlSW03YTU1cU5CTzZvdVpsZGQwTGNvQ2lqMTF0RTc3bDdBVmpVeFpNeFoyaFRUNHJDRVpIaVhqT21QeG1jVFMwMmE2MFpYOEtwalpVTVNEc3J1MXFNVThZanBhc0ttcXhpWkl4SDZrNm81T2NSVzNVbFJJdEpKdEc3UC8yZitDMUJMQXdRVUFBQUFDQUFBQUNFQXBGUEZ6MEVCQUFBSUJBQUFFd0FBQUZ0RGIyNTBaVzUwWDFSNWNHVnpYUzU0Yld5dGs4OU9BakVReHU4bXZrUFRLOWtXUEJoaldEajQ1NmdjOEFGcU84czJkTnVtVXhEZTN0bUNIZ2lLQkMvYjdNNTgzKy9iZGpxZWJqckgxcERRQmwvemtSaHlCbDRIWS8yaTVtL3o1K3FPTTh6S0crV0NoNXB2QWZsMGNuMDFubThqSUNPMXg1cTNPY2Q3S1ZHMzBDa1VJWUtuU2hOU3B6Szlwb1dNU2kvVkF1VE5jSGdyZGZBWmZLNXk3OEVuNDBkbzFNcGw5clNoejdza0NSeHk5ckJyN0ZrMVZ6RTZxMVdtdWx4N2MwQ3A5Z1JCeXRLRHJZMDRvQVl1anhMNnlzK0F2ZTZWdGlaWkEyeW1VbjVSSFhYSmpaTWZJUzNmUTFpSzMwMk9wQXhOWXpXWW9GY2RTUVRHQk1wZ0M1QTdKOG9xT21YOTREUy9OS01zeStpZmczejduOGlSNmJ4aDk3dzhRckU1QWNTOGRZQVhvdzYydlpqK1JpYmhMSVdJTkxrSnpxZC9qV2F2cmlJWlFjcjJqMFN5UGg5NDhMdlFUNzBCYzRRdHl6MmVmQUpRU3dFQ0ZBQVVBQUFBQ0FBQUFDRUF0VlV3SSt3QUFBQk1BZ0FBQ3dBQUFBQUFBQUFCQUFBQUFBQUFBQUFBWDNKbGJITXZMbkpsYkhOUVN3RUNGQUFVQUFBQUNBQUFBQ0VBM2tFVzJYc0JBQUFSQXdBQUVBQUFBQUFBQUFBQkFBQUFBQUFWQVFBQVpHOWpVSEp2Y0hNdllYQndMbmh0YkZCTEFRSVVBQlFBQUFBSUFPZWhka2MrcUdXdzFRQUFBRzBCQUFBUkFBQUFBQUFBQUFFQUlBQUFBTDRDQUFCa2IyTlFjbTl3Y3k5amIzSmxMbmh0YkZCTEFRSVVBQlFBQUFBQUFObWhka2NBQUFBQUFBQUFBQUFBQUFBSkFBQUFBQUFBQUFBQUVBQUFBTUlEQUFCNGJDOWZjbVZzY3k5UVN3RUNGQUFVQUFBQUNBQUFBQ0VBallmYWNOb0FBQUF0QWdBQUdnQUFBQUFBQUFBQkFBQUFBQURwQXdBQWVHd3ZYM0psYkhNdmQyOXlhMkp2YjJzdWVHMXNMbkpsYkhOUVN3RUNGQUFVQUFBQUNBQUFBQ0VBM2lQeTAyNENBQUN4QlFBQURRQUFBQUFBQUFBQkFBQUFBQUQ3QkFBQWVHd3ZjM1I1YkdWekxuaHRiRkJMQVFJVUFCUUFBQUFBQU5taGRrY0FBQUFBQUFBQUFBQUFBQUFKQUFBQUFBQUFBQUFBRUFBQUFKUUhBQUI0YkM5MGFHVnRaUzlRU3dFQ0ZBQVVBQUFBQ0FBQUFDRUFpNEp1V1BVRkFBQ09HZ0FBRXdBQUFBQUFBQUFCQUFBQUFBQzdCd0FBZUd3dmRHaGxiV1V2ZEdobGJXVXhMbmh0YkZCTEFRSVVBQlFBQUFBSUFBQUFJUUI4UE83RExnSUFBSnNFQUFBUEFBQUFBQUFBQUFFQUFBQUFBT0VOQUFCNGJDOTNiM0pyWW05dmF5NTRiV3hRU3dFQ0ZBQVVBQUFBQUFEWm9YWkhBQUFBQUFBQUFBQUFBQUFBRGdBQUFBQUFBQUFBQUJBQUFBQThFQUFBZUd3dmQyOXlhM05vWldWMGN5OVFTd0VDRkFBVUFBQUFDQUFBQUNFQTVsV280MTBCQUFDRUFnQUFHQUFBQUFBQUFBQUJBQUFBQUFCb0VBQUFlR3d2ZDI5eWEzTm9aV1YwY3k5emFHVmxkREV1ZUcxc1VFc0JBaFFBRkFBQUFBZ0FBQUFoQUtSVHhjOUJBUUFBQ0FRQUFCTUFBQUFBQUFBQUFRQUFBQUFBK3hFQUFGdERiMjUwWlc1MFgxUjVjR1Z6WFM1NGJXeFFTd1VHQUFBQUFBd0FEQURvQWdBQWJSTUFBQUFBXCIsIFwiYmFzZTY0XCIpO1xyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxuXHJcbi8qKlxyXG4gKiBMZWdhY3kgY29sb3IgaW5kZXhlcy5cclxuICogaHR0cHM6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9kb2N1bWVudGZvcm1hdC5vcGVueG1sLnNwcmVhZHNoZWV0LmluZGV4ZWRjb2xvcnModj1vZmZpY2UuMTUpLmFzcHhcclxuICovXHJcbm1vZHVsZS5leHBvcnRzID0gW1xyXG4gICAgXCIwMDAwMDBcIixcclxuICAgIFwiRkZGRkZGXCIsXHJcbiAgICBcIkZGMDAwMFwiLFxyXG4gICAgXCIwMEZGMDBcIixcclxuICAgIFwiMDAwMEZGXCIsXHJcbiAgICBcIkZGRkYwMFwiLFxyXG4gICAgXCJGRjAwRkZcIixcclxuICAgIFwiMDBGRkZGXCIsXHJcbiAgICBcIjAwMDAwMFwiLFxyXG4gICAgXCJGRkZGRkZcIixcclxuICAgIFwiRkYwMDAwXCIsXHJcbiAgICBcIjAwRkYwMFwiLFxyXG4gICAgXCIwMDAwRkZcIixcclxuICAgIFwiRkZGRjAwXCIsXHJcbiAgICBcIkZGMDBGRlwiLFxyXG4gICAgXCIwMEZGRkZcIixcclxuICAgIFwiODAwMDAwXCIsXHJcbiAgICBcIjAwODAwMFwiLFxyXG4gICAgXCIwMDAwODBcIixcclxuICAgIFwiODA4MDAwXCIsXHJcbiAgICBcIjgwMDA4MFwiLFxyXG4gICAgXCIwMDgwODBcIixcclxuICAgIFwiQzBDMEMwXCIsXHJcbiAgICBcIjgwODA4MFwiLFxyXG4gICAgXCI5OTk5RkZcIixcclxuICAgIFwiOTkzMzY2XCIsXHJcbiAgICBcIkZGRkZDQ1wiLFxyXG4gICAgXCJDQ0ZGRkZcIixcclxuICAgIFwiNjYwMDY2XCIsXHJcbiAgICBcIkZGODA4MFwiLFxyXG4gICAgXCIwMDY2Q0NcIixcclxuICAgIFwiQ0NDQ0ZGXCIsXHJcbiAgICBcIjAwMDA4MFwiLFxyXG4gICAgXCJGRjAwRkZcIixcclxuICAgIFwiRkZGRjAwXCIsXHJcbiAgICBcIjAwRkZGRlwiLFxyXG4gICAgXCI4MDAwODBcIixcclxuICAgIFwiODAwMDAwXCIsXHJcbiAgICBcIjAwODA4MFwiLFxyXG4gICAgXCIwMDAwRkZcIixcclxuICAgIFwiMDBDQ0ZGXCIsXHJcbiAgICBcIkNDRkZGRlwiLFxyXG4gICAgXCJDQ0ZGQ0NcIixcclxuICAgIFwiRkZGRjk5XCIsXHJcbiAgICBcIjk5Q0NGRlwiLFxyXG4gICAgXCJGRjk5Q0NcIixcclxuICAgIFwiQ0M5OUZGXCIsXHJcbiAgICBcIkZGQ0M5OVwiLFxyXG4gICAgXCIzMzY2RkZcIixcclxuICAgIFwiMzNDQ0NDXCIsXHJcbiAgICBcIjk5Q0MwMFwiLFxyXG4gICAgXCJGRkNDMDBcIixcclxuICAgIFwiRkY5OTAwXCIsXHJcbiAgICBcIkZGNjYwMFwiLFxyXG4gICAgXCI2NjY2OTlcIixcclxuICAgIFwiOTY5Njk2XCIsXHJcbiAgICBcIjAwMzM2NlwiLFxyXG4gICAgXCIzMzk5NjZcIixcclxuICAgIFwiMDAzMzAwXCIsXHJcbiAgICBcIjMzMzMwMFwiLFxyXG4gICAgXCI5OTMzMDBcIixcclxuICAgIFwiOTkzMzY2XCIsXHJcbiAgICBcIjMzMzM5OVwiLFxyXG4gICAgXCIzMzMzMzNcIixcclxuICAgIFwiU3lzdGVtIEZvcmVncm91bmRcIixcclxuICAgIFwiU3lzdGVtIEJhY2tncm91bmRcIlxyXG5dO1xyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxuXHJcbi8vIFRoZSBiYXNlIGRhdGUgPSAwLlxyXG5jb25zdCBkYXRlQmFzZSA9IG5ldyBEYXRlKDE5MDAsIDAsIDApO1xyXG5cclxuLy8gVGhlIGRhdGUgY29udmVyc2lvbiBoYXMgYSBidWcgdGhhdCBhc3N1bWVzIDE5MDAgd2FzIGEgbGVhcCB5ZWFyLiBTbyB3ZSBuZWVkIHRvIGFkZCBvbmUgZm9yIGRhdGVzIGFmdGVyIHRoaXMuXHJcbmNvbnN0IGluY29ycmVjdExlYXBEYXRlID0gbmV3IERhdGUoMTkwMCwgMSwgMjgpO1xyXG5cclxuLy8gTnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBpbiBhIGRheS5cclxuY29uc3QgbWlsbGlzZWNvbmRzSW5EYXkgPSAxMDAwICogNjAgKiA2MCAqIDI0O1xyXG5cclxuLyoqXHJcbiAqIERhdGUgY29udmVydGVyLlxyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxubW9kdWxlLmV4cG9ydHMgPSB7XHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnQgYSBkYXRlIHRvIGEgbnVtYmVyIGZvciBFeGNlbC5cclxuICAgICAqIEBwYXJhbSB7RGF0ZX0gZGF0ZSAtIFRoZSBkYXRlLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVGhlIG51bWJlci5cclxuICAgICAqL1xyXG4gICAgZGF0ZVRvTnVtYmVyKGRhdGUpIHtcclxuICAgICAgICAvLyBDbG9uZSB0aGUgZGF0ZSBhbmQgc3RyaXAgdGhlIHRpbWUgb2ZmLlxyXG4gICAgICAgIGNvbnN0IGRhdGVPbmx5ID0gbmV3IERhdGUoZGF0ZS5nZXRUaW1lKCkpO1xyXG4gICAgICAgIGRhdGVPbmx5LnNldEhvdXJzKDAsIDAsIDAsIDApO1xyXG5cclxuICAgICAgICAvLyBTZXQgdGhlIG51bWJlciB0byBiZSB0aGUgbnVtYmVyIG9mIGRheXMgYmV0d2VlbiB0aGUgZGF0ZSBhbmQgdGhlIGJhc2UgZGF0ZS5cclxuICAgICAgICAvLyBXZSBuZWVkIHRvIHJvdW5kIGFzIGRheWxpZ2h0IHNhdmluZ3Mgd2lsbCBjYXVzZSBmcmFjdGlvbmFsIGRheXMsIHdoaWNoIHdlIGRvbid0IHdhbnQuXHJcbiAgICAgICAgbGV0IG51bWJlciA9IE1hdGgucm91bmQoKGRhdGVPbmx5IC0gZGF0ZUJhc2UpIC8gbWlsbGlzZWNvbmRzSW5EYXkpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIEFkZCB0aGUgdHJ1ZSBmcmFjdGlvbmFsIGRheXMgZnJvbSBqdXN0IHRoZSBtaWxsaXNlY29uZHMgbGVmdCBpbiB0aGUgY3VycmVudCBkYXkuXHJcbiAgICAgICAgbnVtYmVyICs9IChkYXRlIC0gZGF0ZU9ubHkpIC8gbWlsbGlzZWNvbmRzSW5EYXk7XHJcblxyXG4gICAgICAgIC8vIEFkanVzdCBmb3IgdGhlIFwiYnVnXCIgaW4gRXhjZWwgdGhhdCB0cmVhdHMgMTkwMCBhcyBhIGxlYXAgeWVhci5cclxuICAgICAgICBpZiAoZGF0ZSA+IGluY29ycmVjdExlYXBEYXRlKSBudW1iZXIgKz0gMTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG51bWJlcjtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0IGEgbnVtYmVyIHRvIGEgZGF0ZS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXIgLSBUaGUgbnVtYmVyLlxyXG4gICAgICogQHJldHVybnMge0RhdGV9IFRoZSBkYXRlLlxyXG4gICAgICovXHJcbiAgICBudW1iZXJUb0RhdGUobnVtYmVyKSB7XHJcbiAgICAgICAgLy8gSWYgdGhlIG51bWJlciBpcyBncmVhdGVyIHRoYW4gdGhlIGluY29ycmVjdCBsZWFwIGRhdGUsIHdlIHNob3VsZCBzdWJ0cmFjdCBvbmUuXHJcbiAgICAgICAgaWYgKG51bWJlciA+IHRoaXMuZGF0ZVRvTnVtYmVyKGluY29ycmVjdExlYXBEYXRlKSkgbnVtYmVyLS07XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gQnJlYWsgdGhlIG51bWJlciBvZiBmdWxsIGRheXMgYW5kIHRoZSByZW1haW5pbmcgbWlsbGlzZWNvbmRzIGluIHRoZSBjdXJyZW50IGRheS5cclxuICAgICAgICBjb25zdCBmdWxsRGF5cyA9IE1hdGguZmxvb3IobnVtYmVyKTtcclxuICAgICAgICBjb25zdCBwYXJ0aWFsTWlsbGlzZWNvbmRzID0gTWF0aC5yb3VuZCgobnVtYmVyIC0gZnVsbERheXMpICogbWlsbGlzZWNvbmRzSW5EYXkpO1xyXG5cclxuICAgICAgICAvLyBDcmVhdGUgYSBuZXcgZGF0ZSBmcm9tIHRoZSBiYXNlIGRhdGUgcGx1cyB0aGUgdGltZSBpbiB0aGUgY3VycmVudCBkYXkuXHJcbiAgICAgICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKGRhdGVCYXNlLmdldFRpbWUoKSArIHBhcnRpYWxNaWxsaXNlY29uZHMpO1xyXG5cclxuICAgICAgICAvLyBOb3cgYWRkIHRoZSBudW1iZXIgb2YgZnVsbCBkYXlzLiBKUyB3aWxsIHByb3Blcmx5IGhhbmRsZSB0aGUgbW9udGgveWVhciBjaGFuZ2VzLlxyXG4gICAgICAgIGRhdGUuc2V0RGF0ZShkYXRlLmdldERhdGUoKSArIGZ1bGxEYXlzKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGRhdGU7XHJcbiAgICB9XHJcbn07XHJcbiIsIlwidXNlIHN0cmljdFwiO1xyXG5cclxuY29uc3QgSlNaaXAgPSByZXF1aXJlKFwianN6aXBcIik7XHJcblxyXG4vKipcclxuICogRXh0ZXJuYWwgbW9kdWxlcy5cclxuICogQHByaXZhdGVcclxuICovXHJcbm1vZHVsZS5leHBvcnRzID0ge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgUHJvbWlzZSBsaWJyYXJ5LlxyXG4gICAgICogQHR5cGUge1Byb21pc2V9XHJcbiAgICAgKi9cclxuICAgIGdldCBQcm9taXNlKCkge1xyXG4gICAgICAgIHJldHVybiBKU1ppcC5leHRlcm5hbC5Qcm9taXNlO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQgUHJvbWlzZShQcm9taXNlKSB7XHJcbiAgICAgICAgSlNaaXAuZXh0ZXJuYWwuUHJvbWlzZSA9IFByb21pc2U7XHJcbiAgICB9XHJcbn07XHJcbiIsIlwidXNlIHN0cmljdFwiO1xyXG5cclxuY29uc3QgXyA9IHJlcXVpcmUoXCJsb2Rhc2hcIik7XHJcblxyXG4vKipcclxuICogQ29udmVydCBhIHBhdHRlcm4gdG8gYSBSZWdFeHAuXHJcbiAqIEBwYXJhbSB7UmVnRXhwfHN0cmluZ30gcGF0dGVybiAtIFRoZSBwYXR0ZXJuIHRvIGNvbnZlcnQuXHJcbiAqIEByZXR1cm5zIHtSZWdFeHB9IFRoZSByZWdleC5cclxuICogQHByaXZhdGVcclxuICovXHJcbm1vZHVsZS5leHBvcnRzID0gcGF0dGVybiA9PiB7XHJcbiAgICBpZiAodHlwZW9mIHBhdHRlcm4gPT09IFwic3RyaW5nXCIpIHtcclxuICAgICAgICBwYXR0ZXJuID0gbmV3IFJlZ0V4cChfLmVzY2FwZVJlZ0V4cChwYXR0ZXJuKSwgXCJpZ21cIik7XHJcbiAgICB9XHJcblxyXG4gICAgcGF0dGVybi5sYXN0SW5kZXggPSAwO1xyXG5cclxuICAgIHJldHVybiBwYXR0ZXJuO1xyXG59O1xyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxuXHJcbmNvbnN0IF8gPSByZXF1aXJlKFwibG9kYXNoXCIpO1xyXG5cclxuLyoqXHJcbiAqIFhNTCBxdWVyeSBtZXRob2RzLlxyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxubW9kdWxlLmV4cG9ydHMgPSB7XHJcbiAgICAvKipcclxuICAgICAqIEFwcGVuZCBhIGNoaWxkIHRvIHRoZSBub2RlLlxyXG4gICAgICogQHBhcmFtIHt7fX0gbm9kZSAtIFRoZSBwYXJlbnQgbm9kZS5cclxuICAgICAqIEBwYXJhbSB7e319IGNoaWxkIC0gVGhlIGNoaWxkIG5vZGUuXHJcbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gICAgICovXHJcbiAgICBhcHBlbmRDaGlsZChub2RlLCBjaGlsZCkge1xyXG4gICAgICAgIGlmICghbm9kZS5jaGlsZHJlbikgbm9kZS5jaGlsZHJlbiA9IFtdO1xyXG4gICAgICAgIG5vZGUuY2hpbGRyZW4ucHVzaChjaGlsZCk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQXBwZW5kIGEgY2hpbGQgaWYgb25lIHdpdGggdGhlIGdpdmVuIG5hbWUgaXMgbm90IGZvdW5kLlxyXG4gICAgICogQHBhcmFtIHt7fX0gbm9kZSAtIFRoZSBwYXJlbnQgbm9kZS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gVGhlIGNoaWxkIG5vZGUgbmFtZS5cclxuICAgICAqIEByZXR1cm5zIHt7fX0gVGhlIGNoaWxkLlxyXG4gICAgICovXHJcbiAgICBhcHBlbmRDaGlsZElmTm90Rm91bmQobm9kZSwgbmFtZSkge1xyXG4gICAgICAgIGxldCBjaGlsZCA9IHRoaXMuZmluZENoaWxkKG5vZGUsIG5hbWUpO1xyXG4gICAgICAgIGlmICghY2hpbGQpIHtcclxuICAgICAgICAgICAgY2hpbGQgPSB7IG5hbWUsIGF0dHJpYnV0ZXM6IHt9LCBjaGlsZHJlbjogW10gfTtcclxuICAgICAgICAgICAgdGhpcy5hcHBlbmRDaGlsZChub2RlLCBjaGlsZCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gY2hpbGQ7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmluZCBhIGNoaWxkIHdpdGggdGhlIGdpdmVuIG5hbWUuXHJcbiAgICAgKiBAcGFyYW0ge3t9fSBub2RlIC0gVGhlIHBhcmVudCBub2RlLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSB0byBmaW5kLlxyXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZHx7fX0gVGhlIGNoaWxkIGlmIGZvdW5kLlxyXG4gICAgICovXHJcbiAgICBmaW5kQ2hpbGQobm9kZSwgbmFtZSkge1xyXG4gICAgICAgIHJldHVybiBfLmZpbmQobm9kZS5jaGlsZHJlbiwgeyBuYW1lIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldCBhbiBhdHRyaWJ1dGUgZnJvbSBhIGNoaWxkIG5vZGUuXHJcbiAgICAgKiBAcGFyYW0ge3t9fSBub2RlIC0gVGhlIHBhcmVudCBub2RlLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgY2hpbGQgbm9kZS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhdHRyaWJ1dGUgLSBUaGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlLlxyXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZHwqfSBUaGUgdmFsdWUgb2YgdGhlIGF0dHJpYnV0ZSBpZiBmb3VuZC5cclxuICAgICAqL1xyXG4gICAgZ2V0Q2hpbGRBdHRyaWJ1dGUobm9kZSwgbmFtZSwgYXR0cmlidXRlKSB7XHJcbiAgICAgICAgY29uc3QgY2hpbGQgPSB0aGlzLmZpbmRDaGlsZChub2RlLCBuYW1lKTtcclxuICAgICAgICBpZiAoY2hpbGQpIHJldHVybiBjaGlsZC5hdHRyaWJ1dGVzICYmIGNoaWxkLmF0dHJpYnV0ZXNbYXR0cmlidXRlXTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIGEgdmFsdWUgaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBub2RlIGhhcyBhIGNoaWxkIHdpdGggdGhlIGdpdmVuIG5hbWUuXHJcbiAgICAgKiBAcGFyYW0ge3t9fSBub2RlIC0gVGhlIHBhcmVudCBub2RlLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgY2hpbGQgbm9kZS5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIGZvdW5kLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAgICAgKi9cclxuICAgIGhhc0NoaWxkKG5vZGUsIG5hbWUpIHtcclxuICAgICAgICByZXR1cm4gXy5zb21lKG5vZGUuY2hpbGRyZW4sIHsgbmFtZSB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbnNlcnQgdGhlIGNoaWxkIGFmdGVyIHRoZSBzcGVjaWZpZWQgbm9kZS5cclxuICAgICAqIEBwYXJhbSB7e319IG5vZGUgLSBUaGUgcGFyZW50IG5vZGUuXHJcbiAgICAgKiBAcGFyYW0ge3t9fSBjaGlsZCAtIFRoZSBjaGlsZCBub2RlLlxyXG4gICAgICogQHBhcmFtIHt7fX0gYWZ0ZXIgLSBUaGUgbm9kZSB0byBpbnNlcnQgYWZ0ZXIuXHJcbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gICAgICovXHJcbiAgICBpbnNlcnRBZnRlcihub2RlLCBjaGlsZCwgYWZ0ZXIpIHtcclxuICAgICAgICBpZiAoIW5vZGUuY2hpbGRyZW4pIG5vZGUuY2hpbGRyZW4gPSBbXTtcclxuICAgICAgICBjb25zdCBpbmRleCA9IG5vZGUuY2hpbGRyZW4uaW5kZXhPZihhZnRlcik7XHJcbiAgICAgICAgbm9kZS5jaGlsZHJlbi5zcGxpY2UoaW5kZXggKyAxLCAwLCBjaGlsZCk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5zZXJ0IHRoZSBjaGlsZCBiZWZvcmUgdGhlIHNwZWNpZmllZCBub2RlLlxyXG4gICAgICogQHBhcmFtIHt7fX0gbm9kZSAtIFRoZSBwYXJlbnQgbm9kZS5cclxuICAgICAqIEBwYXJhbSB7e319IGNoaWxkIC0gVGhlIGNoaWxkIG5vZGUuXHJcbiAgICAgKiBAcGFyYW0ge3t9fSBiZWZvcmUgLSBUaGUgbm9kZSB0byBpbnNlcnQgYmVmb3JlLlxyXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICAgICAqL1xyXG4gICAgaW5zZXJ0QmVmb3JlKG5vZGUsIGNoaWxkLCBiZWZvcmUpIHtcclxuICAgICAgICBpZiAoIW5vZGUuY2hpbGRyZW4pIG5vZGUuY2hpbGRyZW4gPSBbXTtcclxuICAgICAgICBjb25zdCBpbmRleCA9IG5vZGUuY2hpbGRyZW4uaW5kZXhPZihiZWZvcmUpO1xyXG4gICAgICAgIG5vZGUuY2hpbGRyZW4uc3BsaWNlKGluZGV4LCAwLCBjaGlsZCk7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5zZXJ0IGEgY2hpbGQgbm9kZSBpbiB0aGUgY29ycmVjdCBvcmRlci5cclxuICAgICAqIEBwYXJhbSB7e319IG5vZGUgLSBUaGUgcGFyZW50IG5vZGUuXHJcbiAgICAgKiBAcGFyYW0ge3t9fSBjaGlsZCAtIFRoZSBjaGlsZCBub2RlLlxyXG4gICAgICogQHBhcmFtIHtBcnJheS48c3RyaW5nPn0gbm9kZU9yZGVyIC0gVGhlIG9yZGVyIG9mIHRoZSBub2RlIG5hbWVzLlxyXG4gICAgICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICAgICAqL1xyXG4gICAgaW5zZXJ0SW5PcmRlcihub2RlLCBjaGlsZCwgbm9kZU9yZGVyKSB7XHJcbiAgICAgICAgY29uc3QgY2hpbGRJbmRleCA9IG5vZGVPcmRlci5pbmRleE9mKGNoaWxkLm5hbWUpO1xyXG4gICAgICAgIGlmIChub2RlLmNoaWxkcmVuICYmIGNoaWxkSW5kZXggPj0gMCkge1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gY2hpbGRJbmRleCArIDE7IGkgPCBub2RlT3JkZXIubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHNpYmxpbmcgPSB0aGlzLmZpbmRDaGlsZChub2RlLCBub2RlT3JkZXJbaV0pO1xyXG4gICAgICAgICAgICAgICAgaWYgKHNpYmxpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmluc2VydEJlZm9yZShub2RlLCBjaGlsZCwgc2libGluZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmFwcGVuZENoaWxkKG5vZGUsIGNoaWxkKTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDaGVjayBpZiB0aGUgbm9kZSBpcyBlbXB0eSAobm8gYXR0cmlidXRlcyBhbmQgbm8gY2hpbGRyZW4pLlxyXG4gICAgICogQHBhcmFtIHt7fX0gbm9kZSAtIFRoZSBub2RlLlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgZW1wdHksIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAqL1xyXG4gICAgaXNFbXB0eShub2RlKSB7XHJcbiAgICAgICAgcmV0dXJuIF8uaXNFbXB0eShub2RlLmNoaWxkcmVuKSAmJiBfLmlzRW1wdHkobm9kZS5hdHRyaWJ1dGVzKTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmUgYSBjaGlsZCBub2RlLlxyXG4gICAgICogQHBhcmFtIHt7fX0gbm9kZSAtIFRoZSBwYXJlbnQgbm9kZS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfHt9fSBjaGlsZCAtIFRoZSBjaGlsZCBub2RlIG9yIG5hbWUgb2Ygbm9kZS5cclxuICAgICAqIEByZXR1cm5zIHt1bmRlZmluZWR9XHJcbiAgICAgKi9cclxuICAgIHJlbW92ZUNoaWxkKG5vZGUsIGNoaWxkKSB7XHJcbiAgICAgICAgaWYgKCFub2RlLmNoaWxkcmVuKSByZXR1cm47XHJcbiAgICAgICAgaWYgKHR5cGVvZiBjaGlsZCA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgXy5yZW1vdmUobm9kZS5jaGlsZHJlbiwgeyBuYW1lOiBjaGlsZCB9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IG5vZGUuY2hpbGRyZW4uaW5kZXhPZihjaGlsZCk7XHJcbiAgICAgICAgICAgIGlmIChpbmRleCA+PSAwKSBub2RlLmNoaWxkcmVuLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNldC91bnNldCB0aGUgYXR0cmlidXRlcyBvbiB0aGUgbm9kZS5cclxuICAgICAqIEBwYXJhbSB7e319IG5vZGUgLSBUaGUgbm9kZS5cclxuICAgICAqIEBwYXJhbSB7e319IGF0dHJpYnV0ZXMgLSBUaGUgYXR0cmlidXRlcyB0byBzZXQuXHJcbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gICAgICovXHJcbiAgICBzZXRBdHRyaWJ1dGVzKG5vZGUsIGF0dHJpYnV0ZXMpIHtcclxuICAgICAgICBfLmZvck93bihhdHRyaWJ1dGVzLCAodmFsdWUsIGF0dHJpYnV0ZSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoXy5pc05pbCh2YWx1ZSkpIHtcclxuICAgICAgICAgICAgICAgIGlmIChub2RlLmF0dHJpYnV0ZXMpIGRlbGV0ZSBub2RlLmF0dHJpYnV0ZXNbYXR0cmlidXRlXTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGlmICghbm9kZS5hdHRyaWJ1dGVzKSBub2RlLmF0dHJpYnV0ZXMgPSB7fTtcclxuICAgICAgICAgICAgICAgIG5vZGUuYXR0cmlidXRlc1thdHRyaWJ1dGVdID0gdmFsdWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTZXQgYXR0cmlidXRlcyBvbiBhIGNoaWxkIG5vZGUsIGNyZWF0aW5nIHRoZSBjaGlsZCBpZiBuZWNlc3NhcnkuXHJcbiAgICAgKiBAcGFyYW0ge3t9fSBub2RlIC0gVGhlIHBhcmVudCBub2RlLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgY2hpbGQgbm9kZS5cclxuICAgICAqIEBwYXJhbSB7e319IGF0dHJpYnV0ZXMgLSBUaGUgYXR0cmlidXRlcyB0byBzZXQuXHJcbiAgICAgKiBAcmV0dXJucyB7e319IFRoZSBjaGlsZC5cclxuICAgICAqL1xyXG4gICAgc2V0Q2hpbGRBdHRyaWJ1dGVzKG5vZGUsIG5hbWUsIGF0dHJpYnV0ZXMpIHtcclxuICAgICAgICBsZXQgY2hpbGQgPSB0aGlzLmZpbmRDaGlsZChub2RlLCBuYW1lKTtcclxuICAgICAgICBfLmZvck93bihhdHRyaWJ1dGVzLCAodmFsdWUsIGF0dHJpYnV0ZSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoXy5pc05pbCh2YWx1ZSkpIHtcclxuICAgICAgICAgICAgICAgIGlmIChjaGlsZCAmJiBjaGlsZC5hdHRyaWJ1dGVzKSBkZWxldGUgY2hpbGQuYXR0cmlidXRlc1thdHRyaWJ1dGVdO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFjaGlsZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNoaWxkID0geyBuYW1lLCBhdHRyaWJ1dGVzOiB7fSwgY2hpbGRyZW46IFtdIH07XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBlbmRDaGlsZChub2RlLCBjaGlsZCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCFjaGlsZC5hdHRyaWJ1dGVzKSBjaGlsZC5hdHRyaWJ1dGVzID0ge307XHJcbiAgICAgICAgICAgICAgICBjaGlsZC5hdHRyaWJ1dGVzW2F0dHJpYnV0ZV0gPSB2YWx1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gY2hpbGQ7XHJcbiAgICB9LFxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVtb3ZlIHRoZSBjaGlsZCBub2RlIGlmIGVtcHR5LlxyXG4gICAgICogQHBhcmFtIHt7fX0gbm9kZSAtIFRoZSBwYXJlbnQgbm9kZS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfHt9fSBjaGlsZCAtIFRoZSBjaGlsZCBvciBuYW1lIG9mIGNoaWxkIG5vZGUuXHJcbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxyXG4gICAgICovXHJcbiAgICByZW1vdmVDaGlsZElmRW1wdHkobm9kZSwgY2hpbGQpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGNoaWxkID09PSAnc3RyaW5nJykgY2hpbGQgPSB0aGlzLmZpbmRDaGlsZChub2RlLCBjaGlsZCk7XHJcbiAgICAgICAgaWYgKGNoaWxkICYmIHRoaXMuaXNFbXB0eShjaGlsZCkpIHRoaXMucmVtb3ZlQ2hpbGQobm9kZSwgY2hpbGQpO1xyXG4gICAgfVxyXG59O1xyXG4iLCJ2YXIgYXNuMSA9IGV4cG9ydHM7XG5cbmFzbjEuYmlnbnVtID0gcmVxdWlyZSgnYm4uanMnKTtcblxuYXNuMS5kZWZpbmUgPSByZXF1aXJlKCcuL2FzbjEvYXBpJykuZGVmaW5lO1xuYXNuMS5iYXNlID0gcmVxdWlyZSgnLi9hc24xL2Jhc2UnKTtcbmFzbjEuY29uc3RhbnRzID0gcmVxdWlyZSgnLi9hc24xL2NvbnN0YW50cycpO1xuYXNuMS5kZWNvZGVycyA9IHJlcXVpcmUoJy4vYXNuMS9kZWNvZGVycycpO1xuYXNuMS5lbmNvZGVycyA9IHJlcXVpcmUoJy4vYXNuMS9lbmNvZGVycycpO1xuIiwidmFyIGFzbjEgPSByZXF1aXJlKCcuLi9hc24xJyk7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG52YXIgYXBpID0gZXhwb3J0cztcblxuYXBpLmRlZmluZSA9IGZ1bmN0aW9uIGRlZmluZShuYW1lLCBib2R5KSB7XG4gIHJldHVybiBuZXcgRW50aXR5KG5hbWUsIGJvZHkpO1xufTtcblxuZnVuY3Rpb24gRW50aXR5KG5hbWUsIGJvZHkpIHtcbiAgdGhpcy5uYW1lID0gbmFtZTtcbiAgdGhpcy5ib2R5ID0gYm9keTtcblxuICB0aGlzLmRlY29kZXJzID0ge307XG4gIHRoaXMuZW5jb2RlcnMgPSB7fTtcbn07XG5cbkVudGl0eS5wcm90b3R5cGUuX2NyZWF0ZU5hbWVkID0gZnVuY3Rpb24gY3JlYXRlTmFtZWQoYmFzZSkge1xuICB2YXIgbmFtZWQ7XG4gIHRyeSB7XG4gICAgbmFtZWQgPSByZXF1aXJlKCd2bScpLnJ1bkluVGhpc0NvbnRleHQoXG4gICAgICAnKGZ1bmN0aW9uICcgKyB0aGlzLm5hbWUgKyAnKGVudGl0eSkge1xcbicgK1xuICAgICAgJyAgdGhpcy5faW5pdE5hbWVkKGVudGl0eSk7XFxuJyArXG4gICAgICAnfSknXG4gICAgKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIG5hbWVkID0gZnVuY3Rpb24gKGVudGl0eSkge1xuICAgICAgdGhpcy5faW5pdE5hbWVkKGVudGl0eSk7XG4gICAgfTtcbiAgfVxuICBpbmhlcml0cyhuYW1lZCwgYmFzZSk7XG4gIG5hbWVkLnByb3RvdHlwZS5faW5pdE5hbWVkID0gZnVuY3Rpb24gaW5pdG5hbWVkKGVudGl0eSkge1xuICAgIGJhc2UuY2FsbCh0aGlzLCBlbnRpdHkpO1xuICB9O1xuXG4gIHJldHVybiBuZXcgbmFtZWQodGhpcyk7XG59O1xuXG5FbnRpdHkucHJvdG90eXBlLl9nZXREZWNvZGVyID0gZnVuY3Rpb24gX2dldERlY29kZXIoZW5jKSB7XG4gIGVuYyA9IGVuYyB8fCAnZGVyJztcbiAgLy8gTGF6aWx5IGNyZWF0ZSBkZWNvZGVyXG4gIGlmICghdGhpcy5kZWNvZGVycy5oYXNPd25Qcm9wZXJ0eShlbmMpKVxuICAgIHRoaXMuZGVjb2RlcnNbZW5jXSA9IHRoaXMuX2NyZWF0ZU5hbWVkKGFzbjEuZGVjb2RlcnNbZW5jXSk7XG4gIHJldHVybiB0aGlzLmRlY29kZXJzW2VuY107XG59O1xuXG5FbnRpdHkucHJvdG90eXBlLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShkYXRhLCBlbmMsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIHRoaXMuX2dldERlY29kZXIoZW5jKS5kZWNvZGUoZGF0YSwgb3B0aW9ucyk7XG59O1xuXG5FbnRpdHkucHJvdG90eXBlLl9nZXRFbmNvZGVyID0gZnVuY3Rpb24gX2dldEVuY29kZXIoZW5jKSB7XG4gIGVuYyA9IGVuYyB8fCAnZGVyJztcbiAgLy8gTGF6aWx5IGNyZWF0ZSBlbmNvZGVyXG4gIGlmICghdGhpcy5lbmNvZGVycy5oYXNPd25Qcm9wZXJ0eShlbmMpKVxuICAgIHRoaXMuZW5jb2RlcnNbZW5jXSA9IHRoaXMuX2NyZWF0ZU5hbWVkKGFzbjEuZW5jb2RlcnNbZW5jXSk7XG4gIHJldHVybiB0aGlzLmVuY29kZXJzW2VuY107XG59O1xuXG5FbnRpdHkucHJvdG90eXBlLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShkYXRhLCBlbmMsIC8qIGludGVybmFsICovIHJlcG9ydGVyKSB7XG4gIHJldHVybiB0aGlzLl9nZXRFbmNvZGVyKGVuYykuZW5jb2RlKGRhdGEsIHJlcG9ydGVyKTtcbn07XG4iLCJ2YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xudmFyIFJlcG9ydGVyID0gcmVxdWlyZSgnLi4vYmFzZScpLlJlcG9ydGVyO1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcblxuZnVuY3Rpb24gRGVjb2RlckJ1ZmZlcihiYXNlLCBvcHRpb25zKSB7XG4gIFJlcG9ydGVyLmNhbGwodGhpcywgb3B0aW9ucyk7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJhc2UpKSB7XG4gICAgdGhpcy5lcnJvcignSW5wdXQgbm90IEJ1ZmZlcicpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRoaXMuYmFzZSA9IGJhc2U7XG4gIHRoaXMub2Zmc2V0ID0gMDtcbiAgdGhpcy5sZW5ndGggPSBiYXNlLmxlbmd0aDtcbn1cbmluaGVyaXRzKERlY29kZXJCdWZmZXIsIFJlcG9ydGVyKTtcbmV4cG9ydHMuRGVjb2RlckJ1ZmZlciA9IERlY29kZXJCdWZmZXI7XG5cbkRlY29kZXJCdWZmZXIucHJvdG90eXBlLnNhdmUgPSBmdW5jdGlvbiBzYXZlKCkge1xuICByZXR1cm4geyBvZmZzZXQ6IHRoaXMub2Zmc2V0LCByZXBvcnRlcjogUmVwb3J0ZXIucHJvdG90eXBlLnNhdmUuY2FsbCh0aGlzKSB9O1xufTtcblxuRGVjb2RlckJ1ZmZlci5wcm90b3R5cGUucmVzdG9yZSA9IGZ1bmN0aW9uIHJlc3RvcmUoc2F2ZSkge1xuICAvLyBSZXR1cm4gc2tpcHBlZCBkYXRhXG4gIHZhciByZXMgPSBuZXcgRGVjb2RlckJ1ZmZlcih0aGlzLmJhc2UpO1xuICByZXMub2Zmc2V0ID0gc2F2ZS5vZmZzZXQ7XG4gIHJlcy5sZW5ndGggPSB0aGlzLm9mZnNldDtcblxuICB0aGlzLm9mZnNldCA9IHNhdmUub2Zmc2V0O1xuICBSZXBvcnRlci5wcm90b3R5cGUucmVzdG9yZS5jYWxsKHRoaXMsIHNhdmUucmVwb3J0ZXIpO1xuXG4gIHJldHVybiByZXM7XG59O1xuXG5EZWNvZGVyQnVmZmVyLnByb3RvdHlwZS5pc0VtcHR5ID0gZnVuY3Rpb24gaXNFbXB0eSgpIHtcbiAgcmV0dXJuIHRoaXMub2Zmc2V0ID09PSB0aGlzLmxlbmd0aDtcbn07XG5cbkRlY29kZXJCdWZmZXIucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uIHJlYWRVSW50OChmYWlsKSB7XG4gIGlmICh0aGlzLm9mZnNldCArIDEgPD0gdGhpcy5sZW5ndGgpXG4gICAgcmV0dXJuIHRoaXMuYmFzZS5yZWFkVUludDgodGhpcy5vZmZzZXQrKywgdHJ1ZSk7XG4gIGVsc2VcbiAgICByZXR1cm4gdGhpcy5lcnJvcihmYWlsIHx8ICdEZWNvZGVyQnVmZmVyIG92ZXJydW4nKTtcbn1cblxuRGVjb2RlckJ1ZmZlci5wcm90b3R5cGUuc2tpcCA9IGZ1bmN0aW9uIHNraXAoYnl0ZXMsIGZhaWwpIHtcbiAgaWYgKCEodGhpcy5vZmZzZXQgKyBieXRlcyA8PSB0aGlzLmxlbmd0aCkpXG4gICAgcmV0dXJuIHRoaXMuZXJyb3IoZmFpbCB8fCAnRGVjb2RlckJ1ZmZlciBvdmVycnVuJyk7XG5cbiAgdmFyIHJlcyA9IG5ldyBEZWNvZGVyQnVmZmVyKHRoaXMuYmFzZSk7XG5cbiAgLy8gU2hhcmUgcmVwb3J0ZXIgc3RhdGVcbiAgcmVzLl9yZXBvcnRlclN0YXRlID0gdGhpcy5fcmVwb3J0ZXJTdGF0ZTtcblxuICByZXMub2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gIHJlcy5sZW5ndGggPSB0aGlzLm9mZnNldCArIGJ5dGVzO1xuICB0aGlzLm9mZnNldCArPSBieXRlcztcbiAgcmV0dXJuIHJlcztcbn1cblxuRGVjb2RlckJ1ZmZlci5wcm90b3R5cGUucmF3ID0gZnVuY3Rpb24gcmF3KHNhdmUpIHtcbiAgcmV0dXJuIHRoaXMuYmFzZS5zbGljZShzYXZlID8gc2F2ZS5vZmZzZXQgOiB0aGlzLm9mZnNldCwgdGhpcy5sZW5ndGgpO1xufVxuXG5mdW5jdGlvbiBFbmNvZGVyQnVmZmVyKHZhbHVlLCByZXBvcnRlcikge1xuICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICB0aGlzLmxlbmd0aCA9IDA7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlLm1hcChmdW5jdGlvbihpdGVtKSB7XG4gICAgICBpZiAoIShpdGVtIGluc3RhbmNlb2YgRW5jb2RlckJ1ZmZlcikpXG4gICAgICAgIGl0ZW0gPSBuZXcgRW5jb2RlckJ1ZmZlcihpdGVtLCByZXBvcnRlcik7XG4gICAgICB0aGlzLmxlbmd0aCArPSBpdGVtLmxlbmd0aDtcbiAgICAgIHJldHVybiBpdGVtO1xuICAgIH0sIHRoaXMpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICBpZiAoISgwIDw9IHZhbHVlICYmIHZhbHVlIDw9IDB4ZmYpKVxuICAgICAgcmV0dXJuIHJlcG9ydGVyLmVycm9yKCdub24tYnl0ZSBFbmNvZGVyQnVmZmVyIHZhbHVlJyk7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIHRoaXMubGVuZ3RoID0gMTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIHRoaXMubGVuZ3RoID0gQnVmZmVyLmJ5dGVMZW5ndGgodmFsdWUpO1xuICB9IGVsc2UgaWYgKEJ1ZmZlci5pc0J1ZmZlcih2YWx1ZSkpIHtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgdGhpcy5sZW5ndGggPSB2YWx1ZS5sZW5ndGg7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHJlcG9ydGVyLmVycm9yKCdVbnN1cHBvcnRlZCB0eXBlOiAnICsgdHlwZW9mIHZhbHVlKTtcbiAgfVxufVxuZXhwb3J0cy5FbmNvZGVyQnVmZmVyID0gRW5jb2RlckJ1ZmZlcjtcblxuRW5jb2RlckJ1ZmZlci5wcm90b3R5cGUuam9pbiA9IGZ1bmN0aW9uIGpvaW4ob3V0LCBvZmZzZXQpIHtcbiAgaWYgKCFvdXQpXG4gICAgb3V0ID0gbmV3IEJ1ZmZlcih0aGlzLmxlbmd0aCk7XG4gIGlmICghb2Zmc2V0KVxuICAgIG9mZnNldCA9IDA7XG5cbiAgaWYgKHRoaXMubGVuZ3RoID09PSAwKVxuICAgIHJldHVybiBvdXQ7XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkodGhpcy52YWx1ZSkpIHtcbiAgICB0aGlzLnZhbHVlLmZvckVhY2goZnVuY3Rpb24oaXRlbSkge1xuICAgICAgaXRlbS5qb2luKG91dCwgb2Zmc2V0KTtcbiAgICAgIG9mZnNldCArPSBpdGVtLmxlbmd0aDtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIHRoaXMudmFsdWUgPT09ICdudW1iZXInKVxuICAgICAgb3V0W29mZnNldF0gPSB0aGlzLnZhbHVlO1xuICAgIGVsc2UgaWYgKHR5cGVvZiB0aGlzLnZhbHVlID09PSAnc3RyaW5nJylcbiAgICAgIG91dC53cml0ZSh0aGlzLnZhbHVlLCBvZmZzZXQpO1xuICAgIGVsc2UgaWYgKEJ1ZmZlci5pc0J1ZmZlcih0aGlzLnZhbHVlKSlcbiAgICAgIHRoaXMudmFsdWUuY29weShvdXQsIG9mZnNldCk7XG4gICAgb2Zmc2V0ICs9IHRoaXMubGVuZ3RoO1xuICB9XG5cbiAgcmV0dXJuIG91dDtcbn07XG4iLCJ2YXIgYmFzZSA9IGV4cG9ydHM7XG5cbmJhc2UuUmVwb3J0ZXIgPSByZXF1aXJlKCcuL3JlcG9ydGVyJykuUmVwb3J0ZXI7XG5iYXNlLkRlY29kZXJCdWZmZXIgPSByZXF1aXJlKCcuL2J1ZmZlcicpLkRlY29kZXJCdWZmZXI7XG5iYXNlLkVuY29kZXJCdWZmZXIgPSByZXF1aXJlKCcuL2J1ZmZlcicpLkVuY29kZXJCdWZmZXI7XG5iYXNlLk5vZGUgPSByZXF1aXJlKCcuL25vZGUnKTtcbiIsInZhciBSZXBvcnRlciA9IHJlcXVpcmUoJy4uL2Jhc2UnKS5SZXBvcnRlcjtcbnZhciBFbmNvZGVyQnVmZmVyID0gcmVxdWlyZSgnLi4vYmFzZScpLkVuY29kZXJCdWZmZXI7XG52YXIgRGVjb2RlckJ1ZmZlciA9IHJlcXVpcmUoJy4uL2Jhc2UnKS5EZWNvZGVyQnVmZmVyO1xudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcblxuLy8gU3VwcG9ydGVkIHRhZ3NcbnZhciB0YWdzID0gW1xuICAnc2VxJywgJ3NlcW9mJywgJ3NldCcsICdzZXRvZicsICdvYmppZCcsICdib29sJyxcbiAgJ2dlbnRpbWUnLCAndXRjdGltZScsICdudWxsXycsICdlbnVtJywgJ2ludCcsICdvYmpEZXNjJyxcbiAgJ2JpdHN0cicsICdibXBzdHInLCAnY2hhcnN0cicsICdnZW5zdHInLCAnZ3JhcGhzdHInLCAnaWE1c3RyJywgJ2lzbzY0NnN0cicsXG4gICdudW1zdHInLCAnb2N0c3RyJywgJ3ByaW50c3RyJywgJ3Q2MXN0cicsICd1bmlzdHInLCAndXRmOHN0cicsICd2aWRlb3N0cidcbl07XG5cbi8vIFB1YmxpYyBtZXRob2RzIGxpc3RcbnZhciBtZXRob2RzID0gW1xuICAna2V5JywgJ29iaicsICd1c2UnLCAnb3B0aW9uYWwnLCAnZXhwbGljaXQnLCAnaW1wbGljaXQnLCAnZGVmJywgJ2Nob2ljZScsXG4gICdhbnknLCAnY29udGFpbnMnXG5dLmNvbmNhdCh0YWdzKTtcblxuLy8gT3ZlcnJpZGVkIG1ldGhvZHMgbGlzdFxudmFyIG92ZXJyaWRlZCA9IFtcbiAgJ19wZWVrVGFnJywgJ19kZWNvZGVUYWcnLCAnX3VzZScsXG4gICdfZGVjb2RlU3RyJywgJ19kZWNvZGVPYmppZCcsICdfZGVjb2RlVGltZScsXG4gICdfZGVjb2RlTnVsbCcsICdfZGVjb2RlSW50JywgJ19kZWNvZGVCb29sJywgJ19kZWNvZGVMaXN0JyxcblxuICAnX2VuY29kZUNvbXBvc2l0ZScsICdfZW5jb2RlU3RyJywgJ19lbmNvZGVPYmppZCcsICdfZW5jb2RlVGltZScsXG4gICdfZW5jb2RlTnVsbCcsICdfZW5jb2RlSW50JywgJ19lbmNvZGVCb29sJ1xuXTtcblxuZnVuY3Rpb24gTm9kZShlbmMsIHBhcmVudCkge1xuICB2YXIgc3RhdGUgPSB7fTtcbiAgdGhpcy5fYmFzZVN0YXRlID0gc3RhdGU7XG5cbiAgc3RhdGUuZW5jID0gZW5jO1xuXG4gIHN0YXRlLnBhcmVudCA9IHBhcmVudCB8fCBudWxsO1xuICBzdGF0ZS5jaGlsZHJlbiA9IG51bGw7XG5cbiAgLy8gU3RhdGVcbiAgc3RhdGUudGFnID0gbnVsbDtcbiAgc3RhdGUuYXJncyA9IG51bGw7XG4gIHN0YXRlLnJldmVyc2VBcmdzID0gbnVsbDtcbiAgc3RhdGUuY2hvaWNlID0gbnVsbDtcbiAgc3RhdGUub3B0aW9uYWwgPSBmYWxzZTtcbiAgc3RhdGUuYW55ID0gZmFsc2U7XG4gIHN0YXRlLm9iaiA9IGZhbHNlO1xuICBzdGF0ZS51c2UgPSBudWxsO1xuICBzdGF0ZS51c2VEZWNvZGVyID0gbnVsbDtcbiAgc3RhdGUua2V5ID0gbnVsbDtcbiAgc3RhdGVbJ2RlZmF1bHQnXSA9IG51bGw7XG4gIHN0YXRlLmV4cGxpY2l0ID0gbnVsbDtcbiAgc3RhdGUuaW1wbGljaXQgPSBudWxsO1xuICBzdGF0ZS5jb250YWlucyA9IG51bGw7XG5cbiAgLy8gU2hvdWxkIGNyZWF0ZSBuZXcgaW5zdGFuY2Ugb24gZWFjaCBtZXRob2RcbiAgaWYgKCFzdGF0ZS5wYXJlbnQpIHtcbiAgICBzdGF0ZS5jaGlsZHJlbiA9IFtdO1xuICAgIHRoaXMuX3dyYXAoKTtcbiAgfVxufVxubW9kdWxlLmV4cG9ydHMgPSBOb2RlO1xuXG52YXIgc3RhdGVQcm9wcyA9IFtcbiAgJ2VuYycsICdwYXJlbnQnLCAnY2hpbGRyZW4nLCAndGFnJywgJ2FyZ3MnLCAncmV2ZXJzZUFyZ3MnLCAnY2hvaWNlJyxcbiAgJ29wdGlvbmFsJywgJ2FueScsICdvYmonLCAndXNlJywgJ2FsdGVyZWRVc2UnLCAna2V5JywgJ2RlZmF1bHQnLCAnZXhwbGljaXQnLFxuICAnaW1wbGljaXQnLCAnY29udGFpbnMnXG5dO1xuXG5Ob2RlLnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uIGNsb25lKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG4gIHZhciBjc3RhdGUgPSB7fTtcbiAgc3RhdGVQcm9wcy5mb3JFYWNoKGZ1bmN0aW9uKHByb3ApIHtcbiAgICBjc3RhdGVbcHJvcF0gPSBzdGF0ZVtwcm9wXTtcbiAgfSk7XG4gIHZhciByZXMgPSBuZXcgdGhpcy5jb25zdHJ1Y3Rvcihjc3RhdGUucGFyZW50KTtcbiAgcmVzLl9iYXNlU3RhdGUgPSBjc3RhdGU7XG4gIHJldHVybiByZXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5fd3JhcCA9IGZ1bmN0aW9uIHdyYXAoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcbiAgbWV0aG9kcy5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZCkge1xuICAgIHRoaXNbbWV0aG9kXSA9IGZ1bmN0aW9uIF93cmFwcGVkTWV0aG9kKCkge1xuICAgICAgdmFyIGNsb25lID0gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcyk7XG4gICAgICBzdGF0ZS5jaGlsZHJlbi5wdXNoKGNsb25lKTtcbiAgICAgIHJldHVybiBjbG9uZVttZXRob2RdLmFwcGx5KGNsb25lLCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH0sIHRoaXMpO1xufTtcblxuTm9kZS5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiBpbml0KGJvZHkpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIGFzc2VydChzdGF0ZS5wYXJlbnQgPT09IG51bGwpO1xuICBib2R5LmNhbGwodGhpcyk7XG5cbiAgLy8gRmlsdGVyIGNoaWxkcmVuXG4gIHN0YXRlLmNoaWxkcmVuID0gc3RhdGUuY2hpbGRyZW4uZmlsdGVyKGZ1bmN0aW9uKGNoaWxkKSB7XG4gICAgcmV0dXJuIGNoaWxkLl9iYXNlU3RhdGUucGFyZW50ID09PSB0aGlzO1xuICB9LCB0aGlzKTtcbiAgYXNzZXJ0LmVxdWFsKHN0YXRlLmNoaWxkcmVuLmxlbmd0aCwgMSwgJ1Jvb3Qgbm9kZSBjYW4gaGF2ZSBvbmx5IG9uZSBjaGlsZCcpO1xufTtcblxuTm9kZS5wcm90b3R5cGUuX3VzZUFyZ3MgPSBmdW5jdGlvbiB1c2VBcmdzKGFyZ3MpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIC8vIEZpbHRlciBjaGlsZHJlbiBhbmQgYXJnc1xuICB2YXIgY2hpbGRyZW4gPSBhcmdzLmZpbHRlcihmdW5jdGlvbihhcmcpIHtcbiAgICByZXR1cm4gYXJnIGluc3RhbmNlb2YgdGhpcy5jb25zdHJ1Y3RvcjtcbiAgfSwgdGhpcyk7XG4gIGFyZ3MgPSBhcmdzLmZpbHRlcihmdW5jdGlvbihhcmcpIHtcbiAgICByZXR1cm4gIShhcmcgaW5zdGFuY2VvZiB0aGlzLmNvbnN0cnVjdG9yKTtcbiAgfSwgdGhpcyk7XG5cbiAgaWYgKGNoaWxkcmVuLmxlbmd0aCAhPT0gMCkge1xuICAgIGFzc2VydChzdGF0ZS5jaGlsZHJlbiA9PT0gbnVsbCk7XG4gICAgc3RhdGUuY2hpbGRyZW4gPSBjaGlsZHJlbjtcblxuICAgIC8vIFJlcGxhY2UgcGFyZW50IHRvIG1haW50YWluIGJhY2t3YXJkIGxpbmtcbiAgICBjaGlsZHJlbi5mb3JFYWNoKGZ1bmN0aW9uKGNoaWxkKSB7XG4gICAgICBjaGlsZC5fYmFzZVN0YXRlLnBhcmVudCA9IHRoaXM7XG4gICAgfSwgdGhpcyk7XG4gIH1cbiAgaWYgKGFyZ3MubGVuZ3RoICE9PSAwKSB7XG4gICAgYXNzZXJ0KHN0YXRlLmFyZ3MgPT09IG51bGwpO1xuICAgIHN0YXRlLmFyZ3MgPSBhcmdzO1xuICAgIHN0YXRlLnJldmVyc2VBcmdzID0gYXJncy5tYXAoZnVuY3Rpb24oYXJnKSB7XG4gICAgICBpZiAodHlwZW9mIGFyZyAhPT0gJ29iamVjdCcgfHwgYXJnLmNvbnN0cnVjdG9yICE9PSBPYmplY3QpXG4gICAgICAgIHJldHVybiBhcmc7XG5cbiAgICAgIHZhciByZXMgPSB7fTtcbiAgICAgIE9iamVjdC5rZXlzKGFyZykuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgaWYgKGtleSA9PSAoa2V5IHwgMCkpXG4gICAgICAgICAga2V5IHw9IDA7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFyZ1trZXldO1xuICAgICAgICByZXNbdmFsdWVdID0ga2V5O1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzO1xuICAgIH0pO1xuICB9XG59O1xuXG4vL1xuLy8gT3ZlcnJpZGVkIG1ldGhvZHNcbi8vXG5cbm92ZXJyaWRlZC5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZCkge1xuICBOb2RlLnByb3RvdHlwZVttZXRob2RdID0gZnVuY3Rpb24gX292ZXJyaWRlZCgpIHtcbiAgICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG4gICAgdGhyb3cgbmV3IEVycm9yKG1ldGhvZCArICcgbm90IGltcGxlbWVudGVkIGZvciBlbmNvZGluZzogJyArIHN0YXRlLmVuYyk7XG4gIH07XG59KTtcblxuLy9cbi8vIFB1YmxpYyBtZXRob2RzXG4vL1xuXG50YWdzLmZvckVhY2goZnVuY3Rpb24odGFnKSB7XG4gIE5vZGUucHJvdG90eXBlW3RhZ10gPSBmdW5jdGlvbiBfdGFnTWV0aG9kKCkge1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcbiAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cbiAgICBhc3NlcnQoc3RhdGUudGFnID09PSBudWxsKTtcbiAgICBzdGF0ZS50YWcgPSB0YWc7XG5cbiAgICB0aGlzLl91c2VBcmdzKGFyZ3MpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG59KTtcblxuTm9kZS5wcm90b3R5cGUudXNlID0gZnVuY3Rpb24gdXNlKGl0ZW0pIHtcbiAgYXNzZXJ0KGl0ZW0pO1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgYXNzZXJ0KHN0YXRlLnVzZSA9PT0gbnVsbCk7XG4gIHN0YXRlLnVzZSA9IGl0ZW07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5vcHRpb25hbCA9IGZ1bmN0aW9uIG9wdGlvbmFsKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgc3RhdGUub3B0aW9uYWwgPSB0cnVlO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuTm9kZS5wcm90b3R5cGUuZGVmID0gZnVuY3Rpb24gZGVmKHZhbCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgYXNzZXJ0KHN0YXRlWydkZWZhdWx0J10gPT09IG51bGwpO1xuICBzdGF0ZVsnZGVmYXVsdCddID0gdmFsO1xuICBzdGF0ZS5vcHRpb25hbCA9IHRydWU7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5leHBsaWNpdCA9IGZ1bmN0aW9uIGV4cGxpY2l0KG51bSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgYXNzZXJ0KHN0YXRlLmV4cGxpY2l0ID09PSBudWxsICYmIHN0YXRlLmltcGxpY2l0ID09PSBudWxsKTtcbiAgc3RhdGUuZXhwbGljaXQgPSBudW07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5pbXBsaWNpdCA9IGZ1bmN0aW9uIGltcGxpY2l0KG51bSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgYXNzZXJ0KHN0YXRlLmV4cGxpY2l0ID09PSBudWxsICYmIHN0YXRlLmltcGxpY2l0ID09PSBudWxsKTtcbiAgc3RhdGUuaW1wbGljaXQgPSBudW07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5vYmogPSBmdW5jdGlvbiBvYmooKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcbiAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuXG4gIHN0YXRlLm9iaiA9IHRydWU7XG5cbiAgaWYgKGFyZ3MubGVuZ3RoICE9PSAwKVxuICAgIHRoaXMuX3VzZUFyZ3MoYXJncyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5rZXkgPSBmdW5jdGlvbiBrZXkobmV3S2V5KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICBhc3NlcnQoc3RhdGUua2V5ID09PSBudWxsKTtcbiAgc3RhdGUua2V5ID0gbmV3S2V5O1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuTm9kZS5wcm90b3R5cGUuYW55ID0gZnVuY3Rpb24gYW55KCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgc3RhdGUuYW55ID0gdHJ1ZTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbk5vZGUucHJvdG90eXBlLmNob2ljZSA9IGZ1bmN0aW9uIGNob2ljZShvYmopIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIGFzc2VydChzdGF0ZS5jaG9pY2UgPT09IG51bGwpO1xuICBzdGF0ZS5jaG9pY2UgPSBvYmo7XG4gIHRoaXMuX3VzZUFyZ3MoT2JqZWN0LmtleXMob2JqKS5tYXAoZnVuY3Rpb24oa2V5KSB7XG4gICAgcmV0dXJuIG9ialtrZXldO1xuICB9KSk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5jb250YWlucyA9IGZ1bmN0aW9uIGNvbnRhaW5zKGl0ZW0pIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIGFzc2VydChzdGF0ZS51c2UgPT09IG51bGwpO1xuICBzdGF0ZS5jb250YWlucyA9IGl0ZW07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vL1xuLy8gRGVjb2Rpbmdcbi8vXG5cbk5vZGUucHJvdG90eXBlLl9kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUoaW5wdXQsIG9wdGlvbnMpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gIC8vIERlY29kZSByb290IG5vZGVcbiAgaWYgKHN0YXRlLnBhcmVudCA9PT0gbnVsbClcbiAgICByZXR1cm4gaW5wdXQud3JhcFJlc3VsdChzdGF0ZS5jaGlsZHJlblswXS5fZGVjb2RlKGlucHV0LCBvcHRpb25zKSk7XG5cbiAgdmFyIHJlc3VsdCA9IHN0YXRlWydkZWZhdWx0J107XG4gIHZhciBwcmVzZW50ID0gdHJ1ZTtcblxuICB2YXIgcHJldktleSA9IG51bGw7XG4gIGlmIChzdGF0ZS5rZXkgIT09IG51bGwpXG4gICAgcHJldktleSA9IGlucHV0LmVudGVyS2V5KHN0YXRlLmtleSk7XG5cbiAgLy8gQ2hlY2sgaWYgdGFnIGlzIHRoZXJlXG4gIGlmIChzdGF0ZS5vcHRpb25hbCkge1xuICAgIHZhciB0YWcgPSBudWxsO1xuICAgIGlmIChzdGF0ZS5leHBsaWNpdCAhPT0gbnVsbClcbiAgICAgIHRhZyA9IHN0YXRlLmV4cGxpY2l0O1xuICAgIGVsc2UgaWYgKHN0YXRlLmltcGxpY2l0ICE9PSBudWxsKVxuICAgICAgdGFnID0gc3RhdGUuaW1wbGljaXQ7XG4gICAgZWxzZSBpZiAoc3RhdGUudGFnICE9PSBudWxsKVxuICAgICAgdGFnID0gc3RhdGUudGFnO1xuXG4gICAgaWYgKHRhZyA9PT0gbnVsbCAmJiAhc3RhdGUuYW55KSB7XG4gICAgICAvLyBUcmlhbCBhbmQgRXJyb3JcbiAgICAgIHZhciBzYXZlID0gaW5wdXQuc2F2ZSgpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKHN0YXRlLmNob2ljZSA9PT0gbnVsbClcbiAgICAgICAgICB0aGlzLl9kZWNvZGVHZW5lcmljKHN0YXRlLnRhZywgaW5wdXQsIG9wdGlvbnMpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgdGhpcy5fZGVjb2RlQ2hvaWNlKGlucHV0LCBvcHRpb25zKTtcbiAgICAgICAgcHJlc2VudCA9IHRydWU7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHByZXNlbnQgPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlucHV0LnJlc3RvcmUoc2F2ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByZXNlbnQgPSB0aGlzLl9wZWVrVGFnKGlucHV0LCB0YWcsIHN0YXRlLmFueSk7XG5cbiAgICAgIGlmIChpbnB1dC5pc0Vycm9yKHByZXNlbnQpKVxuICAgICAgICByZXR1cm4gcHJlc2VudDtcbiAgICB9XG4gIH1cblxuICAvLyBQdXNoIG9iamVjdCBvbiBzdGFja1xuICB2YXIgcHJldk9iajtcbiAgaWYgKHN0YXRlLm9iaiAmJiBwcmVzZW50KVxuICAgIHByZXZPYmogPSBpbnB1dC5lbnRlck9iamVjdCgpO1xuXG4gIGlmIChwcmVzZW50KSB7XG4gICAgLy8gVW53cmFwIGV4cGxpY2l0IHZhbHVlc1xuICAgIGlmIChzdGF0ZS5leHBsaWNpdCAhPT0gbnVsbCkge1xuICAgICAgdmFyIGV4cGxpY2l0ID0gdGhpcy5fZGVjb2RlVGFnKGlucHV0LCBzdGF0ZS5leHBsaWNpdCk7XG4gICAgICBpZiAoaW5wdXQuaXNFcnJvcihleHBsaWNpdCkpXG4gICAgICAgIHJldHVybiBleHBsaWNpdDtcbiAgICAgIGlucHV0ID0gZXhwbGljaXQ7XG4gICAgfVxuXG4gICAgdmFyIHN0YXJ0ID0gaW5wdXQub2Zmc2V0O1xuXG4gICAgLy8gVW53cmFwIGltcGxpY2l0IGFuZCBub3JtYWwgdmFsdWVzXG4gICAgaWYgKHN0YXRlLnVzZSA9PT0gbnVsbCAmJiBzdGF0ZS5jaG9pY2UgPT09IG51bGwpIHtcbiAgICAgIGlmIChzdGF0ZS5hbnkpXG4gICAgICAgIHZhciBzYXZlID0gaW5wdXQuc2F2ZSgpO1xuICAgICAgdmFyIGJvZHkgPSB0aGlzLl9kZWNvZGVUYWcoXG4gICAgICAgIGlucHV0LFxuICAgICAgICBzdGF0ZS5pbXBsaWNpdCAhPT0gbnVsbCA/IHN0YXRlLmltcGxpY2l0IDogc3RhdGUudGFnLFxuICAgICAgICBzdGF0ZS5hbnlcbiAgICAgICk7XG4gICAgICBpZiAoaW5wdXQuaXNFcnJvcihib2R5KSlcbiAgICAgICAgcmV0dXJuIGJvZHk7XG5cbiAgICAgIGlmIChzdGF0ZS5hbnkpXG4gICAgICAgIHJlc3VsdCA9IGlucHV0LnJhdyhzYXZlKTtcbiAgICAgIGVsc2VcbiAgICAgICAgaW5wdXQgPSBib2R5O1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMudHJhY2sgJiYgc3RhdGUudGFnICE9PSBudWxsKVxuICAgICAgb3B0aW9ucy50cmFjayhpbnB1dC5wYXRoKCksIHN0YXJ0LCBpbnB1dC5sZW5ndGgsICd0YWdnZWQnKTtcblxuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMudHJhY2sgJiYgc3RhdGUudGFnICE9PSBudWxsKVxuICAgICAgb3B0aW9ucy50cmFjayhpbnB1dC5wYXRoKCksIGlucHV0Lm9mZnNldCwgaW5wdXQubGVuZ3RoLCAnY29udGVudCcpO1xuXG4gICAgLy8gU2VsZWN0IHByb3BlciBtZXRob2QgZm9yIHRhZ1xuICAgIGlmIChzdGF0ZS5hbnkpXG4gICAgICByZXN1bHQgPSByZXN1bHQ7XG4gICAgZWxzZSBpZiAoc3RhdGUuY2hvaWNlID09PSBudWxsKVxuICAgICAgcmVzdWx0ID0gdGhpcy5fZGVjb2RlR2VuZXJpYyhzdGF0ZS50YWcsIGlucHV0LCBvcHRpb25zKTtcbiAgICBlbHNlXG4gICAgICByZXN1bHQgPSB0aGlzLl9kZWNvZGVDaG9pY2UoaW5wdXQsIG9wdGlvbnMpO1xuXG4gICAgaWYgKGlucHV0LmlzRXJyb3IocmVzdWx0KSlcbiAgICAgIHJldHVybiByZXN1bHQ7XG5cbiAgICAvLyBEZWNvZGUgY2hpbGRyZW5cbiAgICBpZiAoIXN0YXRlLmFueSAmJiBzdGF0ZS5jaG9pY2UgPT09IG51bGwgJiYgc3RhdGUuY2hpbGRyZW4gIT09IG51bGwpIHtcbiAgICAgIHN0YXRlLmNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gZGVjb2RlQ2hpbGRyZW4oY2hpbGQpIHtcbiAgICAgICAgLy8gTk9URTogV2UgYXJlIGlnbm9yaW5nIGVycm9ycyBoZXJlLCB0byBsZXQgcGFyc2VyIGNvbnRpbnVlIHdpdGggb3RoZXJcbiAgICAgICAgLy8gcGFydHMgb2YgZW5jb2RlZCBkYXRhXG4gICAgICAgIGNoaWxkLl9kZWNvZGUoaW5wdXQsIG9wdGlvbnMpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gRGVjb2RlIGNvbnRhaW5lZC9lbmNvZGVkIGJ5IHNjaGVtYSwgb25seSBpbiBiaXQgb3Igb2N0ZXQgc3RyaW5nc1xuICAgIGlmIChzdGF0ZS5jb250YWlucyAmJiAoc3RhdGUudGFnID09PSAnb2N0c3RyJyB8fCBzdGF0ZS50YWcgPT09ICdiaXRzdHInKSkge1xuICAgICAgdmFyIGRhdGEgPSBuZXcgRGVjb2RlckJ1ZmZlcihyZXN1bHQpO1xuICAgICAgcmVzdWx0ID0gdGhpcy5fZ2V0VXNlKHN0YXRlLmNvbnRhaW5zLCBpbnB1dC5fcmVwb3J0ZXJTdGF0ZS5vYmopXG4gICAgICAgICAgLl9kZWNvZGUoZGF0YSwgb3B0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgLy8gUG9wIG9iamVjdFxuICBpZiAoc3RhdGUub2JqICYmIHByZXNlbnQpXG4gICAgcmVzdWx0ID0gaW5wdXQubGVhdmVPYmplY3QocHJldk9iaik7XG5cbiAgLy8gU2V0IGtleVxuICBpZiAoc3RhdGUua2V5ICE9PSBudWxsICYmIChyZXN1bHQgIT09IG51bGwgfHwgcHJlc2VudCA9PT0gdHJ1ZSkpXG4gICAgaW5wdXQubGVhdmVLZXkocHJldktleSwgc3RhdGUua2V5LCByZXN1bHQpO1xuICBlbHNlIGlmIChwcmV2S2V5ICE9PSBudWxsKVxuICAgIGlucHV0LmV4aXRLZXkocHJldktleSk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbk5vZGUucHJvdG90eXBlLl9kZWNvZGVHZW5lcmljID0gZnVuY3Rpb24gZGVjb2RlR2VuZXJpYyh0YWcsIGlucHV0LCBvcHRpb25zKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX2Jhc2VTdGF0ZTtcblxuICBpZiAodGFnID09PSAnc2VxJyB8fCB0YWcgPT09ICdzZXQnKVxuICAgIHJldHVybiBudWxsO1xuICBpZiAodGFnID09PSAnc2Vxb2YnIHx8IHRhZyA9PT0gJ3NldG9mJylcbiAgICByZXR1cm4gdGhpcy5fZGVjb2RlTGlzdChpbnB1dCwgdGFnLCBzdGF0ZS5hcmdzWzBdLCBvcHRpb25zKTtcbiAgZWxzZSBpZiAoL3N0ciQvLnRlc3QodGFnKSlcbiAgICByZXR1cm4gdGhpcy5fZGVjb2RlU3RyKGlucHV0LCB0YWcsIG9wdGlvbnMpO1xuICBlbHNlIGlmICh0YWcgPT09ICdvYmppZCcgJiYgc3RhdGUuYXJncylcbiAgICByZXR1cm4gdGhpcy5fZGVjb2RlT2JqaWQoaW5wdXQsIHN0YXRlLmFyZ3NbMF0sIHN0YXRlLmFyZ3NbMV0sIG9wdGlvbnMpO1xuICBlbHNlIGlmICh0YWcgPT09ICdvYmppZCcpXG4gICAgcmV0dXJuIHRoaXMuX2RlY29kZU9iamlkKGlucHV0LCBudWxsLCBudWxsLCBvcHRpb25zKTtcbiAgZWxzZSBpZiAodGFnID09PSAnZ2VudGltZScgfHwgdGFnID09PSAndXRjdGltZScpXG4gICAgcmV0dXJuIHRoaXMuX2RlY29kZVRpbWUoaW5wdXQsIHRhZywgb3B0aW9ucyk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ251bGxfJylcbiAgICByZXR1cm4gdGhpcy5fZGVjb2RlTnVsbChpbnB1dCwgb3B0aW9ucyk7XG4gIGVsc2UgaWYgKHRhZyA9PT0gJ2Jvb2wnKVxuICAgIHJldHVybiB0aGlzLl9kZWNvZGVCb29sKGlucHV0LCBvcHRpb25zKTtcbiAgZWxzZSBpZiAodGFnID09PSAnb2JqRGVzYycpXG4gICAgcmV0dXJuIHRoaXMuX2RlY29kZVN0cihpbnB1dCwgdGFnLCBvcHRpb25zKTtcbiAgZWxzZSBpZiAodGFnID09PSAnaW50JyB8fCB0YWcgPT09ICdlbnVtJylcbiAgICByZXR1cm4gdGhpcy5fZGVjb2RlSW50KGlucHV0LCBzdGF0ZS5hcmdzICYmIHN0YXRlLmFyZ3NbMF0sIG9wdGlvbnMpO1xuXG4gIGlmIChzdGF0ZS51c2UgIT09IG51bGwpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0VXNlKHN0YXRlLnVzZSwgaW5wdXQuX3JlcG9ydGVyU3RhdGUub2JqKVxuICAgICAgICAuX2RlY29kZShpbnB1dCwgb3B0aW9ucyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGlucHV0LmVycm9yKCd1bmtub3duIHRhZzogJyArIHRhZyk7XG4gIH1cbn07XG5cbk5vZGUucHJvdG90eXBlLl9nZXRVc2UgPSBmdW5jdGlvbiBfZ2V0VXNlKGVudGl0eSwgb2JqKSB7XG5cbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuICAvLyBDcmVhdGUgYWx0ZXJlZCB1c2UgZGVjb2RlciBpZiBpbXBsaWNpdCBpcyBzZXRcbiAgc3RhdGUudXNlRGVjb2RlciA9IHRoaXMuX3VzZShlbnRpdHksIG9iaik7XG4gIGFzc2VydChzdGF0ZS51c2VEZWNvZGVyLl9iYXNlU3RhdGUucGFyZW50ID09PSBudWxsKTtcbiAgc3RhdGUudXNlRGVjb2RlciA9IHN0YXRlLnVzZURlY29kZXIuX2Jhc2VTdGF0ZS5jaGlsZHJlblswXTtcbiAgaWYgKHN0YXRlLmltcGxpY2l0ICE9PSBzdGF0ZS51c2VEZWNvZGVyLl9iYXNlU3RhdGUuaW1wbGljaXQpIHtcbiAgICBzdGF0ZS51c2VEZWNvZGVyID0gc3RhdGUudXNlRGVjb2Rlci5jbG9uZSgpO1xuICAgIHN0YXRlLnVzZURlY29kZXIuX2Jhc2VTdGF0ZS5pbXBsaWNpdCA9IHN0YXRlLmltcGxpY2l0O1xuICB9XG4gIHJldHVybiBzdGF0ZS51c2VEZWNvZGVyO1xufTtcblxuTm9kZS5wcm90b3R5cGUuX2RlY29kZUNob2ljZSA9IGZ1bmN0aW9uIGRlY29kZUNob2ljZShpbnB1dCwgb3B0aW9ucykge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG4gIHZhciByZXN1bHQgPSBudWxsO1xuICB2YXIgbWF0Y2ggPSBmYWxzZTtcblxuICBPYmplY3Qua2V5cyhzdGF0ZS5jaG9pY2UpLnNvbWUoZnVuY3Rpb24oa2V5KSB7XG4gICAgdmFyIHNhdmUgPSBpbnB1dC5zYXZlKCk7XG4gICAgdmFyIG5vZGUgPSBzdGF0ZS5jaG9pY2Vba2V5XTtcbiAgICB0cnkge1xuICAgICAgdmFyIHZhbHVlID0gbm9kZS5fZGVjb2RlKGlucHV0LCBvcHRpb25zKTtcbiAgICAgIGlmIChpbnB1dC5pc0Vycm9yKHZhbHVlKSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgICByZXN1bHQgPSB7IHR5cGU6IGtleSwgdmFsdWU6IHZhbHVlIH07XG4gICAgICBtYXRjaCA9IHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaW5wdXQucmVzdG9yZShzYXZlKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH0sIHRoaXMpO1xuXG4gIGlmICghbWF0Y2gpXG4gICAgcmV0dXJuIGlucHV0LmVycm9yKCdDaG9pY2Ugbm90IG1hdGNoZWQnKTtcblxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuLy9cbi8vIEVuY29kaW5nXG4vL1xuXG5Ob2RlLnByb3RvdHlwZS5fY3JlYXRlRW5jb2RlckJ1ZmZlciA9IGZ1bmN0aW9uIGNyZWF0ZUVuY29kZXJCdWZmZXIoZGF0YSkge1xuICByZXR1cm4gbmV3IEVuY29kZXJCdWZmZXIoZGF0YSwgdGhpcy5yZXBvcnRlcik7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5fZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKGRhdGEsIHJlcG9ydGVyLCBwYXJlbnQpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuICBpZiAoc3RhdGVbJ2RlZmF1bHQnXSAhPT0gbnVsbCAmJiBzdGF0ZVsnZGVmYXVsdCddID09PSBkYXRhKVxuICAgIHJldHVybjtcblxuICB2YXIgcmVzdWx0ID0gdGhpcy5fZW5jb2RlVmFsdWUoZGF0YSwgcmVwb3J0ZXIsIHBhcmVudCk7XG4gIGlmIChyZXN1bHQgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm47XG5cbiAgaWYgKHRoaXMuX3NraXBEZWZhdWx0KHJlc3VsdCwgcmVwb3J0ZXIsIHBhcmVudCkpXG4gICAgcmV0dXJuO1xuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5fZW5jb2RlVmFsdWUgPSBmdW5jdGlvbiBlbmNvZGUoZGF0YSwgcmVwb3J0ZXIsIHBhcmVudCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgLy8gRGVjb2RlIHJvb3Qgbm9kZVxuICBpZiAoc3RhdGUucGFyZW50ID09PSBudWxsKVxuICAgIHJldHVybiBzdGF0ZS5jaGlsZHJlblswXS5fZW5jb2RlKGRhdGEsIHJlcG9ydGVyIHx8IG5ldyBSZXBvcnRlcigpKTtcblxuICB2YXIgcmVzdWx0ID0gbnVsbDtcblxuICAvLyBTZXQgcmVwb3J0ZXIgdG8gc2hhcmUgaXQgd2l0aCBhIGNoaWxkIGNsYXNzXG4gIHRoaXMucmVwb3J0ZXIgPSByZXBvcnRlcjtcblxuICAvLyBDaGVjayBpZiBkYXRhIGlzIHRoZXJlXG4gIGlmIChzdGF0ZS5vcHRpb25hbCAmJiBkYXRhID09PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoc3RhdGVbJ2RlZmF1bHQnXSAhPT0gbnVsbClcbiAgICAgIGRhdGEgPSBzdGF0ZVsnZGVmYXVsdCddXG4gICAgZWxzZVxuICAgICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gRW5jb2RlIGNoaWxkcmVuIGZpcnN0XG4gIHZhciBjb250ZW50ID0gbnVsbDtcbiAgdmFyIHByaW1pdGl2ZSA9IGZhbHNlO1xuICBpZiAoc3RhdGUuYW55KSB7XG4gICAgLy8gQW55dGhpbmcgdGhhdCB3YXMgZ2l2ZW4gaXMgdHJhbnNsYXRlZCB0byBidWZmZXJcbiAgICByZXN1bHQgPSB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKGRhdGEpO1xuICB9IGVsc2UgaWYgKHN0YXRlLmNob2ljZSkge1xuICAgIHJlc3VsdCA9IHRoaXMuX2VuY29kZUNob2ljZShkYXRhLCByZXBvcnRlcik7XG4gIH0gZWxzZSBpZiAoc3RhdGUuY29udGFpbnMpIHtcbiAgICBjb250ZW50ID0gdGhpcy5fZ2V0VXNlKHN0YXRlLmNvbnRhaW5zLCBwYXJlbnQpLl9lbmNvZGUoZGF0YSwgcmVwb3J0ZXIpO1xuICAgIHByaW1pdGl2ZSA9IHRydWU7XG4gIH0gZWxzZSBpZiAoc3RhdGUuY2hpbGRyZW4pIHtcbiAgICBjb250ZW50ID0gc3RhdGUuY2hpbGRyZW4ubWFwKGZ1bmN0aW9uKGNoaWxkKSB7XG4gICAgICBpZiAoY2hpbGQuX2Jhc2VTdGF0ZS50YWcgPT09ICdudWxsXycpXG4gICAgICAgIHJldHVybiBjaGlsZC5fZW5jb2RlKG51bGwsIHJlcG9ydGVyLCBkYXRhKTtcblxuICAgICAgaWYgKGNoaWxkLl9iYXNlU3RhdGUua2V5ID09PSBudWxsKVxuICAgICAgICByZXR1cm4gcmVwb3J0ZXIuZXJyb3IoJ0NoaWxkIHNob3VsZCBoYXZlIGEga2V5Jyk7XG4gICAgICB2YXIgcHJldktleSA9IHJlcG9ydGVyLmVudGVyS2V5KGNoaWxkLl9iYXNlU3RhdGUua2V5KTtcblxuICAgICAgaWYgKHR5cGVvZiBkYXRhICE9PSAnb2JqZWN0JylcbiAgICAgICAgcmV0dXJuIHJlcG9ydGVyLmVycm9yKCdDaGlsZCBleHBlY3RlZCwgYnV0IGlucHV0IGlzIG5vdCBvYmplY3QnKTtcblxuICAgICAgdmFyIHJlcyA9IGNoaWxkLl9lbmNvZGUoZGF0YVtjaGlsZC5fYmFzZVN0YXRlLmtleV0sIHJlcG9ydGVyLCBkYXRhKTtcbiAgICAgIHJlcG9ydGVyLmxlYXZlS2V5KHByZXZLZXkpO1xuXG4gICAgICByZXR1cm4gcmVzO1xuICAgIH0sIHRoaXMpLmZpbHRlcihmdW5jdGlvbihjaGlsZCkge1xuICAgICAgcmV0dXJuIGNoaWxkO1xuICAgIH0pO1xuICAgIGNvbnRlbnQgPSB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKGNvbnRlbnQpO1xuICB9IGVsc2Uge1xuICAgIGlmIChzdGF0ZS50YWcgPT09ICdzZXFvZicgfHwgc3RhdGUudGFnID09PSAnc2V0b2YnKSB7XG4gICAgICAvLyBUT0RPKGluZHV0bnkpOiB0aGlzIHNob3VsZCBiZSB0aHJvd24gb24gRFNMIGxldmVsXG4gICAgICBpZiAoIShzdGF0ZS5hcmdzICYmIHN0YXRlLmFyZ3MubGVuZ3RoID09PSAxKSlcbiAgICAgICAgcmV0dXJuIHJlcG9ydGVyLmVycm9yKCdUb28gbWFueSBhcmdzIGZvciA6ICcgKyBzdGF0ZS50YWcpO1xuXG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkoZGF0YSkpXG4gICAgICAgIHJldHVybiByZXBvcnRlci5lcnJvcignc2Vxb2Yvc2V0b2YsIGJ1dCBkYXRhIGlzIG5vdCBBcnJheScpO1xuXG4gICAgICB2YXIgY2hpbGQgPSB0aGlzLmNsb25lKCk7XG4gICAgICBjaGlsZC5fYmFzZVN0YXRlLmltcGxpY2l0ID0gbnVsbDtcbiAgICAgIGNvbnRlbnQgPSB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKGRhdGEubWFwKGZ1bmN0aW9uKGl0ZW0pIHtcbiAgICAgICAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRVc2Uoc3RhdGUuYXJnc1swXSwgZGF0YSkuX2VuY29kZShpdGVtLCByZXBvcnRlcik7XG4gICAgICB9LCBjaGlsZCkpO1xuICAgIH0gZWxzZSBpZiAoc3RhdGUudXNlICE9PSBudWxsKSB7XG4gICAgICByZXN1bHQgPSB0aGlzLl9nZXRVc2Uoc3RhdGUudXNlLCBwYXJlbnQpLl9lbmNvZGUoZGF0YSwgcmVwb3J0ZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZW50ID0gdGhpcy5fZW5jb2RlUHJpbWl0aXZlKHN0YXRlLnRhZywgZGF0YSk7XG4gICAgICBwcmltaXRpdmUgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8vIEVuY29kZSBkYXRhIGl0c2VsZlxuICB2YXIgcmVzdWx0O1xuICBpZiAoIXN0YXRlLmFueSAmJiBzdGF0ZS5jaG9pY2UgPT09IG51bGwpIHtcbiAgICB2YXIgdGFnID0gc3RhdGUuaW1wbGljaXQgIT09IG51bGwgPyBzdGF0ZS5pbXBsaWNpdCA6IHN0YXRlLnRhZztcbiAgICB2YXIgY2xzID0gc3RhdGUuaW1wbGljaXQgPT09IG51bGwgPyAndW5pdmVyc2FsJyA6ICdjb250ZXh0JztcblxuICAgIGlmICh0YWcgPT09IG51bGwpIHtcbiAgICAgIGlmIChzdGF0ZS51c2UgPT09IG51bGwpXG4gICAgICAgIHJlcG9ydGVyLmVycm9yKCdUYWcgY291bGQgYmUgb21pdHRlZCBvbmx5IGZvciAudXNlKCknKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHN0YXRlLnVzZSA9PT0gbnVsbClcbiAgICAgICAgcmVzdWx0ID0gdGhpcy5fZW5jb2RlQ29tcG9zaXRlKHRhZywgcHJpbWl0aXZlLCBjbHMsIGNvbnRlbnQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFdyYXAgaW4gZXhwbGljaXRcbiAgaWYgKHN0YXRlLmV4cGxpY2l0ICE9PSBudWxsKVxuICAgIHJlc3VsdCA9IHRoaXMuX2VuY29kZUNvbXBvc2l0ZShzdGF0ZS5leHBsaWNpdCwgZmFsc2UsICdjb250ZXh0JywgcmVzdWx0KTtcblxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuTm9kZS5wcm90b3R5cGUuX2VuY29kZUNob2ljZSA9IGZ1bmN0aW9uIGVuY29kZUNob2ljZShkYXRhLCByZXBvcnRlcikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgdmFyIG5vZGUgPSBzdGF0ZS5jaG9pY2VbZGF0YS50eXBlXTtcbiAgaWYgKCFub2RlKSB7XG4gICAgYXNzZXJ0KFxuICAgICAgICBmYWxzZSxcbiAgICAgICAgZGF0YS50eXBlICsgJyBub3QgZm91bmQgaW4gJyArXG4gICAgICAgICAgICBKU09OLnN0cmluZ2lmeShPYmplY3Qua2V5cyhzdGF0ZS5jaG9pY2UpKSk7XG4gIH1cbiAgcmV0dXJuIG5vZGUuX2VuY29kZShkYXRhLnZhbHVlLCByZXBvcnRlcik7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5fZW5jb2RlUHJpbWl0aXZlID0gZnVuY3Rpb24gZW5jb2RlUHJpbWl0aXZlKHRhZywgZGF0YSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9iYXNlU3RhdGU7XG5cbiAgaWYgKC9zdHIkLy50ZXN0KHRhZykpXG4gICAgcmV0dXJuIHRoaXMuX2VuY29kZVN0cihkYXRhLCB0YWcpO1xuICBlbHNlIGlmICh0YWcgPT09ICdvYmppZCcgJiYgc3RhdGUuYXJncylcbiAgICByZXR1cm4gdGhpcy5fZW5jb2RlT2JqaWQoZGF0YSwgc3RhdGUucmV2ZXJzZUFyZ3NbMF0sIHN0YXRlLmFyZ3NbMV0pO1xuICBlbHNlIGlmICh0YWcgPT09ICdvYmppZCcpXG4gICAgcmV0dXJuIHRoaXMuX2VuY29kZU9iamlkKGRhdGEsIG51bGwsIG51bGwpO1xuICBlbHNlIGlmICh0YWcgPT09ICdnZW50aW1lJyB8fCB0YWcgPT09ICd1dGN0aW1lJylcbiAgICByZXR1cm4gdGhpcy5fZW5jb2RlVGltZShkYXRhLCB0YWcpO1xuICBlbHNlIGlmICh0YWcgPT09ICdudWxsXycpXG4gICAgcmV0dXJuIHRoaXMuX2VuY29kZU51bGwoKTtcbiAgZWxzZSBpZiAodGFnID09PSAnaW50JyB8fCB0YWcgPT09ICdlbnVtJylcbiAgICByZXR1cm4gdGhpcy5fZW5jb2RlSW50KGRhdGEsIHN0YXRlLmFyZ3MgJiYgc3RhdGUucmV2ZXJzZUFyZ3NbMF0pO1xuICBlbHNlIGlmICh0YWcgPT09ICdib29sJylcbiAgICByZXR1cm4gdGhpcy5fZW5jb2RlQm9vbChkYXRhKTtcbiAgZWxzZSBpZiAodGFnID09PSAnb2JqRGVzYycpXG4gICAgcmV0dXJuIHRoaXMuX2VuY29kZVN0cihkYXRhLCB0YWcpO1xuICBlbHNlXG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCB0YWc6ICcgKyB0YWcpO1xufTtcblxuTm9kZS5wcm90b3R5cGUuX2lzTnVtc3RyID0gZnVuY3Rpb24gaXNOdW1zdHIoc3RyKSB7XG4gIHJldHVybiAvXlswLTkgXSokLy50ZXN0KHN0cik7XG59O1xuXG5Ob2RlLnByb3RvdHlwZS5faXNQcmludHN0ciA9IGZ1bmN0aW9uIGlzUHJpbnRzdHIoc3RyKSB7XG4gIHJldHVybiAvXltBLVphLXowLTkgJ1xcKFxcKVxcKyxcXC1cXC5cXC86PVxcP10qJC8udGVzdChzdHIpO1xufTtcbiIsInZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmZ1bmN0aW9uIFJlcG9ydGVyKG9wdGlvbnMpIHtcbiAgdGhpcy5fcmVwb3J0ZXJTdGF0ZSA9IHtcbiAgICBvYmo6IG51bGwsXG4gICAgcGF0aDogW10sXG4gICAgb3B0aW9uczogb3B0aW9ucyB8fCB7fSxcbiAgICBlcnJvcnM6IFtdXG4gIH07XG59XG5leHBvcnRzLlJlcG9ydGVyID0gUmVwb3J0ZXI7XG5cblJlcG9ydGVyLnByb3RvdHlwZS5pc0Vycm9yID0gZnVuY3Rpb24gaXNFcnJvcihvYmopIHtcbiAgcmV0dXJuIG9iaiBpbnN0YW5jZW9mIFJlcG9ydGVyRXJyb3I7XG59O1xuXG5SZXBvcnRlci5wcm90b3R5cGUuc2F2ZSA9IGZ1bmN0aW9uIHNhdmUoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlcG9ydGVyU3RhdGU7XG5cbiAgcmV0dXJuIHsgb2JqOiBzdGF0ZS5vYmosIHBhdGhMZW46IHN0YXRlLnBhdGgubGVuZ3RoIH07XG59O1xuXG5SZXBvcnRlci5wcm90b3R5cGUucmVzdG9yZSA9IGZ1bmN0aW9uIHJlc3RvcmUoZGF0YSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZXBvcnRlclN0YXRlO1xuXG4gIHN0YXRlLm9iaiA9IGRhdGEub2JqO1xuICBzdGF0ZS5wYXRoID0gc3RhdGUucGF0aC5zbGljZSgwLCBkYXRhLnBhdGhMZW4pO1xufTtcblxuUmVwb3J0ZXIucHJvdG90eXBlLmVudGVyS2V5ID0gZnVuY3Rpb24gZW50ZXJLZXkoa2V5KSB7XG4gIHJldHVybiB0aGlzLl9yZXBvcnRlclN0YXRlLnBhdGgucHVzaChrZXkpO1xufTtcblxuUmVwb3J0ZXIucHJvdG90eXBlLmV4aXRLZXkgPSBmdW5jdGlvbiBleGl0S2V5KGluZGV4KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlcG9ydGVyU3RhdGU7XG5cbiAgc3RhdGUucGF0aCA9IHN0YXRlLnBhdGguc2xpY2UoMCwgaW5kZXggLSAxKTtcbn07XG5cblJlcG9ydGVyLnByb3RvdHlwZS5sZWF2ZUtleSA9IGZ1bmN0aW9uIGxlYXZlS2V5KGluZGV4LCBrZXksIHZhbHVlKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlcG9ydGVyU3RhdGU7XG5cbiAgdGhpcy5leGl0S2V5KGluZGV4KTtcbiAgaWYgKHN0YXRlLm9iaiAhPT0gbnVsbClcbiAgICBzdGF0ZS5vYmpba2V5XSA9IHZhbHVlO1xufTtcblxuUmVwb3J0ZXIucHJvdG90eXBlLnBhdGggPSBmdW5jdGlvbiBwYXRoKCkge1xuICByZXR1cm4gdGhpcy5fcmVwb3J0ZXJTdGF0ZS5wYXRoLmpvaW4oJy8nKTtcbn07XG5cblJlcG9ydGVyLnByb3RvdHlwZS5lbnRlck9iamVjdCA9IGZ1bmN0aW9uIGVudGVyT2JqZWN0KCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZXBvcnRlclN0YXRlO1xuXG4gIHZhciBwcmV2ID0gc3RhdGUub2JqO1xuICBzdGF0ZS5vYmogPSB7fTtcbiAgcmV0dXJuIHByZXY7XG59O1xuXG5SZXBvcnRlci5wcm90b3R5cGUubGVhdmVPYmplY3QgPSBmdW5jdGlvbiBsZWF2ZU9iamVjdChwcmV2KSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlcG9ydGVyU3RhdGU7XG5cbiAgdmFyIG5vdyA9IHN0YXRlLm9iajtcbiAgc3RhdGUub2JqID0gcHJldjtcbiAgcmV0dXJuIG5vdztcbn07XG5cblJlcG9ydGVyLnByb3RvdHlwZS5lcnJvciA9IGZ1bmN0aW9uIGVycm9yKG1zZykge1xuICB2YXIgZXJyO1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZXBvcnRlclN0YXRlO1xuXG4gIHZhciBpbmhlcml0ZWQgPSBtc2cgaW5zdGFuY2VvZiBSZXBvcnRlckVycm9yO1xuICBpZiAoaW5oZXJpdGVkKSB7XG4gICAgZXJyID0gbXNnO1xuICB9IGVsc2Uge1xuICAgIGVyciA9IG5ldyBSZXBvcnRlckVycm9yKHN0YXRlLnBhdGgubWFwKGZ1bmN0aW9uKGVsZW0pIHtcbiAgICAgIHJldHVybiAnWycgKyBKU09OLnN0cmluZ2lmeShlbGVtKSArICddJztcbiAgICB9KS5qb2luKCcnKSwgbXNnLm1lc3NhZ2UgfHwgbXNnLCBtc2cuc3RhY2spO1xuICB9XG5cbiAgaWYgKCFzdGF0ZS5vcHRpb25zLnBhcnRpYWwpXG4gICAgdGhyb3cgZXJyO1xuXG4gIGlmICghaW5oZXJpdGVkKVxuICAgIHN0YXRlLmVycm9ycy5wdXNoKGVycik7XG5cbiAgcmV0dXJuIGVycjtcbn07XG5cblJlcG9ydGVyLnByb3RvdHlwZS53cmFwUmVzdWx0ID0gZnVuY3Rpb24gd3JhcFJlc3VsdChyZXN1bHQpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVwb3J0ZXJTdGF0ZTtcbiAgaWYgKCFzdGF0ZS5vcHRpb25zLnBhcnRpYWwpXG4gICAgcmV0dXJuIHJlc3VsdDtcblxuICByZXR1cm4ge1xuICAgIHJlc3VsdDogdGhpcy5pc0Vycm9yKHJlc3VsdCkgPyBudWxsIDogcmVzdWx0LFxuICAgIGVycm9yczogc3RhdGUuZXJyb3JzXG4gIH07XG59O1xuXG5mdW5jdGlvbiBSZXBvcnRlckVycm9yKHBhdGgsIG1zZykge1xuICB0aGlzLnBhdGggPSBwYXRoO1xuICB0aGlzLnJldGhyb3cobXNnKTtcbn07XG5pbmhlcml0cyhSZXBvcnRlckVycm9yLCBFcnJvcik7XG5cblJlcG9ydGVyRXJyb3IucHJvdG90eXBlLnJldGhyb3cgPSBmdW5jdGlvbiByZXRocm93KG1zZykge1xuICB0aGlzLm1lc3NhZ2UgPSBtc2cgKyAnIGF0OiAnICsgKHRoaXMucGF0aCB8fCAnKHNoYWxsb3cpJyk7XG4gIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSlcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCBSZXBvcnRlckVycm9yKTtcblxuICBpZiAoIXRoaXMuc3RhY2spIHtcbiAgICB0cnkge1xuICAgICAgLy8gSUUgb25seSBhZGRzIHN0YWNrIHdoZW4gdGhyb3duXG4gICAgICB0aHJvdyBuZXcgRXJyb3IodGhpcy5tZXNzYWdlKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLnN0YWNrID0gZS5zdGFjaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuIiwidmFyIGNvbnN0YW50cyA9IHJlcXVpcmUoJy4uL2NvbnN0YW50cycpO1xuXG5leHBvcnRzLnRhZ0NsYXNzID0ge1xuICAwOiAndW5pdmVyc2FsJyxcbiAgMTogJ2FwcGxpY2F0aW9uJyxcbiAgMjogJ2NvbnRleHQnLFxuICAzOiAncHJpdmF0ZSdcbn07XG5leHBvcnRzLnRhZ0NsYXNzQnlOYW1lID0gY29uc3RhbnRzLl9yZXZlcnNlKGV4cG9ydHMudGFnQ2xhc3MpO1xuXG5leHBvcnRzLnRhZyA9IHtcbiAgMHgwMDogJ2VuZCcsXG4gIDB4MDE6ICdib29sJyxcbiAgMHgwMjogJ2ludCcsXG4gIDB4MDM6ICdiaXRzdHInLFxuICAweDA0OiAnb2N0c3RyJyxcbiAgMHgwNTogJ251bGxfJyxcbiAgMHgwNjogJ29iamlkJyxcbiAgMHgwNzogJ29iakRlc2MnLFxuICAweDA4OiAnZXh0ZXJuYWwnLFxuICAweDA5OiAncmVhbCcsXG4gIDB4MGE6ICdlbnVtJyxcbiAgMHgwYjogJ2VtYmVkJyxcbiAgMHgwYzogJ3V0ZjhzdHInLFxuICAweDBkOiAncmVsYXRpdmVPaWQnLFxuICAweDEwOiAnc2VxJyxcbiAgMHgxMTogJ3NldCcsXG4gIDB4MTI6ICdudW1zdHInLFxuICAweDEzOiAncHJpbnRzdHInLFxuICAweDE0OiAndDYxc3RyJyxcbiAgMHgxNTogJ3ZpZGVvc3RyJyxcbiAgMHgxNjogJ2lhNXN0cicsXG4gIDB4MTc6ICd1dGN0aW1lJyxcbiAgMHgxODogJ2dlbnRpbWUnLFxuICAweDE5OiAnZ3JhcGhzdHInLFxuICAweDFhOiAnaXNvNjQ2c3RyJyxcbiAgMHgxYjogJ2dlbnN0cicsXG4gIDB4MWM6ICd1bmlzdHInLFxuICAweDFkOiAnY2hhcnN0cicsXG4gIDB4MWU6ICdibXBzdHInXG59O1xuZXhwb3J0cy50YWdCeU5hbWUgPSBjb25zdGFudHMuX3JldmVyc2UoZXhwb3J0cy50YWcpO1xuIiwidmFyIGNvbnN0YW50cyA9IGV4cG9ydHM7XG5cbi8vIEhlbHBlclxuY29uc3RhbnRzLl9yZXZlcnNlID0gZnVuY3Rpb24gcmV2ZXJzZShtYXApIHtcbiAgdmFyIHJlcyA9IHt9O1xuXG4gIE9iamVjdC5rZXlzKG1hcCkuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICAvLyBDb252ZXJ0IGtleSB0byBpbnRlZ2VyIGlmIGl0IGlzIHN0cmluZ2lmaWVkXG4gICAgaWYgKChrZXkgfCAwKSA9PSBrZXkpXG4gICAgICBrZXkgPSBrZXkgfCAwO1xuXG4gICAgdmFyIHZhbHVlID0gbWFwW2tleV07XG4gICAgcmVzW3ZhbHVlXSA9IGtleTtcbiAgfSk7XG5cbiAgcmV0dXJuIHJlcztcbn07XG5cbmNvbnN0YW50cy5kZXIgPSByZXF1aXJlKCcuL2RlcicpO1xuIiwidmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxudmFyIGFzbjEgPSByZXF1aXJlKCcuLi8uLi9hc24xJyk7XG52YXIgYmFzZSA9IGFzbjEuYmFzZTtcbnZhciBiaWdudW0gPSBhc24xLmJpZ251bTtcblxuLy8gSW1wb3J0IERFUiBjb25zdGFudHNcbnZhciBkZXIgPSBhc24xLmNvbnN0YW50cy5kZXI7XG5cbmZ1bmN0aW9uIERFUkRlY29kZXIoZW50aXR5KSB7XG4gIHRoaXMuZW5jID0gJ2Rlcic7XG4gIHRoaXMubmFtZSA9IGVudGl0eS5uYW1lO1xuICB0aGlzLmVudGl0eSA9IGVudGl0eTtcblxuICAvLyBDb25zdHJ1Y3QgYmFzZSB0cmVlXG4gIHRoaXMudHJlZSA9IG5ldyBERVJOb2RlKCk7XG4gIHRoaXMudHJlZS5faW5pdChlbnRpdHkuYm9keSk7XG59O1xubW9kdWxlLmV4cG9ydHMgPSBERVJEZWNvZGVyO1xuXG5ERVJEZWNvZGVyLnByb3RvdHlwZS5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUoZGF0YSwgb3B0aW9ucykge1xuICBpZiAoIShkYXRhIGluc3RhbmNlb2YgYmFzZS5EZWNvZGVyQnVmZmVyKSlcbiAgICBkYXRhID0gbmV3IGJhc2UuRGVjb2RlckJ1ZmZlcihkYXRhLCBvcHRpb25zKTtcblxuICByZXR1cm4gdGhpcy50cmVlLl9kZWNvZGUoZGF0YSwgb3B0aW9ucyk7XG59O1xuXG4vLyBUcmVlIG1ldGhvZHNcblxuZnVuY3Rpb24gREVSTm9kZShwYXJlbnQpIHtcbiAgYmFzZS5Ob2RlLmNhbGwodGhpcywgJ2RlcicsIHBhcmVudCk7XG59XG5pbmhlcml0cyhERVJOb2RlLCBiYXNlLk5vZGUpO1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fcGVla1RhZyA9IGZ1bmN0aW9uIHBlZWtUYWcoYnVmZmVyLCB0YWcsIGFueSkge1xuICBpZiAoYnVmZmVyLmlzRW1wdHkoKSlcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIHN0YXRlID0gYnVmZmVyLnNhdmUoKTtcbiAgdmFyIGRlY29kZWRUYWcgPSBkZXJEZWNvZGVUYWcoYnVmZmVyLCAnRmFpbGVkIHRvIHBlZWsgdGFnOiBcIicgKyB0YWcgKyAnXCInKTtcbiAgaWYgKGJ1ZmZlci5pc0Vycm9yKGRlY29kZWRUYWcpKVxuICAgIHJldHVybiBkZWNvZGVkVGFnO1xuXG4gIGJ1ZmZlci5yZXN0b3JlKHN0YXRlKTtcblxuICByZXR1cm4gZGVjb2RlZFRhZy50YWcgPT09IHRhZyB8fCBkZWNvZGVkVGFnLnRhZ1N0ciA9PT0gdGFnIHx8XG4gICAgKGRlY29kZWRUYWcudGFnU3RyICsgJ29mJykgPT09IHRhZyB8fCBhbnk7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZGVjb2RlVGFnID0gZnVuY3Rpb24gZGVjb2RlVGFnKGJ1ZmZlciwgdGFnLCBhbnkpIHtcbiAgdmFyIGRlY29kZWRUYWcgPSBkZXJEZWNvZGVUYWcoYnVmZmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnRmFpbGVkIHRvIGRlY29kZSB0YWcgb2YgXCInICsgdGFnICsgJ1wiJyk7XG4gIGlmIChidWZmZXIuaXNFcnJvcihkZWNvZGVkVGFnKSlcbiAgICByZXR1cm4gZGVjb2RlZFRhZztcblxuICB2YXIgbGVuID0gZGVyRGVjb2RlTGVuKGJ1ZmZlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICBkZWNvZGVkVGFnLnByaW1pdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAnRmFpbGVkIHRvIGdldCBsZW5ndGggb2YgXCInICsgdGFnICsgJ1wiJyk7XG5cbiAgLy8gRmFpbHVyZVxuICBpZiAoYnVmZmVyLmlzRXJyb3IobGVuKSlcbiAgICByZXR1cm4gbGVuO1xuXG4gIGlmICghYW55ICYmXG4gICAgICBkZWNvZGVkVGFnLnRhZyAhPT0gdGFnICYmXG4gICAgICBkZWNvZGVkVGFnLnRhZ1N0ciAhPT0gdGFnICYmXG4gICAgICBkZWNvZGVkVGFnLnRhZ1N0ciArICdvZicgIT09IHRhZykge1xuICAgIHJldHVybiBidWZmZXIuZXJyb3IoJ0ZhaWxlZCB0byBtYXRjaCB0YWc6IFwiJyArIHRhZyArICdcIicpO1xuICB9XG5cbiAgaWYgKGRlY29kZWRUYWcucHJpbWl0aXZlIHx8IGxlbiAhPT0gbnVsbClcbiAgICByZXR1cm4gYnVmZmVyLnNraXAobGVuLCAnRmFpbGVkIHRvIG1hdGNoIGJvZHkgb2Y6IFwiJyArIHRhZyArICdcIicpO1xuXG4gIC8vIEluZGVmaW5pdGUgbGVuZ3RoLi4uIGZpbmQgRU5EIHRhZ1xuICB2YXIgc3RhdGUgPSBidWZmZXIuc2F2ZSgpO1xuICB2YXIgcmVzID0gdGhpcy5fc2tpcFVudGlsRW5kKFxuICAgICAgYnVmZmVyLFxuICAgICAgJ0ZhaWxlZCB0byBza2lwIGluZGVmaW5pdGUgbGVuZ3RoIGJvZHk6IFwiJyArIHRoaXMudGFnICsgJ1wiJyk7XG4gIGlmIChidWZmZXIuaXNFcnJvcihyZXMpKVxuICAgIHJldHVybiByZXM7XG5cbiAgbGVuID0gYnVmZmVyLm9mZnNldCAtIHN0YXRlLm9mZnNldDtcbiAgYnVmZmVyLnJlc3RvcmUoc3RhdGUpO1xuICByZXR1cm4gYnVmZmVyLnNraXAobGVuLCAnRmFpbGVkIHRvIG1hdGNoIGJvZHkgb2Y6IFwiJyArIHRhZyArICdcIicpO1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX3NraXBVbnRpbEVuZCA9IGZ1bmN0aW9uIHNraXBVbnRpbEVuZChidWZmZXIsIGZhaWwpIHtcbiAgd2hpbGUgKHRydWUpIHtcbiAgICB2YXIgdGFnID0gZGVyRGVjb2RlVGFnKGJ1ZmZlciwgZmFpbCk7XG4gICAgaWYgKGJ1ZmZlci5pc0Vycm9yKHRhZykpXG4gICAgICByZXR1cm4gdGFnO1xuICAgIHZhciBsZW4gPSBkZXJEZWNvZGVMZW4oYnVmZmVyLCB0YWcucHJpbWl0aXZlLCBmYWlsKTtcbiAgICBpZiAoYnVmZmVyLmlzRXJyb3IobGVuKSlcbiAgICAgIHJldHVybiBsZW47XG5cbiAgICB2YXIgcmVzO1xuICAgIGlmICh0YWcucHJpbWl0aXZlIHx8IGxlbiAhPT0gbnVsbClcbiAgICAgIHJlcyA9IGJ1ZmZlci5za2lwKGxlbilcbiAgICBlbHNlXG4gICAgICByZXMgPSB0aGlzLl9za2lwVW50aWxFbmQoYnVmZmVyLCBmYWlsKTtcblxuICAgIC8vIEZhaWx1cmVcbiAgICBpZiAoYnVmZmVyLmlzRXJyb3IocmVzKSlcbiAgICAgIHJldHVybiByZXM7XG5cbiAgICBpZiAodGFnLnRhZ1N0ciA9PT0gJ2VuZCcpXG4gICAgICBicmVhaztcbiAgfVxufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2RlY29kZUxpc3QgPSBmdW5jdGlvbiBkZWNvZGVMaXN0KGJ1ZmZlciwgdGFnLCBkZWNvZGVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMpIHtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICB3aGlsZSAoIWJ1ZmZlci5pc0VtcHR5KCkpIHtcbiAgICB2YXIgcG9zc2libGVFbmQgPSB0aGlzLl9wZWVrVGFnKGJ1ZmZlciwgJ2VuZCcpO1xuICAgIGlmIChidWZmZXIuaXNFcnJvcihwb3NzaWJsZUVuZCkpXG4gICAgICByZXR1cm4gcG9zc2libGVFbmQ7XG5cbiAgICB2YXIgcmVzID0gZGVjb2Rlci5kZWNvZGUoYnVmZmVyLCAnZGVyJywgb3B0aW9ucyk7XG4gICAgaWYgKGJ1ZmZlci5pc0Vycm9yKHJlcykgJiYgcG9zc2libGVFbmQpXG4gICAgICBicmVhaztcbiAgICByZXN1bHQucHVzaChyZXMpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZGVjb2RlU3RyID0gZnVuY3Rpb24gZGVjb2RlU3RyKGJ1ZmZlciwgdGFnKSB7XG4gIGlmICh0YWcgPT09ICdiaXRzdHInKSB7XG4gICAgdmFyIHVudXNlZCA9IGJ1ZmZlci5yZWFkVUludDgoKTtcbiAgICBpZiAoYnVmZmVyLmlzRXJyb3IodW51c2VkKSlcbiAgICAgIHJldHVybiB1bnVzZWQ7XG4gICAgcmV0dXJuIHsgdW51c2VkOiB1bnVzZWQsIGRhdGE6IGJ1ZmZlci5yYXcoKSB9O1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ2JtcHN0cicpIHtcbiAgICB2YXIgcmF3ID0gYnVmZmVyLnJhdygpO1xuICAgIGlmIChyYXcubGVuZ3RoICUgMiA9PT0gMSlcbiAgICAgIHJldHVybiBidWZmZXIuZXJyb3IoJ0RlY29kaW5nIG9mIHN0cmluZyB0eXBlOiBibXBzdHIgbGVuZ3RoIG1pc21hdGNoJyk7XG5cbiAgICB2YXIgc3RyID0gJyc7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCByYXcubGVuZ3RoIC8gMjsgaSsrKSB7XG4gICAgICBzdHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShyYXcucmVhZFVJbnQxNkJFKGkgKiAyKSk7XG4gICAgfVxuICAgIHJldHVybiBzdHI7XG4gIH0gZWxzZSBpZiAodGFnID09PSAnbnVtc3RyJykge1xuICAgIHZhciBudW1zdHIgPSBidWZmZXIucmF3KCkudG9TdHJpbmcoJ2FzY2lpJyk7XG4gICAgaWYgKCF0aGlzLl9pc051bXN0cihudW1zdHIpKSB7XG4gICAgICByZXR1cm4gYnVmZmVyLmVycm9yKCdEZWNvZGluZyBvZiBzdHJpbmcgdHlwZTogJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdudW1zdHIgdW5zdXBwb3J0ZWQgY2hhcmFjdGVycycpO1xuICAgIH1cbiAgICByZXR1cm4gbnVtc3RyO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ29jdHN0cicpIHtcbiAgICByZXR1cm4gYnVmZmVyLnJhdygpO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gJ29iakRlc2MnKSB7XG4gICAgcmV0dXJuIGJ1ZmZlci5yYXcoKTtcbiAgfSBlbHNlIGlmICh0YWcgPT09ICdwcmludHN0cicpIHtcbiAgICB2YXIgcHJpbnRzdHIgPSBidWZmZXIucmF3KCkudG9TdHJpbmcoJ2FzY2lpJyk7XG4gICAgaWYgKCF0aGlzLl9pc1ByaW50c3RyKHByaW50c3RyKSkge1xuICAgICAgcmV0dXJuIGJ1ZmZlci5lcnJvcignRGVjb2Rpbmcgb2Ygc3RyaW5nIHR5cGU6ICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAncHJpbnRzdHIgdW5zdXBwb3J0ZWQgY2hhcmFjdGVycycpO1xuICAgIH1cbiAgICByZXR1cm4gcHJpbnRzdHI7XG4gIH0gZWxzZSBpZiAoL3N0ciQvLnRlc3QodGFnKSkge1xuICAgIHJldHVybiBidWZmZXIucmF3KCkudG9TdHJpbmcoKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYnVmZmVyLmVycm9yKCdEZWNvZGluZyBvZiBzdHJpbmcgdHlwZTogJyArIHRhZyArICcgdW5zdXBwb3J0ZWQnKTtcbiAgfVxufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2RlY29kZU9iamlkID0gZnVuY3Rpb24gZGVjb2RlT2JqaWQoYnVmZmVyLCB2YWx1ZXMsIHJlbGF0aXZlKSB7XG4gIHZhciByZXN1bHQ7XG4gIHZhciBpZGVudGlmaWVycyA9IFtdO1xuICB2YXIgaWRlbnQgPSAwO1xuICB3aGlsZSAoIWJ1ZmZlci5pc0VtcHR5KCkpIHtcbiAgICB2YXIgc3ViaWRlbnQgPSBidWZmZXIucmVhZFVJbnQ4KCk7XG4gICAgaWRlbnQgPDw9IDc7XG4gICAgaWRlbnQgfD0gc3ViaWRlbnQgJiAweDdmO1xuICAgIGlmICgoc3ViaWRlbnQgJiAweDgwKSA9PT0gMCkge1xuICAgICAgaWRlbnRpZmllcnMucHVzaChpZGVudCk7XG4gICAgICBpZGVudCA9IDA7XG4gICAgfVxuICB9XG4gIGlmIChzdWJpZGVudCAmIDB4ODApXG4gICAgaWRlbnRpZmllcnMucHVzaChpZGVudCk7XG5cbiAgdmFyIGZpcnN0ID0gKGlkZW50aWZpZXJzWzBdIC8gNDApIHwgMDtcbiAgdmFyIHNlY29uZCA9IGlkZW50aWZpZXJzWzBdICUgNDA7XG5cbiAgaWYgKHJlbGF0aXZlKVxuICAgIHJlc3VsdCA9IGlkZW50aWZpZXJzO1xuICBlbHNlXG4gICAgcmVzdWx0ID0gW2ZpcnN0LCBzZWNvbmRdLmNvbmNhdChpZGVudGlmaWVycy5zbGljZSgxKSk7XG5cbiAgaWYgKHZhbHVlcykge1xuICAgIHZhciB0bXAgPSB2YWx1ZXNbcmVzdWx0LmpvaW4oJyAnKV07XG4gICAgaWYgKHRtcCA9PT0gdW5kZWZpbmVkKVxuICAgICAgdG1wID0gdmFsdWVzW3Jlc3VsdC5qb2luKCcuJyldO1xuICAgIGlmICh0bXAgIT09IHVuZGVmaW5lZClcbiAgICAgIHJlc3VsdCA9IHRtcDtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZGVjb2RlVGltZSA9IGZ1bmN0aW9uIGRlY29kZVRpbWUoYnVmZmVyLCB0YWcpIHtcbiAgdmFyIHN0ciA9IGJ1ZmZlci5yYXcoKS50b1N0cmluZygpO1xuICBpZiAodGFnID09PSAnZ2VudGltZScpIHtcbiAgICB2YXIgeWVhciA9IHN0ci5zbGljZSgwLCA0KSB8IDA7XG4gICAgdmFyIG1vbiA9IHN0ci5zbGljZSg0LCA2KSB8IDA7XG4gICAgdmFyIGRheSA9IHN0ci5zbGljZSg2LCA4KSB8IDA7XG4gICAgdmFyIGhvdXIgPSBzdHIuc2xpY2UoOCwgMTApIHwgMDtcbiAgICB2YXIgbWluID0gc3RyLnNsaWNlKDEwLCAxMikgfCAwO1xuICAgIHZhciBzZWMgPSBzdHIuc2xpY2UoMTIsIDE0KSB8IDA7XG4gIH0gZWxzZSBpZiAodGFnID09PSAndXRjdGltZScpIHtcbiAgICB2YXIgeWVhciA9IHN0ci5zbGljZSgwLCAyKSB8IDA7XG4gICAgdmFyIG1vbiA9IHN0ci5zbGljZSgyLCA0KSB8IDA7XG4gICAgdmFyIGRheSA9IHN0ci5zbGljZSg0LCA2KSB8IDA7XG4gICAgdmFyIGhvdXIgPSBzdHIuc2xpY2UoNiwgOCkgfCAwO1xuICAgIHZhciBtaW4gPSBzdHIuc2xpY2UoOCwgMTApIHwgMDtcbiAgICB2YXIgc2VjID0gc3RyLnNsaWNlKDEwLCAxMikgfCAwO1xuICAgIGlmICh5ZWFyIDwgNzApXG4gICAgICB5ZWFyID0gMjAwMCArIHllYXI7XG4gICAgZWxzZVxuICAgICAgeWVhciA9IDE5MDAgKyB5ZWFyO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBidWZmZXIuZXJyb3IoJ0RlY29kaW5nICcgKyB0YWcgKyAnIHRpbWUgaXMgbm90IHN1cHBvcnRlZCB5ZXQnKTtcbiAgfVxuXG4gIHJldHVybiBEYXRlLlVUQyh5ZWFyLCBtb24gLSAxLCBkYXksIGhvdXIsIG1pbiwgc2VjLCAwKTtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9kZWNvZGVOdWxsID0gZnVuY3Rpb24gZGVjb2RlTnVsbChidWZmZXIpIHtcbiAgcmV0dXJuIG51bGw7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZGVjb2RlQm9vbCA9IGZ1bmN0aW9uIGRlY29kZUJvb2woYnVmZmVyKSB7XG4gIHZhciByZXMgPSBidWZmZXIucmVhZFVJbnQ4KCk7XG4gIGlmIChidWZmZXIuaXNFcnJvcihyZXMpKVxuICAgIHJldHVybiByZXM7XG4gIGVsc2VcbiAgICByZXR1cm4gcmVzICE9PSAwO1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2RlY29kZUludCA9IGZ1bmN0aW9uIGRlY29kZUludChidWZmZXIsIHZhbHVlcykge1xuICAvLyBCaWdpbnQsIHJldHVybiBhcyBpdCBpcyAoYXNzdW1lIGJpZyBlbmRpYW4pXG4gIHZhciByYXcgPSBidWZmZXIucmF3KCk7XG4gIHZhciByZXMgPSBuZXcgYmlnbnVtKHJhdyk7XG5cbiAgaWYgKHZhbHVlcylcbiAgICByZXMgPSB2YWx1ZXNbcmVzLnRvU3RyaW5nKDEwKV0gfHwgcmVzO1xuXG4gIHJldHVybiByZXM7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fdXNlID0gZnVuY3Rpb24gdXNlKGVudGl0eSwgb2JqKSB7XG4gIGlmICh0eXBlb2YgZW50aXR5ID09PSAnZnVuY3Rpb24nKVxuICAgIGVudGl0eSA9IGVudGl0eShvYmopO1xuICByZXR1cm4gZW50aXR5Ll9nZXREZWNvZGVyKCdkZXInKS50cmVlO1xufTtcblxuLy8gVXRpbGl0eSBtZXRob2RzXG5cbmZ1bmN0aW9uIGRlckRlY29kZVRhZyhidWYsIGZhaWwpIHtcbiAgdmFyIHRhZyA9IGJ1Zi5yZWFkVUludDgoZmFpbCk7XG4gIGlmIChidWYuaXNFcnJvcih0YWcpKVxuICAgIHJldHVybiB0YWc7XG5cbiAgdmFyIGNscyA9IGRlci50YWdDbGFzc1t0YWcgPj4gNl07XG4gIHZhciBwcmltaXRpdmUgPSAodGFnICYgMHgyMCkgPT09IDA7XG5cbiAgLy8gTXVsdGktb2N0ZXQgdGFnIC0gbG9hZFxuICBpZiAoKHRhZyAmIDB4MWYpID09PSAweDFmKSB7XG4gICAgdmFyIG9jdCA9IHRhZztcbiAgICB0YWcgPSAwO1xuICAgIHdoaWxlICgob2N0ICYgMHg4MCkgPT09IDB4ODApIHtcbiAgICAgIG9jdCA9IGJ1Zi5yZWFkVUludDgoZmFpbCk7XG4gICAgICBpZiAoYnVmLmlzRXJyb3Iob2N0KSlcbiAgICAgICAgcmV0dXJuIG9jdDtcblxuICAgICAgdGFnIDw8PSA3O1xuICAgICAgdGFnIHw9IG9jdCAmIDB4N2Y7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRhZyAmPSAweDFmO1xuICB9XG4gIHZhciB0YWdTdHIgPSBkZXIudGFnW3RhZ107XG5cbiAgcmV0dXJuIHtcbiAgICBjbHM6IGNscyxcbiAgICBwcmltaXRpdmU6IHByaW1pdGl2ZSxcbiAgICB0YWc6IHRhZyxcbiAgICB0YWdTdHI6IHRhZ1N0clxuICB9O1xufVxuXG5mdW5jdGlvbiBkZXJEZWNvZGVMZW4oYnVmLCBwcmltaXRpdmUsIGZhaWwpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5yZWFkVUludDgoZmFpbCk7XG4gIGlmIChidWYuaXNFcnJvcihsZW4pKVxuICAgIHJldHVybiBsZW47XG5cbiAgLy8gSW5kZWZpbml0ZSBmb3JtXG4gIGlmICghcHJpbWl0aXZlICYmIGxlbiA9PT0gMHg4MClcbiAgICByZXR1cm4gbnVsbDtcblxuICAvLyBEZWZpbml0ZSBmb3JtXG4gIGlmICgobGVuICYgMHg4MCkgPT09IDApIHtcbiAgICAvLyBTaG9ydCBmb3JtXG4gICAgcmV0dXJuIGxlbjtcbiAgfVxuXG4gIC8vIExvbmcgZm9ybVxuICB2YXIgbnVtID0gbGVuICYgMHg3ZjtcbiAgaWYgKG51bSA+IDQpXG4gICAgcmV0dXJuIGJ1Zi5lcnJvcignbGVuZ3RoIG9jdGVjdCBpcyB0b28gbG9uZycpO1xuXG4gIGxlbiA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbnVtOyBpKyspIHtcbiAgICBsZW4gPDw9IDg7XG4gICAgdmFyIGogPSBidWYucmVhZFVJbnQ4KGZhaWwpO1xuICAgIGlmIChidWYuaXNFcnJvcihqKSlcbiAgICAgIHJldHVybiBqO1xuICAgIGxlbiB8PSBqO1xuICB9XG5cbiAgcmV0dXJuIGxlbjtcbn1cbiIsInZhciBkZWNvZGVycyA9IGV4cG9ydHM7XG5cbmRlY29kZXJzLmRlciA9IHJlcXVpcmUoJy4vZGVyJyk7XG5kZWNvZGVycy5wZW0gPSByZXF1aXJlKCcuL3BlbScpO1xuIiwidmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG5cbnZhciBERVJEZWNvZGVyID0gcmVxdWlyZSgnLi9kZXInKTtcblxuZnVuY3Rpb24gUEVNRGVjb2RlcihlbnRpdHkpIHtcbiAgREVSRGVjb2Rlci5jYWxsKHRoaXMsIGVudGl0eSk7XG4gIHRoaXMuZW5jID0gJ3BlbSc7XG59O1xuaW5oZXJpdHMoUEVNRGVjb2RlciwgREVSRGVjb2Rlcik7XG5tb2R1bGUuZXhwb3J0cyA9IFBFTURlY29kZXI7XG5cblBFTURlY29kZXIucHJvdG90eXBlLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShkYXRhLCBvcHRpb25zKSB7XG4gIHZhciBsaW5lcyA9IGRhdGEudG9TdHJpbmcoKS5zcGxpdCgvW1xcclxcbl0rL2cpO1xuXG4gIHZhciBsYWJlbCA9IG9wdGlvbnMubGFiZWwudG9VcHBlckNhc2UoKTtcblxuICB2YXIgcmUgPSAvXi0tLS0tKEJFR0lOfEVORCkgKFteLV0rKS0tLS0tJC87XG4gIHZhciBzdGFydCA9IC0xO1xuICB2YXIgZW5kID0gLTE7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgbWF0Y2ggPSBsaW5lc1tpXS5tYXRjaChyZSk7XG4gICAgaWYgKG1hdGNoID09PSBudWxsKVxuICAgICAgY29udGludWU7XG5cbiAgICBpZiAobWF0Y2hbMl0gIT09IGxhYmVsKVxuICAgICAgY29udGludWU7XG5cbiAgICBpZiAoc3RhcnQgPT09IC0xKSB7XG4gICAgICBpZiAobWF0Y2hbMV0gIT09ICdCRUdJTicpXG4gICAgICAgIGJyZWFrO1xuICAgICAgc3RhcnQgPSBpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAobWF0Y2hbMV0gIT09ICdFTkQnKVxuICAgICAgICBicmVhaztcbiAgICAgIGVuZCA9IGk7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgaWYgKHN0YXJ0ID09PSAtMSB8fCBlbmQgPT09IC0xKVxuICAgIHRocm93IG5ldyBFcnJvcignUEVNIHNlY3Rpb24gbm90IGZvdW5kIGZvcjogJyArIGxhYmVsKTtcblxuICB2YXIgYmFzZTY0ID0gbGluZXMuc2xpY2Uoc3RhcnQgKyAxLCBlbmQpLmpvaW4oJycpO1xuICAvLyBSZW1vdmUgZXhjZXNzaXZlIHN5bWJvbHNcbiAgYmFzZTY0LnJlcGxhY2UoL1teYS16MC05XFwrXFwvPV0rL2dpLCAnJyk7XG5cbiAgdmFyIGlucHV0ID0gbmV3IEJ1ZmZlcihiYXNlNjQsICdiYXNlNjQnKTtcbiAgcmV0dXJuIERFUkRlY29kZXIucHJvdG90eXBlLmRlY29kZS5jYWxsKHRoaXMsIGlucHV0LCBvcHRpb25zKTtcbn07XG4iLCJ2YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcblxudmFyIGFzbjEgPSByZXF1aXJlKCcuLi8uLi9hc24xJyk7XG52YXIgYmFzZSA9IGFzbjEuYmFzZTtcblxuLy8gSW1wb3J0IERFUiBjb25zdGFudHNcbnZhciBkZXIgPSBhc24xLmNvbnN0YW50cy5kZXI7XG5cbmZ1bmN0aW9uIERFUkVuY29kZXIoZW50aXR5KSB7XG4gIHRoaXMuZW5jID0gJ2Rlcic7XG4gIHRoaXMubmFtZSA9IGVudGl0eS5uYW1lO1xuICB0aGlzLmVudGl0eSA9IGVudGl0eTtcblxuICAvLyBDb25zdHJ1Y3QgYmFzZSB0cmVlXG4gIHRoaXMudHJlZSA9IG5ldyBERVJOb2RlKCk7XG4gIHRoaXMudHJlZS5faW5pdChlbnRpdHkuYm9keSk7XG59O1xubW9kdWxlLmV4cG9ydHMgPSBERVJFbmNvZGVyO1xuXG5ERVJFbmNvZGVyLnByb3RvdHlwZS5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUoZGF0YSwgcmVwb3J0ZXIpIHtcbiAgcmV0dXJuIHRoaXMudHJlZS5fZW5jb2RlKGRhdGEsIHJlcG9ydGVyKS5qb2luKCk7XG59O1xuXG4vLyBUcmVlIG1ldGhvZHNcblxuZnVuY3Rpb24gREVSTm9kZShwYXJlbnQpIHtcbiAgYmFzZS5Ob2RlLmNhbGwodGhpcywgJ2RlcicsIHBhcmVudCk7XG59XG5pbmhlcml0cyhERVJOb2RlLCBiYXNlLk5vZGUpO1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZW5jb2RlQ29tcG9zaXRlID0gZnVuY3Rpb24gZW5jb2RlQ29tcG9zaXRlKHRhZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbWl0aXZlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbHMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQpIHtcbiAgdmFyIGVuY29kZWRUYWcgPSBlbmNvZGVUYWcodGFnLCBwcmltaXRpdmUsIGNscywgdGhpcy5yZXBvcnRlcik7XG5cbiAgLy8gU2hvcnQgZm9ybVxuICBpZiAoY29udGVudC5sZW5ndGggPCAweDgwKSB7XG4gICAgdmFyIGhlYWRlciA9IG5ldyBCdWZmZXIoMik7XG4gICAgaGVhZGVyWzBdID0gZW5jb2RlZFRhZztcbiAgICBoZWFkZXJbMV0gPSBjb250ZW50Lmxlbmd0aDtcbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihbIGhlYWRlciwgY29udGVudCBdKTtcbiAgfVxuXG4gIC8vIExvbmcgZm9ybVxuICAvLyBDb3VudCBvY3RldHMgcmVxdWlyZWQgdG8gc3RvcmUgbGVuZ3RoXG4gIHZhciBsZW5PY3RldHMgPSAxO1xuICBmb3IgKHZhciBpID0gY29udGVudC5sZW5ndGg7IGkgPj0gMHgxMDA7IGkgPj49IDgpXG4gICAgbGVuT2N0ZXRzKys7XG5cbiAgdmFyIGhlYWRlciA9IG5ldyBCdWZmZXIoMSArIDEgKyBsZW5PY3RldHMpO1xuICBoZWFkZXJbMF0gPSBlbmNvZGVkVGFnO1xuICBoZWFkZXJbMV0gPSAweDgwIHwgbGVuT2N0ZXRzO1xuXG4gIGZvciAodmFyIGkgPSAxICsgbGVuT2N0ZXRzLCBqID0gY29udGVudC5sZW5ndGg7IGogPiAwOyBpLS0sIGogPj49IDgpXG4gICAgaGVhZGVyW2ldID0gaiAmIDB4ZmY7XG5cbiAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoWyBoZWFkZXIsIGNvbnRlbnQgXSk7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZW5jb2RlU3RyID0gZnVuY3Rpb24gZW5jb2RlU3RyKHN0ciwgdGFnKSB7XG4gIGlmICh0YWcgPT09ICdiaXRzdHInKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoWyBzdHIudW51c2VkIHwgMCwgc3RyLmRhdGEgXSk7XG4gIH0gZWxzZSBpZiAodGFnID09PSAnYm1wc3RyJykge1xuICAgIHZhciBidWYgPSBuZXcgQnVmZmVyKHN0ci5sZW5ndGggKiAyKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgICAgYnVmLndyaXRlVUludDE2QkUoc3RyLmNoYXJDb2RlQXQoaSksIGkgKiAyKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoYnVmKTtcbiAgfSBlbHNlIGlmICh0YWcgPT09ICdudW1zdHInKSB7XG4gICAgaWYgKCF0aGlzLl9pc051bXN0cihzdHIpKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXBvcnRlci5lcnJvcignRW5jb2Rpbmcgb2Ygc3RyaW5nIHR5cGU6IG51bXN0ciBzdXBwb3J0cyAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdvbmx5IGRpZ2l0cyBhbmQgc3BhY2UnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIoc3RyKTtcbiAgfSBlbHNlIGlmICh0YWcgPT09ICdwcmludHN0cicpIHtcbiAgICBpZiAoIXRoaXMuX2lzUHJpbnRzdHIoc3RyKSkge1xuICAgICAgcmV0dXJuIHRoaXMucmVwb3J0ZXIuZXJyb3IoJ0VuY29kaW5nIG9mIHN0cmluZyB0eXBlOiBwcmludHN0ciBzdXBwb3J0cyAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdvbmx5IGxhdGluIHVwcGVyIGFuZCBsb3dlciBjYXNlIGxldHRlcnMsICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2RpZ2l0cywgc3BhY2UsIGFwb3N0cm9waGUsIGxlZnQgYW5kIHJpZ3RoICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3BhcmVudGhlc2lzLCBwbHVzIHNpZ24sIGNvbW1hLCBoeXBoZW4sICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2RvdCwgc2xhc2gsIGNvbG9uLCBlcXVhbCBzaWduLCAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdxdWVzdGlvbiBtYXJrJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKHN0cik7XG4gIH0gZWxzZSBpZiAoL3N0ciQvLnRlc3QodGFnKSkge1xuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKHN0cik7XG4gIH0gZWxzZSBpZiAodGFnID09PSAnb2JqRGVzYycpIHtcbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihzdHIpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB0aGlzLnJlcG9ydGVyLmVycm9yKCdFbmNvZGluZyBvZiBzdHJpbmcgdHlwZTogJyArIHRhZyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyB1bnN1cHBvcnRlZCcpO1xuICB9XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZW5jb2RlT2JqaWQgPSBmdW5jdGlvbiBlbmNvZGVPYmppZChpZCwgdmFsdWVzLCByZWxhdGl2ZSkge1xuICBpZiAodHlwZW9mIGlkID09PSAnc3RyaW5nJykge1xuICAgIGlmICghdmFsdWVzKVxuICAgICAgcmV0dXJuIHRoaXMucmVwb3J0ZXIuZXJyb3IoJ3N0cmluZyBvYmppZCBnaXZlbiwgYnV0IG5vIHZhbHVlcyBtYXAgZm91bmQnKTtcbiAgICBpZiAoIXZhbHVlcy5oYXNPd25Qcm9wZXJ0eShpZCkpXG4gICAgICByZXR1cm4gdGhpcy5yZXBvcnRlci5lcnJvcignb2JqaWQgbm90IGZvdW5kIGluIHZhbHVlcyBtYXAnKTtcbiAgICBpZCA9IHZhbHVlc1tpZF0uc3BsaXQoL1tcXHNcXC5dKy9nKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGlkLmxlbmd0aDsgaSsrKVxuICAgICAgaWRbaV0gfD0gMDtcbiAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGlkKSkge1xuICAgIGlkID0gaWQuc2xpY2UoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGlkLmxlbmd0aDsgaSsrKVxuICAgICAgaWRbaV0gfD0gMDtcbiAgfVxuXG4gIGlmICghQXJyYXkuaXNBcnJheShpZCkpIHtcbiAgICByZXR1cm4gdGhpcy5yZXBvcnRlci5lcnJvcignb2JqaWQoKSBzaG91bGQgYmUgZWl0aGVyIGFycmF5IG9yIHN0cmluZywgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2dvdDogJyArIEpTT04uc3RyaW5naWZ5KGlkKSk7XG4gIH1cblxuICBpZiAoIXJlbGF0aXZlKSB7XG4gICAgaWYgKGlkWzFdID49IDQwKVxuICAgICAgcmV0dXJuIHRoaXMucmVwb3J0ZXIuZXJyb3IoJ1NlY29uZCBvYmppZCBpZGVudGlmaWVyIE9PQicpO1xuICAgIGlkLnNwbGljZSgwLCAyLCBpZFswXSAqIDQwICsgaWRbMV0pO1xuICB9XG5cbiAgLy8gQ291bnQgbnVtYmVyIG9mIG9jdGV0c1xuICB2YXIgc2l6ZSA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgaWQubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaWRlbnQgPSBpZFtpXTtcbiAgICBmb3IgKHNpemUrKzsgaWRlbnQgPj0gMHg4MDsgaWRlbnQgPj49IDcpXG4gICAgICBzaXplKys7XG4gIH1cblxuICB2YXIgb2JqaWQgPSBuZXcgQnVmZmVyKHNpemUpO1xuICB2YXIgb2Zmc2V0ID0gb2JqaWQubGVuZ3RoIC0gMTtcbiAgZm9yICh2YXIgaSA9IGlkLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgdmFyIGlkZW50ID0gaWRbaV07XG4gICAgb2JqaWRbb2Zmc2V0LS1dID0gaWRlbnQgJiAweDdmO1xuICAgIHdoaWxlICgoaWRlbnQgPj49IDcpID4gMClcbiAgICAgIG9iamlkW29mZnNldC0tXSA9IDB4ODAgfCAoaWRlbnQgJiAweDdmKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKG9iamlkKTtcbn07XG5cbmZ1bmN0aW9uIHR3byhudW0pIHtcbiAgaWYgKG51bSA8IDEwKVxuICAgIHJldHVybiAnMCcgKyBudW07XG4gIGVsc2VcbiAgICByZXR1cm4gbnVtO1xufVxuXG5ERVJOb2RlLnByb3RvdHlwZS5fZW5jb2RlVGltZSA9IGZ1bmN0aW9uIGVuY29kZVRpbWUodGltZSwgdGFnKSB7XG4gIHZhciBzdHI7XG4gIHZhciBkYXRlID0gbmV3IERhdGUodGltZSk7XG5cbiAgaWYgKHRhZyA9PT0gJ2dlbnRpbWUnKSB7XG4gICAgc3RyID0gW1xuICAgICAgdHdvKGRhdGUuZ2V0RnVsbFllYXIoKSksXG4gICAgICB0d28oZGF0ZS5nZXRVVENNb250aCgpICsgMSksXG4gICAgICB0d28oZGF0ZS5nZXRVVENEYXRlKCkpLFxuICAgICAgdHdvKGRhdGUuZ2V0VVRDSG91cnMoKSksXG4gICAgICB0d28oZGF0ZS5nZXRVVENNaW51dGVzKCkpLFxuICAgICAgdHdvKGRhdGUuZ2V0VVRDU2Vjb25kcygpKSxcbiAgICAgICdaJ1xuICAgIF0uam9pbignJyk7XG4gIH0gZWxzZSBpZiAodGFnID09PSAndXRjdGltZScpIHtcbiAgICBzdHIgPSBbXG4gICAgICB0d28oZGF0ZS5nZXRGdWxsWWVhcigpICUgMTAwKSxcbiAgICAgIHR3byhkYXRlLmdldFVUQ01vbnRoKCkgKyAxKSxcbiAgICAgIHR3byhkYXRlLmdldFVUQ0RhdGUoKSksXG4gICAgICB0d28oZGF0ZS5nZXRVVENIb3VycygpKSxcbiAgICAgIHR3byhkYXRlLmdldFVUQ01pbnV0ZXMoKSksXG4gICAgICB0d28oZGF0ZS5nZXRVVENTZWNvbmRzKCkpLFxuICAgICAgJ1onXG4gICAgXS5qb2luKCcnKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnJlcG9ydGVyLmVycm9yKCdFbmNvZGluZyAnICsgdGFnICsgJyB0aW1lIGlzIG5vdCBzdXBwb3J0ZWQgeWV0Jyk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5fZW5jb2RlU3RyKHN0ciwgJ29jdHN0cicpO1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2VuY29kZU51bGwgPSBmdW5jdGlvbiBlbmNvZGVOdWxsKCkge1xuICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcignJyk7XG59O1xuXG5ERVJOb2RlLnByb3RvdHlwZS5fZW5jb2RlSW50ID0gZnVuY3Rpb24gZW5jb2RlSW50KG51bSwgdmFsdWVzKSB7XG4gIGlmICh0eXBlb2YgbnVtID09PSAnc3RyaW5nJykge1xuICAgIGlmICghdmFsdWVzKVxuICAgICAgcmV0dXJuIHRoaXMucmVwb3J0ZXIuZXJyb3IoJ1N0cmluZyBpbnQgb3IgZW51bSBnaXZlbiwgYnV0IG5vIHZhbHVlcyBtYXAnKTtcbiAgICBpZiAoIXZhbHVlcy5oYXNPd25Qcm9wZXJ0eShudW0pKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXBvcnRlci5lcnJvcignVmFsdWVzIG1hcCBkb2VzblxcJ3QgY29udGFpbjogJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShudW0pKTtcbiAgICB9XG4gICAgbnVtID0gdmFsdWVzW251bV07XG4gIH1cblxuICAvLyBCaWdudW0sIGFzc3VtZSBiaWcgZW5kaWFuXG4gIGlmICh0eXBlb2YgbnVtICE9PSAnbnVtYmVyJyAmJiAhQnVmZmVyLmlzQnVmZmVyKG51bSkpIHtcbiAgICB2YXIgbnVtQXJyYXkgPSBudW0udG9BcnJheSgpO1xuICAgIGlmICghbnVtLnNpZ24gJiYgbnVtQXJyYXlbMF0gJiAweDgwKSB7XG4gICAgICBudW1BcnJheS51bnNoaWZ0KDApO1xuICAgIH1cbiAgICBudW0gPSBuZXcgQnVmZmVyKG51bUFycmF5KTtcbiAgfVxuXG4gIGlmIChCdWZmZXIuaXNCdWZmZXIobnVtKSkge1xuICAgIHZhciBzaXplID0gbnVtLmxlbmd0aDtcbiAgICBpZiAobnVtLmxlbmd0aCA9PT0gMClcbiAgICAgIHNpemUrKztcblxuICAgIHZhciBvdXQgPSBuZXcgQnVmZmVyKHNpemUpO1xuICAgIG51bS5jb3B5KG91dCk7XG4gICAgaWYgKG51bS5sZW5ndGggPT09IDApXG4gICAgICBvdXRbMF0gPSAwXG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVuY29kZXJCdWZmZXIob3V0KTtcbiAgfVxuXG4gIGlmIChudW0gPCAweDgwKVxuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKG51bSk7XG5cbiAgaWYgKG51bSA8IDB4MTAwKVxuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKFswLCBudW1dKTtcblxuICB2YXIgc2l6ZSA9IDE7XG4gIGZvciAodmFyIGkgPSBudW07IGkgPj0gMHgxMDA7IGkgPj49IDgpXG4gICAgc2l6ZSsrO1xuXG4gIHZhciBvdXQgPSBuZXcgQXJyYXkoc2l6ZSk7XG4gIGZvciAodmFyIGkgPSBvdXQubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBvdXRbaV0gPSBudW0gJiAweGZmO1xuICAgIG51bSA+Pj0gODtcbiAgfVxuICBpZihvdXRbMF0gJiAweDgwKSB7XG4gICAgb3V0LnVuc2hpZnQoMCk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5fY3JlYXRlRW5jb2RlckJ1ZmZlcihuZXcgQnVmZmVyKG91dCkpO1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX2VuY29kZUJvb2wgPSBmdW5jdGlvbiBlbmNvZGVCb29sKHZhbHVlKSB7XG4gIHJldHVybiB0aGlzLl9jcmVhdGVFbmNvZGVyQnVmZmVyKHZhbHVlID8gMHhmZiA6IDApO1xufTtcblxuREVSTm9kZS5wcm90b3R5cGUuX3VzZSA9IGZ1bmN0aW9uIHVzZShlbnRpdHksIG9iaikge1xuICBpZiAodHlwZW9mIGVudGl0eSA9PT0gJ2Z1bmN0aW9uJylcbiAgICBlbnRpdHkgPSBlbnRpdHkob2JqKTtcbiAgcmV0dXJuIGVudGl0eS5fZ2V0RW5jb2RlcignZGVyJykudHJlZTtcbn07XG5cbkRFUk5vZGUucHJvdG90eXBlLl9za2lwRGVmYXVsdCA9IGZ1bmN0aW9uIHNraXBEZWZhdWx0KGRhdGFCdWZmZXIsIHJlcG9ydGVyLCBwYXJlbnQpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fYmFzZVN0YXRlO1xuICB2YXIgaTtcbiAgaWYgKHN0YXRlWydkZWZhdWx0J10gPT09IG51bGwpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciBkYXRhID0gZGF0YUJ1ZmZlci5qb2luKCk7XG4gIGlmIChzdGF0ZS5kZWZhdWx0QnVmZmVyID09PSB1bmRlZmluZWQpXG4gICAgc3RhdGUuZGVmYXVsdEJ1ZmZlciA9IHRoaXMuX2VuY29kZVZhbHVlKHN0YXRlWydkZWZhdWx0J10sIHJlcG9ydGVyLCBwYXJlbnQpLmpvaW4oKTtcblxuICBpZiAoZGF0YS5sZW5ndGggIT09IHN0YXRlLmRlZmF1bHRCdWZmZXIubGVuZ3RoKVxuICAgIHJldHVybiBmYWxzZTtcblxuICBmb3IgKGk9MDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspXG4gICAgaWYgKGRhdGFbaV0gIT09IHN0YXRlLmRlZmF1bHRCdWZmZXJbaV0pXG4gICAgICByZXR1cm4gZmFsc2U7XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG4vLyBVdGlsaXR5IG1ldGhvZHNcblxuZnVuY3Rpb24gZW5jb2RlVGFnKHRhZywgcHJpbWl0aXZlLCBjbHMsIHJlcG9ydGVyKSB7XG4gIHZhciByZXM7XG5cbiAgaWYgKHRhZyA9PT0gJ3NlcW9mJylcbiAgICB0YWcgPSAnc2VxJztcbiAgZWxzZSBpZiAodGFnID09PSAnc2V0b2YnKVxuICAgIHRhZyA9ICdzZXQnO1xuXG4gIGlmIChkZXIudGFnQnlOYW1lLmhhc093blByb3BlcnR5KHRhZykpXG4gICAgcmVzID0gZGVyLnRhZ0J5TmFtZVt0YWddO1xuICBlbHNlIGlmICh0eXBlb2YgdGFnID09PSAnbnVtYmVyJyAmJiAodGFnIHwgMCkgPT09IHRhZylcbiAgICByZXMgPSB0YWc7XG4gIGVsc2VcbiAgICByZXR1cm4gcmVwb3J0ZXIuZXJyb3IoJ1Vua25vd24gdGFnOiAnICsgdGFnKTtcblxuICBpZiAocmVzID49IDB4MWYpXG4gICAgcmV0dXJuIHJlcG9ydGVyLmVycm9yKCdNdWx0aS1vY3RldCB0YWcgZW5jb2RpbmcgdW5zdXBwb3J0ZWQnKTtcblxuICBpZiAoIXByaW1pdGl2ZSlcbiAgICByZXMgfD0gMHgyMDtcblxuICByZXMgfD0gKGRlci50YWdDbGFzc0J5TmFtZVtjbHMgfHwgJ3VuaXZlcnNhbCddIDw8IDYpO1xuXG4gIHJldHVybiByZXM7XG59XG4iLCJ2YXIgZW5jb2RlcnMgPSBleHBvcnRzO1xuXG5lbmNvZGVycy5kZXIgPSByZXF1aXJlKCcuL2RlcicpO1xuZW5jb2RlcnMucGVtID0gcmVxdWlyZSgnLi9wZW0nKTtcbiIsInZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbnZhciBERVJFbmNvZGVyID0gcmVxdWlyZSgnLi9kZXInKTtcblxuZnVuY3Rpb24gUEVNRW5jb2RlcihlbnRpdHkpIHtcbiAgREVSRW5jb2Rlci5jYWxsKHRoaXMsIGVudGl0eSk7XG4gIHRoaXMuZW5jID0gJ3BlbSc7XG59O1xuaW5oZXJpdHMoUEVNRW5jb2RlciwgREVSRW5jb2Rlcik7XG5tb2R1bGUuZXhwb3J0cyA9IFBFTUVuY29kZXI7XG5cblBFTUVuY29kZXIucHJvdG90eXBlLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShkYXRhLCBvcHRpb25zKSB7XG4gIHZhciBidWYgPSBERVJFbmNvZGVyLnByb3RvdHlwZS5lbmNvZGUuY2FsbCh0aGlzLCBkYXRhKTtcblxuICB2YXIgcCA9IGJ1Zi50b1N0cmluZygnYmFzZTY0Jyk7XG4gIHZhciBvdXQgPSBbICctLS0tLUJFR0lOICcgKyBvcHRpb25zLmxhYmVsICsgJy0tLS0tJyBdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHAubGVuZ3RoOyBpICs9IDY0KVxuICAgIG91dC5wdXNoKHAuc2xpY2UoaSwgaSArIDY0KSk7XG4gIG91dC5wdXNoKCctLS0tLUVORCAnICsgb3B0aW9ucy5sYWJlbCArICctLS0tLScpO1xuICByZXR1cm4gb3V0LmpvaW4oJ1xcbicpO1xufTtcbiIsIid1c2Ugc3RyaWN0J1xuXG5leHBvcnRzLmJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoXG5leHBvcnRzLnRvQnl0ZUFycmF5ID0gdG9CeXRlQXJyYXlcbmV4cG9ydHMuZnJvbUJ5dGVBcnJheSA9IGZyb21CeXRlQXJyYXlcblxudmFyIGxvb2t1cCA9IFtdXG52YXIgcmV2TG9va3VwID0gW11cbnZhciBBcnIgPSB0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcgPyBVaW50OEFycmF5IDogQXJyYXlcblxudmFyIGNvZGUgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLydcbmZvciAodmFyIGkgPSAwLCBsZW4gPSBjb2RlLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gIGxvb2t1cFtpXSA9IGNvZGVbaV1cbiAgcmV2TG9va3VwW2NvZGUuY2hhckNvZGVBdChpKV0gPSBpXG59XG5cbi8vIFN1cHBvcnQgZGVjb2RpbmcgVVJMLXNhZmUgYmFzZTY0IHN0cmluZ3MsIGFzIE5vZGUuanMgZG9lcy5cbi8vIFNlZTogaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQmFzZTY0I1VSTF9hcHBsaWNhdGlvbnNcbnJldkxvb2t1cFsnLScuY2hhckNvZGVBdCgwKV0gPSA2MlxucmV2TG9va3VwWydfJy5jaGFyQ29kZUF0KDApXSA9IDYzXG5cbmZ1bmN0aW9uIGdldExlbnMgKGI2NCkge1xuICB2YXIgbGVuID0gYjY0Lmxlbmd0aFxuXG4gIGlmIChsZW4gJSA0ID4gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdHJpbmcuIExlbmd0aCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNCcpXG4gIH1cblxuICAvLyBUcmltIG9mZiBleHRyYSBieXRlcyBhZnRlciBwbGFjZWhvbGRlciBieXRlcyBhcmUgZm91bmRcbiAgLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vYmVhdGdhbW1pdC9iYXNlNjQtanMvaXNzdWVzLzQyXG4gIHZhciB2YWxpZExlbiA9IGI2NC5pbmRleE9mKCc9JylcbiAgaWYgKHZhbGlkTGVuID09PSAtMSkgdmFsaWRMZW4gPSBsZW5cblxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gdmFsaWRMZW4gPT09IGxlblxuICAgID8gMFxuICAgIDogNCAtICh2YWxpZExlbiAlIDQpXG5cbiAgcmV0dXJuIFt2YWxpZExlbiwgcGxhY2VIb2xkZXJzTGVuXVxufVxuXG4vLyBiYXNlNjQgaXMgNC8zICsgdXAgdG8gdHdvIGNoYXJhY3RlcnMgb2YgdGhlIG9yaWdpbmFsIGRhdGFcbmZ1bmN0aW9uIGJ5dGVMZW5ndGggKGI2NCkge1xuICB2YXIgbGVucyA9IGdldExlbnMoYjY0KVxuICB2YXIgdmFsaWRMZW4gPSBsZW5zWzBdXG4gIHZhciBwbGFjZUhvbGRlcnNMZW4gPSBsZW5zWzFdXG4gIHJldHVybiAoKHZhbGlkTGVuICsgcGxhY2VIb2xkZXJzTGVuKSAqIDMgLyA0KSAtIHBsYWNlSG9sZGVyc0xlblxufVxuXG5mdW5jdGlvbiBfYnl0ZUxlbmd0aCAoYjY0LCB2YWxpZExlbiwgcGxhY2VIb2xkZXJzTGVuKSB7XG4gIHJldHVybiAoKHZhbGlkTGVuICsgcGxhY2VIb2xkZXJzTGVuKSAqIDMgLyA0KSAtIHBsYWNlSG9sZGVyc0xlblxufVxuXG5mdW5jdGlvbiB0b0J5dGVBcnJheSAoYjY0KSB7XG4gIHZhciB0bXBcbiAgdmFyIGxlbnMgPSBnZXRMZW5zKGI2NClcbiAgdmFyIHZhbGlkTGVuID0gbGVuc1swXVxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gbGVuc1sxXVxuXG4gIHZhciBhcnIgPSBuZXcgQXJyKF9ieXRlTGVuZ3RoKGI2NCwgdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbikpXG5cbiAgdmFyIGN1ckJ5dGUgPSAwXG5cbiAgLy8gaWYgdGhlcmUgYXJlIHBsYWNlaG9sZGVycywgb25seSBnZXQgdXAgdG8gdGhlIGxhc3QgY29tcGxldGUgNCBjaGFyc1xuICB2YXIgbGVuID0gcGxhY2VIb2xkZXJzTGVuID4gMFxuICAgID8gdmFsaWRMZW4gLSA0XG4gICAgOiB2YWxpZExlblxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTgpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCAxMikgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMildIDw8IDYpIHxcbiAgICAgIHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMyldXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDE2KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICBpZiAocGxhY2VIb2xkZXJzTGVuID09PSAyKSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDIpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA+PiA0KVxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVyc0xlbiA9PT0gMSkge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAxMCkgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldIDw8IDQpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA+PiAyKVxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiA4KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcbiAgcmV0dXJuIGxvb2t1cFtudW0gPj4gMTggJiAweDNGXSArXG4gICAgbG9va3VwW251bSA+PiAxMiAmIDB4M0ZdICtcbiAgICBsb29rdXBbbnVtID4+IDYgJiAweDNGXSArXG4gICAgbG9va3VwW251bSAmIDB4M0ZdXG59XG5cbmZ1bmN0aW9uIGVuY29kZUNodW5rICh1aW50OCwgc3RhcnQsIGVuZCkge1xuICB2YXIgdG1wXG4gIHZhciBvdXRwdXQgPSBbXVxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkgKz0gMykge1xuICAgIHRtcCA9XG4gICAgICAoKHVpbnQ4W2ldIDw8IDE2KSAmIDB4RkYwMDAwKSArXG4gICAgICAoKHVpbnQ4W2kgKyAxXSA8PCA4KSAmIDB4RkYwMCkgK1xuICAgICAgKHVpbnQ4W2kgKyAyXSAmIDB4RkYpXG4gICAgb3V0cHV0LnB1c2godHJpcGxldFRvQmFzZTY0KHRtcCkpXG4gIH1cbiAgcmV0dXJuIG91dHB1dC5qb2luKCcnKVxufVxuXG5mdW5jdGlvbiBmcm9tQnl0ZUFycmF5ICh1aW50OCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW4gPSB1aW50OC5sZW5ndGhcbiAgdmFyIGV4dHJhQnl0ZXMgPSBsZW4gJSAzIC8vIGlmIHdlIGhhdmUgMSBieXRlIGxlZnQsIHBhZCAyIGJ5dGVzXG4gIHZhciBwYXJ0cyA9IFtdXG4gIHZhciBtYXhDaHVua0xlbmd0aCA9IDE2MzgzIC8vIG11c3QgYmUgbXVsdGlwbGUgb2YgM1xuXG4gIC8vIGdvIHRocm91Z2ggdGhlIGFycmF5IGV2ZXJ5IHRocmVlIGJ5dGVzLCB3ZSdsbCBkZWFsIHdpdGggdHJhaWxpbmcgc3R1ZmYgbGF0ZXJcbiAgZm9yICh2YXIgaSA9IDAsIGxlbjIgPSBsZW4gLSBleHRyYUJ5dGVzOyBpIDwgbGVuMjsgaSArPSBtYXhDaHVua0xlbmd0aCkge1xuICAgIHBhcnRzLnB1c2goZW5jb2RlQ2h1bmsoXG4gICAgICB1aW50OCwgaSwgKGkgKyBtYXhDaHVua0xlbmd0aCkgPiBsZW4yID8gbGVuMiA6IChpICsgbWF4Q2h1bmtMZW5ndGgpXG4gICAgKSlcbiAgfVxuXG4gIC8vIHBhZCB0aGUgZW5kIHdpdGggemVyb3MsIGJ1dCBtYWtlIHN1cmUgdG8gbm90IGZvcmdldCB0aGUgZXh0cmEgYnl0ZXNcbiAgaWYgKGV4dHJhQnl0ZXMgPT09IDEpIHtcbiAgICB0bXAgPSB1aW50OFtsZW4gLSAxXVxuICAgIHBhcnRzLnB1c2goXG4gICAgICBsb29rdXBbdG1wID4+IDJdICtcbiAgICAgIGxvb2t1cFsodG1wIDw8IDQpICYgMHgzRl0gK1xuICAgICAgJz09J1xuICAgIClcbiAgfSBlbHNlIGlmIChleHRyYUJ5dGVzID09PSAyKSB7XG4gICAgdG1wID0gKHVpbnQ4W2xlbiAtIDJdIDw8IDgpICsgdWludDhbbGVuIC0gMV1cbiAgICBwYXJ0cy5wdXNoKFxuICAgICAgbG9va3VwW3RtcCA+PiAxMF0gK1xuICAgICAgbG9va3VwWyh0bXAgPj4gNCkgJiAweDNGXSArXG4gICAgICBsb29rdXBbKHRtcCA8PCAyKSAmIDB4M0ZdICtcbiAgICAgICc9J1xuICAgIClcbiAgfVxuXG4gIHJldHVybiBwYXJ0cy5qb2luKCcnKVxufVxuIiwiKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMpIHtcbiAgJ3VzZSBzdHJpY3QnO1xuXG4gIC8vIFV0aWxzXG4gIGZ1bmN0aW9uIGFzc2VydCAodmFsLCBtc2cpIHtcbiAgICBpZiAoIXZhbCkgdGhyb3cgbmV3IEVycm9yKG1zZyB8fCAnQXNzZXJ0aW9uIGZhaWxlZCcpO1xuICB9XG5cbiAgLy8gQ291bGQgdXNlIGBpbmhlcml0c2AgbW9kdWxlLCBidXQgZG9uJ3Qgd2FudCB0byBtb3ZlIGZyb20gc2luZ2xlIGZpbGVcbiAgLy8gYXJjaGl0ZWN0dXJlIHlldC5cbiAgZnVuY3Rpb24gaW5oZXJpdHMgKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yO1xuICAgIHZhciBUZW1wQ3RvciA9IGZ1bmN0aW9uICgpIHt9O1xuICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGU7XG4gICAgY3Rvci5wcm90b3R5cGUgPSBuZXcgVGVtcEN0b3IoKTtcbiAgICBjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGN0b3I7XG4gIH1cblxuICAvLyBCTlxuXG4gIGZ1bmN0aW9uIEJOIChudW1iZXIsIGJhc2UsIGVuZGlhbikge1xuICAgIGlmIChCTi5pc0JOKG51bWJlcikpIHtcbiAgICAgIHJldHVybiBudW1iZXI7XG4gICAgfVxuXG4gICAgdGhpcy5uZWdhdGl2ZSA9IDA7XG4gICAgdGhpcy53b3JkcyA9IG51bGw7XG4gICAgdGhpcy5sZW5ndGggPSAwO1xuXG4gICAgLy8gUmVkdWN0aW9uIGNvbnRleHRcbiAgICB0aGlzLnJlZCA9IG51bGw7XG5cbiAgICBpZiAobnVtYmVyICE9PSBudWxsKSB7XG4gICAgICBpZiAoYmFzZSA9PT0gJ2xlJyB8fCBiYXNlID09PSAnYmUnKSB7XG4gICAgICAgIGVuZGlhbiA9IGJhc2U7XG4gICAgICAgIGJhc2UgPSAxMDtcbiAgICAgIH1cblxuICAgICAgdGhpcy5faW5pdChudW1iZXIgfHwgMCwgYmFzZSB8fCAxMCwgZW5kaWFuIHx8ICdiZScpO1xuICAgIH1cbiAgfVxuICBpZiAodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IEJOO1xuICB9IGVsc2Uge1xuICAgIGV4cG9ydHMuQk4gPSBCTjtcbiAgfVxuXG4gIEJOLkJOID0gQk47XG4gIEJOLndvcmRTaXplID0gMjY7XG5cbiAgdmFyIEJ1ZmZlcjtcbiAgdHJ5IHtcbiAgICBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgfVxuXG4gIEJOLmlzQk4gPSBmdW5jdGlvbiBpc0JOIChudW0pIHtcbiAgICBpZiAobnVtIGluc3RhbmNlb2YgQk4pIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBudW0gIT09IG51bGwgJiYgdHlwZW9mIG51bSA9PT0gJ29iamVjdCcgJiZcbiAgICAgIG51bS5jb25zdHJ1Y3Rvci53b3JkU2l6ZSA9PT0gQk4ud29yZFNpemUgJiYgQXJyYXkuaXNBcnJheShudW0ud29yZHMpO1xuICB9O1xuXG4gIEJOLm1heCA9IGZ1bmN0aW9uIG1heCAobGVmdCwgcmlnaHQpIHtcbiAgICBpZiAobGVmdC5jbXAocmlnaHQpID4gMCkgcmV0dXJuIGxlZnQ7XG4gICAgcmV0dXJuIHJpZ2h0O1xuICB9O1xuXG4gIEJOLm1pbiA9IGZ1bmN0aW9uIG1pbiAobGVmdCwgcmlnaHQpIHtcbiAgICBpZiAobGVmdC5jbXAocmlnaHQpIDwgMCkgcmV0dXJuIGxlZnQ7XG4gICAgcmV0dXJuIHJpZ2h0O1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uIGluaXQgKG51bWJlciwgYmFzZSwgZW5kaWFuKSB7XG4gICAgaWYgKHR5cGVvZiBudW1iZXIgPT09ICdudW1iZXInKSB7XG4gICAgICByZXR1cm4gdGhpcy5faW5pdE51bWJlcihudW1iZXIsIGJhc2UsIGVuZGlhbik7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBudW1iZXIgPT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm4gdGhpcy5faW5pdEFycmF5KG51bWJlciwgYmFzZSwgZW5kaWFuKTtcbiAgICB9XG5cbiAgICBpZiAoYmFzZSA9PT0gJ2hleCcpIHtcbiAgICAgIGJhc2UgPSAxNjtcbiAgICB9XG4gICAgYXNzZXJ0KGJhc2UgPT09IChiYXNlIHwgMCkgJiYgYmFzZSA+PSAyICYmIGJhc2UgPD0gMzYpO1xuXG4gICAgbnVtYmVyID0gbnVtYmVyLnRvU3RyaW5nKCkucmVwbGFjZSgvXFxzKy9nLCAnJyk7XG4gICAgdmFyIHN0YXJ0ID0gMDtcbiAgICBpZiAobnVtYmVyWzBdID09PSAnLScpIHtcbiAgICAgIHN0YXJ0Kys7XG4gICAgfVxuXG4gICAgaWYgKGJhc2UgPT09IDE2KSB7XG4gICAgICB0aGlzLl9wYXJzZUhleChudW1iZXIsIHN0YXJ0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fcGFyc2VCYXNlKG51bWJlciwgYmFzZSwgc3RhcnQpO1xuICAgIH1cblxuICAgIGlmIChudW1iZXJbMF0gPT09ICctJykge1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDE7XG4gICAgfVxuXG4gICAgdGhpcy5zdHJpcCgpO1xuXG4gICAgaWYgKGVuZGlhbiAhPT0gJ2xlJykgcmV0dXJuO1xuXG4gICAgdGhpcy5faW5pdEFycmF5KHRoaXMudG9BcnJheSgpLCBiYXNlLCBlbmRpYW4pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5faW5pdE51bWJlciA9IGZ1bmN0aW9uIF9pbml0TnVtYmVyIChudW1iZXIsIGJhc2UsIGVuZGlhbikge1xuICAgIGlmIChudW1iZXIgPCAwKSB7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMTtcbiAgICAgIG51bWJlciA9IC1udW1iZXI7XG4gICAgfVxuICAgIGlmIChudW1iZXIgPCAweDQwMDAwMDApIHtcbiAgICAgIHRoaXMud29yZHMgPSBbIG51bWJlciAmIDB4M2ZmZmZmZiBdO1xuICAgICAgdGhpcy5sZW5ndGggPSAxO1xuICAgIH0gZWxzZSBpZiAobnVtYmVyIDwgMHgxMDAwMDAwMDAwMDAwMCkge1xuICAgICAgdGhpcy53b3JkcyA9IFtcbiAgICAgICAgbnVtYmVyICYgMHgzZmZmZmZmLFxuICAgICAgICAobnVtYmVyIC8gMHg0MDAwMDAwKSAmIDB4M2ZmZmZmZlxuICAgICAgXTtcbiAgICAgIHRoaXMubGVuZ3RoID0gMjtcbiAgICB9IGVsc2Uge1xuICAgICAgYXNzZXJ0KG51bWJlciA8IDB4MjAwMDAwMDAwMDAwMDApOyAvLyAyIF4gNTMgKHVuc2FmZSlcbiAgICAgIHRoaXMud29yZHMgPSBbXG4gICAgICAgIG51bWJlciAmIDB4M2ZmZmZmZixcbiAgICAgICAgKG51bWJlciAvIDB4NDAwMDAwMCkgJiAweDNmZmZmZmYsXG4gICAgICAgIDFcbiAgICAgIF07XG4gICAgICB0aGlzLmxlbmd0aCA9IDM7XG4gICAgfVxuXG4gICAgaWYgKGVuZGlhbiAhPT0gJ2xlJykgcmV0dXJuO1xuXG4gICAgLy8gUmV2ZXJzZSB0aGUgYnl0ZXNcbiAgICB0aGlzLl9pbml0QXJyYXkodGhpcy50b0FycmF5KCksIGJhc2UsIGVuZGlhbik7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLl9pbml0QXJyYXkgPSBmdW5jdGlvbiBfaW5pdEFycmF5IChudW1iZXIsIGJhc2UsIGVuZGlhbikge1xuICAgIC8vIFBlcmhhcHMgYSBVaW50OEFycmF5XG4gICAgYXNzZXJ0KHR5cGVvZiBudW1iZXIubGVuZ3RoID09PSAnbnVtYmVyJyk7XG4gICAgaWYgKG51bWJlci5sZW5ndGggPD0gMCkge1xuICAgICAgdGhpcy53b3JkcyA9IFsgMCBdO1xuICAgICAgdGhpcy5sZW5ndGggPSAxO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgdGhpcy5sZW5ndGggPSBNYXRoLmNlaWwobnVtYmVyLmxlbmd0aCAvIDMpO1xuICAgIHRoaXMud29yZHMgPSBuZXcgQXJyYXkodGhpcy5sZW5ndGgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IDA7XG4gICAgfVxuXG4gICAgdmFyIGosIHc7XG4gICAgdmFyIG9mZiA9IDA7XG4gICAgaWYgKGVuZGlhbiA9PT0gJ2JlJykge1xuICAgICAgZm9yIChpID0gbnVtYmVyLmxlbmd0aCAtIDEsIGogPSAwOyBpID49IDA7IGkgLT0gMykge1xuICAgICAgICB3ID0gbnVtYmVyW2ldIHwgKG51bWJlcltpIC0gMV0gPDwgOCkgfCAobnVtYmVyW2kgLSAyXSA8PCAxNik7XG4gICAgICAgIHRoaXMud29yZHNbal0gfD0gKHcgPDwgb2ZmKSAmIDB4M2ZmZmZmZjtcbiAgICAgICAgdGhpcy53b3Jkc1tqICsgMV0gPSAodyA+Pj4gKDI2IC0gb2ZmKSkgJiAweDNmZmZmZmY7XG4gICAgICAgIG9mZiArPSAyNDtcbiAgICAgICAgaWYgKG9mZiA+PSAyNikge1xuICAgICAgICAgIG9mZiAtPSAyNjtcbiAgICAgICAgICBqKys7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGVuZGlhbiA9PT0gJ2xlJykge1xuICAgICAgZm9yIChpID0gMCwgaiA9IDA7IGkgPCBudW1iZXIubGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgICAgdyA9IG51bWJlcltpXSB8IChudW1iZXJbaSArIDFdIDw8IDgpIHwgKG51bWJlcltpICsgMl0gPDwgMTYpO1xuICAgICAgICB0aGlzLndvcmRzW2pdIHw9ICh3IDw8IG9mZikgJiAweDNmZmZmZmY7XG4gICAgICAgIHRoaXMud29yZHNbaiArIDFdID0gKHcgPj4+ICgyNiAtIG9mZikpICYgMHgzZmZmZmZmO1xuICAgICAgICBvZmYgKz0gMjQ7XG4gICAgICAgIGlmIChvZmYgPj0gMjYpIHtcbiAgICAgICAgICBvZmYgLT0gMjY7XG4gICAgICAgICAgaisrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgZnVuY3Rpb24gcGFyc2VIZXggKHN0ciwgc3RhcnQsIGVuZCkge1xuICAgIHZhciByID0gMDtcbiAgICB2YXIgbGVuID0gTWF0aC5taW4oc3RyLmxlbmd0aCwgZW5kKTtcbiAgICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBsZW47IGkrKykge1xuICAgICAgdmFyIGMgPSBzdHIuY2hhckNvZGVBdChpKSAtIDQ4O1xuXG4gICAgICByIDw8PSA0O1xuXG4gICAgICAvLyAnYScgLSAnZidcbiAgICAgIGlmIChjID49IDQ5ICYmIGMgPD0gNTQpIHtcbiAgICAgICAgciB8PSBjIC0gNDkgKyAweGE7XG5cbiAgICAgIC8vICdBJyAtICdGJ1xuICAgICAgfSBlbHNlIGlmIChjID49IDE3ICYmIGMgPD0gMjIpIHtcbiAgICAgICAgciB8PSBjIC0gMTcgKyAweGE7XG5cbiAgICAgIC8vICcwJyAtICc5J1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgciB8PSBjICYgMHhmO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcjtcbiAgfVxuXG4gIEJOLnByb3RvdHlwZS5fcGFyc2VIZXggPSBmdW5jdGlvbiBfcGFyc2VIZXggKG51bWJlciwgc3RhcnQpIHtcbiAgICAvLyBDcmVhdGUgcG9zc2libHkgYmlnZ2VyIGFycmF5IHRvIGVuc3VyZSB0aGF0IGl0IGZpdHMgdGhlIG51bWJlclxuICAgIHRoaXMubGVuZ3RoID0gTWF0aC5jZWlsKChudW1iZXIubGVuZ3RoIC0gc3RhcnQpIC8gNik7XG4gICAgdGhpcy53b3JkcyA9IG5ldyBBcnJheSh0aGlzLmxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLndvcmRzW2ldID0gMDtcbiAgICB9XG5cbiAgICB2YXIgaiwgdztcbiAgICAvLyBTY2FuIDI0LWJpdCBjaHVua3MgYW5kIGFkZCB0aGVtIHRvIHRoZSBudW1iZXJcbiAgICB2YXIgb2ZmID0gMDtcbiAgICBmb3IgKGkgPSBudW1iZXIubGVuZ3RoIC0gNiwgaiA9IDA7IGkgPj0gc3RhcnQ7IGkgLT0gNikge1xuICAgICAgdyA9IHBhcnNlSGV4KG51bWJlciwgaSwgaSArIDYpO1xuICAgICAgdGhpcy53b3Jkc1tqXSB8PSAodyA8PCBvZmYpICYgMHgzZmZmZmZmO1xuICAgICAgLy8gTk9URTogYDB4M2ZmZmZmYCBpcyBpbnRlbnRpb25hbCBoZXJlLCAyNmJpdHMgbWF4IHNoaWZ0ICsgMjRiaXQgaGV4IGxpbWJcbiAgICAgIHRoaXMud29yZHNbaiArIDFdIHw9IHcgPj4+ICgyNiAtIG9mZikgJiAweDNmZmZmZjtcbiAgICAgIG9mZiArPSAyNDtcbiAgICAgIGlmIChvZmYgPj0gMjYpIHtcbiAgICAgICAgb2ZmIC09IDI2O1xuICAgICAgICBqKys7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChpICsgNiAhPT0gc3RhcnQpIHtcbiAgICAgIHcgPSBwYXJzZUhleChudW1iZXIsIHN0YXJ0LCBpICsgNik7XG4gICAgICB0aGlzLndvcmRzW2pdIHw9ICh3IDw8IG9mZikgJiAweDNmZmZmZmY7XG4gICAgICB0aGlzLndvcmRzW2ogKyAxXSB8PSB3ID4+PiAoMjYgLSBvZmYpICYgMHgzZmZmZmY7XG4gICAgfVxuICAgIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBmdW5jdGlvbiBwYXJzZUJhc2UgKHN0ciwgc3RhcnQsIGVuZCwgbXVsKSB7XG4gICAgdmFyIHIgPSAwO1xuICAgIHZhciBsZW4gPSBNYXRoLm1pbihzdHIubGVuZ3RoLCBlbmQpO1xuICAgIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICB2YXIgYyA9IHN0ci5jaGFyQ29kZUF0KGkpIC0gNDg7XG5cbiAgICAgIHIgKj0gbXVsO1xuXG4gICAgICAvLyAnYSdcbiAgICAgIGlmIChjID49IDQ5KSB7XG4gICAgICAgIHIgKz0gYyAtIDQ5ICsgMHhhO1xuXG4gICAgICAvLyAnQSdcbiAgICAgIH0gZWxzZSBpZiAoYyA+PSAxNykge1xuICAgICAgICByICs9IGMgLSAxNyArIDB4YTtcblxuICAgICAgLy8gJzAnIC0gJzknXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByICs9IGM7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByO1xuICB9XG5cbiAgQk4ucHJvdG90eXBlLl9wYXJzZUJhc2UgPSBmdW5jdGlvbiBfcGFyc2VCYXNlIChudW1iZXIsIGJhc2UsIHN0YXJ0KSB7XG4gICAgLy8gSW5pdGlhbGl6ZSBhcyB6ZXJvXG4gICAgdGhpcy53b3JkcyA9IFsgMCBdO1xuICAgIHRoaXMubGVuZ3RoID0gMTtcblxuICAgIC8vIEZpbmQgbGVuZ3RoIG9mIGxpbWIgaW4gYmFzZVxuICAgIGZvciAodmFyIGxpbWJMZW4gPSAwLCBsaW1iUG93ID0gMTsgbGltYlBvdyA8PSAweDNmZmZmZmY7IGxpbWJQb3cgKj0gYmFzZSkge1xuICAgICAgbGltYkxlbisrO1xuICAgIH1cbiAgICBsaW1iTGVuLS07XG4gICAgbGltYlBvdyA9IChsaW1iUG93IC8gYmFzZSkgfCAwO1xuXG4gICAgdmFyIHRvdGFsID0gbnVtYmVyLmxlbmd0aCAtIHN0YXJ0O1xuICAgIHZhciBtb2QgPSB0b3RhbCAlIGxpbWJMZW47XG4gICAgdmFyIGVuZCA9IE1hdGgubWluKHRvdGFsLCB0b3RhbCAtIG1vZCkgKyBzdGFydDtcblxuICAgIHZhciB3b3JkID0gMDtcbiAgICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkgKz0gbGltYkxlbikge1xuICAgICAgd29yZCA9IHBhcnNlQmFzZShudW1iZXIsIGksIGkgKyBsaW1iTGVuLCBiYXNlKTtcblxuICAgICAgdGhpcy5pbXVsbihsaW1iUG93KTtcbiAgICAgIGlmICh0aGlzLndvcmRzWzBdICsgd29yZCA8IDB4NDAwMDAwMCkge1xuICAgICAgICB0aGlzLndvcmRzWzBdICs9IHdvcmQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9pYWRkbih3b3JkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobW9kICE9PSAwKSB7XG4gICAgICB2YXIgcG93ID0gMTtcbiAgICAgIHdvcmQgPSBwYXJzZUJhc2UobnVtYmVyLCBpLCBudW1iZXIubGVuZ3RoLCBiYXNlKTtcblxuICAgICAgZm9yIChpID0gMDsgaSA8IG1vZDsgaSsrKSB7XG4gICAgICAgIHBvdyAqPSBiYXNlO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmltdWxuKHBvdyk7XG4gICAgICBpZiAodGhpcy53b3Jkc1swXSArIHdvcmQgPCAweDQwMDAwMDApIHtcbiAgICAgICAgdGhpcy53b3Jkc1swXSArPSB3b3JkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5faWFkZG4od29yZCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gY29weSAoZGVzdCkge1xuICAgIGRlc3Qud29yZHMgPSBuZXcgQXJyYXkodGhpcy5sZW5ndGgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgZGVzdC53b3Jkc1tpXSA9IHRoaXMud29yZHNbaV07XG4gICAgfVxuICAgIGRlc3QubGVuZ3RoID0gdGhpcy5sZW5ndGg7XG4gICAgZGVzdC5uZWdhdGl2ZSA9IHRoaXMubmVnYXRpdmU7XG4gICAgZGVzdC5yZWQgPSB0aGlzLnJlZDtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiBjbG9uZSAoKSB7XG4gICAgdmFyIHIgPSBuZXcgQk4obnVsbCk7XG4gICAgdGhpcy5jb3B5KHIpO1xuICAgIHJldHVybiByO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5fZXhwYW5kID0gZnVuY3Rpb24gX2V4cGFuZCAoc2l6ZSkge1xuICAgIHdoaWxlICh0aGlzLmxlbmd0aCA8IHNpemUpIHtcbiAgICAgIHRoaXMud29yZHNbdGhpcy5sZW5ndGgrK10gPSAwO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvLyBSZW1vdmUgbGVhZGluZyBgMGAgZnJvbSBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLnN0cmlwID0gZnVuY3Rpb24gc3RyaXAgKCkge1xuICAgIHdoaWxlICh0aGlzLmxlbmd0aCA+IDEgJiYgdGhpcy53b3Jkc1t0aGlzLmxlbmd0aCAtIDFdID09PSAwKSB7XG4gICAgICB0aGlzLmxlbmd0aC0tO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fbm9ybVNpZ24oKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuX25vcm1TaWduID0gZnVuY3Rpb24gX25vcm1TaWduICgpIHtcbiAgICAvLyAtMCA9IDBcbiAgICBpZiAodGhpcy5sZW5ndGggPT09IDEgJiYgdGhpcy53b3Jkc1swXSA9PT0gMCkge1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDA7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCAoKSB7XG4gICAgcmV0dXJuICh0aGlzLnJlZCA/ICc8Qk4tUjogJyA6ICc8Qk46ICcpICsgdGhpcy50b1N0cmluZygxNikgKyAnPic7XG4gIH07XG5cbiAgLypcblxuICB2YXIgemVyb3MgPSBbXTtcbiAgdmFyIGdyb3VwU2l6ZXMgPSBbXTtcbiAgdmFyIGdyb3VwQmFzZXMgPSBbXTtcblxuICB2YXIgcyA9ICcnO1xuICB2YXIgaSA9IC0xO1xuICB3aGlsZSAoKytpIDwgQk4ud29yZFNpemUpIHtcbiAgICB6ZXJvc1tpXSA9IHM7XG4gICAgcyArPSAnMCc7XG4gIH1cbiAgZ3JvdXBTaXplc1swXSA9IDA7XG4gIGdyb3VwU2l6ZXNbMV0gPSAwO1xuICBncm91cEJhc2VzWzBdID0gMDtcbiAgZ3JvdXBCYXNlc1sxXSA9IDA7XG4gIHZhciBiYXNlID0gMiAtIDE7XG4gIHdoaWxlICgrK2Jhc2UgPCAzNiArIDEpIHtcbiAgICB2YXIgZ3JvdXBTaXplID0gMDtcbiAgICB2YXIgZ3JvdXBCYXNlID0gMTtcbiAgICB3aGlsZSAoZ3JvdXBCYXNlIDwgKDEgPDwgQk4ud29yZFNpemUpIC8gYmFzZSkge1xuICAgICAgZ3JvdXBCYXNlICo9IGJhc2U7XG4gICAgICBncm91cFNpemUgKz0gMTtcbiAgICB9XG4gICAgZ3JvdXBTaXplc1tiYXNlXSA9IGdyb3VwU2l6ZTtcbiAgICBncm91cEJhc2VzW2Jhc2VdID0gZ3JvdXBCYXNlO1xuICB9XG5cbiAgKi9cblxuICB2YXIgemVyb3MgPSBbXG4gICAgJycsXG4gICAgJzAnLFxuICAgICcwMCcsXG4gICAgJzAwMCcsXG4gICAgJzAwMDAnLFxuICAgICcwMDAwMCcsXG4gICAgJzAwMDAwMCcsXG4gICAgJzAwMDAwMDAnLFxuICAgICcwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAnLFxuICAgICcwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAnXG4gIF07XG5cbiAgdmFyIGdyb3VwU2l6ZXMgPSBbXG4gICAgMCwgMCxcbiAgICAyNSwgMTYsIDEyLCAxMSwgMTAsIDksIDgsXG4gICAgOCwgNywgNywgNywgNywgNiwgNixcbiAgICA2LCA2LCA2LCA2LCA2LCA1LCA1LFxuICAgIDUsIDUsIDUsIDUsIDUsIDUsIDUsXG4gICAgNSwgNSwgNSwgNSwgNSwgNSwgNVxuICBdO1xuXG4gIHZhciBncm91cEJhc2VzID0gW1xuICAgIDAsIDAsXG4gICAgMzM1NTQ0MzIsIDQzMDQ2NzIxLCAxNjc3NzIxNiwgNDg4MjgxMjUsIDYwNDY2MTc2LCA0MDM1MzYwNywgMTY3NzcyMTYsXG4gICAgNDMwNDY3MjEsIDEwMDAwMDAwLCAxOTQ4NzE3MSwgMzU4MzE4MDgsIDYyNzQ4NTE3LCA3NTI5NTM2LCAxMTM5MDYyNSxcbiAgICAxNjc3NzIxNiwgMjQxMzc1NjksIDM0MDEyMjI0LCA0NzA0NTg4MSwgNjQwMDAwMDAsIDQwODQxMDEsIDUxNTM2MzIsXG4gICAgNjQzNjM0MywgNzk2MjYyNCwgOTc2NTYyNSwgMTE4ODEzNzYsIDE0MzQ4OTA3LCAxNzIxMDM2OCwgMjA1MTExNDksXG4gICAgMjQzMDAwMDAsIDI4NjI5MTUxLCAzMzU1NDQzMiwgMzkxMzUzOTMsIDQ1NDM1NDI0LCA1MjUyMTg3NSwgNjA0NjYxNzZcbiAgXTtcblxuICBCTi5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyAoYmFzZSwgcGFkZGluZykge1xuICAgIGJhc2UgPSBiYXNlIHx8IDEwO1xuICAgIHBhZGRpbmcgPSBwYWRkaW5nIHwgMCB8fCAxO1xuXG4gICAgdmFyIG91dDtcbiAgICBpZiAoYmFzZSA9PT0gMTYgfHwgYmFzZSA9PT0gJ2hleCcpIHtcbiAgICAgIG91dCA9ICcnO1xuICAgICAgdmFyIG9mZiA9IDA7XG4gICAgICB2YXIgY2FycnkgPSAwO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciB3ID0gdGhpcy53b3Jkc1tpXTtcbiAgICAgICAgdmFyIHdvcmQgPSAoKCh3IDw8IG9mZikgfCBjYXJyeSkgJiAweGZmZmZmZikudG9TdHJpbmcoMTYpO1xuICAgICAgICBjYXJyeSA9ICh3ID4+PiAoMjQgLSBvZmYpKSAmIDB4ZmZmZmZmO1xuICAgICAgICBpZiAoY2FycnkgIT09IDAgfHwgaSAhPT0gdGhpcy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgb3V0ID0gemVyb3NbNiAtIHdvcmQubGVuZ3RoXSArIHdvcmQgKyBvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb3V0ID0gd29yZCArIG91dDtcbiAgICAgICAgfVxuICAgICAgICBvZmYgKz0gMjtcbiAgICAgICAgaWYgKG9mZiA+PSAyNikge1xuICAgICAgICAgIG9mZiAtPSAyNjtcbiAgICAgICAgICBpLS07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChjYXJyeSAhPT0gMCkge1xuICAgICAgICBvdXQgPSBjYXJyeS50b1N0cmluZygxNikgKyBvdXQ7XG4gICAgICB9XG4gICAgICB3aGlsZSAob3V0Lmxlbmd0aCAlIHBhZGRpbmcgIT09IDApIHtcbiAgICAgICAgb3V0ID0gJzAnICsgb3V0O1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDApIHtcbiAgICAgICAgb3V0ID0gJy0nICsgb3V0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG91dDtcbiAgICB9XG5cbiAgICBpZiAoYmFzZSA9PT0gKGJhc2UgfCAwKSAmJiBiYXNlID49IDIgJiYgYmFzZSA8PSAzNikge1xuICAgICAgLy8gdmFyIGdyb3VwU2l6ZSA9IE1hdGguZmxvb3IoQk4ud29yZFNpemUgKiBNYXRoLkxOMiAvIE1hdGgubG9nKGJhc2UpKTtcbiAgICAgIHZhciBncm91cFNpemUgPSBncm91cFNpemVzW2Jhc2VdO1xuICAgICAgLy8gdmFyIGdyb3VwQmFzZSA9IE1hdGgucG93KGJhc2UsIGdyb3VwU2l6ZSk7XG4gICAgICB2YXIgZ3JvdXBCYXNlID0gZ3JvdXBCYXNlc1tiYXNlXTtcbiAgICAgIG91dCA9ICcnO1xuICAgICAgdmFyIGMgPSB0aGlzLmNsb25lKCk7XG4gICAgICBjLm5lZ2F0aXZlID0gMDtcbiAgICAgIHdoaWxlICghYy5pc1plcm8oKSkge1xuICAgICAgICB2YXIgciA9IGMubW9kbihncm91cEJhc2UpLnRvU3RyaW5nKGJhc2UpO1xuICAgICAgICBjID0gYy5pZGl2bihncm91cEJhc2UpO1xuXG4gICAgICAgIGlmICghYy5pc1plcm8oKSkge1xuICAgICAgICAgIG91dCA9IHplcm9zW2dyb3VwU2l6ZSAtIHIubGVuZ3RoXSArIHIgKyBvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb3V0ID0gciArIG91dDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHRoaXMuaXNaZXJvKCkpIHtcbiAgICAgICAgb3V0ID0gJzAnICsgb3V0O1xuICAgICAgfVxuICAgICAgd2hpbGUgKG91dC5sZW5ndGggJSBwYWRkaW5nICE9PSAwKSB7XG4gICAgICAgIG91dCA9ICcwJyArIG91dDtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICAgIG91dCA9ICctJyArIG91dDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvdXQ7XG4gICAgfVxuXG4gICAgYXNzZXJ0KGZhbHNlLCAnQmFzZSBzaG91bGQgYmUgYmV0d2VlbiAyIGFuZCAzNicpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS50b051bWJlciA9IGZ1bmN0aW9uIHRvTnVtYmVyICgpIHtcbiAgICB2YXIgcmV0ID0gdGhpcy53b3Jkc1swXTtcbiAgICBpZiAodGhpcy5sZW5ndGggPT09IDIpIHtcbiAgICAgIHJldCArPSB0aGlzLndvcmRzWzFdICogMHg0MDAwMDAwO1xuICAgIH0gZWxzZSBpZiAodGhpcy5sZW5ndGggPT09IDMgJiYgdGhpcy53b3Jkc1syXSA9PT0gMHgwMSkge1xuICAgICAgLy8gTk9URTogYXQgdGhpcyBzdGFnZSBpdCBpcyBrbm93biB0aGF0IHRoZSB0b3AgYml0IGlzIHNldFxuICAgICAgcmV0ICs9IDB4MTAwMDAwMDAwMDAwMDAgKyAodGhpcy53b3Jkc1sxXSAqIDB4NDAwMDAwMCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmxlbmd0aCA+IDIpIHtcbiAgICAgIGFzc2VydChmYWxzZSwgJ051bWJlciBjYW4gb25seSBzYWZlbHkgc3RvcmUgdXAgdG8gNTMgYml0cycpO1xuICAgIH1cbiAgICByZXR1cm4gKHRoaXMubmVnYXRpdmUgIT09IDApID8gLXJldCA6IHJldDtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgICByZXR1cm4gdGhpcy50b1N0cmluZygxNik7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnRvQnVmZmVyID0gZnVuY3Rpb24gdG9CdWZmZXIgKGVuZGlhbiwgbGVuZ3RoKSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBCdWZmZXIgIT09ICd1bmRlZmluZWQnKTtcbiAgICByZXR1cm4gdGhpcy50b0FycmF5TGlrZShCdWZmZXIsIGVuZGlhbiwgbGVuZ3RoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUudG9BcnJheSA9IGZ1bmN0aW9uIHRvQXJyYXkgKGVuZGlhbiwgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIHRoaXMudG9BcnJheUxpa2UoQXJyYXksIGVuZGlhbiwgbGVuZ3RoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUudG9BcnJheUxpa2UgPSBmdW5jdGlvbiB0b0FycmF5TGlrZSAoQXJyYXlUeXBlLCBlbmRpYW4sIGxlbmd0aCkge1xuICAgIHZhciBieXRlTGVuZ3RoID0gdGhpcy5ieXRlTGVuZ3RoKCk7XG4gICAgdmFyIHJlcUxlbmd0aCA9IGxlbmd0aCB8fCBNYXRoLm1heCgxLCBieXRlTGVuZ3RoKTtcbiAgICBhc3NlcnQoYnl0ZUxlbmd0aCA8PSByZXFMZW5ndGgsICdieXRlIGFycmF5IGxvbmdlciB0aGFuIGRlc2lyZWQgbGVuZ3RoJyk7XG4gICAgYXNzZXJ0KHJlcUxlbmd0aCA+IDAsICdSZXF1ZXN0ZWQgYXJyYXkgbGVuZ3RoIDw9IDAnKTtcblxuICAgIHRoaXMuc3RyaXAoKTtcbiAgICB2YXIgbGl0dGxlRW5kaWFuID0gZW5kaWFuID09PSAnbGUnO1xuICAgIHZhciByZXMgPSBuZXcgQXJyYXlUeXBlKHJlcUxlbmd0aCk7XG5cbiAgICB2YXIgYiwgaTtcbiAgICB2YXIgcSA9IHRoaXMuY2xvbmUoKTtcbiAgICBpZiAoIWxpdHRsZUVuZGlhbikge1xuICAgICAgLy8gQXNzdW1lIGJpZy1lbmRpYW5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCByZXFMZW5ndGggLSBieXRlTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcmVzW2ldID0gMDtcbiAgICAgIH1cblxuICAgICAgZm9yIChpID0gMDsgIXEuaXNaZXJvKCk7IGkrKykge1xuICAgICAgICBiID0gcS5hbmRsbigweGZmKTtcbiAgICAgICAgcS5pdXNocm4oOCk7XG5cbiAgICAgICAgcmVzW3JlcUxlbmd0aCAtIGkgLSAxXSA9IGI7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAoaSA9IDA7ICFxLmlzWmVybygpOyBpKyspIHtcbiAgICAgICAgYiA9IHEuYW5kbG4oMHhmZik7XG4gICAgICAgIHEuaXVzaHJuKDgpO1xuXG4gICAgICAgIHJlc1tpXSA9IGI7XG4gICAgICB9XG5cbiAgICAgIGZvciAoOyBpIDwgcmVxTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcmVzW2ldID0gMDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIGlmIChNYXRoLmNsejMyKSB7XG4gICAgQk4ucHJvdG90eXBlLl9jb3VudEJpdHMgPSBmdW5jdGlvbiBfY291bnRCaXRzICh3KSB7XG4gICAgICByZXR1cm4gMzIgLSBNYXRoLmNsejMyKHcpO1xuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgQk4ucHJvdG90eXBlLl9jb3VudEJpdHMgPSBmdW5jdGlvbiBfY291bnRCaXRzICh3KSB7XG4gICAgICB2YXIgdCA9IHc7XG4gICAgICB2YXIgciA9IDA7XG4gICAgICBpZiAodCA+PSAweDEwMDApIHtcbiAgICAgICAgciArPSAxMztcbiAgICAgICAgdCA+Pj49IDEzO1xuICAgICAgfVxuICAgICAgaWYgKHQgPj0gMHg0MCkge1xuICAgICAgICByICs9IDc7XG4gICAgICAgIHQgPj4+PSA3O1xuICAgICAgfVxuICAgICAgaWYgKHQgPj0gMHg4KSB7XG4gICAgICAgIHIgKz0gNDtcbiAgICAgICAgdCA+Pj49IDQ7XG4gICAgICB9XG4gICAgICBpZiAodCA+PSAweDAyKSB7XG4gICAgICAgIHIgKz0gMjtcbiAgICAgICAgdCA+Pj49IDI7XG4gICAgICB9XG4gICAgICByZXR1cm4gciArIHQ7XG4gICAgfTtcbiAgfVxuXG4gIEJOLnByb3RvdHlwZS5femVyb0JpdHMgPSBmdW5jdGlvbiBfemVyb0JpdHMgKHcpIHtcbiAgICAvLyBTaG9ydC1jdXRcbiAgICBpZiAodyA9PT0gMCkgcmV0dXJuIDI2O1xuXG4gICAgdmFyIHQgPSB3O1xuICAgIHZhciByID0gMDtcbiAgICBpZiAoKHQgJiAweDFmZmYpID09PSAwKSB7XG4gICAgICByICs9IDEzO1xuICAgICAgdCA+Pj49IDEzO1xuICAgIH1cbiAgICBpZiAoKHQgJiAweDdmKSA9PT0gMCkge1xuICAgICAgciArPSA3O1xuICAgICAgdCA+Pj49IDc7XG4gICAgfVxuICAgIGlmICgodCAmIDB4ZikgPT09IDApIHtcbiAgICAgIHIgKz0gNDtcbiAgICAgIHQgPj4+PSA0O1xuICAgIH1cbiAgICBpZiAoKHQgJiAweDMpID09PSAwKSB7XG4gICAgICByICs9IDI7XG4gICAgICB0ID4+Pj0gMjtcbiAgICB9XG4gICAgaWYgKCh0ICYgMHgxKSA9PT0gMCkge1xuICAgICAgcisrO1xuICAgIH1cbiAgICByZXR1cm4gcjtcbiAgfTtcblxuICAvLyBSZXR1cm4gbnVtYmVyIG9mIHVzZWQgYml0cyBpbiBhIEJOXG4gIEJOLnByb3RvdHlwZS5iaXRMZW5ndGggPSBmdW5jdGlvbiBiaXRMZW5ndGggKCkge1xuICAgIHZhciB3ID0gdGhpcy53b3Jkc1t0aGlzLmxlbmd0aCAtIDFdO1xuICAgIHZhciBoaSA9IHRoaXMuX2NvdW50Qml0cyh3KTtcbiAgICByZXR1cm4gKHRoaXMubGVuZ3RoIC0gMSkgKiAyNiArIGhpO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHRvQml0QXJyYXkgKG51bSkge1xuICAgIHZhciB3ID0gbmV3IEFycmF5KG51bS5iaXRMZW5ndGgoKSk7XG5cbiAgICBmb3IgKHZhciBiaXQgPSAwOyBiaXQgPCB3Lmxlbmd0aDsgYml0KyspIHtcbiAgICAgIHZhciBvZmYgPSAoYml0IC8gMjYpIHwgMDtcbiAgICAgIHZhciB3Yml0ID0gYml0ICUgMjY7XG5cbiAgICAgIHdbYml0XSA9IChudW0ud29yZHNbb2ZmXSAmICgxIDw8IHdiaXQpKSA+Pj4gd2JpdDtcbiAgICB9XG5cbiAgICByZXR1cm4gdztcbiAgfVxuXG4gIC8vIE51bWJlciBvZiB0cmFpbGluZyB6ZXJvIGJpdHNcbiAgQk4ucHJvdG90eXBlLnplcm9CaXRzID0gZnVuY3Rpb24gemVyb0JpdHMgKCkge1xuICAgIGlmICh0aGlzLmlzWmVybygpKSByZXR1cm4gMDtcblxuICAgIHZhciByID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBiID0gdGhpcy5femVyb0JpdHModGhpcy53b3Jkc1tpXSk7XG4gICAgICByICs9IGI7XG4gICAgICBpZiAoYiAhPT0gMjYpIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gcjtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuYnl0ZUxlbmd0aCA9IGZ1bmN0aW9uIGJ5dGVMZW5ndGggKCkge1xuICAgIHJldHVybiBNYXRoLmNlaWwodGhpcy5iaXRMZW5ndGgoKSAvIDgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS50b1R3b3MgPSBmdW5jdGlvbiB0b1R3b3MgKHdpZHRoKSB7XG4gICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIHJldHVybiB0aGlzLmFicygpLmlub3RuKHdpZHRoKS5pYWRkbigxKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuZnJvbVR3b3MgPSBmdW5jdGlvbiBmcm9tVHdvcyAod2lkdGgpIHtcbiAgICBpZiAodGhpcy50ZXN0bih3aWR0aCAtIDEpKSB7XG4gICAgICByZXR1cm4gdGhpcy5ub3RuKHdpZHRoKS5pYWRkbigxKS5pbmVnKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNsb25lKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmlzTmVnID0gZnVuY3Rpb24gaXNOZWcgKCkge1xuICAgIHJldHVybiB0aGlzLm5lZ2F0aXZlICE9PSAwO1xuICB9O1xuXG4gIC8vIFJldHVybiBuZWdhdGl2ZSBjbG9uZSBvZiBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLm5lZyA9IGZ1bmN0aW9uIG5lZyAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pbmVnKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmluZWcgPSBmdW5jdGlvbiBpbmVnICgpIHtcbiAgICBpZiAoIXRoaXMuaXNaZXJvKCkpIHtcbiAgICAgIHRoaXMubmVnYXRpdmUgXj0gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvLyBPciBgbnVtYCB3aXRoIGB0aGlzYCBpbi1wbGFjZVxuICBCTi5wcm90b3R5cGUuaXVvciA9IGZ1bmN0aW9uIGl1b3IgKG51bSkge1xuICAgIHdoaWxlICh0aGlzLmxlbmd0aCA8IG51bS5sZW5ndGgpIHtcbiAgICAgIHRoaXMud29yZHNbdGhpcy5sZW5ndGgrK10gPSAwO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbnVtLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLndvcmRzW2ldID0gdGhpcy53b3Jkc1tpXSB8IG51bS53b3Jkc1tpXTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5pb3IgPSBmdW5jdGlvbiBpb3IgKG51bSkge1xuICAgIGFzc2VydCgodGhpcy5uZWdhdGl2ZSB8IG51bS5uZWdhdGl2ZSkgPT09IDApO1xuICAgIHJldHVybiB0aGlzLml1b3IobnVtKTtcbiAgfTtcblxuICAvLyBPciBgbnVtYCB3aXRoIGB0aGlzYFxuICBCTi5wcm90b3R5cGUub3IgPSBmdW5jdGlvbiBvciAobnVtKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkgcmV0dXJuIHRoaXMuY2xvbmUoKS5pb3IobnVtKTtcbiAgICByZXR1cm4gbnVtLmNsb25lKCkuaW9yKHRoaXMpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS51b3IgPSBmdW5jdGlvbiB1b3IgKG51bSkge1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IG51bS5sZW5ndGgpIHJldHVybiB0aGlzLmNsb25lKCkuaXVvcihudW0pO1xuICAgIHJldHVybiBudW0uY2xvbmUoKS5pdW9yKHRoaXMpO1xuICB9O1xuXG4gIC8vIEFuZCBgbnVtYCB3aXRoIGB0aGlzYCBpbi1wbGFjZVxuICBCTi5wcm90b3R5cGUuaXVhbmQgPSBmdW5jdGlvbiBpdWFuZCAobnVtKSB7XG4gICAgLy8gYiA9IG1pbi1sZW5ndGgobnVtLCB0aGlzKVxuICAgIHZhciBiO1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IG51bS5sZW5ndGgpIHtcbiAgICAgIGIgPSBudW07XG4gICAgfSBlbHNlIHtcbiAgICAgIGIgPSB0aGlzO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYi5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IHRoaXMud29yZHNbaV0gJiBudW0ud29yZHNbaV07XG4gICAgfVxuXG4gICAgdGhpcy5sZW5ndGggPSBiLmxlbmd0aDtcblxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmlhbmQgPSBmdW5jdGlvbiBpYW5kIChudW0pIHtcbiAgICBhc3NlcnQoKHRoaXMubmVnYXRpdmUgfCBudW0ubmVnYXRpdmUpID09PSAwKTtcbiAgICByZXR1cm4gdGhpcy5pdWFuZChudW0pO1xuICB9O1xuXG4gIC8vIEFuZCBgbnVtYCB3aXRoIGB0aGlzYFxuICBCTi5wcm90b3R5cGUuYW5kID0gZnVuY3Rpb24gYW5kIChudW0pIHtcbiAgICBpZiAodGhpcy5sZW5ndGggPiBudW0ubGVuZ3RoKSByZXR1cm4gdGhpcy5jbG9uZSgpLmlhbmQobnVtKTtcbiAgICByZXR1cm4gbnVtLmNsb25lKCkuaWFuZCh0aGlzKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUudWFuZCA9IGZ1bmN0aW9uIHVhbmQgKG51bSkge1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IG51bS5sZW5ndGgpIHJldHVybiB0aGlzLmNsb25lKCkuaXVhbmQobnVtKTtcbiAgICByZXR1cm4gbnVtLmNsb25lKCkuaXVhbmQodGhpcyk7XG4gIH07XG5cbiAgLy8gWG9yIGBudW1gIHdpdGggYHRoaXNgIGluLXBsYWNlXG4gIEJOLnByb3RvdHlwZS5pdXhvciA9IGZ1bmN0aW9uIGl1eG9yIChudW0pIHtcbiAgICAvLyBhLmxlbmd0aCA+IGIubGVuZ3RoXG4gICAgdmFyIGE7XG4gICAgdmFyIGI7XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkge1xuICAgICAgYSA9IHRoaXM7XG4gICAgICBiID0gbnVtO1xuICAgIH0gZWxzZSB7XG4gICAgICBhID0gbnVtO1xuICAgICAgYiA9IHRoaXM7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBiLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLndvcmRzW2ldID0gYS53b3Jkc1tpXSBeIGIud29yZHNbaV07XG4gICAgfVxuXG4gICAgaWYgKHRoaXMgIT09IGEpIHtcbiAgICAgIGZvciAoOyBpIDwgYS5sZW5ndGg7IGkrKykge1xuICAgICAgICB0aGlzLndvcmRzW2ldID0gYS53b3Jkc1tpXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmxlbmd0aCA9IGEubGVuZ3RoO1xuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaXhvciA9IGZ1bmN0aW9uIGl4b3IgKG51bSkge1xuICAgIGFzc2VydCgodGhpcy5uZWdhdGl2ZSB8IG51bS5uZWdhdGl2ZSkgPT09IDApO1xuICAgIHJldHVybiB0aGlzLml1eG9yKG51bSk7XG4gIH07XG5cbiAgLy8gWG9yIGBudW1gIHdpdGggYHRoaXNgXG4gIEJOLnByb3RvdHlwZS54b3IgPSBmdW5jdGlvbiB4b3IgKG51bSkge1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IG51bS5sZW5ndGgpIHJldHVybiB0aGlzLmNsb25lKCkuaXhvcihudW0pO1xuICAgIHJldHVybiBudW0uY2xvbmUoKS5peG9yKHRoaXMpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS51eG9yID0gZnVuY3Rpb24gdXhvciAobnVtKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkgcmV0dXJuIHRoaXMuY2xvbmUoKS5pdXhvcihudW0pO1xuICAgIHJldHVybiBudW0uY2xvbmUoKS5pdXhvcih0aGlzKTtcbiAgfTtcblxuICAvLyBOb3QgYGB0aGlzYGAgd2l0aCBgYHdpZHRoYGAgYml0d2lkdGhcbiAgQk4ucHJvdG90eXBlLmlub3RuID0gZnVuY3Rpb24gaW5vdG4gKHdpZHRoKSB7XG4gICAgYXNzZXJ0KHR5cGVvZiB3aWR0aCA9PT0gJ251bWJlcicgJiYgd2lkdGggPj0gMCk7XG5cbiAgICB2YXIgYnl0ZXNOZWVkZWQgPSBNYXRoLmNlaWwod2lkdGggLyAyNikgfCAwO1xuICAgIHZhciBiaXRzTGVmdCA9IHdpZHRoICUgMjY7XG5cbiAgICAvLyBFeHRlbmQgdGhlIGJ1ZmZlciB3aXRoIGxlYWRpbmcgemVyb2VzXG4gICAgdGhpcy5fZXhwYW5kKGJ5dGVzTmVlZGVkKTtcblxuICAgIGlmIChiaXRzTGVmdCA+IDApIHtcbiAgICAgIGJ5dGVzTmVlZGVkLS07XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIGNvbXBsZXRlIHdvcmRzXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlc05lZWRlZDsgaSsrKSB7XG4gICAgICB0aGlzLndvcmRzW2ldID0gfnRoaXMud29yZHNbaV0gJiAweDNmZmZmZmY7XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIHRoZSByZXNpZHVlXG4gICAgaWYgKGJpdHNMZWZ0ID4gMCkge1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IH50aGlzLndvcmRzW2ldICYgKDB4M2ZmZmZmZiA+PiAoMjYgLSBiaXRzTGVmdCkpO1xuICAgIH1cblxuICAgIC8vIEFuZCByZW1vdmUgbGVhZGluZyB6ZXJvZXNcbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5ub3RuID0gZnVuY3Rpb24gbm90biAod2lkdGgpIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLmlub3RuKHdpZHRoKTtcbiAgfTtcblxuICAvLyBTZXQgYGJpdGAgb2YgYHRoaXNgXG4gIEJOLnByb3RvdHlwZS5zZXRuID0gZnVuY3Rpb24gc2V0biAoYml0LCB2YWwpIHtcbiAgICBhc3NlcnQodHlwZW9mIGJpdCA9PT0gJ251bWJlcicgJiYgYml0ID49IDApO1xuXG4gICAgdmFyIG9mZiA9IChiaXQgLyAyNikgfCAwO1xuICAgIHZhciB3Yml0ID0gYml0ICUgMjY7XG5cbiAgICB0aGlzLl9leHBhbmQob2ZmICsgMSk7XG5cbiAgICBpZiAodmFsKSB7XG4gICAgICB0aGlzLndvcmRzW29mZl0gPSB0aGlzLndvcmRzW29mZl0gfCAoMSA8PCB3Yml0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy53b3Jkc1tvZmZdID0gdGhpcy53b3Jkc1tvZmZdICYgfigxIDw8IHdiaXQpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgLy8gQWRkIGBudW1gIHRvIGB0aGlzYCBpbi1wbGFjZVxuICBCTi5wcm90b3R5cGUuaWFkZCA9IGZ1bmN0aW9uIGlhZGQgKG51bSkge1xuICAgIHZhciByO1xuXG4gICAgLy8gbmVnYXRpdmUgKyBwb3NpdGl2ZVxuICAgIGlmICh0aGlzLm5lZ2F0aXZlICE9PSAwICYmIG51bS5uZWdhdGl2ZSA9PT0gMCkge1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDA7XG4gICAgICByID0gdGhpcy5pc3ViKG51bSk7XG4gICAgICB0aGlzLm5lZ2F0aXZlIF49IDE7XG4gICAgICByZXR1cm4gdGhpcy5fbm9ybVNpZ24oKTtcblxuICAgIC8vIHBvc2l0aXZlICsgbmVnYXRpdmVcbiAgICB9IGVsc2UgaWYgKHRoaXMubmVnYXRpdmUgPT09IDAgJiYgbnVtLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICBudW0ubmVnYXRpdmUgPSAwO1xuICAgICAgciA9IHRoaXMuaXN1YihudW0pO1xuICAgICAgbnVtLm5lZ2F0aXZlID0gMTtcbiAgICAgIHJldHVybiByLl9ub3JtU2lnbigpO1xuICAgIH1cblxuICAgIC8vIGEubGVuZ3RoID4gYi5sZW5ndGhcbiAgICB2YXIgYSwgYjtcbiAgICBpZiAodGhpcy5sZW5ndGggPiBudW0ubGVuZ3RoKSB7XG4gICAgICBhID0gdGhpcztcbiAgICAgIGIgPSBudW07XG4gICAgfSBlbHNlIHtcbiAgICAgIGEgPSBudW07XG4gICAgICBiID0gdGhpcztcbiAgICB9XG5cbiAgICB2YXIgY2FycnkgPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYi5sZW5ndGg7IGkrKykge1xuICAgICAgciA9IChhLndvcmRzW2ldIHwgMCkgKyAoYi53b3Jkc1tpXSB8IDApICsgY2Fycnk7XG4gICAgICB0aGlzLndvcmRzW2ldID0gciAmIDB4M2ZmZmZmZjtcbiAgICAgIGNhcnJ5ID0gciA+Pj4gMjY7XG4gICAgfVxuICAgIGZvciAoOyBjYXJyeSAhPT0gMCAmJiBpIDwgYS5sZW5ndGg7IGkrKykge1xuICAgICAgciA9IChhLndvcmRzW2ldIHwgMCkgKyBjYXJyeTtcbiAgICAgIHRoaXMud29yZHNbaV0gPSByICYgMHgzZmZmZmZmO1xuICAgICAgY2FycnkgPSByID4+PiAyNjtcbiAgICB9XG5cbiAgICB0aGlzLmxlbmd0aCA9IGEubGVuZ3RoO1xuICAgIGlmIChjYXJyeSAhPT0gMCkge1xuICAgICAgdGhpcy53b3Jkc1t0aGlzLmxlbmd0aF0gPSBjYXJyeTtcbiAgICAgIHRoaXMubGVuZ3RoKys7XG4gICAgLy8gQ29weSB0aGUgcmVzdCBvZiB0aGUgd29yZHNcbiAgICB9IGVsc2UgaWYgKGEgIT09IHRoaXMpIHtcbiAgICAgIGZvciAoOyBpIDwgYS5sZW5ndGg7IGkrKykge1xuICAgICAgICB0aGlzLndvcmRzW2ldID0gYS53b3Jkc1tpXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvLyBBZGQgYG51bWAgdG8gYHRoaXNgXG4gIEJOLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiBhZGQgKG51bSkge1xuICAgIHZhciByZXM7XG4gICAgaWYgKG51bS5uZWdhdGl2ZSAhPT0gMCAmJiB0aGlzLm5lZ2F0aXZlID09PSAwKSB7XG4gICAgICBudW0ubmVnYXRpdmUgPSAwO1xuICAgICAgcmVzID0gdGhpcy5zdWIobnVtKTtcbiAgICAgIG51bS5uZWdhdGl2ZSBePSAxO1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9IGVsc2UgaWYgKG51bS5uZWdhdGl2ZSA9PT0gMCAmJiB0aGlzLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMDtcbiAgICAgIHJlcyA9IG51bS5zdWIodGhpcyk7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMTtcbiAgICAgIHJldHVybiByZXM7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkgcmV0dXJuIHRoaXMuY2xvbmUoKS5pYWRkKG51bSk7XG5cbiAgICByZXR1cm4gbnVtLmNsb25lKCkuaWFkZCh0aGlzKTtcbiAgfTtcblxuICAvLyBTdWJ0cmFjdCBgbnVtYCBmcm9tIGB0aGlzYCBpbi1wbGFjZVxuICBCTi5wcm90b3R5cGUuaXN1YiA9IGZ1bmN0aW9uIGlzdWIgKG51bSkge1xuICAgIC8vIHRoaXMgLSAoLW51bSkgPSB0aGlzICsgbnVtXG4gICAgaWYgKG51bS5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgbnVtLm5lZ2F0aXZlID0gMDtcbiAgICAgIHZhciByID0gdGhpcy5pYWRkKG51bSk7XG4gICAgICBudW0ubmVnYXRpdmUgPSAxO1xuICAgICAgcmV0dXJuIHIuX25vcm1TaWduKCk7XG5cbiAgICAvLyAtdGhpcyAtIG51bSA9IC0odGhpcyArIG51bSlcbiAgICB9IGVsc2UgaWYgKHRoaXMubmVnYXRpdmUgIT09IDApIHtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuICAgICAgdGhpcy5pYWRkKG51bSk7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMTtcbiAgICAgIHJldHVybiB0aGlzLl9ub3JtU2lnbigpO1xuICAgIH1cblxuICAgIC8vIEF0IHRoaXMgcG9pbnQgYm90aCBudW1iZXJzIGFyZSBwb3NpdGl2ZVxuICAgIHZhciBjbXAgPSB0aGlzLmNtcChudW0pO1xuXG4gICAgLy8gT3B0aW1pemF0aW9uIC0gemVyb2lmeVxuICAgIGlmIChjbXAgPT09IDApIHtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAwO1xuICAgICAgdGhpcy5sZW5ndGggPSAxO1xuICAgICAgdGhpcy53b3Jkc1swXSA9IDA7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvLyBhID4gYlxuICAgIHZhciBhLCBiO1xuICAgIGlmIChjbXAgPiAwKSB7XG4gICAgICBhID0gdGhpcztcbiAgICAgIGIgPSBudW07XG4gICAgfSBlbHNlIHtcbiAgICAgIGEgPSBudW07XG4gICAgICBiID0gdGhpcztcbiAgICB9XG5cbiAgICB2YXIgY2FycnkgPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYi5sZW5ndGg7IGkrKykge1xuICAgICAgciA9IChhLndvcmRzW2ldIHwgMCkgLSAoYi53b3Jkc1tpXSB8IDApICsgY2Fycnk7XG4gICAgICBjYXJyeSA9IHIgPj4gMjY7XG4gICAgICB0aGlzLndvcmRzW2ldID0gciAmIDB4M2ZmZmZmZjtcbiAgICB9XG4gICAgZm9yICg7IGNhcnJ5ICE9PSAwICYmIGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgICByID0gKGEud29yZHNbaV0gfCAwKSArIGNhcnJ5O1xuICAgICAgY2FycnkgPSByID4+IDI2O1xuICAgICAgdGhpcy53b3Jkc1tpXSA9IHIgJiAweDNmZmZmZmY7XG4gICAgfVxuXG4gICAgLy8gQ29weSByZXN0IG9mIHRoZSB3b3Jkc1xuICAgIGlmIChjYXJyeSA9PT0gMCAmJiBpIDwgYS5sZW5ndGggJiYgYSAhPT0gdGhpcykge1xuICAgICAgZm9yICg7IGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMud29yZHNbaV0gPSBhLndvcmRzW2ldO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMubGVuZ3RoID0gTWF0aC5tYXgodGhpcy5sZW5ndGgsIGkpO1xuXG4gICAgaWYgKGEgIT09IHRoaXMpIHtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAxO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnN0cmlwKCk7XG4gIH07XG5cbiAgLy8gU3VidHJhY3QgYG51bWAgZnJvbSBgdGhpc2BcbiAgQk4ucHJvdG90eXBlLnN1YiA9IGZ1bmN0aW9uIHN1YiAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pc3ViKG51bSk7XG4gIH07XG5cbiAgZnVuY3Rpb24gc21hbGxNdWxUbyAoc2VsZiwgbnVtLCBvdXQpIHtcbiAgICBvdXQubmVnYXRpdmUgPSBudW0ubmVnYXRpdmUgXiBzZWxmLm5lZ2F0aXZlO1xuICAgIHZhciBsZW4gPSAoc2VsZi5sZW5ndGggKyBudW0ubGVuZ3RoKSB8IDA7XG4gICAgb3V0Lmxlbmd0aCA9IGxlbjtcbiAgICBsZW4gPSAobGVuIC0gMSkgfCAwO1xuXG4gICAgLy8gUGVlbCBvbmUgaXRlcmF0aW9uIChjb21waWxlciBjYW4ndCBkbyBpdCwgYmVjYXVzZSBvZiBjb2RlIGNvbXBsZXhpdHkpXG4gICAgdmFyIGEgPSBzZWxmLndvcmRzWzBdIHwgMDtcbiAgICB2YXIgYiA9IG51bS53b3Jkc1swXSB8IDA7XG4gICAgdmFyIHIgPSBhICogYjtcblxuICAgIHZhciBsbyA9IHIgJiAweDNmZmZmZmY7XG4gICAgdmFyIGNhcnJ5ID0gKHIgLyAweDQwMDAwMDApIHwgMDtcbiAgICBvdXQud29yZHNbMF0gPSBsbztcblxuICAgIGZvciAodmFyIGsgPSAxOyBrIDwgbGVuOyBrKyspIHtcbiAgICAgIC8vIFN1bSBhbGwgd29yZHMgd2l0aCB0aGUgc2FtZSBgaSArIGogPSBrYCBhbmQgYWNjdW11bGF0ZSBgbmNhcnJ5YCxcbiAgICAgIC8vIG5vdGUgdGhhdCBuY2FycnkgY291bGQgYmUgPj0gMHgzZmZmZmZmXG4gICAgICB2YXIgbmNhcnJ5ID0gY2FycnkgPj4+IDI2O1xuICAgICAgdmFyIHJ3b3JkID0gY2FycnkgJiAweDNmZmZmZmY7XG4gICAgICB2YXIgbWF4SiA9IE1hdGgubWluKGssIG51bS5sZW5ndGggLSAxKTtcbiAgICAgIGZvciAodmFyIGogPSBNYXRoLm1heCgwLCBrIC0gc2VsZi5sZW5ndGggKyAxKTsgaiA8PSBtYXhKOyBqKyspIHtcbiAgICAgICAgdmFyIGkgPSAoayAtIGopIHwgMDtcbiAgICAgICAgYSA9IHNlbGYud29yZHNbaV0gfCAwO1xuICAgICAgICBiID0gbnVtLndvcmRzW2pdIHwgMDtcbiAgICAgICAgciA9IGEgKiBiICsgcndvcmQ7XG4gICAgICAgIG5jYXJyeSArPSAociAvIDB4NDAwMDAwMCkgfCAwO1xuICAgICAgICByd29yZCA9IHIgJiAweDNmZmZmZmY7XG4gICAgICB9XG4gICAgICBvdXQud29yZHNba10gPSByd29yZCB8IDA7XG4gICAgICBjYXJyeSA9IG5jYXJyeSB8IDA7XG4gICAgfVxuICAgIGlmIChjYXJyeSAhPT0gMCkge1xuICAgICAgb3V0LndvcmRzW2tdID0gY2FycnkgfCAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXQubGVuZ3RoLS07XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dC5zdHJpcCgpO1xuICB9XG5cbiAgLy8gVE9ETyhpbmR1dG55KTogaXQgbWF5IGJlIHJlYXNvbmFibGUgdG8gb21pdCBpdCBmb3IgdXNlcnMgd2hvIGRvbid0IG5lZWRcbiAgLy8gdG8gd29yayB3aXRoIDI1Ni1iaXQgbnVtYmVycywgb3RoZXJ3aXNlIGl0IGdpdmVzIDIwJSBpbXByb3ZlbWVudCBmb3IgMjU2LWJpdFxuICAvLyBtdWx0aXBsaWNhdGlvbiAobGlrZSBlbGxpcHRpYyBzZWNwMjU2azEpLlxuICB2YXIgY29tYjEwTXVsVG8gPSBmdW5jdGlvbiBjb21iMTBNdWxUbyAoc2VsZiwgbnVtLCBvdXQpIHtcbiAgICB2YXIgYSA9IHNlbGYud29yZHM7XG4gICAgdmFyIGIgPSBudW0ud29yZHM7XG4gICAgdmFyIG8gPSBvdXQud29yZHM7XG4gICAgdmFyIGMgPSAwO1xuICAgIHZhciBsbztcbiAgICB2YXIgbWlkO1xuICAgIHZhciBoaTtcbiAgICB2YXIgYTAgPSBhWzBdIHwgMDtcbiAgICB2YXIgYWwwID0gYTAgJiAweDFmZmY7XG4gICAgdmFyIGFoMCA9IGEwID4+PiAxMztcbiAgICB2YXIgYTEgPSBhWzFdIHwgMDtcbiAgICB2YXIgYWwxID0gYTEgJiAweDFmZmY7XG4gICAgdmFyIGFoMSA9IGExID4+PiAxMztcbiAgICB2YXIgYTIgPSBhWzJdIHwgMDtcbiAgICB2YXIgYWwyID0gYTIgJiAweDFmZmY7XG4gICAgdmFyIGFoMiA9IGEyID4+PiAxMztcbiAgICB2YXIgYTMgPSBhWzNdIHwgMDtcbiAgICB2YXIgYWwzID0gYTMgJiAweDFmZmY7XG4gICAgdmFyIGFoMyA9IGEzID4+PiAxMztcbiAgICB2YXIgYTQgPSBhWzRdIHwgMDtcbiAgICB2YXIgYWw0ID0gYTQgJiAweDFmZmY7XG4gICAgdmFyIGFoNCA9IGE0ID4+PiAxMztcbiAgICB2YXIgYTUgPSBhWzVdIHwgMDtcbiAgICB2YXIgYWw1ID0gYTUgJiAweDFmZmY7XG4gICAgdmFyIGFoNSA9IGE1ID4+PiAxMztcbiAgICB2YXIgYTYgPSBhWzZdIHwgMDtcbiAgICB2YXIgYWw2ID0gYTYgJiAweDFmZmY7XG4gICAgdmFyIGFoNiA9IGE2ID4+PiAxMztcbiAgICB2YXIgYTcgPSBhWzddIHwgMDtcbiAgICB2YXIgYWw3ID0gYTcgJiAweDFmZmY7XG4gICAgdmFyIGFoNyA9IGE3ID4+PiAxMztcbiAgICB2YXIgYTggPSBhWzhdIHwgMDtcbiAgICB2YXIgYWw4ID0gYTggJiAweDFmZmY7XG4gICAgdmFyIGFoOCA9IGE4ID4+PiAxMztcbiAgICB2YXIgYTkgPSBhWzldIHwgMDtcbiAgICB2YXIgYWw5ID0gYTkgJiAweDFmZmY7XG4gICAgdmFyIGFoOSA9IGE5ID4+PiAxMztcbiAgICB2YXIgYjAgPSBiWzBdIHwgMDtcbiAgICB2YXIgYmwwID0gYjAgJiAweDFmZmY7XG4gICAgdmFyIGJoMCA9IGIwID4+PiAxMztcbiAgICB2YXIgYjEgPSBiWzFdIHwgMDtcbiAgICB2YXIgYmwxID0gYjEgJiAweDFmZmY7XG4gICAgdmFyIGJoMSA9IGIxID4+PiAxMztcbiAgICB2YXIgYjIgPSBiWzJdIHwgMDtcbiAgICB2YXIgYmwyID0gYjIgJiAweDFmZmY7XG4gICAgdmFyIGJoMiA9IGIyID4+PiAxMztcbiAgICB2YXIgYjMgPSBiWzNdIHwgMDtcbiAgICB2YXIgYmwzID0gYjMgJiAweDFmZmY7XG4gICAgdmFyIGJoMyA9IGIzID4+PiAxMztcbiAgICB2YXIgYjQgPSBiWzRdIHwgMDtcbiAgICB2YXIgYmw0ID0gYjQgJiAweDFmZmY7XG4gICAgdmFyIGJoNCA9IGI0ID4+PiAxMztcbiAgICB2YXIgYjUgPSBiWzVdIHwgMDtcbiAgICB2YXIgYmw1ID0gYjUgJiAweDFmZmY7XG4gICAgdmFyIGJoNSA9IGI1ID4+PiAxMztcbiAgICB2YXIgYjYgPSBiWzZdIHwgMDtcbiAgICB2YXIgYmw2ID0gYjYgJiAweDFmZmY7XG4gICAgdmFyIGJoNiA9IGI2ID4+PiAxMztcbiAgICB2YXIgYjcgPSBiWzddIHwgMDtcbiAgICB2YXIgYmw3ID0gYjcgJiAweDFmZmY7XG4gICAgdmFyIGJoNyA9IGI3ID4+PiAxMztcbiAgICB2YXIgYjggPSBiWzhdIHwgMDtcbiAgICB2YXIgYmw4ID0gYjggJiAweDFmZmY7XG4gICAgdmFyIGJoOCA9IGI4ID4+PiAxMztcbiAgICB2YXIgYjkgPSBiWzldIHwgMDtcbiAgICB2YXIgYmw5ID0gYjkgJiAweDFmZmY7XG4gICAgdmFyIGJoOSA9IGI5ID4+PiAxMztcblxuICAgIG91dC5uZWdhdGl2ZSA9IHNlbGYubmVnYXRpdmUgXiBudW0ubmVnYXRpdmU7XG4gICAgb3V0Lmxlbmd0aCA9IDE5O1xuICAgIC8qIGsgPSAwICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWwwLCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDAsIGJoMCk7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDAsIGJsMCkpIHwgMDtcbiAgICBoaSA9IE1hdGguaW11bChhaDAsIGJoMCk7XG4gICAgdmFyIHcwID0gKCgoYyArIGxvKSB8IDApICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKSkgfCAwO1xuICAgIGMgPSAoKChoaSArIChtaWQgPj4+IDEzKSkgfCAwKSArICh3MCA+Pj4gMjYpKSB8IDA7XG4gICAgdzAgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAxICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWwxLCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDEsIGJoMCk7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDEsIGJsMCkpIHwgMDtcbiAgICBoaSA9IE1hdGguaW11bChhaDEsIGJoMCk7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwwLCBibDEpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDAsIGJoMSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMCwgYmwxKSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMCwgYmgxKSkgfCAwO1xuICAgIHZhciB3MSA9ICgoKGMgKyBsbykgfCAwKSArICgobWlkICYgMHgxZmZmKSA8PCAxMykpIHwgMDtcbiAgICBjID0gKCgoaGkgKyAobWlkID4+PiAxMykpIHwgMCkgKyAodzEgPj4+IDI2KSkgfCAwO1xuICAgIHcxICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gMiAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsMiwgYmwwKTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWwyLCBiaDApO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgyLCBibDApKSB8IDA7XG4gICAgaGkgPSBNYXRoLmltdWwoYWgyLCBiaDApO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMSwgYmwxKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwxLCBiaDEpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDEsIGJsMSkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDEsIGJoMSkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDAsIGJsMikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMCwgYmgyKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgwLCBibDIpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgwLCBiaDIpKSB8IDA7XG4gICAgdmFyIHcyID0gKCgoYyArIGxvKSB8IDApICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKSkgfCAwO1xuICAgIGMgPSAoKChoaSArIChtaWQgPj4+IDEzKSkgfCAwKSArICh3MiA+Pj4gMjYpKSB8IDA7XG4gICAgdzIgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAzICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWwzLCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDMsIGJoMCk7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDMsIGJsMCkpIHwgMDtcbiAgICBoaSA9IE1hdGguaW11bChhaDMsIGJoMCk7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwyLCBibDEpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDIsIGJoMSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMiwgYmwxKSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMiwgYmgxKSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMSwgYmwyKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwxLCBiaDIpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDEsIGJsMikpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDEsIGJoMikpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDAsIGJsMykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMCwgYmgzKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgwLCBibDMpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgwLCBiaDMpKSB8IDA7XG4gICAgdmFyIHczID0gKCgoYyArIGxvKSB8IDApICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKSkgfCAwO1xuICAgIGMgPSAoKChoaSArIChtaWQgPj4+IDEzKSkgfCAwKSArICh3MyA+Pj4gMjYpKSB8IDA7XG4gICAgdzMgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSA0ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw0LCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDQsIGJoMCk7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDQsIGJsMCkpIHwgMDtcbiAgICBoaSA9IE1hdGguaW11bChhaDQsIGJoMCk7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwzLCBibDEpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDMsIGJoMSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMywgYmwxKSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMywgYmgxKSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMiwgYmwyKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwyLCBiaDIpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDIsIGJsMikpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDIsIGJoMikpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDEsIGJsMykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMSwgYmgzKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgxLCBibDMpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgxLCBiaDMpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwwLCBibDQpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDAsIGJoNCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMCwgYmw0KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMCwgYmg0KSkgfCAwO1xuICAgIHZhciB3NCA9ICgoKGMgKyBsbykgfCAwKSArICgobWlkICYgMHgxZmZmKSA8PCAxMykpIHwgMDtcbiAgICBjID0gKCgoaGkgKyAobWlkID4+PiAxMykpIHwgMCkgKyAodzQgPj4+IDI2KSkgfCAwO1xuICAgIHc0ICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gNSAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsNSwgYmwwKTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw1LCBiaDApO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg1LCBibDApKSB8IDA7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg1LCBiaDApO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNCwgYmwxKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw0LCBiaDEpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDQsIGJsMSkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDQsIGJoMSkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDMsIGJsMikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMywgYmgyKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgzLCBibDIpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgzLCBiaDIpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwyLCBibDMpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDIsIGJoMykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMiwgYmwzKSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMiwgYmgzKSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMSwgYmw0KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwxLCBiaDQpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDEsIGJsNCkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDEsIGJoNCkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDAsIGJsNSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMCwgYmg1KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgwLCBibDUpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgwLCBiaDUpKSB8IDA7XG4gICAgdmFyIHc1ID0gKCgoYyArIGxvKSB8IDApICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKSkgfCAwO1xuICAgIGMgPSAoKChoaSArIChtaWQgPj4+IDEzKSkgfCAwKSArICh3NSA+Pj4gMjYpKSB8IDA7XG4gICAgdzUgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSA2ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw2LCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDYsIGJoMCk7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDYsIGJsMCkpIHwgMDtcbiAgICBoaSA9IE1hdGguaW11bChhaDYsIGJoMCk7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw1LCBibDEpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDUsIGJoMSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNSwgYmwxKSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNSwgYmgxKSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNCwgYmwyKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw0LCBiaDIpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDQsIGJsMikpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDQsIGJoMikpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDMsIGJsMykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMywgYmgzKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgzLCBibDMpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgzLCBiaDMpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwyLCBibDQpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDIsIGJoNCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMiwgYmw0KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMiwgYmg0KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMSwgYmw1KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwxLCBiaDUpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDEsIGJsNSkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDEsIGJoNSkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDAsIGJsNikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMCwgYmg2KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgwLCBibDYpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgwLCBiaDYpKSB8IDA7XG4gICAgdmFyIHc2ID0gKCgoYyArIGxvKSB8IDApICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKSkgfCAwO1xuICAgIGMgPSAoKChoaSArIChtaWQgPj4+IDEzKSkgfCAwKSArICh3NiA+Pj4gMjYpKSB8IDA7XG4gICAgdzYgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSA3ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw3LCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDcsIGJoMCk7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDcsIGJsMCkpIHwgMDtcbiAgICBoaSA9IE1hdGguaW11bChhaDcsIGJoMCk7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw2LCBibDEpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDYsIGJoMSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNiwgYmwxKSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNiwgYmgxKSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNSwgYmwyKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw1LCBiaDIpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDUsIGJsMikpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDUsIGJoMikpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDQsIGJsMykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNCwgYmgzKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg0LCBibDMpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg0LCBiaDMpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwzLCBibDQpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDMsIGJoNCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMywgYmw0KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMywgYmg0KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMiwgYmw1KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwyLCBiaDUpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDIsIGJsNSkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDIsIGJoNSkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDEsIGJsNikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMSwgYmg2KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgxLCBibDYpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgxLCBiaDYpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwwLCBibDcpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDAsIGJoNykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMCwgYmw3KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMCwgYmg3KSkgfCAwO1xuICAgIHZhciB3NyA9ICgoKGMgKyBsbykgfCAwKSArICgobWlkICYgMHgxZmZmKSA8PCAxMykpIHwgMDtcbiAgICBjID0gKCgoaGkgKyAobWlkID4+PiAxMykpIHwgMCkgKyAodzcgPj4+IDI2KSkgfCAwO1xuICAgIHc3ICY9IDB4M2ZmZmZmZjtcbiAgICAvKiBrID0gOCAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsOCwgYmwwKTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw4LCBiaDApO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg4LCBibDApKSB8IDA7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg4LCBiaDApO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNywgYmwxKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw3LCBiaDEpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDcsIGJsMSkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDcsIGJoMSkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDYsIGJsMikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNiwgYmgyKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg2LCBibDIpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg2LCBiaDIpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw1LCBibDMpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDUsIGJoMykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNSwgYmwzKSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNSwgYmgzKSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNCwgYmw0KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw0LCBiaDQpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDQsIGJsNCkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDQsIGJoNCkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDMsIGJsNSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMywgYmg1KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgzLCBibDUpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgzLCBiaDUpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwyLCBibDYpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDIsIGJoNikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMiwgYmw2KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMiwgYmg2KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMSwgYmw3KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwxLCBiaDcpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDEsIGJsNykpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDEsIGJoNykpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDAsIGJsOCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMCwgYmg4KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgwLCBibDgpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgwLCBiaDgpKSB8IDA7XG4gICAgdmFyIHc4ID0gKCgoYyArIGxvKSB8IDApICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKSkgfCAwO1xuICAgIGMgPSAoKChoaSArIChtaWQgPj4+IDEzKSkgfCAwKSArICh3OCA+Pj4gMjYpKSB8IDA7XG4gICAgdzggJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSA5ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDApO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoMCk7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDksIGJsMCkpIHwgMDtcbiAgICBoaSA9IE1hdGguaW11bChhaDksIGJoMCk7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw4LCBibDEpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDgsIGJoMSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoOCwgYmwxKSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoOCwgYmgxKSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNywgYmwyKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw3LCBiaDIpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDcsIGJsMikpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDcsIGJoMikpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDYsIGJsMykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNiwgYmgzKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg2LCBibDMpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg2LCBiaDMpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw1LCBibDQpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDUsIGJoNCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNSwgYmw0KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNSwgYmg0KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNCwgYmw1KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw0LCBiaDUpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDQsIGJsNSkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDQsIGJoNSkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDMsIGJsNikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMywgYmg2KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgzLCBibDYpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgzLCBiaDYpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwyLCBibDcpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDIsIGJoNykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMiwgYmw3KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMiwgYmg3KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMSwgYmw4KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwxLCBiaDgpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDEsIGJsOCkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDEsIGJoOCkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDAsIGJsOSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMCwgYmg5KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgwLCBibDkpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgwLCBiaDkpKSB8IDA7XG4gICAgdmFyIHc5ID0gKCgoYyArIGxvKSB8IDApICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKSkgfCAwO1xuICAgIGMgPSAoKChoaSArIChtaWQgPj4+IDEzKSkgfCAwKSArICh3OSA+Pj4gMjYpKSB8IDA7XG4gICAgdzkgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAxMCAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsOSwgYmwxKTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw5LCBiaDEpO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg5LCBibDEpKSB8IDA7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDEpO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsOCwgYmwyKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw4LCBiaDIpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDgsIGJsMikpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDgsIGJoMikpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDcsIGJsMykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNywgYmgzKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg3LCBibDMpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg3LCBiaDMpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw2LCBibDQpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDYsIGJoNCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNiwgYmw0KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNiwgYmg0KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNSwgYmw1KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw1LCBiaDUpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDUsIGJsNSkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDUsIGJoNSkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDQsIGJsNikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNCwgYmg2KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg0LCBibDYpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg0LCBiaDYpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwzLCBibDcpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDMsIGJoNykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMywgYmw3KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMywgYmg3KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMiwgYmw4KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwyLCBiaDgpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDIsIGJsOCkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDIsIGJoOCkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDEsIGJsOSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMSwgYmg5KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgxLCBibDkpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgxLCBiaDkpKSB8IDA7XG4gICAgdmFyIHcxMCA9ICgoKGMgKyBsbykgfCAwKSArICgobWlkICYgMHgxZmZmKSA8PCAxMykpIHwgMDtcbiAgICBjID0gKCgoaGkgKyAobWlkID4+PiAxMykpIHwgMCkgKyAodzEwID4+PiAyNikpIHwgMDtcbiAgICB3MTAgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAxMSAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsOSwgYmwyKTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw5LCBiaDIpO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg5LCBibDIpKSB8IDA7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDIpO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsOCwgYmwzKSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw4LCBiaDMpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDgsIGJsMykpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDgsIGJoMykpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDcsIGJsNCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNywgYmg0KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg3LCBibDQpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg3LCBiaDQpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw2LCBibDUpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDYsIGJoNSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNiwgYmw1KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNiwgYmg1KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNSwgYmw2KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw1LCBiaDYpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDUsIGJsNikpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDUsIGJoNikpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDQsIGJsNykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNCwgYmg3KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg0LCBibDcpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg0LCBiaDcpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWwzLCBibDgpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDMsIGJoOCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoMywgYmw4KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoMywgYmg4KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsMiwgYmw5KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWwyLCBiaDkpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDIsIGJsOSkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDIsIGJoOSkpIHwgMDtcbiAgICB2YXIgdzExID0gKCgoYyArIGxvKSB8IDApICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKSkgfCAwO1xuICAgIGMgPSAoKChoaSArIChtaWQgPj4+IDEzKSkgfCAwKSArICh3MTEgPj4+IDI2KSkgfCAwO1xuICAgIHcxMSAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDEyICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDMpO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoMyk7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDksIGJsMykpIHwgMDtcbiAgICBoaSA9IE1hdGguaW11bChhaDksIGJoMyk7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw4LCBibDQpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDgsIGJoNCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoOCwgYmw0KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoOCwgYmg0KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNywgYmw1KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw3LCBiaDUpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDcsIGJsNSkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDcsIGJoNSkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDYsIGJsNikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNiwgYmg2KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg2LCBibDYpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg2LCBiaDYpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw1LCBibDcpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDUsIGJoNykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNSwgYmw3KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNSwgYmg3KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNCwgYmw4KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw0LCBiaDgpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDQsIGJsOCkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDQsIGJoOCkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDMsIGJsOSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsMywgYmg5KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWgzLCBibDkpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWgzLCBiaDkpKSB8IDA7XG4gICAgdmFyIHcxMiA9ICgoKGMgKyBsbykgfCAwKSArICgobWlkICYgMHgxZmZmKSA8PCAxMykpIHwgMDtcbiAgICBjID0gKCgoaGkgKyAobWlkID4+PiAxMykpIHwgMCkgKyAodzEyID4+PiAyNikpIHwgMDtcbiAgICB3MTIgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAxMyAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsOSwgYmw0KTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw5LCBiaDQpO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg5LCBibDQpKSB8IDA7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDQpO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsOCwgYmw1KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw4LCBiaDUpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDgsIGJsNSkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDgsIGJoNSkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDcsIGJsNikpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNywgYmg2KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg3LCBibDYpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg3LCBiaDYpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw2LCBibDcpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDYsIGJoNykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNiwgYmw3KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNiwgYmg3KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNSwgYmw4KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw1LCBiaDgpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDUsIGJsOCkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDUsIGJoOCkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDQsIGJsOSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNCwgYmg5KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg0LCBibDkpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg0LCBiaDkpKSB8IDA7XG4gICAgdmFyIHcxMyA9ICgoKGMgKyBsbykgfCAwKSArICgobWlkICYgMHgxZmZmKSA8PCAxMykpIHwgMDtcbiAgICBjID0gKCgoaGkgKyAobWlkID4+PiAxMykpIHwgMCkgKyAodzEzID4+PiAyNikpIHwgMDtcbiAgICB3MTMgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAxNCAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsOSwgYmw1KTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw5LCBiaDUpO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg5LCBibDUpKSB8IDA7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDUpO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsOCwgYmw2KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw4LCBiaDYpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDgsIGJsNikpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDgsIGJoNikpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDcsIGJsNykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNywgYmg3KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg3LCBibDcpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg3LCBiaDcpKSB8IDA7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw2LCBibDgpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDYsIGJoOCkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoNiwgYmw4KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoNiwgYmg4KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNSwgYmw5KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw1LCBiaDkpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDUsIGJsOSkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDUsIGJoOSkpIHwgMDtcbiAgICB2YXIgdzE0ID0gKCgoYyArIGxvKSB8IDApICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKSkgfCAwO1xuICAgIGMgPSAoKChoaSArIChtaWQgPj4+IDEzKSkgfCAwKSArICh3MTQgPj4+IDI2KSkgfCAwO1xuICAgIHcxNCAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDE1ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDYpO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoNik7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDksIGJsNikpIHwgMDtcbiAgICBoaSA9IE1hdGguaW11bChhaDksIGJoNik7XG4gICAgbG8gPSAobG8gKyBNYXRoLmltdWwoYWw4LCBibDcpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhbDgsIGJoNykpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFoOCwgYmw3KSkgfCAwO1xuICAgIGhpID0gKGhpICsgTWF0aC5pbXVsKGFoOCwgYmg3KSkgfCAwO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsNywgYmw4KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw3LCBiaDgpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDcsIGJsOCkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDcsIGJoOCkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDYsIGJsOSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNiwgYmg5KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg2LCBibDkpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg2LCBiaDkpKSB8IDA7XG4gICAgdmFyIHcxNSA9ICgoKGMgKyBsbykgfCAwKSArICgobWlkICYgMHgxZmZmKSA8PCAxMykpIHwgMDtcbiAgICBjID0gKCgoaGkgKyAobWlkID4+PiAxMykpIHwgMCkgKyAodzE1ID4+PiAyNikpIHwgMDtcbiAgICB3MTUgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAxNiAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsOSwgYmw3KTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw5LCBiaDcpO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg5LCBibDcpKSB8IDA7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDcpO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsOCwgYmw4KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw4LCBiaDgpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDgsIGJsOCkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDgsIGJoOCkpIHwgMDtcbiAgICBsbyA9IChsbyArIE1hdGguaW11bChhbDcsIGJsOSkpIHwgMDtcbiAgICBtaWQgPSAobWlkICsgTWF0aC5pbXVsKGFsNywgYmg5KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg3LCBibDkpKSB8IDA7XG4gICAgaGkgPSAoaGkgKyBNYXRoLmltdWwoYWg3LCBiaDkpKSB8IDA7XG4gICAgdmFyIHcxNiA9ICgoKGMgKyBsbykgfCAwKSArICgobWlkICYgMHgxZmZmKSA8PCAxMykpIHwgMDtcbiAgICBjID0gKCgoaGkgKyAobWlkID4+PiAxMykpIHwgMCkgKyAodzE2ID4+PiAyNikpIHwgMDtcbiAgICB3MTYgJj0gMHgzZmZmZmZmO1xuICAgIC8qIGsgPSAxNyAqL1xuICAgIGxvID0gTWF0aC5pbXVsKGFsOSwgYmw4KTtcbiAgICBtaWQgPSBNYXRoLmltdWwoYWw5LCBiaDgpO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWg5LCBibDgpKSB8IDA7XG4gICAgaGkgPSBNYXRoLmltdWwoYWg5LCBiaDgpO1xuICAgIGxvID0gKGxvICsgTWF0aC5pbXVsKGFsOCwgYmw5KSkgfCAwO1xuICAgIG1pZCA9IChtaWQgKyBNYXRoLmltdWwoYWw4LCBiaDkpKSB8IDA7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDgsIGJsOSkpIHwgMDtcbiAgICBoaSA9IChoaSArIE1hdGguaW11bChhaDgsIGJoOSkpIHwgMDtcbiAgICB2YXIgdzE3ID0gKCgoYyArIGxvKSB8IDApICsgKChtaWQgJiAweDFmZmYpIDw8IDEzKSkgfCAwO1xuICAgIGMgPSAoKChoaSArIChtaWQgPj4+IDEzKSkgfCAwKSArICh3MTcgPj4+IDI2KSkgfCAwO1xuICAgIHcxNyAmPSAweDNmZmZmZmY7XG4gICAgLyogayA9IDE4ICovXG4gICAgbG8gPSBNYXRoLmltdWwoYWw5LCBibDkpO1xuICAgIG1pZCA9IE1hdGguaW11bChhbDksIGJoOSk7XG4gICAgbWlkID0gKG1pZCArIE1hdGguaW11bChhaDksIGJsOSkpIHwgMDtcbiAgICBoaSA9IE1hdGguaW11bChhaDksIGJoOSk7XG4gICAgdmFyIHcxOCA9ICgoKGMgKyBsbykgfCAwKSArICgobWlkICYgMHgxZmZmKSA8PCAxMykpIHwgMDtcbiAgICBjID0gKCgoaGkgKyAobWlkID4+PiAxMykpIHwgMCkgKyAodzE4ID4+PiAyNikpIHwgMDtcbiAgICB3MTggJj0gMHgzZmZmZmZmO1xuICAgIG9bMF0gPSB3MDtcbiAgICBvWzFdID0gdzE7XG4gICAgb1syXSA9IHcyO1xuICAgIG9bM10gPSB3MztcbiAgICBvWzRdID0gdzQ7XG4gICAgb1s1XSA9IHc1O1xuICAgIG9bNl0gPSB3NjtcbiAgICBvWzddID0gdzc7XG4gICAgb1s4XSA9IHc4O1xuICAgIG9bOV0gPSB3OTtcbiAgICBvWzEwXSA9IHcxMDtcbiAgICBvWzExXSA9IHcxMTtcbiAgICBvWzEyXSA9IHcxMjtcbiAgICBvWzEzXSA9IHcxMztcbiAgICBvWzE0XSA9IHcxNDtcbiAgICBvWzE1XSA9IHcxNTtcbiAgICBvWzE2XSA9IHcxNjtcbiAgICBvWzE3XSA9IHcxNztcbiAgICBvWzE4XSA9IHcxODtcbiAgICBpZiAoYyAhPT0gMCkge1xuICAgICAgb1sxOV0gPSBjO1xuICAgICAgb3V0Lmxlbmd0aCsrO1xuICAgIH1cbiAgICByZXR1cm4gb3V0O1xuICB9O1xuXG4gIC8vIFBvbHlmaWxsIGNvbWJcbiAgaWYgKCFNYXRoLmltdWwpIHtcbiAgICBjb21iMTBNdWxUbyA9IHNtYWxsTXVsVG87XG4gIH1cblxuICBmdW5jdGlvbiBiaWdNdWxUbyAoc2VsZiwgbnVtLCBvdXQpIHtcbiAgICBvdXQubmVnYXRpdmUgPSBudW0ubmVnYXRpdmUgXiBzZWxmLm5lZ2F0aXZlO1xuICAgIG91dC5sZW5ndGggPSBzZWxmLmxlbmd0aCArIG51bS5sZW5ndGg7XG5cbiAgICB2YXIgY2FycnkgPSAwO1xuICAgIHZhciBobmNhcnJ5ID0gMDtcbiAgICBmb3IgKHZhciBrID0gMDsgayA8IG91dC5sZW5ndGggLSAxOyBrKyspIHtcbiAgICAgIC8vIFN1bSBhbGwgd29yZHMgd2l0aCB0aGUgc2FtZSBgaSArIGogPSBrYCBhbmQgYWNjdW11bGF0ZSBgbmNhcnJ5YCxcbiAgICAgIC8vIG5vdGUgdGhhdCBuY2FycnkgY291bGQgYmUgPj0gMHgzZmZmZmZmXG4gICAgICB2YXIgbmNhcnJ5ID0gaG5jYXJyeTtcbiAgICAgIGhuY2FycnkgPSAwO1xuICAgICAgdmFyIHJ3b3JkID0gY2FycnkgJiAweDNmZmZmZmY7XG4gICAgICB2YXIgbWF4SiA9IE1hdGgubWluKGssIG51bS5sZW5ndGggLSAxKTtcbiAgICAgIGZvciAodmFyIGogPSBNYXRoLm1heCgwLCBrIC0gc2VsZi5sZW5ndGggKyAxKTsgaiA8PSBtYXhKOyBqKyspIHtcbiAgICAgICAgdmFyIGkgPSBrIC0gajtcbiAgICAgICAgdmFyIGEgPSBzZWxmLndvcmRzW2ldIHwgMDtcbiAgICAgICAgdmFyIGIgPSBudW0ud29yZHNbal0gfCAwO1xuICAgICAgICB2YXIgciA9IGEgKiBiO1xuXG4gICAgICAgIHZhciBsbyA9IHIgJiAweDNmZmZmZmY7XG4gICAgICAgIG5jYXJyeSA9IChuY2FycnkgKyAoKHIgLyAweDQwMDAwMDApIHwgMCkpIHwgMDtcbiAgICAgICAgbG8gPSAobG8gKyByd29yZCkgfCAwO1xuICAgICAgICByd29yZCA9IGxvICYgMHgzZmZmZmZmO1xuICAgICAgICBuY2FycnkgPSAobmNhcnJ5ICsgKGxvID4+PiAyNikpIHwgMDtcblxuICAgICAgICBobmNhcnJ5ICs9IG5jYXJyeSA+Pj4gMjY7XG4gICAgICAgIG5jYXJyeSAmPSAweDNmZmZmZmY7XG4gICAgICB9XG4gICAgICBvdXQud29yZHNba10gPSByd29yZDtcbiAgICAgIGNhcnJ5ID0gbmNhcnJ5O1xuICAgICAgbmNhcnJ5ID0gaG5jYXJyeTtcbiAgICB9XG4gICAgaWYgKGNhcnJ5ICE9PSAwKSB7XG4gICAgICBvdXQud29yZHNba10gPSBjYXJyeTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0Lmxlbmd0aC0tO1xuICAgIH1cblxuICAgIHJldHVybiBvdXQuc3RyaXAoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGp1bWJvTXVsVG8gKHNlbGYsIG51bSwgb3V0KSB7XG4gICAgdmFyIGZmdG0gPSBuZXcgRkZUTSgpO1xuICAgIHJldHVybiBmZnRtLm11bHAoc2VsZiwgbnVtLCBvdXQpO1xuICB9XG5cbiAgQk4ucHJvdG90eXBlLm11bFRvID0gZnVuY3Rpb24gbXVsVG8gKG51bSwgb3V0KSB7XG4gICAgdmFyIHJlcztcbiAgICB2YXIgbGVuID0gdGhpcy5sZW5ndGggKyBudW0ubGVuZ3RoO1xuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMTAgJiYgbnVtLmxlbmd0aCA9PT0gMTApIHtcbiAgICAgIHJlcyA9IGNvbWIxME11bFRvKHRoaXMsIG51bSwgb3V0KTtcbiAgICB9IGVsc2UgaWYgKGxlbiA8IDYzKSB7XG4gICAgICByZXMgPSBzbWFsbE11bFRvKHRoaXMsIG51bSwgb3V0KTtcbiAgICB9IGVsc2UgaWYgKGxlbiA8IDEwMjQpIHtcbiAgICAgIHJlcyA9IGJpZ011bFRvKHRoaXMsIG51bSwgb3V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzID0ganVtYm9NdWxUbyh0aGlzLCBudW0sIG91dCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcztcbiAgfTtcblxuICAvLyBDb29sZXktVHVrZXkgYWxnb3JpdGhtIGZvciBGRlRcbiAgLy8gc2xpZ2h0bHkgcmV2aXNpdGVkIHRvIHJlbHkgb24gbG9vcGluZyBpbnN0ZWFkIG9mIHJlY3Vyc2lvblxuXG4gIGZ1bmN0aW9uIEZGVE0gKHgsIHkpIHtcbiAgICB0aGlzLnggPSB4O1xuICAgIHRoaXMueSA9IHk7XG4gIH1cblxuICBGRlRNLnByb3RvdHlwZS5tYWtlUkJUID0gZnVuY3Rpb24gbWFrZVJCVCAoTikge1xuICAgIHZhciB0ID0gbmV3IEFycmF5KE4pO1xuICAgIHZhciBsID0gQk4ucHJvdG90eXBlLl9jb3VudEJpdHMoTikgLSAxO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgTjsgaSsrKSB7XG4gICAgICB0W2ldID0gdGhpcy5yZXZCaW4oaSwgbCwgTik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHQ7XG4gIH07XG5cbiAgLy8gUmV0dXJucyBiaW5hcnktcmV2ZXJzZWQgcmVwcmVzZW50YXRpb24gb2YgYHhgXG4gIEZGVE0ucHJvdG90eXBlLnJldkJpbiA9IGZ1bmN0aW9uIHJldkJpbiAoeCwgbCwgTikge1xuICAgIGlmICh4ID09PSAwIHx8IHggPT09IE4gLSAxKSByZXR1cm4geDtcblxuICAgIHZhciByYiA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsOyBpKyspIHtcbiAgICAgIHJiIHw9ICh4ICYgMSkgPDwgKGwgLSBpIC0gMSk7XG4gICAgICB4ID4+PSAxO1xuICAgIH1cblxuICAgIHJldHVybiByYjtcbiAgfTtcblxuICAvLyBQZXJmb3JtcyBcInR3ZWVkbGluZ1wiIHBoYXNlLCB0aGVyZWZvcmUgJ2VtdWxhdGluZydcbiAgLy8gYmVoYXZpb3VyIG9mIHRoZSByZWN1cnNpdmUgYWxnb3JpdGhtXG4gIEZGVE0ucHJvdG90eXBlLnBlcm11dGUgPSBmdW5jdGlvbiBwZXJtdXRlIChyYnQsIHJ3cywgaXdzLCBydHdzLCBpdHdzLCBOKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBOOyBpKyspIHtcbiAgICAgIHJ0d3NbaV0gPSByd3NbcmJ0W2ldXTtcbiAgICAgIGl0d3NbaV0gPSBpd3NbcmJ0W2ldXTtcbiAgICB9XG4gIH07XG5cbiAgRkZUTS5wcm90b3R5cGUudHJhbnNmb3JtID0gZnVuY3Rpb24gdHJhbnNmb3JtIChyd3MsIGl3cywgcnR3cywgaXR3cywgTiwgcmJ0KSB7XG4gICAgdGhpcy5wZXJtdXRlKHJidCwgcndzLCBpd3MsIHJ0d3MsIGl0d3MsIE4pO1xuXG4gICAgZm9yICh2YXIgcyA9IDE7IHMgPCBOOyBzIDw8PSAxKSB7XG4gICAgICB2YXIgbCA9IHMgPDwgMTtcblxuICAgICAgdmFyIHJ0d2RmID0gTWF0aC5jb3MoMiAqIE1hdGguUEkgLyBsKTtcbiAgICAgIHZhciBpdHdkZiA9IE1hdGguc2luKDIgKiBNYXRoLlBJIC8gbCk7XG5cbiAgICAgIGZvciAodmFyIHAgPSAwOyBwIDwgTjsgcCArPSBsKSB7XG4gICAgICAgIHZhciBydHdkZl8gPSBydHdkZjtcbiAgICAgICAgdmFyIGl0d2RmXyA9IGl0d2RmO1xuXG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgczsgaisrKSB7XG4gICAgICAgICAgdmFyIHJlID0gcnR3c1twICsgal07XG4gICAgICAgICAgdmFyIGllID0gaXR3c1twICsgal07XG5cbiAgICAgICAgICB2YXIgcm8gPSBydHdzW3AgKyBqICsgc107XG4gICAgICAgICAgdmFyIGlvID0gaXR3c1twICsgaiArIHNdO1xuXG4gICAgICAgICAgdmFyIHJ4ID0gcnR3ZGZfICogcm8gLSBpdHdkZl8gKiBpbztcblxuICAgICAgICAgIGlvID0gcnR3ZGZfICogaW8gKyBpdHdkZl8gKiBybztcbiAgICAgICAgICBybyA9IHJ4O1xuXG4gICAgICAgICAgcnR3c1twICsgal0gPSByZSArIHJvO1xuICAgICAgICAgIGl0d3NbcCArIGpdID0gaWUgKyBpbztcblxuICAgICAgICAgIHJ0d3NbcCArIGogKyBzXSA9IHJlIC0gcm87XG4gICAgICAgICAgaXR3c1twICsgaiArIHNdID0gaWUgLSBpbztcblxuICAgICAgICAgIC8qIGpzaGludCBtYXhkZXB0aCA6IGZhbHNlICovXG4gICAgICAgICAgaWYgKGogIT09IGwpIHtcbiAgICAgICAgICAgIHJ4ID0gcnR3ZGYgKiBydHdkZl8gLSBpdHdkZiAqIGl0d2RmXztcblxuICAgICAgICAgICAgaXR3ZGZfID0gcnR3ZGYgKiBpdHdkZl8gKyBpdHdkZiAqIHJ0d2RmXztcbiAgICAgICAgICAgIHJ0d2RmXyA9IHJ4O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBGRlRNLnByb3RvdHlwZS5ndWVzc0xlbjEzYiA9IGZ1bmN0aW9uIGd1ZXNzTGVuMTNiIChuLCBtKSB7XG4gICAgdmFyIE4gPSBNYXRoLm1heChtLCBuKSB8IDE7XG4gICAgdmFyIG9kZCA9IE4gJiAxO1xuICAgIHZhciBpID0gMDtcbiAgICBmb3IgKE4gPSBOIC8gMiB8IDA7IE47IE4gPSBOID4+PiAxKSB7XG4gICAgICBpKys7XG4gICAgfVxuXG4gICAgcmV0dXJuIDEgPDwgaSArIDEgKyBvZGQ7XG4gIH07XG5cbiAgRkZUTS5wcm90b3R5cGUuY29uanVnYXRlID0gZnVuY3Rpb24gY29uanVnYXRlIChyd3MsIGl3cywgTikge1xuICAgIGlmIChOIDw9IDEpIHJldHVybjtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgTiAvIDI7IGkrKykge1xuICAgICAgdmFyIHQgPSByd3NbaV07XG5cbiAgICAgIHJ3c1tpXSA9IHJ3c1tOIC0gaSAtIDFdO1xuICAgICAgcndzW04gLSBpIC0gMV0gPSB0O1xuXG4gICAgICB0ID0gaXdzW2ldO1xuXG4gICAgICBpd3NbaV0gPSAtaXdzW04gLSBpIC0gMV07XG4gICAgICBpd3NbTiAtIGkgLSAxXSA9IC10O1xuICAgIH1cbiAgfTtcblxuICBGRlRNLnByb3RvdHlwZS5ub3JtYWxpemUxM2IgPSBmdW5jdGlvbiBub3JtYWxpemUxM2IgKHdzLCBOKSB7XG4gICAgdmFyIGNhcnJ5ID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IE4gLyAyOyBpKyspIHtcbiAgICAgIHZhciB3ID0gTWF0aC5yb3VuZCh3c1syICogaSArIDFdIC8gTikgKiAweDIwMDAgK1xuICAgICAgICBNYXRoLnJvdW5kKHdzWzIgKiBpXSAvIE4pICtcbiAgICAgICAgY2Fycnk7XG5cbiAgICAgIHdzW2ldID0gdyAmIDB4M2ZmZmZmZjtcblxuICAgICAgaWYgKHcgPCAweDQwMDAwMDApIHtcbiAgICAgICAgY2FycnkgPSAwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FycnkgPSB3IC8gMHg0MDAwMDAwIHwgMDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gd3M7XG4gIH07XG5cbiAgRkZUTS5wcm90b3R5cGUuY29udmVydDEzYiA9IGZ1bmN0aW9uIGNvbnZlcnQxM2IgKHdzLCBsZW4sIHJ3cywgTikge1xuICAgIHZhciBjYXJyeSA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgY2FycnkgPSBjYXJyeSArICh3c1tpXSB8IDApO1xuXG4gICAgICByd3NbMiAqIGldID0gY2FycnkgJiAweDFmZmY7IGNhcnJ5ID0gY2FycnkgPj4+IDEzO1xuICAgICAgcndzWzIgKiBpICsgMV0gPSBjYXJyeSAmIDB4MWZmZjsgY2FycnkgPSBjYXJyeSA+Pj4gMTM7XG4gICAgfVxuXG4gICAgLy8gUGFkIHdpdGggemVyb2VzXG4gICAgZm9yIChpID0gMiAqIGxlbjsgaSA8IE47ICsraSkge1xuICAgICAgcndzW2ldID0gMDtcbiAgICB9XG5cbiAgICBhc3NlcnQoY2FycnkgPT09IDApO1xuICAgIGFzc2VydCgoY2FycnkgJiB+MHgxZmZmKSA9PT0gMCk7XG4gIH07XG5cbiAgRkZUTS5wcm90b3R5cGUuc3R1YiA9IGZ1bmN0aW9uIHN0dWIgKE4pIHtcbiAgICB2YXIgcGggPSBuZXcgQXJyYXkoTik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBOOyBpKyspIHtcbiAgICAgIHBoW2ldID0gMDtcbiAgICB9XG5cbiAgICByZXR1cm4gcGg7XG4gIH07XG5cbiAgRkZUTS5wcm90b3R5cGUubXVscCA9IGZ1bmN0aW9uIG11bHAgKHgsIHksIG91dCkge1xuICAgIHZhciBOID0gMiAqIHRoaXMuZ3Vlc3NMZW4xM2IoeC5sZW5ndGgsIHkubGVuZ3RoKTtcblxuICAgIHZhciByYnQgPSB0aGlzLm1ha2VSQlQoTik7XG5cbiAgICB2YXIgXyA9IHRoaXMuc3R1YihOKTtcblxuICAgIHZhciByd3MgPSBuZXcgQXJyYXkoTik7XG4gICAgdmFyIHJ3c3QgPSBuZXcgQXJyYXkoTik7XG4gICAgdmFyIGl3c3QgPSBuZXcgQXJyYXkoTik7XG5cbiAgICB2YXIgbnJ3cyA9IG5ldyBBcnJheShOKTtcbiAgICB2YXIgbnJ3c3QgPSBuZXcgQXJyYXkoTik7XG4gICAgdmFyIG5pd3N0ID0gbmV3IEFycmF5KE4pO1xuXG4gICAgdmFyIHJtd3MgPSBvdXQud29yZHM7XG4gICAgcm13cy5sZW5ndGggPSBOO1xuXG4gICAgdGhpcy5jb252ZXJ0MTNiKHgud29yZHMsIHgubGVuZ3RoLCByd3MsIE4pO1xuICAgIHRoaXMuY29udmVydDEzYih5LndvcmRzLCB5Lmxlbmd0aCwgbnJ3cywgTik7XG5cbiAgICB0aGlzLnRyYW5zZm9ybShyd3MsIF8sIHJ3c3QsIGl3c3QsIE4sIHJidCk7XG4gICAgdGhpcy50cmFuc2Zvcm0obnJ3cywgXywgbnJ3c3QsIG5pd3N0LCBOLCByYnQpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBOOyBpKyspIHtcbiAgICAgIHZhciByeCA9IHJ3c3RbaV0gKiBucndzdFtpXSAtIGl3c3RbaV0gKiBuaXdzdFtpXTtcbiAgICAgIGl3c3RbaV0gPSByd3N0W2ldICogbml3c3RbaV0gKyBpd3N0W2ldICogbnJ3c3RbaV07XG4gICAgICByd3N0W2ldID0gcng7XG4gICAgfVxuXG4gICAgdGhpcy5jb25qdWdhdGUocndzdCwgaXdzdCwgTik7XG4gICAgdGhpcy50cmFuc2Zvcm0ocndzdCwgaXdzdCwgcm13cywgXywgTiwgcmJ0KTtcbiAgICB0aGlzLmNvbmp1Z2F0ZShybXdzLCBfLCBOKTtcbiAgICB0aGlzLm5vcm1hbGl6ZTEzYihybXdzLCBOKTtcblxuICAgIG91dC5uZWdhdGl2ZSA9IHgubmVnYXRpdmUgXiB5Lm5lZ2F0aXZlO1xuICAgIG91dC5sZW5ndGggPSB4Lmxlbmd0aCArIHkubGVuZ3RoO1xuICAgIHJldHVybiBvdXQuc3RyaXAoKTtcbiAgfTtcblxuICAvLyBNdWx0aXBseSBgdGhpc2AgYnkgYG51bWBcbiAgQk4ucHJvdG90eXBlLm11bCA9IGZ1bmN0aW9uIG11bCAobnVtKSB7XG4gICAgdmFyIG91dCA9IG5ldyBCTihudWxsKTtcbiAgICBvdXQud29yZHMgPSBuZXcgQXJyYXkodGhpcy5sZW5ndGggKyBudW0ubGVuZ3RoKTtcbiAgICByZXR1cm4gdGhpcy5tdWxUbyhudW0sIG91dCk7XG4gIH07XG5cbiAgLy8gTXVsdGlwbHkgZW1wbG95aW5nIEZGVFxuICBCTi5wcm90b3R5cGUubXVsZiA9IGZ1bmN0aW9uIG11bGYgKG51bSkge1xuICAgIHZhciBvdXQgPSBuZXcgQk4obnVsbCk7XG4gICAgb3V0LndvcmRzID0gbmV3IEFycmF5KHRoaXMubGVuZ3RoICsgbnVtLmxlbmd0aCk7XG4gICAgcmV0dXJuIGp1bWJvTXVsVG8odGhpcywgbnVtLCBvdXQpO1xuICB9O1xuXG4gIC8vIEluLXBsYWNlIE11bHRpcGxpY2F0aW9uXG4gIEJOLnByb3RvdHlwZS5pbXVsID0gZnVuY3Rpb24gaW11bCAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5tdWxUbyhudW0sIHRoaXMpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5pbXVsbiA9IGZ1bmN0aW9uIGltdWxuIChudW0pIHtcbiAgICBhc3NlcnQodHlwZW9mIG51bSA9PT0gJ251bWJlcicpO1xuICAgIGFzc2VydChudW0gPCAweDQwMDAwMDApO1xuXG4gICAgLy8gQ2FycnlcbiAgICB2YXIgY2FycnkgPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHcgPSAodGhpcy53b3Jkc1tpXSB8IDApICogbnVtO1xuICAgICAgdmFyIGxvID0gKHcgJiAweDNmZmZmZmYpICsgKGNhcnJ5ICYgMHgzZmZmZmZmKTtcbiAgICAgIGNhcnJ5ID4+PSAyNjtcbiAgICAgIGNhcnJ5ICs9ICh3IC8gMHg0MDAwMDAwKSB8IDA7XG4gICAgICAvLyBOT1RFOiBsbyBpcyAyN2JpdCBtYXhpbXVtXG4gICAgICBjYXJyeSArPSBsbyA+Pj4gMjY7XG4gICAgICB0aGlzLndvcmRzW2ldID0gbG8gJiAweDNmZmZmZmY7XG4gICAgfVxuXG4gICAgaWYgKGNhcnJ5ICE9PSAwKSB7XG4gICAgICB0aGlzLndvcmRzW2ldID0gY2Fycnk7XG4gICAgICB0aGlzLmxlbmd0aCsrO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5tdWxuID0gZnVuY3Rpb24gbXVsbiAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pbXVsbihudW0pO1xuICB9O1xuXG4gIC8vIGB0aGlzYCAqIGB0aGlzYFxuICBCTi5wcm90b3R5cGUuc3FyID0gZnVuY3Rpb24gc3FyICgpIHtcbiAgICByZXR1cm4gdGhpcy5tdWwodGhpcyk7XG4gIH07XG5cbiAgLy8gYHRoaXNgICogYHRoaXNgIGluLXBsYWNlXG4gIEJOLnByb3RvdHlwZS5pc3FyID0gZnVuY3Rpb24gaXNxciAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW11bCh0aGlzLmNsb25lKCkpO1xuICB9O1xuXG4gIC8vIE1hdGgucG93KGB0aGlzYCwgYG51bWApXG4gIEJOLnByb3RvdHlwZS5wb3cgPSBmdW5jdGlvbiBwb3cgKG51bSkge1xuICAgIHZhciB3ID0gdG9CaXRBcnJheShudW0pO1xuICAgIGlmICh3Lmxlbmd0aCA9PT0gMCkgcmV0dXJuIG5ldyBCTigxKTtcblxuICAgIC8vIFNraXAgbGVhZGluZyB6ZXJvZXNcbiAgICB2YXIgcmVzID0gdGhpcztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHcubGVuZ3RoOyBpKyssIHJlcyA9IHJlcy5zcXIoKSkge1xuICAgICAgaWYgKHdbaV0gIT09IDApIGJyZWFrO1xuICAgIH1cblxuICAgIGlmICgrK2kgPCB3Lmxlbmd0aCkge1xuICAgICAgZm9yICh2YXIgcSA9IHJlcy5zcXIoKTsgaSA8IHcubGVuZ3RoOyBpKyssIHEgPSBxLnNxcigpKSB7XG4gICAgICAgIGlmICh3W2ldID09PSAwKSBjb250aW51ZTtcblxuICAgICAgICByZXMgPSByZXMubXVsKHEpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXM7XG4gIH07XG5cbiAgLy8gU2hpZnQtbGVmdCBpbi1wbGFjZVxuICBCTi5wcm90b3R5cGUuaXVzaGxuID0gZnVuY3Rpb24gaXVzaGxuIChiaXRzKSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBiaXRzID09PSAnbnVtYmVyJyAmJiBiaXRzID49IDApO1xuICAgIHZhciByID0gYml0cyAlIDI2O1xuICAgIHZhciBzID0gKGJpdHMgLSByKSAvIDI2O1xuICAgIHZhciBjYXJyeU1hc2sgPSAoMHgzZmZmZmZmID4+PiAoMjYgLSByKSkgPDwgKDI2IC0gcik7XG4gICAgdmFyIGk7XG5cbiAgICBpZiAociAhPT0gMCkge1xuICAgICAgdmFyIGNhcnJ5ID0gMDtcblxuICAgICAgZm9yIChpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIG5ld0NhcnJ5ID0gdGhpcy53b3Jkc1tpXSAmIGNhcnJ5TWFzaztcbiAgICAgICAgdmFyIGMgPSAoKHRoaXMud29yZHNbaV0gfCAwKSAtIG5ld0NhcnJ5KSA8PCByO1xuICAgICAgICB0aGlzLndvcmRzW2ldID0gYyB8IGNhcnJ5O1xuICAgICAgICBjYXJyeSA9IG5ld0NhcnJ5ID4+PiAoMjYgLSByKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNhcnJ5KSB7XG4gICAgICAgIHRoaXMud29yZHNbaV0gPSBjYXJyeTtcbiAgICAgICAgdGhpcy5sZW5ndGgrKztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocyAhPT0gMCkge1xuICAgICAgZm9yIChpID0gdGhpcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICB0aGlzLndvcmRzW2kgKyBzXSA9IHRoaXMud29yZHNbaV07XG4gICAgICB9XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBzOyBpKyspIHtcbiAgICAgICAgdGhpcy53b3Jkc1tpXSA9IDA7XG4gICAgICB9XG5cbiAgICAgIHRoaXMubGVuZ3RoICs9IHM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaXNobG4gPSBmdW5jdGlvbiBpc2hsbiAoYml0cykge1xuICAgIC8vIFRPRE8oaW5kdXRueSk6IGltcGxlbWVudCBtZVxuICAgIGFzc2VydCh0aGlzLm5lZ2F0aXZlID09PSAwKTtcbiAgICByZXR1cm4gdGhpcy5pdXNobG4oYml0cyk7XG4gIH07XG5cbiAgLy8gU2hpZnQtcmlnaHQgaW4tcGxhY2VcbiAgLy8gTk9URTogYGhpbnRgIGlzIGEgbG93ZXN0IGJpdCBiZWZvcmUgdHJhaWxpbmcgemVyb2VzXG4gIC8vIE5PVEU6IGlmIGBleHRlbmRlZGAgaXMgcHJlc2VudCAtIGl0IHdpbGwgYmUgZmlsbGVkIHdpdGggZGVzdHJveWVkIGJpdHNcbiAgQk4ucHJvdG90eXBlLml1c2hybiA9IGZ1bmN0aW9uIGl1c2hybiAoYml0cywgaGludCwgZXh0ZW5kZWQpIHtcbiAgICBhc3NlcnQodHlwZW9mIGJpdHMgPT09ICdudW1iZXInICYmIGJpdHMgPj0gMCk7XG4gICAgdmFyIGg7XG4gICAgaWYgKGhpbnQpIHtcbiAgICAgIGggPSAoaGludCAtIChoaW50ICUgMjYpKSAvIDI2O1xuICAgIH0gZWxzZSB7XG4gICAgICBoID0gMDtcbiAgICB9XG5cbiAgICB2YXIgciA9IGJpdHMgJSAyNjtcbiAgICB2YXIgcyA9IE1hdGgubWluKChiaXRzIC0gcikgLyAyNiwgdGhpcy5sZW5ndGgpO1xuICAgIHZhciBtYXNrID0gMHgzZmZmZmZmIF4gKCgweDNmZmZmZmYgPj4+IHIpIDw8IHIpO1xuICAgIHZhciBtYXNrZWRXb3JkcyA9IGV4dGVuZGVkO1xuXG4gICAgaCAtPSBzO1xuICAgIGggPSBNYXRoLm1heCgwLCBoKTtcblxuICAgIC8vIEV4dGVuZGVkIG1vZGUsIGNvcHkgbWFza2VkIHBhcnRcbiAgICBpZiAobWFza2VkV29yZHMpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgczsgaSsrKSB7XG4gICAgICAgIG1hc2tlZFdvcmRzLndvcmRzW2ldID0gdGhpcy53b3Jkc1tpXTtcbiAgICAgIH1cbiAgICAgIG1hc2tlZFdvcmRzLmxlbmd0aCA9IHM7XG4gICAgfVxuXG4gICAgaWYgKHMgPT09IDApIHtcbiAgICAgIC8vIE5vLW9wLCB3ZSBzaG91bGQgbm90IG1vdmUgYW55dGhpbmcgYXQgYWxsXG4gICAgfSBlbHNlIGlmICh0aGlzLmxlbmd0aCA+IHMpIHtcbiAgICAgIHRoaXMubGVuZ3RoIC09IHM7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB0aGlzLndvcmRzW2ldID0gdGhpcy53b3Jkc1tpICsgc107XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMud29yZHNbMF0gPSAwO1xuICAgICAgdGhpcy5sZW5ndGggPSAxO1xuICAgIH1cblxuICAgIHZhciBjYXJyeSA9IDA7XG4gICAgZm9yIChpID0gdGhpcy5sZW5ndGggLSAxOyBpID49IDAgJiYgKGNhcnJ5ICE9PSAwIHx8IGkgPj0gaCk7IGktLSkge1xuICAgICAgdmFyIHdvcmQgPSB0aGlzLndvcmRzW2ldIHwgMDtcbiAgICAgIHRoaXMud29yZHNbaV0gPSAoY2FycnkgPDwgKDI2IC0gcikpIHwgKHdvcmQgPj4+IHIpO1xuICAgICAgY2FycnkgPSB3b3JkICYgbWFzaztcbiAgICB9XG5cbiAgICAvLyBQdXNoIGNhcnJpZWQgYml0cyBhcyBhIG1hc2tcbiAgICBpZiAobWFza2VkV29yZHMgJiYgY2FycnkgIT09IDApIHtcbiAgICAgIG1hc2tlZFdvcmRzLndvcmRzW21hc2tlZFdvcmRzLmxlbmd0aCsrXSA9IGNhcnJ5O1xuICAgIH1cblxuICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy53b3Jkc1swXSA9IDA7XG4gICAgICB0aGlzLmxlbmd0aCA9IDE7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaXNocm4gPSBmdW5jdGlvbiBpc2hybiAoYml0cywgaGludCwgZXh0ZW5kZWQpIHtcbiAgICAvLyBUT0RPKGluZHV0bnkpOiBpbXBsZW1lbnQgbWVcbiAgICBhc3NlcnQodGhpcy5uZWdhdGl2ZSA9PT0gMCk7XG4gICAgcmV0dXJuIHRoaXMuaXVzaHJuKGJpdHMsIGhpbnQsIGV4dGVuZGVkKTtcbiAgfTtcblxuICAvLyBTaGlmdC1sZWZ0XG4gIEJOLnByb3RvdHlwZS5zaGxuID0gZnVuY3Rpb24gc2hsbiAoYml0cykge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaXNobG4oYml0cyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnVzaGxuID0gZnVuY3Rpb24gdXNobG4gKGJpdHMpIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLml1c2hsbihiaXRzKTtcbiAgfTtcblxuICAvLyBTaGlmdC1yaWdodFxuICBCTi5wcm90b3R5cGUuc2hybiA9IGZ1bmN0aW9uIHNocm4gKGJpdHMpIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLmlzaHJuKGJpdHMpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS51c2hybiA9IGZ1bmN0aW9uIHVzaHJuIChiaXRzKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pdXNocm4oYml0cyk7XG4gIH07XG5cbiAgLy8gVGVzdCBpZiBuIGJpdCBpcyBzZXRcbiAgQk4ucHJvdG90eXBlLnRlc3RuID0gZnVuY3Rpb24gdGVzdG4gKGJpdCkge1xuICAgIGFzc2VydCh0eXBlb2YgYml0ID09PSAnbnVtYmVyJyAmJiBiaXQgPj0gMCk7XG4gICAgdmFyIHIgPSBiaXQgJSAyNjtcbiAgICB2YXIgcyA9IChiaXQgLSByKSAvIDI2O1xuICAgIHZhciBxID0gMSA8PCByO1xuXG4gICAgLy8gRmFzdCBjYXNlOiBiaXQgaXMgbXVjaCBoaWdoZXIgdGhhbiBhbGwgZXhpc3Rpbmcgd29yZHNcbiAgICBpZiAodGhpcy5sZW5ndGggPD0gcykgcmV0dXJuIGZhbHNlO1xuXG4gICAgLy8gQ2hlY2sgYml0IGFuZCByZXR1cm5cbiAgICB2YXIgdyA9IHRoaXMud29yZHNbc107XG5cbiAgICByZXR1cm4gISEodyAmIHEpO1xuICB9O1xuXG4gIC8vIFJldHVybiBvbmx5IGxvd2VycyBiaXRzIG9mIG51bWJlciAoaW4tcGxhY2UpXG4gIEJOLnByb3RvdHlwZS5pbWFza24gPSBmdW5jdGlvbiBpbWFza24gKGJpdHMpIHtcbiAgICBhc3NlcnQodHlwZW9mIGJpdHMgPT09ICdudW1iZXInICYmIGJpdHMgPj0gMCk7XG4gICAgdmFyIHIgPSBiaXRzICUgMjY7XG4gICAgdmFyIHMgPSAoYml0cyAtIHIpIC8gMjY7XG5cbiAgICBhc3NlcnQodGhpcy5uZWdhdGl2ZSA9PT0gMCwgJ2ltYXNrbiB3b3JrcyBvbmx5IHdpdGggcG9zaXRpdmUgbnVtYmVycycpO1xuXG4gICAgaWYgKHRoaXMubGVuZ3RoIDw9IHMpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGlmIChyICE9PSAwKSB7XG4gICAgICBzKys7XG4gICAgfVxuICAgIHRoaXMubGVuZ3RoID0gTWF0aC5taW4ocywgdGhpcy5sZW5ndGgpO1xuXG4gICAgaWYgKHIgIT09IDApIHtcbiAgICAgIHZhciBtYXNrID0gMHgzZmZmZmZmIF4gKCgweDNmZmZmZmYgPj4+IHIpIDw8IHIpO1xuICAgICAgdGhpcy53b3Jkc1t0aGlzLmxlbmd0aCAtIDFdICY9IG1hc2s7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICAvLyBSZXR1cm4gb25seSBsb3dlcnMgYml0cyBvZiBudW1iZXJcbiAgQk4ucHJvdG90eXBlLm1hc2tuID0gZnVuY3Rpb24gbWFza24gKGJpdHMpIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLmltYXNrbihiaXRzKTtcbiAgfTtcblxuICAvLyBBZGQgcGxhaW4gbnVtYmVyIGBudW1gIHRvIGB0aGlzYFxuICBCTi5wcm90b3R5cGUuaWFkZG4gPSBmdW5jdGlvbiBpYWRkbiAobnVtKSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBudW0gPT09ICdudW1iZXInKTtcbiAgICBhc3NlcnQobnVtIDwgMHg0MDAwMDAwKTtcbiAgICBpZiAobnVtIDwgMCkgcmV0dXJuIHRoaXMuaXN1Ym4oLW51bSk7XG5cbiAgICAvLyBQb3NzaWJsZSBzaWduIGNoYW5nZVxuICAgIGlmICh0aGlzLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICBpZiAodGhpcy5sZW5ndGggPT09IDEgJiYgKHRoaXMud29yZHNbMF0gfCAwKSA8IG51bSkge1xuICAgICAgICB0aGlzLndvcmRzWzBdID0gbnVtIC0gKHRoaXMud29yZHNbMF0gfCAwKTtcbiAgICAgICAgdGhpcy5uZWdhdGl2ZSA9IDA7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMDtcbiAgICAgIHRoaXMuaXN1Ym4obnVtKTtcbiAgICAgIHRoaXMubmVnYXRpdmUgPSAxO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLy8gQWRkIHdpdGhvdXQgY2hlY2tzXG4gICAgcmV0dXJuIHRoaXMuX2lhZGRuKG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLl9pYWRkbiA9IGZ1bmN0aW9uIF9pYWRkbiAobnVtKSB7XG4gICAgdGhpcy53b3Jkc1swXSArPSBudW07XG5cbiAgICAvLyBDYXJyeVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGggJiYgdGhpcy53b3Jkc1tpXSA+PSAweDQwMDAwMDA7IGkrKykge1xuICAgICAgdGhpcy53b3Jkc1tpXSAtPSAweDQwMDAwMDA7XG4gICAgICBpZiAoaSA9PT0gdGhpcy5sZW5ndGggLSAxKSB7XG4gICAgICAgIHRoaXMud29yZHNbaSArIDFdID0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMud29yZHNbaSArIDFdKys7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMubGVuZ3RoID0gTWF0aC5tYXgodGhpcy5sZW5ndGgsIGkgKyAxKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIC8vIFN1YnRyYWN0IHBsYWluIG51bWJlciBgbnVtYCBmcm9tIGB0aGlzYFxuICBCTi5wcm90b3R5cGUuaXN1Ym4gPSBmdW5jdGlvbiBpc3VibiAobnVtKSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBudW0gPT09ICdudW1iZXInKTtcbiAgICBhc3NlcnQobnVtIDwgMHg0MDAwMDAwKTtcbiAgICBpZiAobnVtIDwgMCkgcmV0dXJuIHRoaXMuaWFkZG4oLW51bSk7XG5cbiAgICBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgdGhpcy5uZWdhdGl2ZSA9IDA7XG4gICAgICB0aGlzLmlhZGRuKG51bSk7XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHRoaXMud29yZHNbMF0gLT0gbnVtO1xuXG4gICAgaWYgKHRoaXMubGVuZ3RoID09PSAxICYmIHRoaXMud29yZHNbMF0gPCAwKSB7XG4gICAgICB0aGlzLndvcmRzWzBdID0gLXRoaXMud29yZHNbMF07XG4gICAgICB0aGlzLm5lZ2F0aXZlID0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQ2FycnlcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGggJiYgdGhpcy53b3Jkc1tpXSA8IDA7IGkrKykge1xuICAgICAgICB0aGlzLndvcmRzW2ldICs9IDB4NDAwMDAwMDtcbiAgICAgICAgdGhpcy53b3Jkc1tpICsgMV0gLT0gMTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5hZGRuID0gZnVuY3Rpb24gYWRkbiAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pYWRkbihudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5zdWJuID0gZnVuY3Rpb24gc3VibiAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5pc3VibihudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5pYWJzID0gZnVuY3Rpb24gaWFicyAoKSB7XG4gICAgdGhpcy5uZWdhdGl2ZSA9IDA7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuYWJzID0gZnVuY3Rpb24gYWJzICgpIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSgpLmlhYnMoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuX2lzaGxuc3VibXVsID0gZnVuY3Rpb24gX2lzaGxuc3VibXVsIChudW0sIG11bCwgc2hpZnQpIHtcbiAgICB2YXIgbGVuID0gbnVtLmxlbmd0aCArIHNoaWZ0O1xuICAgIHZhciBpO1xuXG4gICAgdGhpcy5fZXhwYW5kKGxlbik7XG5cbiAgICB2YXIgdztcbiAgICB2YXIgY2FycnkgPSAwO1xuICAgIGZvciAoaSA9IDA7IGkgPCBudW0ubGVuZ3RoOyBpKyspIHtcbiAgICAgIHcgPSAodGhpcy53b3Jkc1tpICsgc2hpZnRdIHwgMCkgKyBjYXJyeTtcbiAgICAgIHZhciByaWdodCA9IChudW0ud29yZHNbaV0gfCAwKSAqIG11bDtcbiAgICAgIHcgLT0gcmlnaHQgJiAweDNmZmZmZmY7XG4gICAgICBjYXJyeSA9ICh3ID4+IDI2KSAtICgocmlnaHQgLyAweDQwMDAwMDApIHwgMCk7XG4gICAgICB0aGlzLndvcmRzW2kgKyBzaGlmdF0gPSB3ICYgMHgzZmZmZmZmO1xuICAgIH1cbiAgICBmb3IgKDsgaSA8IHRoaXMubGVuZ3RoIC0gc2hpZnQ7IGkrKykge1xuICAgICAgdyA9ICh0aGlzLndvcmRzW2kgKyBzaGlmdF0gfCAwKSArIGNhcnJ5O1xuICAgICAgY2FycnkgPSB3ID4+IDI2O1xuICAgICAgdGhpcy53b3Jkc1tpICsgc2hpZnRdID0gdyAmIDB4M2ZmZmZmZjtcbiAgICB9XG5cbiAgICBpZiAoY2FycnkgPT09IDApIHJldHVybiB0aGlzLnN0cmlwKCk7XG5cbiAgICAvLyBTdWJ0cmFjdGlvbiBvdmVyZmxvd1xuICAgIGFzc2VydChjYXJyeSA9PT0gLTEpO1xuICAgIGNhcnJ5ID0gMDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgdyA9IC0odGhpcy53b3Jkc1tpXSB8IDApICsgY2Fycnk7XG4gICAgICBjYXJyeSA9IHcgPj4gMjY7XG4gICAgICB0aGlzLndvcmRzW2ldID0gdyAmIDB4M2ZmZmZmZjtcbiAgICB9XG4gICAgdGhpcy5uZWdhdGl2ZSA9IDE7XG5cbiAgICByZXR1cm4gdGhpcy5zdHJpcCgpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5fd29yZERpdiA9IGZ1bmN0aW9uIF93b3JkRGl2IChudW0sIG1vZGUpIHtcbiAgICB2YXIgc2hpZnQgPSB0aGlzLmxlbmd0aCAtIG51bS5sZW5ndGg7XG5cbiAgICB2YXIgYSA9IHRoaXMuY2xvbmUoKTtcbiAgICB2YXIgYiA9IG51bTtcblxuICAgIC8vIE5vcm1hbGl6ZVxuICAgIHZhciBiaGkgPSBiLndvcmRzW2IubGVuZ3RoIC0gMV0gfCAwO1xuICAgIHZhciBiaGlCaXRzID0gdGhpcy5fY291bnRCaXRzKGJoaSk7XG4gICAgc2hpZnQgPSAyNiAtIGJoaUJpdHM7XG4gICAgaWYgKHNoaWZ0ICE9PSAwKSB7XG4gICAgICBiID0gYi51c2hsbihzaGlmdCk7XG4gICAgICBhLml1c2hsbihzaGlmdCk7XG4gICAgICBiaGkgPSBiLndvcmRzW2IubGVuZ3RoIC0gMV0gfCAwO1xuICAgIH1cblxuICAgIC8vIEluaXRpYWxpemUgcXVvdGllbnRcbiAgICB2YXIgbSA9IGEubGVuZ3RoIC0gYi5sZW5ndGg7XG4gICAgdmFyIHE7XG5cbiAgICBpZiAobW9kZSAhPT0gJ21vZCcpIHtcbiAgICAgIHEgPSBuZXcgQk4obnVsbCk7XG4gICAgICBxLmxlbmd0aCA9IG0gKyAxO1xuICAgICAgcS53b3JkcyA9IG5ldyBBcnJheShxLmxlbmd0aCk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcS53b3Jkc1tpXSA9IDA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGRpZmYgPSBhLmNsb25lKCkuX2lzaGxuc3VibXVsKGIsIDEsIG0pO1xuICAgIGlmIChkaWZmLm5lZ2F0aXZlID09PSAwKSB7XG4gICAgICBhID0gZGlmZjtcbiAgICAgIGlmIChxKSB7XG4gICAgICAgIHEud29yZHNbbV0gPSAxO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIGogPSBtIC0gMTsgaiA+PSAwOyBqLS0pIHtcbiAgICAgIHZhciBxaiA9IChhLndvcmRzW2IubGVuZ3RoICsgal0gfCAwKSAqIDB4NDAwMDAwMCArXG4gICAgICAgIChhLndvcmRzW2IubGVuZ3RoICsgaiAtIDFdIHwgMCk7XG5cbiAgICAgIC8vIE5PVEU6IChxaiAvIGJoaSkgaXMgKDB4M2ZmZmZmZiAqIDB4NDAwMDAwMCArIDB4M2ZmZmZmZikgLyAweDIwMDAwMDAgbWF4XG4gICAgICAvLyAoMHg3ZmZmZmZmKVxuICAgICAgcWogPSBNYXRoLm1pbigocWogLyBiaGkpIHwgMCwgMHgzZmZmZmZmKTtcblxuICAgICAgYS5faXNobG5zdWJtdWwoYiwgcWosIGopO1xuICAgICAgd2hpbGUgKGEubmVnYXRpdmUgIT09IDApIHtcbiAgICAgICAgcWotLTtcbiAgICAgICAgYS5uZWdhdGl2ZSA9IDA7XG4gICAgICAgIGEuX2lzaGxuc3VibXVsKGIsIDEsIGopO1xuICAgICAgICBpZiAoIWEuaXNaZXJvKCkpIHtcbiAgICAgICAgICBhLm5lZ2F0aXZlIF49IDE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChxKSB7XG4gICAgICAgIHEud29yZHNbal0gPSBxajtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHEpIHtcbiAgICAgIHEuc3RyaXAoKTtcbiAgICB9XG4gICAgYS5zdHJpcCgpO1xuXG4gICAgLy8gRGVub3JtYWxpemVcbiAgICBpZiAobW9kZSAhPT0gJ2RpdicgJiYgc2hpZnQgIT09IDApIHtcbiAgICAgIGEuaXVzaHJuKHNoaWZ0KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGl2OiBxIHx8IG51bGwsXG4gICAgICBtb2Q6IGFcbiAgICB9O1xuICB9O1xuXG4gIC8vIE5PVEU6IDEpIGBtb2RlYCBjYW4gYmUgc2V0IHRvIGBtb2RgIHRvIHJlcXVlc3QgbW9kIG9ubHksXG4gIC8vICAgICAgIHRvIGBkaXZgIHRvIHJlcXVlc3QgZGl2IG9ubHksIG9yIGJlIGFic2VudCB0b1xuICAvLyAgICAgICByZXF1ZXN0IGJvdGggZGl2ICYgbW9kXG4gIC8vICAgICAgIDIpIGBwb3NpdGl2ZWAgaXMgdHJ1ZSBpZiB1bnNpZ25lZCBtb2QgaXMgcmVxdWVzdGVkXG4gIEJOLnByb3RvdHlwZS5kaXZtb2QgPSBmdW5jdGlvbiBkaXZtb2QgKG51bSwgbW9kZSwgcG9zaXRpdmUpIHtcbiAgICBhc3NlcnQoIW51bS5pc1plcm8oKSk7XG5cbiAgICBpZiAodGhpcy5pc1plcm8oKSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGl2OiBuZXcgQk4oMCksXG4gICAgICAgIG1vZDogbmV3IEJOKDApXG4gICAgICB9O1xuICAgIH1cblxuICAgIHZhciBkaXYsIG1vZCwgcmVzO1xuICAgIGlmICh0aGlzLm5lZ2F0aXZlICE9PSAwICYmIG51bS5uZWdhdGl2ZSA9PT0gMCkge1xuICAgICAgcmVzID0gdGhpcy5uZWcoKS5kaXZtb2QobnVtLCBtb2RlKTtcblxuICAgICAgaWYgKG1vZGUgIT09ICdtb2QnKSB7XG4gICAgICAgIGRpdiA9IHJlcy5kaXYubmVnKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChtb2RlICE9PSAnZGl2Jykge1xuICAgICAgICBtb2QgPSByZXMubW9kLm5lZygpO1xuICAgICAgICBpZiAocG9zaXRpdmUgJiYgbW9kLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICAgICAgbW9kLmlhZGQobnVtKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkaXY6IGRpdixcbiAgICAgICAgbW9kOiBtb2RcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubmVnYXRpdmUgPT09IDAgJiYgbnVtLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICByZXMgPSB0aGlzLmRpdm1vZChudW0ubmVnKCksIG1vZGUpO1xuXG4gICAgICBpZiAobW9kZSAhPT0gJ21vZCcpIHtcbiAgICAgICAgZGl2ID0gcmVzLmRpdi5uZWcoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGl2OiBkaXYsXG4gICAgICAgIG1vZDogcmVzLm1vZFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoKHRoaXMubmVnYXRpdmUgJiBudW0ubmVnYXRpdmUpICE9PSAwKSB7XG4gICAgICByZXMgPSB0aGlzLm5lZygpLmRpdm1vZChudW0ubmVnKCksIG1vZGUpO1xuXG4gICAgICBpZiAobW9kZSAhPT0gJ2RpdicpIHtcbiAgICAgICAgbW9kID0gcmVzLm1vZC5uZWcoKTtcbiAgICAgICAgaWYgKHBvc2l0aXZlICYmIG1vZC5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgICAgIG1vZC5pc3ViKG51bSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGl2OiByZXMuZGl2LFxuICAgICAgICBtb2Q6IG1vZFxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBCb3RoIG51bWJlcnMgYXJlIHBvc2l0aXZlIGF0IHRoaXMgcG9pbnRcblxuICAgIC8vIFN0cmlwIGJvdGggbnVtYmVycyB0byBhcHByb3hpbWF0ZSBzaGlmdCB2YWx1ZVxuICAgIGlmIChudW0ubGVuZ3RoID4gdGhpcy5sZW5ndGggfHwgdGhpcy5jbXAobnVtKSA8IDApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRpdjogbmV3IEJOKDApLFxuICAgICAgICBtb2Q6IHRoaXNcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gVmVyeSBzaG9ydCByZWR1Y3Rpb25cbiAgICBpZiAobnVtLmxlbmd0aCA9PT0gMSkge1xuICAgICAgaWYgKG1vZGUgPT09ICdkaXYnKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZGl2OiB0aGlzLmRpdm4obnVtLndvcmRzWzBdKSxcbiAgICAgICAgICBtb2Q6IG51bGxcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1vZGUgPT09ICdtb2QnKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZGl2OiBudWxsLFxuICAgICAgICAgIG1vZDogbmV3IEJOKHRoaXMubW9kbihudW0ud29yZHNbMF0pKVxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkaXY6IHRoaXMuZGl2bihudW0ud29yZHNbMF0pLFxuICAgICAgICBtb2Q6IG5ldyBCTih0aGlzLm1vZG4obnVtLndvcmRzWzBdKSlcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3dvcmREaXYobnVtLCBtb2RlKTtcbiAgfTtcblxuICAvLyBGaW5kIGB0aGlzYCAvIGBudW1gXG4gIEJOLnByb3RvdHlwZS5kaXYgPSBmdW5jdGlvbiBkaXYgKG51bSkge1xuICAgIHJldHVybiB0aGlzLmRpdm1vZChudW0sICdkaXYnLCBmYWxzZSkuZGl2O1xuICB9O1xuXG4gIC8vIEZpbmQgYHRoaXNgICUgYG51bWBcbiAgQk4ucHJvdG90eXBlLm1vZCA9IGZ1bmN0aW9uIG1vZCAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuZGl2bW9kKG51bSwgJ21vZCcsIGZhbHNlKS5tb2Q7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnVtb2QgPSBmdW5jdGlvbiB1bW9kIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5kaXZtb2QobnVtLCAnbW9kJywgdHJ1ZSkubW9kO1xuICB9O1xuXG4gIC8vIEZpbmQgUm91bmQoYHRoaXNgIC8gYG51bWApXG4gIEJOLnByb3RvdHlwZS5kaXZSb3VuZCA9IGZ1bmN0aW9uIGRpdlJvdW5kIChudW0pIHtcbiAgICB2YXIgZG0gPSB0aGlzLmRpdm1vZChudW0pO1xuXG4gICAgLy8gRmFzdCBjYXNlIC0gZXhhY3QgZGl2aXNpb25cbiAgICBpZiAoZG0ubW9kLmlzWmVybygpKSByZXR1cm4gZG0uZGl2O1xuXG4gICAgdmFyIG1vZCA9IGRtLmRpdi5uZWdhdGl2ZSAhPT0gMCA/IGRtLm1vZC5pc3ViKG51bSkgOiBkbS5tb2Q7XG5cbiAgICB2YXIgaGFsZiA9IG51bS51c2hybigxKTtcbiAgICB2YXIgcjIgPSBudW0uYW5kbG4oMSk7XG4gICAgdmFyIGNtcCA9IG1vZC5jbXAoaGFsZik7XG5cbiAgICAvLyBSb3VuZCBkb3duXG4gICAgaWYgKGNtcCA8IDAgfHwgcjIgPT09IDEgJiYgY21wID09PSAwKSByZXR1cm4gZG0uZGl2O1xuXG4gICAgLy8gUm91bmQgdXBcbiAgICByZXR1cm4gZG0uZGl2Lm5lZ2F0aXZlICE9PSAwID8gZG0uZGl2LmlzdWJuKDEpIDogZG0uZGl2LmlhZGRuKDEpO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5tb2RuID0gZnVuY3Rpb24gbW9kbiAobnVtKSB7XG4gICAgYXNzZXJ0KG51bSA8PSAweDNmZmZmZmYpO1xuICAgIHZhciBwID0gKDEgPDwgMjYpICUgbnVtO1xuXG4gICAgdmFyIGFjYyA9IDA7XG4gICAgZm9yICh2YXIgaSA9IHRoaXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGFjYyA9IChwICogYWNjICsgKHRoaXMud29yZHNbaV0gfCAwKSkgJSBudW07XG4gICAgfVxuXG4gICAgcmV0dXJuIGFjYztcbiAgfTtcblxuICAvLyBJbi1wbGFjZSBkaXZpc2lvbiBieSBudW1iZXJcbiAgQk4ucHJvdG90eXBlLmlkaXZuID0gZnVuY3Rpb24gaWRpdm4gKG51bSkge1xuICAgIGFzc2VydChudW0gPD0gMHgzZmZmZmZmKTtcblxuICAgIHZhciBjYXJyeSA9IDA7XG4gICAgZm9yICh2YXIgaSA9IHRoaXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHZhciB3ID0gKHRoaXMud29yZHNbaV0gfCAwKSArIGNhcnJ5ICogMHg0MDAwMDAwO1xuICAgICAgdGhpcy53b3Jkc1tpXSA9ICh3IC8gbnVtKSB8IDA7XG4gICAgICBjYXJyeSA9IHcgJSBudW07XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc3RyaXAoKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuZGl2biA9IGZ1bmN0aW9uIGRpdm4gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNsb25lKCkuaWRpdm4obnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuZWdjZCA9IGZ1bmN0aW9uIGVnY2QgKHApIHtcbiAgICBhc3NlcnQocC5uZWdhdGl2ZSA9PT0gMCk7XG4gICAgYXNzZXJ0KCFwLmlzWmVybygpKTtcblxuICAgIHZhciB4ID0gdGhpcztcbiAgICB2YXIgeSA9IHAuY2xvbmUoKTtcblxuICAgIGlmICh4Lm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICB4ID0geC51bW9kKHApO1xuICAgIH0gZWxzZSB7XG4gICAgICB4ID0geC5jbG9uZSgpO1xuICAgIH1cblxuICAgIC8vIEEgKiB4ICsgQiAqIHkgPSB4XG4gICAgdmFyIEEgPSBuZXcgQk4oMSk7XG4gICAgdmFyIEIgPSBuZXcgQk4oMCk7XG5cbiAgICAvLyBDICogeCArIEQgKiB5ID0geVxuICAgIHZhciBDID0gbmV3IEJOKDApO1xuICAgIHZhciBEID0gbmV3IEJOKDEpO1xuXG4gICAgdmFyIGcgPSAwO1xuXG4gICAgd2hpbGUgKHguaXNFdmVuKCkgJiYgeS5pc0V2ZW4oKSkge1xuICAgICAgeC5pdXNocm4oMSk7XG4gICAgICB5Lml1c2hybigxKTtcbiAgICAgICsrZztcbiAgICB9XG5cbiAgICB2YXIgeXAgPSB5LmNsb25lKCk7XG4gICAgdmFyIHhwID0geC5jbG9uZSgpO1xuXG4gICAgd2hpbGUgKCF4LmlzWmVybygpKSB7XG4gICAgICBmb3IgKHZhciBpID0gMCwgaW0gPSAxOyAoeC53b3Jkc1swXSAmIGltKSA9PT0gMCAmJiBpIDwgMjY7ICsraSwgaW0gPDw9IDEpO1xuICAgICAgaWYgKGkgPiAwKSB7XG4gICAgICAgIHguaXVzaHJuKGkpO1xuICAgICAgICB3aGlsZSAoaS0tID4gMCkge1xuICAgICAgICAgIGlmIChBLmlzT2RkKCkgfHwgQi5pc09kZCgpKSB7XG4gICAgICAgICAgICBBLmlhZGQoeXApO1xuICAgICAgICAgICAgQi5pc3ViKHhwKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBBLml1c2hybigxKTtcbiAgICAgICAgICBCLml1c2hybigxKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmb3IgKHZhciBqID0gMCwgam0gPSAxOyAoeS53b3Jkc1swXSAmIGptKSA9PT0gMCAmJiBqIDwgMjY7ICsraiwgam0gPDw9IDEpO1xuICAgICAgaWYgKGogPiAwKSB7XG4gICAgICAgIHkuaXVzaHJuKGopO1xuICAgICAgICB3aGlsZSAoai0tID4gMCkge1xuICAgICAgICAgIGlmIChDLmlzT2RkKCkgfHwgRC5pc09kZCgpKSB7XG4gICAgICAgICAgICBDLmlhZGQoeXApO1xuICAgICAgICAgICAgRC5pc3ViKHhwKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBDLml1c2hybigxKTtcbiAgICAgICAgICBELml1c2hybigxKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoeC5jbXAoeSkgPj0gMCkge1xuICAgICAgICB4LmlzdWIoeSk7XG4gICAgICAgIEEuaXN1YihDKTtcbiAgICAgICAgQi5pc3ViKEQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgeS5pc3ViKHgpO1xuICAgICAgICBDLmlzdWIoQSk7XG4gICAgICAgIEQuaXN1YihCKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgYTogQyxcbiAgICAgIGI6IEQsXG4gICAgICBnY2Q6IHkuaXVzaGxuKGcpXG4gICAgfTtcbiAgfTtcblxuICAvLyBUaGlzIGlzIHJlZHVjZWQgaW5jYXJuYXRpb24gb2YgdGhlIGJpbmFyeSBFRUFcbiAgLy8gYWJvdmUsIGRlc2lnbmF0ZWQgdG8gaW52ZXJ0IG1lbWJlcnMgb2YgdGhlXG4gIC8vIF9wcmltZV8gZmllbGRzIEYocCkgYXQgYSBtYXhpbWFsIHNwZWVkXG4gIEJOLnByb3RvdHlwZS5faW52bXAgPSBmdW5jdGlvbiBfaW52bXAgKHApIHtcbiAgICBhc3NlcnQocC5uZWdhdGl2ZSA9PT0gMCk7XG4gICAgYXNzZXJ0KCFwLmlzWmVybygpKTtcblxuICAgIHZhciBhID0gdGhpcztcbiAgICB2YXIgYiA9IHAuY2xvbmUoKTtcblxuICAgIGlmIChhLm5lZ2F0aXZlICE9PSAwKSB7XG4gICAgICBhID0gYS51bW9kKHApO1xuICAgIH0gZWxzZSB7XG4gICAgICBhID0gYS5jbG9uZSgpO1xuICAgIH1cblxuICAgIHZhciB4MSA9IG5ldyBCTigxKTtcbiAgICB2YXIgeDIgPSBuZXcgQk4oMCk7XG5cbiAgICB2YXIgZGVsdGEgPSBiLmNsb25lKCk7XG5cbiAgICB3aGlsZSAoYS5jbXBuKDEpID4gMCAmJiBiLmNtcG4oMSkgPiAwKSB7XG4gICAgICBmb3IgKHZhciBpID0gMCwgaW0gPSAxOyAoYS53b3Jkc1swXSAmIGltKSA9PT0gMCAmJiBpIDwgMjY7ICsraSwgaW0gPDw9IDEpO1xuICAgICAgaWYgKGkgPiAwKSB7XG4gICAgICAgIGEuaXVzaHJuKGkpO1xuICAgICAgICB3aGlsZSAoaS0tID4gMCkge1xuICAgICAgICAgIGlmICh4MS5pc09kZCgpKSB7XG4gICAgICAgICAgICB4MS5pYWRkKGRlbHRhKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB4MS5pdXNocm4oMSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIgaiA9IDAsIGptID0gMTsgKGIud29yZHNbMF0gJiBqbSkgPT09IDAgJiYgaiA8IDI2OyArK2osIGptIDw8PSAxKTtcbiAgICAgIGlmIChqID4gMCkge1xuICAgICAgICBiLml1c2hybihqKTtcbiAgICAgICAgd2hpbGUgKGotLSA+IDApIHtcbiAgICAgICAgICBpZiAoeDIuaXNPZGQoKSkge1xuICAgICAgICAgICAgeDIuaWFkZChkZWx0YSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgeDIuaXVzaHJuKDEpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChhLmNtcChiKSA+PSAwKSB7XG4gICAgICAgIGEuaXN1YihiKTtcbiAgICAgICAgeDEuaXN1Yih4Mik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBiLmlzdWIoYSk7XG4gICAgICAgIHgyLmlzdWIoeDEpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciByZXM7XG4gICAgaWYgKGEuY21wbigxKSA9PT0gMCkge1xuICAgICAgcmVzID0geDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlcyA9IHgyO1xuICAgIH1cblxuICAgIGlmIChyZXMuY21wbigwKSA8IDApIHtcbiAgICAgIHJlcy5pYWRkKHApO1xuICAgIH1cblxuICAgIHJldHVybiByZXM7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmdjZCA9IGZ1bmN0aW9uIGdjZCAobnVtKSB7XG4gICAgaWYgKHRoaXMuaXNaZXJvKCkpIHJldHVybiBudW0uYWJzKCk7XG4gICAgaWYgKG51bS5pc1plcm8oKSkgcmV0dXJuIHRoaXMuYWJzKCk7XG5cbiAgICB2YXIgYSA9IHRoaXMuY2xvbmUoKTtcbiAgICB2YXIgYiA9IG51bS5jbG9uZSgpO1xuICAgIGEubmVnYXRpdmUgPSAwO1xuICAgIGIubmVnYXRpdmUgPSAwO1xuXG4gICAgLy8gUmVtb3ZlIGNvbW1vbiBmYWN0b3Igb2YgdHdvXG4gICAgZm9yICh2YXIgc2hpZnQgPSAwOyBhLmlzRXZlbigpICYmIGIuaXNFdmVuKCk7IHNoaWZ0KyspIHtcbiAgICAgIGEuaXVzaHJuKDEpO1xuICAgICAgYi5pdXNocm4oMSk7XG4gICAgfVxuXG4gICAgZG8ge1xuICAgICAgd2hpbGUgKGEuaXNFdmVuKCkpIHtcbiAgICAgICAgYS5pdXNocm4oMSk7XG4gICAgICB9XG4gICAgICB3aGlsZSAoYi5pc0V2ZW4oKSkge1xuICAgICAgICBiLml1c2hybigxKTtcbiAgICAgIH1cblxuICAgICAgdmFyIHIgPSBhLmNtcChiKTtcbiAgICAgIGlmIChyIDwgMCkge1xuICAgICAgICAvLyBTd2FwIGBhYCBhbmQgYGJgIHRvIG1ha2UgYGFgIGFsd2F5cyBiaWdnZXIgdGhhbiBgYmBcbiAgICAgICAgdmFyIHQgPSBhO1xuICAgICAgICBhID0gYjtcbiAgICAgICAgYiA9IHQ7XG4gICAgICB9IGVsc2UgaWYgKHIgPT09IDAgfHwgYi5jbXBuKDEpID09PSAwKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBhLmlzdWIoYik7XG4gICAgfSB3aGlsZSAodHJ1ZSk7XG5cbiAgICByZXR1cm4gYi5pdXNobG4oc2hpZnQpO1xuICB9O1xuXG4gIC8vIEludmVydCBudW1iZXIgaW4gdGhlIGZpZWxkIEYobnVtKVxuICBCTi5wcm90b3R5cGUuaW52bSA9IGZ1bmN0aW9uIGludm0gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmVnY2QobnVtKS5hLnVtb2QobnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaXNFdmVuID0gZnVuY3Rpb24gaXNFdmVuICgpIHtcbiAgICByZXR1cm4gKHRoaXMud29yZHNbMF0gJiAxKSA9PT0gMDtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaXNPZGQgPSBmdW5jdGlvbiBpc09kZCAoKSB7XG4gICAgcmV0dXJuICh0aGlzLndvcmRzWzBdICYgMSkgPT09IDE7XG4gIH07XG5cbiAgLy8gQW5kIGZpcnN0IHdvcmQgYW5kIG51bVxuICBCTi5wcm90b3R5cGUuYW5kbG4gPSBmdW5jdGlvbiBhbmRsbiAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMud29yZHNbMF0gJiBudW07XG4gIH07XG5cbiAgLy8gSW5jcmVtZW50IGF0IHRoZSBiaXQgcG9zaXRpb24gaW4tbGluZVxuICBCTi5wcm90b3R5cGUuYmluY24gPSBmdW5jdGlvbiBiaW5jbiAoYml0KSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBiaXQgPT09ICdudW1iZXInKTtcbiAgICB2YXIgciA9IGJpdCAlIDI2O1xuICAgIHZhciBzID0gKGJpdCAtIHIpIC8gMjY7XG4gICAgdmFyIHEgPSAxIDw8IHI7XG5cbiAgICAvLyBGYXN0IGNhc2U6IGJpdCBpcyBtdWNoIGhpZ2hlciB0aGFuIGFsbCBleGlzdGluZyB3b3Jkc1xuICAgIGlmICh0aGlzLmxlbmd0aCA8PSBzKSB7XG4gICAgICB0aGlzLl9leHBhbmQocyArIDEpO1xuICAgICAgdGhpcy53b3Jkc1tzXSB8PSBxO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLy8gQWRkIGJpdCBhbmQgcHJvcGFnYXRlLCBpZiBuZWVkZWRcbiAgICB2YXIgY2FycnkgPSBxO1xuICAgIGZvciAodmFyIGkgPSBzOyBjYXJyeSAhPT0gMCAmJiBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHcgPSB0aGlzLndvcmRzW2ldIHwgMDtcbiAgICAgIHcgKz0gY2Fycnk7XG4gICAgICBjYXJyeSA9IHcgPj4+IDI2O1xuICAgICAgdyAmPSAweDNmZmZmZmY7XG4gICAgICB0aGlzLndvcmRzW2ldID0gdztcbiAgICB9XG4gICAgaWYgKGNhcnJ5ICE9PSAwKSB7XG4gICAgICB0aGlzLndvcmRzW2ldID0gY2Fycnk7XG4gICAgICB0aGlzLmxlbmd0aCsrO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuaXNaZXJvID0gZnVuY3Rpb24gaXNaZXJvICgpIHtcbiAgICByZXR1cm4gdGhpcy5sZW5ndGggPT09IDEgJiYgdGhpcy53b3Jkc1swXSA9PT0gMDtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuY21wbiA9IGZ1bmN0aW9uIGNtcG4gKG51bSkge1xuICAgIHZhciBuZWdhdGl2ZSA9IG51bSA8IDA7XG5cbiAgICBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCAmJiAhbmVnYXRpdmUpIHJldHVybiAtMTtcbiAgICBpZiAodGhpcy5uZWdhdGl2ZSA9PT0gMCAmJiBuZWdhdGl2ZSkgcmV0dXJuIDE7XG5cbiAgICB0aGlzLnN0cmlwKCk7XG5cbiAgICB2YXIgcmVzO1xuICAgIGlmICh0aGlzLmxlbmd0aCA+IDEpIHtcbiAgICAgIHJlcyA9IDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChuZWdhdGl2ZSkge1xuICAgICAgICBudW0gPSAtbnVtO1xuICAgICAgfVxuXG4gICAgICBhc3NlcnQobnVtIDw9IDB4M2ZmZmZmZiwgJ051bWJlciBpcyB0b28gYmlnJyk7XG5cbiAgICAgIHZhciB3ID0gdGhpcy53b3Jkc1swXSB8IDA7XG4gICAgICByZXMgPSB3ID09PSBudW0gPyAwIDogdyA8IG51bSA/IC0xIDogMTtcbiAgICB9XG4gICAgaWYgKHRoaXMubmVnYXRpdmUgIT09IDApIHJldHVybiAtcmVzIHwgMDtcbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIC8vIENvbXBhcmUgdHdvIG51bWJlcnMgYW5kIHJldHVybjpcbiAgLy8gMSAtIGlmIGB0aGlzYCA+IGBudW1gXG4gIC8vIDAgLSBpZiBgdGhpc2AgPT0gYG51bWBcbiAgLy8gLTEgLSBpZiBgdGhpc2AgPCBgbnVtYFxuICBCTi5wcm90b3R5cGUuY21wID0gZnVuY3Rpb24gY21wIChudW0pIHtcbiAgICBpZiAodGhpcy5uZWdhdGl2ZSAhPT0gMCAmJiBudW0ubmVnYXRpdmUgPT09IDApIHJldHVybiAtMTtcbiAgICBpZiAodGhpcy5uZWdhdGl2ZSA9PT0gMCAmJiBudW0ubmVnYXRpdmUgIT09IDApIHJldHVybiAxO1xuXG4gICAgdmFyIHJlcyA9IHRoaXMudWNtcChudW0pO1xuICAgIGlmICh0aGlzLm5lZ2F0aXZlICE9PSAwKSByZXR1cm4gLXJlcyB8IDA7XG4gICAgcmV0dXJuIHJlcztcbiAgfTtcblxuICAvLyBVbnNpZ25lZCBjb21wYXJpc29uXG4gIEJOLnByb3RvdHlwZS51Y21wID0gZnVuY3Rpb24gdWNtcCAobnVtKSB7XG4gICAgLy8gQXQgdGhpcyBwb2ludCBib3RoIG51bWJlcnMgaGF2ZSB0aGUgc2FtZSBzaWduXG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbnVtLmxlbmd0aCkgcmV0dXJuIDE7XG4gICAgaWYgKHRoaXMubGVuZ3RoIDwgbnVtLmxlbmd0aCkgcmV0dXJuIC0xO1xuXG4gICAgdmFyIHJlcyA9IDA7XG4gICAgZm9yICh2YXIgaSA9IHRoaXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHZhciBhID0gdGhpcy53b3Jkc1tpXSB8IDA7XG4gICAgICB2YXIgYiA9IG51bS53b3Jkc1tpXSB8IDA7XG5cbiAgICAgIGlmIChhID09PSBiKSBjb250aW51ZTtcbiAgICAgIGlmIChhIDwgYikge1xuICAgICAgICByZXMgPSAtMTtcbiAgICAgIH0gZWxzZSBpZiAoYSA+IGIpIHtcbiAgICAgICAgcmVzID0gMTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5ndG4gPSBmdW5jdGlvbiBndG4gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNtcG4obnVtKSA9PT0gMTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuZ3QgPSBmdW5jdGlvbiBndCAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY21wKG51bSkgPT09IDE7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmd0ZW4gPSBmdW5jdGlvbiBndGVuIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbXBuKG51bSkgPj0gMDtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuZ3RlID0gZnVuY3Rpb24gZ3RlIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbXAobnVtKSA+PSAwO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5sdG4gPSBmdW5jdGlvbiBsdG4gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNtcG4obnVtKSA9PT0gLTE7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmx0ID0gZnVuY3Rpb24gbHQgKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNtcChudW0pID09PSAtMTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUubHRlbiA9IGZ1bmN0aW9uIGx0ZW4gKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNtcG4obnVtKSA8PSAwO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5sdGUgPSBmdW5jdGlvbiBsdGUgKG51bSkge1xuICAgIHJldHVybiB0aGlzLmNtcChudW0pIDw9IDA7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmVxbiA9IGZ1bmN0aW9uIGVxbiAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuY21wbihudW0pID09PSAwO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5lcSA9IGZ1bmN0aW9uIGVxIChudW0pIHtcbiAgICByZXR1cm4gdGhpcy5jbXAobnVtKSA9PT0gMDtcbiAgfTtcblxuICAvL1xuICAvLyBBIHJlZHVjZSBjb250ZXh0LCBjb3VsZCBiZSB1c2luZyBtb250Z29tZXJ5IG9yIHNvbWV0aGluZyBiZXR0ZXIsIGRlcGVuZGluZ1xuICAvLyBvbiB0aGUgYG1gIGl0c2VsZi5cbiAgLy9cbiAgQk4ucmVkID0gZnVuY3Rpb24gcmVkIChudW0pIHtcbiAgICByZXR1cm4gbmV3IFJlZChudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS50b1JlZCA9IGZ1bmN0aW9uIHRvUmVkIChjdHgpIHtcbiAgICBhc3NlcnQoIXRoaXMucmVkLCAnQWxyZWFkeSBhIG51bWJlciBpbiByZWR1Y3Rpb24gY29udGV4dCcpO1xuICAgIGFzc2VydCh0aGlzLm5lZ2F0aXZlID09PSAwLCAncmVkIHdvcmtzIG9ubHkgd2l0aCBwb3NpdGl2ZXMnKTtcbiAgICByZXR1cm4gY3R4LmNvbnZlcnRUbyh0aGlzKS5fZm9yY2VSZWQoY3R4KTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUuZnJvbVJlZCA9IGZ1bmN0aW9uIGZyb21SZWQgKCkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ2Zyb21SZWQgd29ya3Mgb25seSB3aXRoIG51bWJlcnMgaW4gcmVkdWN0aW9uIGNvbnRleHQnKTtcbiAgICByZXR1cm4gdGhpcy5yZWQuY29udmVydEZyb20odGhpcyk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLl9mb3JjZVJlZCA9IGZ1bmN0aW9uIF9mb3JjZVJlZCAoY3R4KSB7XG4gICAgdGhpcy5yZWQgPSBjdHg7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLmZvcmNlUmVkID0gZnVuY3Rpb24gZm9yY2VSZWQgKGN0eCkge1xuICAgIGFzc2VydCghdGhpcy5yZWQsICdBbHJlYWR5IGEgbnVtYmVyIGluIHJlZHVjdGlvbiBjb250ZXh0Jyk7XG4gICAgcmV0dXJuIHRoaXMuX2ZvcmNlUmVkKGN0eCk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZEFkZCA9IGZ1bmN0aW9uIHJlZEFkZCAobnVtKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkQWRkIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHJldHVybiB0aGlzLnJlZC5hZGQodGhpcywgbnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkSUFkZCA9IGZ1bmN0aW9uIHJlZElBZGQgKG51bSkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZElBZGQgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLmlhZGQodGhpcywgbnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkU3ViID0gZnVuY3Rpb24gcmVkU3ViIChudW0pIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdyZWRTdWIgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLnN1Yih0aGlzLCBudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5yZWRJU3ViID0gZnVuY3Rpb24gcmVkSVN1YiAobnVtKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkSVN1YiB3b3JrcyBvbmx5IHdpdGggcmVkIG51bWJlcnMnKTtcbiAgICByZXR1cm4gdGhpcy5yZWQuaXN1Yih0aGlzLCBudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5yZWRTaGwgPSBmdW5jdGlvbiByZWRTaGwgKG51bSkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZFNobCB3b3JrcyBvbmx5IHdpdGggcmVkIG51bWJlcnMnKTtcbiAgICByZXR1cm4gdGhpcy5yZWQuc2hsKHRoaXMsIG51bSk7XG4gIH07XG5cbiAgQk4ucHJvdG90eXBlLnJlZE11bCA9IGZ1bmN0aW9uIHJlZE11bCAobnVtKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkTXVsIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHRoaXMucmVkLl92ZXJpZnkyKHRoaXMsIG51bSk7XG4gICAgcmV0dXJuIHRoaXMucmVkLm11bCh0aGlzLCBudW0pO1xuICB9O1xuXG4gIEJOLnByb3RvdHlwZS5yZWRJTXVsID0gZnVuY3Rpb24gcmVkSU11bCAobnVtKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkTXVsIHdvcmtzIG9ubHkgd2l0aCByZWQgbnVtYmVycycpO1xuICAgIHRoaXMucmVkLl92ZXJpZnkyKHRoaXMsIG51bSk7XG4gICAgcmV0dXJuIHRoaXMucmVkLmltdWwodGhpcywgbnVtKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkU3FyID0gZnVuY3Rpb24gcmVkU3FyICgpIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdyZWRTcXIgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgdGhpcy5yZWQuX3ZlcmlmeTEodGhpcyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLnNxcih0aGlzKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkSVNxciA9IGZ1bmN0aW9uIHJlZElTcXIgKCkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZElTcXIgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgdGhpcy5yZWQuX3ZlcmlmeTEodGhpcyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLmlzcXIodGhpcyk7XG4gIH07XG5cbiAgLy8gU3F1YXJlIHJvb3Qgb3ZlciBwXG4gIEJOLnByb3RvdHlwZS5yZWRTcXJ0ID0gZnVuY3Rpb24gcmVkU3FydCAoKSB7XG4gICAgYXNzZXJ0KHRoaXMucmVkLCAncmVkU3FydCB3b3JrcyBvbmx5IHdpdGggcmVkIG51bWJlcnMnKTtcbiAgICB0aGlzLnJlZC5fdmVyaWZ5MSh0aGlzKTtcbiAgICByZXR1cm4gdGhpcy5yZWQuc3FydCh0aGlzKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkSW52bSA9IGZ1bmN0aW9uIHJlZEludm0gKCkge1xuICAgIGFzc2VydCh0aGlzLnJlZCwgJ3JlZEludm0gd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgdGhpcy5yZWQuX3ZlcmlmeTEodGhpcyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLmludm0odGhpcyk7XG4gIH07XG5cbiAgLy8gUmV0dXJuIG5lZ2F0aXZlIGNsb25lIG9mIGB0aGlzYCAlIGByZWQgbW9kdWxvYFxuICBCTi5wcm90b3R5cGUucmVkTmVnID0gZnVuY3Rpb24gcmVkTmVnICgpIHtcbiAgICBhc3NlcnQodGhpcy5yZWQsICdyZWROZWcgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gICAgdGhpcy5yZWQuX3ZlcmlmeTEodGhpcyk7XG4gICAgcmV0dXJuIHRoaXMucmVkLm5lZyh0aGlzKTtcbiAgfTtcblxuICBCTi5wcm90b3R5cGUucmVkUG93ID0gZnVuY3Rpb24gcmVkUG93IChudW0pIHtcbiAgICBhc3NlcnQodGhpcy5yZWQgJiYgIW51bS5yZWQsICdyZWRQb3cobm9ybWFsTnVtKScpO1xuICAgIHRoaXMucmVkLl92ZXJpZnkxKHRoaXMpO1xuICAgIHJldHVybiB0aGlzLnJlZC5wb3codGhpcywgbnVtKTtcbiAgfTtcblxuICAvLyBQcmltZSBudW1iZXJzIHdpdGggZWZmaWNpZW50IHJlZHVjdGlvblxuICB2YXIgcHJpbWVzID0ge1xuICAgIGsyNTY6IG51bGwsXG4gICAgcDIyNDogbnVsbCxcbiAgICBwMTkyOiBudWxsLFxuICAgIHAyNTUxOTogbnVsbFxuICB9O1xuXG4gIC8vIFBzZXVkby1NZXJzZW5uZSBwcmltZVxuICBmdW5jdGlvbiBNUHJpbWUgKG5hbWUsIHApIHtcbiAgICAvLyBQID0gMiBeIE4gLSBLXG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICB0aGlzLnAgPSBuZXcgQk4ocCwgMTYpO1xuICAgIHRoaXMubiA9IHRoaXMucC5iaXRMZW5ndGgoKTtcbiAgICB0aGlzLmsgPSBuZXcgQk4oMSkuaXVzaGxuKHRoaXMubikuaXN1Yih0aGlzLnApO1xuXG4gICAgdGhpcy50bXAgPSB0aGlzLl90bXAoKTtcbiAgfVxuXG4gIE1QcmltZS5wcm90b3R5cGUuX3RtcCA9IGZ1bmN0aW9uIF90bXAgKCkge1xuICAgIHZhciB0bXAgPSBuZXcgQk4obnVsbCk7XG4gICAgdG1wLndvcmRzID0gbmV3IEFycmF5KE1hdGguY2VpbCh0aGlzLm4gLyAxMykpO1xuICAgIHJldHVybiB0bXA7XG4gIH07XG5cbiAgTVByaW1lLnByb3RvdHlwZS5pcmVkdWNlID0gZnVuY3Rpb24gaXJlZHVjZSAobnVtKSB7XG4gICAgLy8gQXNzdW1lcyB0aGF0IGBudW1gIGlzIGxlc3MgdGhhbiBgUF4yYFxuICAgIC8vIG51bSA9IEhJICogKDIgXiBOIC0gSykgKyBISSAqIEsgKyBMTyA9IEhJICogSyArIExPIChtb2QgUClcbiAgICB2YXIgciA9IG51bTtcbiAgICB2YXIgcmxlbjtcblxuICAgIGRvIHtcbiAgICAgIHRoaXMuc3BsaXQociwgdGhpcy50bXApO1xuICAgICAgciA9IHRoaXMuaW11bEsocik7XG4gICAgICByID0gci5pYWRkKHRoaXMudG1wKTtcbiAgICAgIHJsZW4gPSByLmJpdExlbmd0aCgpO1xuICAgIH0gd2hpbGUgKHJsZW4gPiB0aGlzLm4pO1xuXG4gICAgdmFyIGNtcCA9IHJsZW4gPCB0aGlzLm4gPyAtMSA6IHIudWNtcCh0aGlzLnApO1xuICAgIGlmIChjbXAgPT09IDApIHtcbiAgICAgIHIud29yZHNbMF0gPSAwO1xuICAgICAgci5sZW5ndGggPSAxO1xuICAgIH0gZWxzZSBpZiAoY21wID4gMCkge1xuICAgICAgci5pc3ViKHRoaXMucCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHIuc3RyaXAoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcjtcbiAgfTtcblxuICBNUHJpbWUucHJvdG90eXBlLnNwbGl0ID0gZnVuY3Rpb24gc3BsaXQgKGlucHV0LCBvdXQpIHtcbiAgICBpbnB1dC5pdXNocm4odGhpcy5uLCAwLCBvdXQpO1xuICB9O1xuXG4gIE1QcmltZS5wcm90b3R5cGUuaW11bEsgPSBmdW5jdGlvbiBpbXVsSyAobnVtKSB7XG4gICAgcmV0dXJuIG51bS5pbXVsKHRoaXMuayk7XG4gIH07XG5cbiAgZnVuY3Rpb24gSzI1NiAoKSB7XG4gICAgTVByaW1lLmNhbGwoXG4gICAgICB0aGlzLFxuICAgICAgJ2syNTYnLFxuICAgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZlIGZmZmZmYzJmJyk7XG4gIH1cbiAgaW5oZXJpdHMoSzI1NiwgTVByaW1lKTtcblxuICBLMjU2LnByb3RvdHlwZS5zcGxpdCA9IGZ1bmN0aW9uIHNwbGl0IChpbnB1dCwgb3V0cHV0KSB7XG4gICAgLy8gMjU2ID0gOSAqIDI2ICsgMjJcbiAgICB2YXIgbWFzayA9IDB4M2ZmZmZmO1xuXG4gICAgdmFyIG91dExlbiA9IE1hdGgubWluKGlucHV0Lmxlbmd0aCwgOSk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvdXRMZW47IGkrKykge1xuICAgICAgb3V0cHV0LndvcmRzW2ldID0gaW5wdXQud29yZHNbaV07XG4gICAgfVxuICAgIG91dHB1dC5sZW5ndGggPSBvdXRMZW47XG5cbiAgICBpZiAoaW5wdXQubGVuZ3RoIDw9IDkpIHtcbiAgICAgIGlucHV0LndvcmRzWzBdID0gMDtcbiAgICAgIGlucHV0Lmxlbmd0aCA9IDE7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gU2hpZnQgYnkgOSBsaW1ic1xuICAgIHZhciBwcmV2ID0gaW5wdXQud29yZHNbOV07XG4gICAgb3V0cHV0LndvcmRzW291dHB1dC5sZW5ndGgrK10gPSBwcmV2ICYgbWFzaztcblxuICAgIGZvciAoaSA9IDEwOyBpIDwgaW5wdXQubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBuZXh0ID0gaW5wdXQud29yZHNbaV0gfCAwO1xuICAgICAgaW5wdXQud29yZHNbaSAtIDEwXSA9ICgobmV4dCAmIG1hc2spIDw8IDQpIHwgKHByZXYgPj4+IDIyKTtcbiAgICAgIHByZXYgPSBuZXh0O1xuICAgIH1cbiAgICBwcmV2ID4+Pj0gMjI7XG4gICAgaW5wdXQud29yZHNbaSAtIDEwXSA9IHByZXY7XG4gICAgaWYgKHByZXYgPT09IDAgJiYgaW5wdXQubGVuZ3RoID4gMTApIHtcbiAgICAgIGlucHV0Lmxlbmd0aCAtPSAxMDtcbiAgICB9IGVsc2Uge1xuICAgICAgaW5wdXQubGVuZ3RoIC09IDk7XG4gICAgfVxuICB9O1xuXG4gIEsyNTYucHJvdG90eXBlLmltdWxLID0gZnVuY3Rpb24gaW11bEsgKG51bSkge1xuICAgIC8vIEsgPSAweDEwMDAwMDNkMSA9IFsgMHg0MCwgMHgzZDEgXVxuICAgIG51bS53b3Jkc1tudW0ubGVuZ3RoXSA9IDA7XG4gICAgbnVtLndvcmRzW251bS5sZW5ndGggKyAxXSA9IDA7XG4gICAgbnVtLmxlbmd0aCArPSAyO1xuXG4gICAgLy8gYm91bmRlZCBhdDogMHg0MCAqIDB4M2ZmZmZmZiArIDB4M2QwID0gMHgxMDAwMDAzOTBcbiAgICB2YXIgbG8gPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbnVtLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdyA9IG51bS53b3Jkc1tpXSB8IDA7XG4gICAgICBsbyArPSB3ICogMHgzZDE7XG4gICAgICBudW0ud29yZHNbaV0gPSBsbyAmIDB4M2ZmZmZmZjtcbiAgICAgIGxvID0gdyAqIDB4NDAgKyAoKGxvIC8gMHg0MDAwMDAwKSB8IDApO1xuICAgIH1cblxuICAgIC8vIEZhc3QgbGVuZ3RoIHJlZHVjdGlvblxuICAgIGlmIChudW0ud29yZHNbbnVtLmxlbmd0aCAtIDFdID09PSAwKSB7XG4gICAgICBudW0ubGVuZ3RoLS07XG4gICAgICBpZiAobnVtLndvcmRzW251bS5sZW5ndGggLSAxXSA9PT0gMCkge1xuICAgICAgICBudW0ubGVuZ3RoLS07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudW07XG4gIH07XG5cbiAgZnVuY3Rpb24gUDIyNCAoKSB7XG4gICAgTVByaW1lLmNhbGwoXG4gICAgICB0aGlzLFxuICAgICAgJ3AyMjQnLFxuICAgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIDAwMDAwMDAwIDAwMDAwMDAwIDAwMDAwMDAxJyk7XG4gIH1cbiAgaW5oZXJpdHMoUDIyNCwgTVByaW1lKTtcblxuICBmdW5jdGlvbiBQMTkyICgpIHtcbiAgICBNUHJpbWUuY2FsbChcbiAgICAgIHRoaXMsXG4gICAgICAncDE5MicsXG4gICAgICAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmUgZmZmZmZmZmYgZmZmZmZmZmYnKTtcbiAgfVxuICBpbmhlcml0cyhQMTkyLCBNUHJpbWUpO1xuXG4gIGZ1bmN0aW9uIFAyNTUxOSAoKSB7XG4gICAgLy8gMiBeIDI1NSAtIDE5XG4gICAgTVByaW1lLmNhbGwoXG4gICAgICB0aGlzLFxuICAgICAgJzI1NTE5JyxcbiAgICAgICc3ZmZmZmZmZmZmZmZmZmZmIGZmZmZmZmZmZmZmZmZmZmYgZmZmZmZmZmZmZmZmZmZmZiBmZmZmZmZmZmZmZmZmZmVkJyk7XG4gIH1cbiAgaW5oZXJpdHMoUDI1NTE5LCBNUHJpbWUpO1xuXG4gIFAyNTUxOS5wcm90b3R5cGUuaW11bEsgPSBmdW5jdGlvbiBpbXVsSyAobnVtKSB7XG4gICAgLy8gSyA9IDB4MTNcbiAgICB2YXIgY2FycnkgPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbnVtLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgaGkgPSAobnVtLndvcmRzW2ldIHwgMCkgKiAweDEzICsgY2Fycnk7XG4gICAgICB2YXIgbG8gPSBoaSAmIDB4M2ZmZmZmZjtcbiAgICAgIGhpID4+Pj0gMjY7XG5cbiAgICAgIG51bS53b3Jkc1tpXSA9IGxvO1xuICAgICAgY2FycnkgPSBoaTtcbiAgICB9XG4gICAgaWYgKGNhcnJ5ICE9PSAwKSB7XG4gICAgICBudW0ud29yZHNbbnVtLmxlbmd0aCsrXSA9IGNhcnJ5O1xuICAgIH1cbiAgICByZXR1cm4gbnVtO1xuICB9O1xuXG4gIC8vIEV4cG9ydGVkIG1vc3RseSBmb3IgdGVzdGluZyBwdXJwb3NlcywgdXNlIHBsYWluIG5hbWUgaW5zdGVhZFxuICBCTi5fcHJpbWUgPSBmdW5jdGlvbiBwcmltZSAobmFtZSkge1xuICAgIC8vIENhY2hlZCB2ZXJzaW9uIG9mIHByaW1lXG4gICAgaWYgKHByaW1lc1tuYW1lXSkgcmV0dXJuIHByaW1lc1tuYW1lXTtcblxuICAgIHZhciBwcmltZTtcbiAgICBpZiAobmFtZSA9PT0gJ2syNTYnKSB7XG4gICAgICBwcmltZSA9IG5ldyBLMjU2KCk7XG4gICAgfSBlbHNlIGlmIChuYW1lID09PSAncDIyNCcpIHtcbiAgICAgIHByaW1lID0gbmV3IFAyMjQoKTtcbiAgICB9IGVsc2UgaWYgKG5hbWUgPT09ICdwMTkyJykge1xuICAgICAgcHJpbWUgPSBuZXcgUDE5MigpO1xuICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ3AyNTUxOScpIHtcbiAgICAgIHByaW1lID0gbmV3IFAyNTUxOSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gcHJpbWUgJyArIG5hbWUpO1xuICAgIH1cbiAgICBwcmltZXNbbmFtZV0gPSBwcmltZTtcblxuICAgIHJldHVybiBwcmltZTtcbiAgfTtcblxuICAvL1xuICAvLyBCYXNlIHJlZHVjdGlvbiBlbmdpbmVcbiAgLy9cbiAgZnVuY3Rpb24gUmVkIChtKSB7XG4gICAgaWYgKHR5cGVvZiBtID09PSAnc3RyaW5nJykge1xuICAgICAgdmFyIHByaW1lID0gQk4uX3ByaW1lKG0pO1xuICAgICAgdGhpcy5tID0gcHJpbWUucDtcbiAgICAgIHRoaXMucHJpbWUgPSBwcmltZTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXNzZXJ0KG0uZ3RuKDEpLCAnbW9kdWx1cyBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAxJyk7XG4gICAgICB0aGlzLm0gPSBtO1xuICAgICAgdGhpcy5wcmltZSA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgUmVkLnByb3RvdHlwZS5fdmVyaWZ5MSA9IGZ1bmN0aW9uIF92ZXJpZnkxIChhKSB7XG4gICAgYXNzZXJ0KGEubmVnYXRpdmUgPT09IDAsICdyZWQgd29ya3Mgb25seSB3aXRoIHBvc2l0aXZlcycpO1xuICAgIGFzc2VydChhLnJlZCwgJ3JlZCB3b3JrcyBvbmx5IHdpdGggcmVkIG51bWJlcnMnKTtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLl92ZXJpZnkyID0gZnVuY3Rpb24gX3ZlcmlmeTIgKGEsIGIpIHtcbiAgICBhc3NlcnQoKGEubmVnYXRpdmUgfCBiLm5lZ2F0aXZlKSA9PT0gMCwgJ3JlZCB3b3JrcyBvbmx5IHdpdGggcG9zaXRpdmVzJyk7XG4gICAgYXNzZXJ0KGEucmVkICYmIGEucmVkID09PSBiLnJlZCxcbiAgICAgICdyZWQgd29ya3Mgb25seSB3aXRoIHJlZCBudW1iZXJzJyk7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5pbW9kID0gZnVuY3Rpb24gaW1vZCAoYSkge1xuICAgIGlmICh0aGlzLnByaW1lKSByZXR1cm4gdGhpcy5wcmltZS5pcmVkdWNlKGEpLl9mb3JjZVJlZCh0aGlzKTtcbiAgICByZXR1cm4gYS51bW9kKHRoaXMubSkuX2ZvcmNlUmVkKHRoaXMpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUubmVnID0gZnVuY3Rpb24gbmVnIChhKSB7XG4gICAgaWYgKGEuaXNaZXJvKCkpIHtcbiAgICAgIHJldHVybiBhLmNsb25lKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMubS5zdWIoYSkuX2ZvcmNlUmVkKHRoaXMpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gYWRkIChhLCBiKSB7XG4gICAgdGhpcy5fdmVyaWZ5MihhLCBiKTtcblxuICAgIHZhciByZXMgPSBhLmFkZChiKTtcbiAgICBpZiAocmVzLmNtcCh0aGlzLm0pID49IDApIHtcbiAgICAgIHJlcy5pc3ViKHRoaXMubSk7XG4gICAgfVxuICAgIHJldHVybiByZXMuX2ZvcmNlUmVkKHRoaXMpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuaWFkZCA9IGZ1bmN0aW9uIGlhZGQgKGEsIGIpIHtcbiAgICB0aGlzLl92ZXJpZnkyKGEsIGIpO1xuXG4gICAgdmFyIHJlcyA9IGEuaWFkZChiKTtcbiAgICBpZiAocmVzLmNtcCh0aGlzLm0pID49IDApIHtcbiAgICAgIHJlcy5pc3ViKHRoaXMubSk7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5zdWIgPSBmdW5jdGlvbiBzdWIgKGEsIGIpIHtcbiAgICB0aGlzLl92ZXJpZnkyKGEsIGIpO1xuXG4gICAgdmFyIHJlcyA9IGEuc3ViKGIpO1xuICAgIGlmIChyZXMuY21wbigwKSA8IDApIHtcbiAgICAgIHJlcy5pYWRkKHRoaXMubSk7XG4gICAgfVxuICAgIHJldHVybiByZXMuX2ZvcmNlUmVkKHRoaXMpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuaXN1YiA9IGZ1bmN0aW9uIGlzdWIgKGEsIGIpIHtcbiAgICB0aGlzLl92ZXJpZnkyKGEsIGIpO1xuXG4gICAgdmFyIHJlcyA9IGEuaXN1YihiKTtcbiAgICBpZiAocmVzLmNtcG4oMCkgPCAwKSB7XG4gICAgICByZXMuaWFkZCh0aGlzLm0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuc2hsID0gZnVuY3Rpb24gc2hsIChhLCBudW0pIHtcbiAgICB0aGlzLl92ZXJpZnkxKGEpO1xuICAgIHJldHVybiB0aGlzLmltb2QoYS51c2hsbihudW0pKTtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLmltdWwgPSBmdW5jdGlvbiBpbXVsIChhLCBiKSB7XG4gICAgdGhpcy5fdmVyaWZ5MihhLCBiKTtcbiAgICByZXR1cm4gdGhpcy5pbW9kKGEuaW11bChiKSk7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5tdWwgPSBmdW5jdGlvbiBtdWwgKGEsIGIpIHtcbiAgICB0aGlzLl92ZXJpZnkyKGEsIGIpO1xuICAgIHJldHVybiB0aGlzLmltb2QoYS5tdWwoYikpO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuaXNxciA9IGZ1bmN0aW9uIGlzcXIgKGEpIHtcbiAgICByZXR1cm4gdGhpcy5pbXVsKGEsIGEuY2xvbmUoKSk7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5zcXIgPSBmdW5jdGlvbiBzcXIgKGEpIHtcbiAgICByZXR1cm4gdGhpcy5tdWwoYSwgYSk7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5zcXJ0ID0gZnVuY3Rpb24gc3FydCAoYSkge1xuICAgIGlmIChhLmlzWmVybygpKSByZXR1cm4gYS5jbG9uZSgpO1xuXG4gICAgdmFyIG1vZDMgPSB0aGlzLm0uYW5kbG4oMyk7XG4gICAgYXNzZXJ0KG1vZDMgJSAyID09PSAxKTtcblxuICAgIC8vIEZhc3QgY2FzZVxuICAgIGlmIChtb2QzID09PSAzKSB7XG4gICAgICB2YXIgcG93ID0gdGhpcy5tLmFkZChuZXcgQk4oMSkpLml1c2hybigyKTtcbiAgICAgIHJldHVybiB0aGlzLnBvdyhhLCBwb3cpO1xuICAgIH1cblxuICAgIC8vIFRvbmVsbGktU2hhbmtzIGFsZ29yaXRobSAoVG90YWxseSB1bm9wdGltaXplZCBhbmQgc2xvdylcbiAgICAvL1xuICAgIC8vIEZpbmQgUSBhbmQgUywgdGhhdCBRICogMiBeIFMgPSAoUCAtIDEpXG4gICAgdmFyIHEgPSB0aGlzLm0uc3VibigxKTtcbiAgICB2YXIgcyA9IDA7XG4gICAgd2hpbGUgKCFxLmlzWmVybygpICYmIHEuYW5kbG4oMSkgPT09IDApIHtcbiAgICAgIHMrKztcbiAgICAgIHEuaXVzaHJuKDEpO1xuICAgIH1cbiAgICBhc3NlcnQoIXEuaXNaZXJvKCkpO1xuXG4gICAgdmFyIG9uZSA9IG5ldyBCTigxKS50b1JlZCh0aGlzKTtcbiAgICB2YXIgbk9uZSA9IG9uZS5yZWROZWcoKTtcblxuICAgIC8vIEZpbmQgcXVhZHJhdGljIG5vbi1yZXNpZHVlXG4gICAgLy8gTk9URTogTWF4IGlzIHN1Y2ggYmVjYXVzZSBvZiBnZW5lcmFsaXplZCBSaWVtYW5uIGh5cG90aGVzaXMuXG4gICAgdmFyIGxwb3cgPSB0aGlzLm0uc3VibigxKS5pdXNocm4oMSk7XG4gICAgdmFyIHogPSB0aGlzLm0uYml0TGVuZ3RoKCk7XG4gICAgeiA9IG5ldyBCTigyICogeiAqIHopLnRvUmVkKHRoaXMpO1xuXG4gICAgd2hpbGUgKHRoaXMucG93KHosIGxwb3cpLmNtcChuT25lKSAhPT0gMCkge1xuICAgICAgei5yZWRJQWRkKG5PbmUpO1xuICAgIH1cblxuICAgIHZhciBjID0gdGhpcy5wb3coeiwgcSk7XG4gICAgdmFyIHIgPSB0aGlzLnBvdyhhLCBxLmFkZG4oMSkuaXVzaHJuKDEpKTtcbiAgICB2YXIgdCA9IHRoaXMucG93KGEsIHEpO1xuICAgIHZhciBtID0gcztcbiAgICB3aGlsZSAodC5jbXAob25lKSAhPT0gMCkge1xuICAgICAgdmFyIHRtcCA9IHQ7XG4gICAgICBmb3IgKHZhciBpID0gMDsgdG1wLmNtcChvbmUpICE9PSAwOyBpKyspIHtcbiAgICAgICAgdG1wID0gdG1wLnJlZFNxcigpO1xuICAgICAgfVxuICAgICAgYXNzZXJ0KGkgPCBtKTtcbiAgICAgIHZhciBiID0gdGhpcy5wb3coYywgbmV3IEJOKDEpLml1c2hsbihtIC0gaSAtIDEpKTtcblxuICAgICAgciA9IHIucmVkTXVsKGIpO1xuICAgICAgYyA9IGIucmVkU3FyKCk7XG4gICAgICB0ID0gdC5yZWRNdWwoYyk7XG4gICAgICBtID0gaTtcbiAgICB9XG5cbiAgICByZXR1cm4gcjtcbiAgfTtcblxuICBSZWQucHJvdG90eXBlLmludm0gPSBmdW5jdGlvbiBpbnZtIChhKSB7XG4gICAgdmFyIGludiA9IGEuX2ludm1wKHRoaXMubSk7XG4gICAgaWYgKGludi5uZWdhdGl2ZSAhPT0gMCkge1xuICAgICAgaW52Lm5lZ2F0aXZlID0gMDtcbiAgICAgIHJldHVybiB0aGlzLmltb2QoaW52KS5yZWROZWcoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuaW1vZChpbnYpO1xuICAgIH1cbiAgfTtcblxuICBSZWQucHJvdG90eXBlLnBvdyA9IGZ1bmN0aW9uIHBvdyAoYSwgbnVtKSB7XG4gICAgaWYgKG51bS5pc1plcm8oKSkgcmV0dXJuIG5ldyBCTigxKS50b1JlZCh0aGlzKTtcbiAgICBpZiAobnVtLmNtcG4oMSkgPT09IDApIHJldHVybiBhLmNsb25lKCk7XG5cbiAgICB2YXIgd2luZG93U2l6ZSA9IDQ7XG4gICAgdmFyIHduZCA9IG5ldyBBcnJheSgxIDw8IHdpbmRvd1NpemUpO1xuICAgIHduZFswXSA9IG5ldyBCTigxKS50b1JlZCh0aGlzKTtcbiAgICB3bmRbMV0gPSBhO1xuICAgIGZvciAodmFyIGkgPSAyOyBpIDwgd25kLmxlbmd0aDsgaSsrKSB7XG4gICAgICB3bmRbaV0gPSB0aGlzLm11bCh3bmRbaSAtIDFdLCBhKTtcbiAgICB9XG5cbiAgICB2YXIgcmVzID0gd25kWzBdO1xuICAgIHZhciBjdXJyZW50ID0gMDtcbiAgICB2YXIgY3VycmVudExlbiA9IDA7XG4gICAgdmFyIHN0YXJ0ID0gbnVtLmJpdExlbmd0aCgpICUgMjY7XG4gICAgaWYgKHN0YXJ0ID09PSAwKSB7XG4gICAgICBzdGFydCA9IDI2O1xuICAgIH1cblxuICAgIGZvciAoaSA9IG51bS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgdmFyIHdvcmQgPSBudW0ud29yZHNbaV07XG4gICAgICBmb3IgKHZhciBqID0gc3RhcnQgLSAxOyBqID49IDA7IGotLSkge1xuICAgICAgICB2YXIgYml0ID0gKHdvcmQgPj4gaikgJiAxO1xuICAgICAgICBpZiAocmVzICE9PSB3bmRbMF0pIHtcbiAgICAgICAgICByZXMgPSB0aGlzLnNxcihyZXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGJpdCA9PT0gMCAmJiBjdXJyZW50ID09PSAwKSB7XG4gICAgICAgICAgY3VycmVudExlbiA9IDA7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBjdXJyZW50IDw8PSAxO1xuICAgICAgICBjdXJyZW50IHw9IGJpdDtcbiAgICAgICAgY3VycmVudExlbisrO1xuICAgICAgICBpZiAoY3VycmVudExlbiAhPT0gd2luZG93U2l6ZSAmJiAoaSAhPT0gMCB8fCBqICE9PSAwKSkgY29udGludWU7XG5cbiAgICAgICAgcmVzID0gdGhpcy5tdWwocmVzLCB3bmRbY3VycmVudF0pO1xuICAgICAgICBjdXJyZW50TGVuID0gMDtcbiAgICAgICAgY3VycmVudCA9IDA7XG4gICAgICB9XG4gICAgICBzdGFydCA9IDI2O1xuICAgIH1cblxuICAgIHJldHVybiByZXM7XG4gIH07XG5cbiAgUmVkLnByb3RvdHlwZS5jb252ZXJ0VG8gPSBmdW5jdGlvbiBjb252ZXJ0VG8gKG51bSkge1xuICAgIHZhciByID0gbnVtLnVtb2QodGhpcy5tKTtcblxuICAgIHJldHVybiByID09PSBudW0gPyByLmNsb25lKCkgOiByO1xuICB9O1xuXG4gIFJlZC5wcm90b3R5cGUuY29udmVydEZyb20gPSBmdW5jdGlvbiBjb252ZXJ0RnJvbSAobnVtKSB7XG4gICAgdmFyIHJlcyA9IG51bS5jbG9uZSgpO1xuICAgIHJlcy5yZWQgPSBudWxsO1xuICAgIHJldHVybiByZXM7XG4gIH07XG5cbiAgLy9cbiAgLy8gTW9udGdvbWVyeSBtZXRob2QgZW5naW5lXG4gIC8vXG5cbiAgQk4ubW9udCA9IGZ1bmN0aW9uIG1vbnQgKG51bSkge1xuICAgIHJldHVybiBuZXcgTW9udChudW0pO1xuICB9O1xuXG4gIGZ1bmN0aW9uIE1vbnQgKG0pIHtcbiAgICBSZWQuY2FsbCh0aGlzLCBtKTtcblxuICAgIHRoaXMuc2hpZnQgPSB0aGlzLm0uYml0TGVuZ3RoKCk7XG4gICAgaWYgKHRoaXMuc2hpZnQgJSAyNiAhPT0gMCkge1xuICAgICAgdGhpcy5zaGlmdCArPSAyNiAtICh0aGlzLnNoaWZ0ICUgMjYpO1xuICAgIH1cblxuICAgIHRoaXMuciA9IG5ldyBCTigxKS5pdXNobG4odGhpcy5zaGlmdCk7XG4gICAgdGhpcy5yMiA9IHRoaXMuaW1vZCh0aGlzLnIuc3FyKCkpO1xuICAgIHRoaXMucmludiA9IHRoaXMuci5faW52bXAodGhpcy5tKTtcblxuICAgIHRoaXMubWludiA9IHRoaXMucmludi5tdWwodGhpcy5yKS5pc3VibigxKS5kaXYodGhpcy5tKTtcbiAgICB0aGlzLm1pbnYgPSB0aGlzLm1pbnYudW1vZCh0aGlzLnIpO1xuICAgIHRoaXMubWludiA9IHRoaXMuci5zdWIodGhpcy5taW52KTtcbiAgfVxuICBpbmhlcml0cyhNb250LCBSZWQpO1xuXG4gIE1vbnQucHJvdG90eXBlLmNvbnZlcnRUbyA9IGZ1bmN0aW9uIGNvbnZlcnRUbyAobnVtKSB7XG4gICAgcmV0dXJuIHRoaXMuaW1vZChudW0udXNobG4odGhpcy5zaGlmdCkpO1xuICB9O1xuXG4gIE1vbnQucHJvdG90eXBlLmNvbnZlcnRGcm9tID0gZnVuY3Rpb24gY29udmVydEZyb20gKG51bSkge1xuICAgIHZhciByID0gdGhpcy5pbW9kKG51bS5tdWwodGhpcy5yaW52KSk7XG4gICAgci5yZWQgPSBudWxsO1xuICAgIHJldHVybiByO1xuICB9O1xuXG4gIE1vbnQucHJvdG90eXBlLmltdWwgPSBmdW5jdGlvbiBpbXVsIChhLCBiKSB7XG4gICAgaWYgKGEuaXNaZXJvKCkgfHwgYi5pc1plcm8oKSkge1xuICAgICAgYS53b3Jkc1swXSA9IDA7XG4gICAgICBhLmxlbmd0aCA9IDE7XG4gICAgICByZXR1cm4gYTtcbiAgICB9XG5cbiAgICB2YXIgdCA9IGEuaW11bChiKTtcbiAgICB2YXIgYyA9IHQubWFza24odGhpcy5zaGlmdCkubXVsKHRoaXMubWludikuaW1hc2tuKHRoaXMuc2hpZnQpLm11bCh0aGlzLm0pO1xuICAgIHZhciB1ID0gdC5pc3ViKGMpLml1c2hybih0aGlzLnNoaWZ0KTtcbiAgICB2YXIgcmVzID0gdTtcblxuICAgIGlmICh1LmNtcCh0aGlzLm0pID49IDApIHtcbiAgICAgIHJlcyA9IHUuaXN1Yih0aGlzLm0pO1xuICAgIH0gZWxzZSBpZiAodS5jbXBuKDApIDwgMCkge1xuICAgICAgcmVzID0gdS5pYWRkKHRoaXMubSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcy5fZm9yY2VSZWQodGhpcyk7XG4gIH07XG5cbiAgTW9udC5wcm90b3R5cGUubXVsID0gZnVuY3Rpb24gbXVsIChhLCBiKSB7XG4gICAgaWYgKGEuaXNaZXJvKCkgfHwgYi5pc1plcm8oKSkgcmV0dXJuIG5ldyBCTigwKS5fZm9yY2VSZWQodGhpcyk7XG5cbiAgICB2YXIgdCA9IGEubXVsKGIpO1xuICAgIHZhciBjID0gdC5tYXNrbih0aGlzLnNoaWZ0KS5tdWwodGhpcy5taW52KS5pbWFza24odGhpcy5zaGlmdCkubXVsKHRoaXMubSk7XG4gICAgdmFyIHUgPSB0LmlzdWIoYykuaXVzaHJuKHRoaXMuc2hpZnQpO1xuICAgIHZhciByZXMgPSB1O1xuICAgIGlmICh1LmNtcCh0aGlzLm0pID49IDApIHtcbiAgICAgIHJlcyA9IHUuaXN1Yih0aGlzLm0pO1xuICAgIH0gZWxzZSBpZiAodS5jbXBuKDApIDwgMCkge1xuICAgICAgcmVzID0gdS5pYWRkKHRoaXMubSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcy5fZm9yY2VSZWQodGhpcyk7XG4gIH07XG5cbiAgTW9udC5wcm90b3R5cGUuaW52bSA9IGZ1bmN0aW9uIGludm0gKGEpIHtcbiAgICAvLyAoQVIpXi0xICogUl4yID0gKEFeLTEgKiBSXi0xKSAqIFJeMiA9IEFeLTEgKiBSXG4gICAgdmFyIHJlcyA9IHRoaXMuaW1vZChhLl9pbnZtcCh0aGlzLm0pLm11bCh0aGlzLnIyKSk7XG4gICAgcmV0dXJuIHJlcy5fZm9yY2VSZWQodGhpcyk7XG4gIH07XG59KSh0eXBlb2YgbW9kdWxlID09PSAndW5kZWZpbmVkJyB8fCBtb2R1bGUsIHRoaXMpO1xuIiwidmFyIHI7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcmFuZChsZW4pIHtcbiAgaWYgKCFyKVxuICAgIHIgPSBuZXcgUmFuZChudWxsKTtcblxuICByZXR1cm4gci5nZW5lcmF0ZShsZW4pO1xufTtcblxuZnVuY3Rpb24gUmFuZChyYW5kKSB7XG4gIHRoaXMucmFuZCA9IHJhbmQ7XG59XG5tb2R1bGUuZXhwb3J0cy5SYW5kID0gUmFuZDtcblxuUmFuZC5wcm90b3R5cGUuZ2VuZXJhdGUgPSBmdW5jdGlvbiBnZW5lcmF0ZShsZW4pIHtcbiAgcmV0dXJuIHRoaXMuX3JhbmQobGVuKTtcbn07XG5cbi8vIEVtdWxhdGUgY3J5cHRvIEFQSSB1c2luZyByYW5keVxuUmFuZC5wcm90b3R5cGUuX3JhbmQgPSBmdW5jdGlvbiBfcmFuZChuKSB7XG4gIGlmICh0aGlzLnJhbmQuZ2V0Qnl0ZXMpXG4gICAgcmV0dXJuIHRoaXMucmFuZC5nZXRCeXRlcyhuKTtcblxuICB2YXIgcmVzID0gbmV3IFVpbnQ4QXJyYXkobik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzLmxlbmd0aDsgaSsrKVxuICAgIHJlc1tpXSA9IHRoaXMucmFuZC5nZXRCeXRlKCk7XG4gIHJldHVybiByZXM7XG59O1xuXG5pZiAodHlwZW9mIHNlbGYgPT09ICdvYmplY3QnKSB7XG4gIGlmIChzZWxmLmNyeXB0byAmJiBzZWxmLmNyeXB0by5nZXRSYW5kb21WYWx1ZXMpIHtcbiAgICAvLyBNb2Rlcm4gYnJvd3NlcnNcbiAgICBSYW5kLnByb3RvdHlwZS5fcmFuZCA9IGZ1bmN0aW9uIF9yYW5kKG4pIHtcbiAgICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheShuKTtcbiAgICAgIHNlbGYuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhhcnIpO1xuICAgICAgcmV0dXJuIGFycjtcbiAgICB9O1xuICB9IGVsc2UgaWYgKHNlbGYubXNDcnlwdG8gJiYgc2VsZi5tc0NyeXB0by5nZXRSYW5kb21WYWx1ZXMpIHtcbiAgICAvLyBJRVxuICAgIFJhbmQucHJvdG90eXBlLl9yYW5kID0gZnVuY3Rpb24gX3JhbmQobikge1xuICAgICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KG4pO1xuICAgICAgc2VsZi5tc0NyeXB0by5nZXRSYW5kb21WYWx1ZXMoYXJyKTtcbiAgICAgIHJldHVybiBhcnI7XG4gICAgfTtcblxuICAvLyBTYWZhcmkncyBXZWJXb3JrZXJzIGRvIG5vdCBoYXZlIGBjcnlwdG9gXG4gIH0gZWxzZSBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcpIHtcbiAgICAvLyBPbGQganVua1xuICAgIFJhbmQucHJvdG90eXBlLl9yYW5kID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCB5ZXQnKTtcbiAgICB9O1xuICB9XG59IGVsc2Uge1xuICAvLyBOb2RlLmpzIG9yIFdlYiB3b3JrZXIgd2l0aCBubyBjcnlwdG8gc3VwcG9ydFxuICB0cnkge1xuICAgIHZhciBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcbiAgICBpZiAodHlwZW9mIGNyeXB0by5yYW5kb21CeXRlcyAhPT0gJ2Z1bmN0aW9uJylcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm90IHN1cHBvcnRlZCcpO1xuXG4gICAgUmFuZC5wcm90b3R5cGUuX3JhbmQgPSBmdW5jdGlvbiBfcmFuZChuKSB7XG4gICAgICByZXR1cm4gY3J5cHRvLnJhbmRvbUJ5dGVzKG4pO1xuICAgIH07XG4gIH0gY2F0Y2ggKGUpIHtcbiAgfVxufVxuIiwiIiwiLy8gYmFzZWQgb24gdGhlIGFlcyBpbXBsaW1lbnRhdGlvbiBpbiB0cmlwbGUgc2VjXG4vLyBodHRwczovL2dpdGh1Yi5jb20va2V5YmFzZS90cmlwbGVzZWNcbi8vIHdoaWNoIGlzIGluIHR1cm4gYmFzZWQgb24gdGhlIG9uZSBmcm9tIGNyeXB0by1qc1xuLy8gaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanMvXG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxuXG5mdW5jdGlvbiBhc1VJbnQzMkFycmF5IChidWYpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkgYnVmID0gQnVmZmVyLmZyb20oYnVmKVxuXG4gIHZhciBsZW4gPSAoYnVmLmxlbmd0aCAvIDQpIHwgMFxuICB2YXIgb3V0ID0gbmV3IEFycmF5KGxlbilcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgb3V0W2ldID0gYnVmLnJlYWRVSW50MzJCRShpICogNClcbiAgfVxuXG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gc2NydWJWZWMgKHYpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB2Lmxlbmd0aDsgdisrKSB7XG4gICAgdltpXSA9IDBcbiAgfVxufVxuXG5mdW5jdGlvbiBjcnlwdEJsb2NrIChNLCBrZXlTY2hlZHVsZSwgU1VCX01JWCwgU0JPWCwgblJvdW5kcykge1xuICB2YXIgU1VCX01JWDAgPSBTVUJfTUlYWzBdXG4gIHZhciBTVUJfTUlYMSA9IFNVQl9NSVhbMV1cbiAgdmFyIFNVQl9NSVgyID0gU1VCX01JWFsyXVxuICB2YXIgU1VCX01JWDMgPSBTVUJfTUlYWzNdXG5cbiAgdmFyIHMwID0gTVswXSBeIGtleVNjaGVkdWxlWzBdXG4gIHZhciBzMSA9IE1bMV0gXiBrZXlTY2hlZHVsZVsxXVxuICB2YXIgczIgPSBNWzJdIF4ga2V5U2NoZWR1bGVbMl1cbiAgdmFyIHMzID0gTVszXSBeIGtleVNjaGVkdWxlWzNdXG4gIHZhciB0MCwgdDEsIHQyLCB0M1xuICB2YXIga3NSb3cgPSA0XG5cbiAgZm9yICh2YXIgcm91bmQgPSAxOyByb3VuZCA8IG5Sb3VuZHM7IHJvdW5kKyspIHtcbiAgICB0MCA9IFNVQl9NSVgwW3MwID4+PiAyNF0gXiBTVUJfTUlYMVsoczEgPj4+IDE2KSAmIDB4ZmZdIF4gU1VCX01JWDJbKHMyID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWDNbczMgJiAweGZmXSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gICAgdDEgPSBTVUJfTUlYMFtzMSA+Pj4gMjRdIF4gU1VCX01JWDFbKHMyID4+PiAxNikgJiAweGZmXSBeIFNVQl9NSVgyWyhzMyA+Pj4gOCkgJiAweGZmXSBeIFNVQl9NSVgzW3MwICYgMHhmZl0gXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICAgIHQyID0gU1VCX01JWDBbczIgPj4+IDI0XSBeIFNVQl9NSVgxWyhzMyA+Pj4gMTYpICYgMHhmZl0gXiBTVUJfTUlYMlsoczAgPj4+IDgpICYgMHhmZl0gXiBTVUJfTUlYM1tzMSAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgICB0MyA9IFNVQl9NSVgwW3MzID4+PiAyNF0gXiBTVUJfTUlYMVsoczAgPj4+IDE2KSAmIDB4ZmZdIF4gU1VCX01JWDJbKHMxID4+PiA4KSAmIDB4ZmZdIF4gU1VCX01JWDNbczIgJiAweGZmXSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gICAgczAgPSB0MFxuICAgIHMxID0gdDFcbiAgICBzMiA9IHQyXG4gICAgczMgPSB0M1xuICB9XG5cbiAgdDAgPSAoKFNCT1hbczAgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczEgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMiA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczMgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICB0MSA9ICgoU0JPWFtzMSA+Pj4gMjRdIDw8IDI0KSB8IChTQk9YWyhzMiA+Pj4gMTYpICYgMHhmZl0gPDwgMTYpIHwgKFNCT1hbKHMzID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHwgU0JPWFtzMCAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdXG4gIHQyID0gKChTQk9YW3MyID4+PiAyNF0gPDwgMjQpIHwgKFNCT1hbKHMzID4+PiAxNikgJiAweGZmXSA8PCAxNikgfCAoU0JPWFsoczAgPj4+IDgpICYgMHhmZl0gPDwgOCkgfCBTQk9YW3MxICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK11cbiAgdDMgPSAoKFNCT1hbczMgPj4+IDI0XSA8PCAyNCkgfCAoU0JPWFsoczAgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8IChTQk9YWyhzMSA+Pj4gOCkgJiAweGZmXSA8PCA4KSB8IFNCT1hbczIgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXVxuICB0MCA9IHQwID4+PiAwXG4gIHQxID0gdDEgPj4+IDBcbiAgdDIgPSB0MiA+Pj4gMFxuICB0MyA9IHQzID4+PiAwXG5cbiAgcmV0dXJuIFt0MCwgdDEsIHQyLCB0M11cbn1cblxuLy8gQUVTIGNvbnN0YW50c1xudmFyIFJDT04gPSBbMHgwMCwgMHgwMSwgMHgwMiwgMHgwNCwgMHgwOCwgMHgxMCwgMHgyMCwgMHg0MCwgMHg4MCwgMHgxYiwgMHgzNl1cbnZhciBHID0gKGZ1bmN0aW9uICgpIHtcbiAgLy8gQ29tcHV0ZSBkb3VibGUgdGFibGVcbiAgdmFyIGQgPSBuZXcgQXJyYXkoMjU2KVxuICBmb3IgKHZhciBqID0gMDsgaiA8IDI1NjsgaisrKSB7XG4gICAgaWYgKGogPCAxMjgpIHtcbiAgICAgIGRbal0gPSBqIDw8IDFcbiAgICB9IGVsc2Uge1xuICAgICAgZFtqXSA9IChqIDw8IDEpIF4gMHgxMWJcbiAgICB9XG4gIH1cblxuICB2YXIgU0JPWCA9IFtdXG4gIHZhciBJTlZfU0JPWCA9IFtdXG4gIHZhciBTVUJfTUlYID0gW1tdLCBbXSwgW10sIFtdXVxuICB2YXIgSU5WX1NVQl9NSVggPSBbW10sIFtdLCBbXSwgW11dXG5cbiAgLy8gV2FsayBHRigyXjgpXG4gIHZhciB4ID0gMFxuICB2YXIgeGkgPSAwXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyArK2kpIHtcbiAgICAvLyBDb21wdXRlIHNib3hcbiAgICB2YXIgc3ggPSB4aSBeICh4aSA8PCAxKSBeICh4aSA8PCAyKSBeICh4aSA8PCAzKSBeICh4aSA8PCA0KVxuICAgIHN4ID0gKHN4ID4+PiA4KSBeIChzeCAmIDB4ZmYpIF4gMHg2M1xuICAgIFNCT1hbeF0gPSBzeFxuICAgIElOVl9TQk9YW3N4XSA9IHhcblxuICAgIC8vIENvbXB1dGUgbXVsdGlwbGljYXRpb25cbiAgICB2YXIgeDIgPSBkW3hdXG4gICAgdmFyIHg0ID0gZFt4Ml1cbiAgICB2YXIgeDggPSBkW3g0XVxuXG4gICAgLy8gQ29tcHV0ZSBzdWIgYnl0ZXMsIG1peCBjb2x1bW5zIHRhYmxlc1xuICAgIHZhciB0ID0gKGRbc3hdICogMHgxMDEpIF4gKHN4ICogMHgxMDEwMTAwKVxuICAgIFNVQl9NSVhbMF1beF0gPSAodCA8PCAyNCkgfCAodCA+Pj4gOClcbiAgICBTVUJfTUlYWzFdW3hdID0gKHQgPDwgMTYpIHwgKHQgPj4+IDE2KVxuICAgIFNVQl9NSVhbMl1beF0gPSAodCA8PCA4KSB8ICh0ID4+PiAyNClcbiAgICBTVUJfTUlYWzNdW3hdID0gdFxuXG4gICAgLy8gQ29tcHV0ZSBpbnYgc3ViIGJ5dGVzLCBpbnYgbWl4IGNvbHVtbnMgdGFibGVzXG4gICAgdCA9ICh4OCAqIDB4MTAxMDEwMSkgXiAoeDQgKiAweDEwMDAxKSBeICh4MiAqIDB4MTAxKSBeICh4ICogMHgxMDEwMTAwKVxuICAgIElOVl9TVUJfTUlYWzBdW3N4XSA9ICh0IDw8IDI0KSB8ICh0ID4+PiA4KVxuICAgIElOVl9TVUJfTUlYWzFdW3N4XSA9ICh0IDw8IDE2KSB8ICh0ID4+PiAxNilcbiAgICBJTlZfU1VCX01JWFsyXVtzeF0gPSAodCA8PCA4KSB8ICh0ID4+PiAyNClcbiAgICBJTlZfU1VCX01JWFszXVtzeF0gPSB0XG5cbiAgICBpZiAoeCA9PT0gMCkge1xuICAgICAgeCA9IHhpID0gMVxuICAgIH0gZWxzZSB7XG4gICAgICB4ID0geDIgXiBkW2RbZFt4OCBeIHgyXV1dXG4gICAgICB4aSBePSBkW2RbeGldXVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgU0JPWDogU0JPWCxcbiAgICBJTlZfU0JPWDogSU5WX1NCT1gsXG4gICAgU1VCX01JWDogU1VCX01JWCxcbiAgICBJTlZfU1VCX01JWDogSU5WX1NVQl9NSVhcbiAgfVxufSkoKVxuXG5mdW5jdGlvbiBBRVMgKGtleSkge1xuICB0aGlzLl9rZXkgPSBhc1VJbnQzMkFycmF5KGtleSlcbiAgdGhpcy5fcmVzZXQoKVxufVxuXG5BRVMuYmxvY2tTaXplID0gNCAqIDRcbkFFUy5rZXlTaXplID0gMjU2IC8gOFxuQUVTLnByb3RvdHlwZS5ibG9ja1NpemUgPSBBRVMuYmxvY2tTaXplXG5BRVMucHJvdG90eXBlLmtleVNpemUgPSBBRVMua2V5U2l6ZVxuQUVTLnByb3RvdHlwZS5fcmVzZXQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBrZXlXb3JkcyA9IHRoaXMuX2tleVxuICB2YXIga2V5U2l6ZSA9IGtleVdvcmRzLmxlbmd0aFxuICB2YXIgblJvdW5kcyA9IGtleVNpemUgKyA2XG4gIHZhciBrc1Jvd3MgPSAoblJvdW5kcyArIDEpICogNFxuXG4gIHZhciBrZXlTY2hlZHVsZSA9IFtdXG4gIGZvciAodmFyIGsgPSAwOyBrIDwga2V5U2l6ZTsgaysrKSB7XG4gICAga2V5U2NoZWR1bGVba10gPSBrZXlXb3Jkc1trXVxuICB9XG5cbiAgZm9yIChrID0ga2V5U2l6ZTsgayA8IGtzUm93czsgaysrKSB7XG4gICAgdmFyIHQgPSBrZXlTY2hlZHVsZVtrIC0gMV1cblxuICAgIGlmIChrICUga2V5U2l6ZSA9PT0gMCkge1xuICAgICAgdCA9ICh0IDw8IDgpIHwgKHQgPj4+IDI0KVxuICAgICAgdCA9XG4gICAgICAgIChHLlNCT1hbdCA+Pj4gMjRdIDw8IDI0KSB8XG4gICAgICAgIChHLlNCT1hbKHQgPj4+IDE2KSAmIDB4ZmZdIDw8IDE2KSB8XG4gICAgICAgIChHLlNCT1hbKHQgPj4+IDgpICYgMHhmZl0gPDwgOCkgfFxuICAgICAgICAoRy5TQk9YW3QgJiAweGZmXSlcblxuICAgICAgdCBePSBSQ09OWyhrIC8ga2V5U2l6ZSkgfCAwXSA8PCAyNFxuICAgIH0gZWxzZSBpZiAoa2V5U2l6ZSA+IDYgJiYgayAlIGtleVNpemUgPT09IDQpIHtcbiAgICAgIHQgPVxuICAgICAgICAoRy5TQk9YW3QgPj4+IDI0XSA8PCAyNCkgfFxuICAgICAgICAoRy5TQk9YWyh0ID4+PiAxNikgJiAweGZmXSA8PCAxNikgfFxuICAgICAgICAoRy5TQk9YWyh0ID4+PiA4KSAmIDB4ZmZdIDw8IDgpIHxcbiAgICAgICAgKEcuU0JPWFt0ICYgMHhmZl0pXG4gICAgfVxuXG4gICAga2V5U2NoZWR1bGVba10gPSBrZXlTY2hlZHVsZVtrIC0ga2V5U2l6ZV0gXiB0XG4gIH1cblxuICB2YXIgaW52S2V5U2NoZWR1bGUgPSBbXVxuICBmb3IgKHZhciBpayA9IDA7IGlrIDwga3NSb3dzOyBpaysrKSB7XG4gICAgdmFyIGtzUiA9IGtzUm93cyAtIGlrXG4gICAgdmFyIHR0ID0ga2V5U2NoZWR1bGVba3NSIC0gKGlrICUgNCA/IDAgOiA0KV1cblxuICAgIGlmIChpayA8IDQgfHwga3NSIDw9IDQpIHtcbiAgICAgIGludktleVNjaGVkdWxlW2lrXSA9IHR0XG4gICAgfSBlbHNlIHtcbiAgICAgIGludktleVNjaGVkdWxlW2lrXSA9XG4gICAgICAgIEcuSU5WX1NVQl9NSVhbMF1bRy5TQk9YW3R0ID4+PiAyNF1dIF5cbiAgICAgICAgRy5JTlZfU1VCX01JWFsxXVtHLlNCT1hbKHR0ID4+PiAxNikgJiAweGZmXV0gXlxuICAgICAgICBHLklOVl9TVUJfTUlYWzJdW0cuU0JPWFsodHQgPj4+IDgpICYgMHhmZl1dIF5cbiAgICAgICAgRy5JTlZfU1VCX01JWFszXVtHLlNCT1hbdHQgJiAweGZmXV1cbiAgICB9XG4gIH1cblxuICB0aGlzLl9uUm91bmRzID0gblJvdW5kc1xuICB0aGlzLl9rZXlTY2hlZHVsZSA9IGtleVNjaGVkdWxlXG4gIHRoaXMuX2ludktleVNjaGVkdWxlID0gaW52S2V5U2NoZWR1bGVcbn1cblxuQUVTLnByb3RvdHlwZS5lbmNyeXB0QmxvY2tSYXcgPSBmdW5jdGlvbiAoTSkge1xuICBNID0gYXNVSW50MzJBcnJheShNKVxuICByZXR1cm4gY3J5cHRCbG9jayhNLCB0aGlzLl9rZXlTY2hlZHVsZSwgRy5TVUJfTUlYLCBHLlNCT1gsIHRoaXMuX25Sb3VuZHMpXG59XG5cbkFFUy5wcm90b3R5cGUuZW5jcnlwdEJsb2NrID0gZnVuY3Rpb24gKE0pIHtcbiAgdmFyIG91dCA9IHRoaXMuZW5jcnlwdEJsb2NrUmF3KE0pXG4gIHZhciBidWYgPSBCdWZmZXIuYWxsb2NVbnNhZmUoMTYpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFswXSwgMClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzFdLCA0KVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMl0sIDgpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFszXSwgMTIpXG4gIHJldHVybiBidWZcbn1cblxuQUVTLnByb3RvdHlwZS5kZWNyeXB0QmxvY2sgPSBmdW5jdGlvbiAoTSkge1xuICBNID0gYXNVSW50MzJBcnJheShNKVxuXG4gIC8vIHN3YXBcbiAgdmFyIG0xID0gTVsxXVxuICBNWzFdID0gTVszXVxuICBNWzNdID0gbTFcblxuICB2YXIgb3V0ID0gY3J5cHRCbG9jayhNLCB0aGlzLl9pbnZLZXlTY2hlZHVsZSwgRy5JTlZfU1VCX01JWCwgRy5JTlZfU0JPWCwgdGhpcy5fblJvdW5kcylcbiAgdmFyIGJ1ZiA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSgxNilcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzBdLCAwKVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbM10sIDQpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFsyXSwgOClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzFdLCAxMilcbiAgcmV0dXJuIGJ1ZlxufVxuXG5BRVMucHJvdG90eXBlLnNjcnViID0gZnVuY3Rpb24gKCkge1xuICBzY3J1YlZlYyh0aGlzLl9rZXlTY2hlZHVsZSlcbiAgc2NydWJWZWModGhpcy5faW52S2V5U2NoZWR1bGUpXG4gIHNjcnViVmVjKHRoaXMuX2tleSlcbn1cblxubW9kdWxlLmV4cG9ydHMuQUVTID0gQUVTXG4iLCJ2YXIgYWVzID0gcmVxdWlyZSgnLi9hZXMnKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEdIQVNIID0gcmVxdWlyZSgnLi9naGFzaCcpXG52YXIgeG9yID0gcmVxdWlyZSgnYnVmZmVyLXhvcicpXG52YXIgaW5jcjMyID0gcmVxdWlyZSgnLi9pbmNyMzInKVxuXG5mdW5jdGlvbiB4b3JUZXN0IChhLCBiKSB7XG4gIHZhciBvdXQgPSAwXG4gIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIG91dCsrXG5cbiAgdmFyIGxlbiA9IE1hdGgubWluKGEubGVuZ3RoLCBiLmxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgIG91dCArPSAoYVtpXSBeIGJbaV0pXG4gIH1cblxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIGNhbGNJdiAoc2VsZiwgaXYsIGNrKSB7XG4gIGlmIChpdi5sZW5ndGggPT09IDEyKSB7XG4gICAgc2VsZi5fZmluSUQgPSBCdWZmZXIuY29uY2F0KFtpdiwgQnVmZmVyLmZyb20oWzAsIDAsIDAsIDFdKV0pXG4gICAgcmV0dXJuIEJ1ZmZlci5jb25jYXQoW2l2LCBCdWZmZXIuZnJvbShbMCwgMCwgMCwgMl0pXSlcbiAgfVxuICB2YXIgZ2hhc2ggPSBuZXcgR0hBU0goY2spXG4gIHZhciBsZW4gPSBpdi5sZW5ndGhcbiAgdmFyIHRvUGFkID0gbGVuICUgMTZcbiAgZ2hhc2gudXBkYXRlKGl2KVxuICBpZiAodG9QYWQpIHtcbiAgICB0b1BhZCA9IDE2IC0gdG9QYWRcbiAgICBnaGFzaC51cGRhdGUoQnVmZmVyLmFsbG9jKHRvUGFkLCAwKSlcbiAgfVxuICBnaGFzaC51cGRhdGUoQnVmZmVyLmFsbG9jKDgsIDApKVxuICB2YXIgaXZCaXRzID0gbGVuICogOFxuICB2YXIgdGFpbCA9IEJ1ZmZlci5hbGxvYyg4KVxuICB0YWlsLndyaXRlVUludEJFKGl2Qml0cywgMCwgOClcbiAgZ2hhc2gudXBkYXRlKHRhaWwpXG4gIHNlbGYuX2ZpbklEID0gZ2hhc2guc3RhdGVcbiAgdmFyIG91dCA9IEJ1ZmZlci5mcm9tKHNlbGYuX2ZpbklEKVxuICBpbmNyMzIob3V0KVxuICByZXR1cm4gb3V0XG59XG5mdW5jdGlvbiBTdHJlYW1DaXBoZXIgKG1vZGUsIGtleSwgaXYsIGRlY3J5cHQpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcblxuICB2YXIgaCA9IEJ1ZmZlci5hbGxvYyg0LCAwKVxuXG4gIHRoaXMuX2NpcGhlciA9IG5ldyBhZXMuQUVTKGtleSlcbiAgdmFyIGNrID0gdGhpcy5fY2lwaGVyLmVuY3J5cHRCbG9jayhoKVxuICB0aGlzLl9naGFzaCA9IG5ldyBHSEFTSChjaylcbiAgaXYgPSBjYWxjSXYodGhpcywgaXYsIGNrKVxuXG4gIHRoaXMuX3ByZXYgPSBCdWZmZXIuZnJvbShpdilcbiAgdGhpcy5fY2FjaGUgPSBCdWZmZXIuYWxsb2NVbnNhZmUoMClcbiAgdGhpcy5fc2VjQ2FjaGUgPSBCdWZmZXIuYWxsb2NVbnNhZmUoMClcbiAgdGhpcy5fZGVjcnlwdCA9IGRlY3J5cHRcbiAgdGhpcy5fYWxlbiA9IDBcbiAgdGhpcy5fbGVuID0gMFxuICB0aGlzLl9tb2RlID0gbW9kZVxuXG4gIHRoaXMuX2F1dGhUYWcgPSBudWxsXG4gIHRoaXMuX2NhbGxlZCA9IGZhbHNlXG59XG5cbmluaGVyaXRzKFN0cmVhbUNpcGhlciwgVHJhbnNmb3JtKVxuXG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoY2h1bmspIHtcbiAgaWYgKCF0aGlzLl9jYWxsZWQgJiYgdGhpcy5fYWxlbikge1xuICAgIHZhciBydW1wID0gMTYgLSAodGhpcy5fYWxlbiAlIDE2KVxuICAgIGlmIChydW1wIDwgMTYpIHtcbiAgICAgIHJ1bXAgPSBCdWZmZXIuYWxsb2MocnVtcCwgMClcbiAgICAgIHRoaXMuX2doYXNoLnVwZGF0ZShydW1wKVxuICAgIH1cbiAgfVxuXG4gIHRoaXMuX2NhbGxlZCA9IHRydWVcbiAgdmFyIG91dCA9IHRoaXMuX21vZGUuZW5jcnlwdCh0aGlzLCBjaHVuaylcbiAgaWYgKHRoaXMuX2RlY3J5cHQpIHtcbiAgICB0aGlzLl9naGFzaC51cGRhdGUoY2h1bmspXG4gIH0gZWxzZSB7XG4gICAgdGhpcy5fZ2hhc2gudXBkYXRlKG91dClcbiAgfVxuICB0aGlzLl9sZW4gKz0gY2h1bmsubGVuZ3RoXG4gIHJldHVybiBvdXRcbn1cblxuU3RyZWFtQ2lwaGVyLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLl9kZWNyeXB0ICYmICF0aGlzLl9hdXRoVGFnKSB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIHN0YXRlIG9yIHVuYWJsZSB0byBhdXRoZW50aWNhdGUgZGF0YScpXG5cbiAgdmFyIHRhZyA9IHhvcih0aGlzLl9naGFzaC5maW5hbCh0aGlzLl9hbGVuICogOCwgdGhpcy5fbGVuICogOCksIHRoaXMuX2NpcGhlci5lbmNyeXB0QmxvY2sodGhpcy5fZmluSUQpKVxuICBpZiAodGhpcy5fZGVjcnlwdCAmJiB4b3JUZXN0KHRhZywgdGhpcy5fYXV0aFRhZykpIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgc3RhdGUgb3IgdW5hYmxlIHRvIGF1dGhlbnRpY2F0ZSBkYXRhJylcblxuICB0aGlzLl9hdXRoVGFnID0gdGFnXG4gIHRoaXMuX2NpcGhlci5zY3J1YigpXG59XG5cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuZ2V0QXV0aFRhZyA9IGZ1bmN0aW9uIGdldEF1dGhUYWcgKCkge1xuICBpZiAodGhpcy5fZGVjcnlwdCB8fCAhQnVmZmVyLmlzQnVmZmVyKHRoaXMuX2F1dGhUYWcpKSB0aHJvdyBuZXcgRXJyb3IoJ0F0dGVtcHRpbmcgdG8gZ2V0IGF1dGggdGFnIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcblxuICByZXR1cm4gdGhpcy5fYXV0aFRhZ1xufVxuXG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLnNldEF1dGhUYWcgPSBmdW5jdGlvbiBzZXRBdXRoVGFnICh0YWcpIHtcbiAgaWYgKCF0aGlzLl9kZWNyeXB0KSB0aHJvdyBuZXcgRXJyb3IoJ0F0dGVtcHRpbmcgdG8gc2V0IGF1dGggdGFnIGluIHVuc3VwcG9ydGVkIHN0YXRlJylcblxuICB0aGlzLl9hdXRoVGFnID0gdGFnXG59XG5cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuc2V0QUFEID0gZnVuY3Rpb24gc2V0QUFEIChidWYpIHtcbiAgaWYgKHRoaXMuX2NhbGxlZCkgdGhyb3cgbmV3IEVycm9yKCdBdHRlbXB0aW5nIHRvIHNldCBBQUQgaW4gdW5zdXBwb3J0ZWQgc3RhdGUnKVxuXG4gIHRoaXMuX2doYXNoLnVwZGF0ZShidWYpXG4gIHRoaXMuX2FsZW4gKz0gYnVmLmxlbmd0aFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFN0cmVhbUNpcGhlclxuIiwidmFyIGNpcGhlcnMgPSByZXF1aXJlKCcuL2VuY3J5cHRlcicpXG52YXIgZGVjaXBoZXJzID0gcmVxdWlyZSgnLi9kZWNyeXB0ZXInKVxudmFyIG1vZGVzID0gcmVxdWlyZSgnLi9tb2Rlcy9saXN0Lmpzb24nKVxuXG5mdW5jdGlvbiBnZXRDaXBoZXJzICgpIHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKG1vZGVzKVxufVxuXG5leHBvcnRzLmNyZWF0ZUNpcGhlciA9IGV4cG9ydHMuQ2lwaGVyID0gY2lwaGVycy5jcmVhdGVDaXBoZXJcbmV4cG9ydHMuY3JlYXRlQ2lwaGVyaXYgPSBleHBvcnRzLkNpcGhlcml2ID0gY2lwaGVycy5jcmVhdGVDaXBoZXJpdlxuZXhwb3J0cy5jcmVhdGVEZWNpcGhlciA9IGV4cG9ydHMuRGVjaXBoZXIgPSBkZWNpcGhlcnMuY3JlYXRlRGVjaXBoZXJcbmV4cG9ydHMuY3JlYXRlRGVjaXBoZXJpdiA9IGV4cG9ydHMuRGVjaXBoZXJpdiA9IGRlY2lwaGVycy5jcmVhdGVEZWNpcGhlcml2XG5leHBvcnRzLmxpc3RDaXBoZXJzID0gZXhwb3J0cy5nZXRDaXBoZXJzID0gZ2V0Q2lwaGVyc1xuIiwidmFyIEF1dGhDaXBoZXIgPSByZXF1aXJlKCcuL2F1dGhDaXBoZXInKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG52YXIgTU9ERVMgPSByZXF1aXJlKCcuL21vZGVzJylcbnZhciBTdHJlYW1DaXBoZXIgPSByZXF1aXJlKCcuL3N0cmVhbUNpcGhlcicpXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBlYnRrID0gcmVxdWlyZSgnZXZwX2J5dGVzdG9rZXknKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxuXG5mdW5jdGlvbiBEZWNpcGhlciAobW9kZSwga2V5LCBpdikge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzKVxuXG4gIHRoaXMuX2NhY2hlID0gbmV3IFNwbGl0dGVyKClcbiAgdGhpcy5fbGFzdCA9IHZvaWQgMFxuICB0aGlzLl9jaXBoZXIgPSBuZXcgYWVzLkFFUyhrZXkpXG4gIHRoaXMuX3ByZXYgPSBCdWZmZXIuZnJvbShpdilcbiAgdGhpcy5fbW9kZSA9IG1vZGVcbiAgdGhpcy5fYXV0b3BhZGRpbmcgPSB0cnVlXG59XG5cbmluaGVyaXRzKERlY2lwaGVyLCBUcmFuc2Zvcm0pXG5cbkRlY2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5fY2FjaGUuYWRkKGRhdGEpXG4gIHZhciBjaHVua1xuICB2YXIgdGhpbmdcbiAgdmFyIG91dCA9IFtdXG4gIHdoaWxlICgoY2h1bmsgPSB0aGlzLl9jYWNoZS5nZXQodGhpcy5fYXV0b3BhZGRpbmcpKSkge1xuICAgIHRoaW5nID0gdGhpcy5fbW9kZS5kZWNyeXB0KHRoaXMsIGNodW5rKVxuICAgIG91dC5wdXNoKHRoaW5nKVxuICB9XG4gIHJldHVybiBCdWZmZXIuY29uY2F0KG91dClcbn1cblxuRGVjaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNodW5rID0gdGhpcy5fY2FjaGUuZmx1c2goKVxuICBpZiAodGhpcy5fYXV0b3BhZGRpbmcpIHtcbiAgICByZXR1cm4gdW5wYWQodGhpcy5fbW9kZS5kZWNyeXB0KHRoaXMsIGNodW5rKSlcbiAgfSBlbHNlIGlmIChjaHVuaykge1xuICAgIHRocm93IG5ldyBFcnJvcignZGF0YSBub3QgbXVsdGlwbGUgb2YgYmxvY2sgbGVuZ3RoJylcbiAgfVxufVxuXG5EZWNpcGhlci5wcm90b3R5cGUuc2V0QXV0b1BhZGRpbmcgPSBmdW5jdGlvbiAoc2V0VG8pIHtcbiAgdGhpcy5fYXV0b3BhZGRpbmcgPSAhIXNldFRvXG4gIHJldHVybiB0aGlzXG59XG5cbmZ1bmN0aW9uIFNwbGl0dGVyICgpIHtcbiAgdGhpcy5jYWNoZSA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSgwKVxufVxuXG5TcGxpdHRlci5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIGRhdGFdKVxufVxuXG5TcGxpdHRlci5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGF1dG9QYWRkaW5nKSB7XG4gIHZhciBvdXRcbiAgaWYgKGF1dG9QYWRkaW5nKSB7XG4gICAgaWYgKHRoaXMuY2FjaGUubGVuZ3RoID4gMTYpIHtcbiAgICAgIG91dCA9IHRoaXMuY2FjaGUuc2xpY2UoMCwgMTYpXG4gICAgICB0aGlzLmNhY2hlID0gdGhpcy5jYWNoZS5zbGljZSgxNilcbiAgICAgIHJldHVybiBvdXRcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKHRoaXMuY2FjaGUubGVuZ3RoID49IDE2KSB7XG4gICAgICBvdXQgPSB0aGlzLmNhY2hlLnNsaWNlKDAsIDE2KVxuICAgICAgdGhpcy5jYWNoZSA9IHRoaXMuY2FjaGUuc2xpY2UoMTYpXG4gICAgICByZXR1cm4gb3V0XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGxcbn1cblxuU3BsaXR0ZXIucHJvdG90eXBlLmZsdXNoID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jYWNoZS5sZW5ndGgpIHJldHVybiB0aGlzLmNhY2hlXG59XG5cbmZ1bmN0aW9uIHVucGFkIChsYXN0KSB7XG4gIHZhciBwYWRkZWQgPSBsYXN0WzE1XVxuICBpZiAocGFkZGVkIDwgMSB8fCBwYWRkZWQgPiAxNikge1xuICAgIHRocm93IG5ldyBFcnJvcigndW5hYmxlIHRvIGRlY3J5cHQgZGF0YScpXG4gIH1cbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgcGFkZGVkKSB7XG4gICAgaWYgKGxhc3RbKGkgKyAoMTYgLSBwYWRkZWQpKV0gIT09IHBhZGRlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmFibGUgdG8gZGVjcnlwdCBkYXRhJylcbiAgICB9XG4gIH1cbiAgaWYgKHBhZGRlZCA9PT0gMTYpIHJldHVyblxuXG4gIHJldHVybiBsYXN0LnNsaWNlKDAsIDE2IC0gcGFkZGVkKVxufVxuXG5mdW5jdGlvbiBjcmVhdGVEZWNpcGhlcml2IChzdWl0ZSwgcGFzc3dvcmQsIGl2KSB7XG4gIHZhciBjb25maWcgPSBNT0RFU1tzdWl0ZS50b0xvd2VyQ2FzZSgpXVxuICBpZiAoIWNvbmZpZykgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBzdWl0ZSB0eXBlJylcblxuICBpZiAodHlwZW9mIGl2ID09PSAnc3RyaW5nJykgaXYgPSBCdWZmZXIuZnJvbShpdilcbiAgaWYgKGNvbmZpZy5tb2RlICE9PSAnR0NNJyAmJiBpdi5sZW5ndGggIT09IGNvbmZpZy5pdikgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBpdiBsZW5ndGggJyArIGl2Lmxlbmd0aClcblxuICBpZiAodHlwZW9mIHBhc3N3b3JkID09PSAnc3RyaW5nJykgcGFzc3dvcmQgPSBCdWZmZXIuZnJvbShwYXNzd29yZClcbiAgaWYgKHBhc3N3b3JkLmxlbmd0aCAhPT0gY29uZmlnLmtleSAvIDgpIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQga2V5IGxlbmd0aCAnICsgcGFzc3dvcmQubGVuZ3RoKVxuXG4gIGlmIChjb25maWcudHlwZSA9PT0gJ3N0cmVhbScpIHtcbiAgICByZXR1cm4gbmV3IFN0cmVhbUNpcGhlcihjb25maWcubW9kdWxlLCBwYXNzd29yZCwgaXYsIHRydWUpXG4gIH0gZWxzZSBpZiAoY29uZmlnLnR5cGUgPT09ICdhdXRoJykge1xuICAgIHJldHVybiBuZXcgQXV0aENpcGhlcihjb25maWcubW9kdWxlLCBwYXNzd29yZCwgaXYsIHRydWUpXG4gIH1cblxuICByZXR1cm4gbmV3IERlY2lwaGVyKGNvbmZpZy5tb2R1bGUsIHBhc3N3b3JkLCBpdilcbn1cblxuZnVuY3Rpb24gY3JlYXRlRGVjaXBoZXIgKHN1aXRlLCBwYXNzd29yZCkge1xuICB2YXIgY29uZmlnID0gTU9ERVNbc3VpdGUudG9Mb3dlckNhc2UoKV1cbiAgaWYgKCFjb25maWcpIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG5cbiAgdmFyIGtleXMgPSBlYnRrKHBhc3N3b3JkLCBmYWxzZSwgY29uZmlnLmtleSwgY29uZmlnLml2KVxuICByZXR1cm4gY3JlYXRlRGVjaXBoZXJpdihzdWl0ZSwga2V5cy5rZXksIGtleXMuaXYpXG59XG5cbmV4cG9ydHMuY3JlYXRlRGVjaXBoZXIgPSBjcmVhdGVEZWNpcGhlclxuZXhwb3J0cy5jcmVhdGVEZWNpcGhlcml2ID0gY3JlYXRlRGVjaXBoZXJpdlxuIiwidmFyIE1PREVTID0gcmVxdWlyZSgnLi9tb2RlcycpXG52YXIgQXV0aENpcGhlciA9IHJlcXVpcmUoJy4vYXV0aENpcGhlcicpXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcbnZhciBTdHJlYW1DaXBoZXIgPSByZXF1aXJlKCcuL3N0cmVhbUNpcGhlcicpXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzJylcbnZhciBlYnRrID0gcmVxdWlyZSgnZXZwX2J5dGVzdG9rZXknKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxuXG5mdW5jdGlvbiBDaXBoZXIgKG1vZGUsIGtleSwgaXYpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcblxuICB0aGlzLl9jYWNoZSA9IG5ldyBTcGxpdHRlcigpXG4gIHRoaXMuX2NpcGhlciA9IG5ldyBhZXMuQUVTKGtleSlcbiAgdGhpcy5fcHJldiA9IEJ1ZmZlci5mcm9tKGl2KVxuICB0aGlzLl9tb2RlID0gbW9kZVxuICB0aGlzLl9hdXRvcGFkZGluZyA9IHRydWVcbn1cblxuaW5oZXJpdHMoQ2lwaGVyLCBUcmFuc2Zvcm0pXG5cbkNpcGhlci5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuX2NhY2hlLmFkZChkYXRhKVxuICB2YXIgY2h1bmtcbiAgdmFyIHRoaW5nXG4gIHZhciBvdXQgPSBbXVxuXG4gIHdoaWxlICgoY2h1bmsgPSB0aGlzLl9jYWNoZS5nZXQoKSkpIHtcbiAgICB0aGluZyA9IHRoaXMuX21vZGUuZW5jcnlwdCh0aGlzLCBjaHVuaylcbiAgICBvdXQucHVzaCh0aGluZylcbiAgfVxuXG4gIHJldHVybiBCdWZmZXIuY29uY2F0KG91dClcbn1cblxudmFyIFBBRERJTkcgPSBCdWZmZXIuYWxsb2MoMTYsIDB4MTApXG5cbkNpcGhlci5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICB2YXIgY2h1bmsgPSB0aGlzLl9jYWNoZS5mbHVzaCgpXG4gIGlmICh0aGlzLl9hdXRvcGFkZGluZykge1xuICAgIGNodW5rID0gdGhpcy5fbW9kZS5lbmNyeXB0KHRoaXMsIGNodW5rKVxuICAgIHRoaXMuX2NpcGhlci5zY3J1YigpXG4gICAgcmV0dXJuIGNodW5rXG4gIH1cblxuICBpZiAoIWNodW5rLmVxdWFscyhQQURESU5HKSkge1xuICAgIHRoaXMuX2NpcGhlci5zY3J1YigpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdkYXRhIG5vdCBtdWx0aXBsZSBvZiBibG9jayBsZW5ndGgnKVxuICB9XG59XG5cbkNpcGhlci5wcm90b3R5cGUuc2V0QXV0b1BhZGRpbmcgPSBmdW5jdGlvbiAoc2V0VG8pIHtcbiAgdGhpcy5fYXV0b3BhZGRpbmcgPSAhIXNldFRvXG4gIHJldHVybiB0aGlzXG59XG5cbmZ1bmN0aW9uIFNwbGl0dGVyICgpIHtcbiAgdGhpcy5jYWNoZSA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSgwKVxufVxuXG5TcGxpdHRlci5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5jYWNoZSA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIGRhdGFdKVxufVxuXG5TcGxpdHRlci5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jYWNoZS5sZW5ndGggPiAxNSkge1xuICAgIHZhciBvdXQgPSB0aGlzLmNhY2hlLnNsaWNlKDAsIDE2KVxuICAgIHRoaXMuY2FjaGUgPSB0aGlzLmNhY2hlLnNsaWNlKDE2KVxuICAgIHJldHVybiBvdXRcbiAgfVxuICByZXR1cm4gbnVsbFxufVxuXG5TcGxpdHRlci5wcm90b3R5cGUuZmx1c2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBsZW4gPSAxNiAtIHRoaXMuY2FjaGUubGVuZ3RoXG4gIHZhciBwYWRCdWZmID0gQnVmZmVyLmFsbG9jVW5zYWZlKGxlbilcblxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBwYWRCdWZmLndyaXRlVUludDgobGVuLCBpKVxuICB9XG5cbiAgcmV0dXJuIEJ1ZmZlci5jb25jYXQoW3RoaXMuY2FjaGUsIHBhZEJ1ZmZdKVxufVxuXG5mdW5jdGlvbiBjcmVhdGVDaXBoZXJpdiAoc3VpdGUsIHBhc3N3b3JkLCBpdikge1xuICB2YXIgY29uZmlnID0gTU9ERVNbc3VpdGUudG9Mb3dlckNhc2UoKV1cbiAgaWYgKCFjb25maWcpIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG5cbiAgaWYgKHR5cGVvZiBwYXNzd29yZCA9PT0gJ3N0cmluZycpIHBhc3N3b3JkID0gQnVmZmVyLmZyb20ocGFzc3dvcmQpXG4gIGlmIChwYXNzd29yZC5sZW5ndGggIT09IGNvbmZpZy5rZXkgLyA4KSB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIGtleSBsZW5ndGggJyArIHBhc3N3b3JkLmxlbmd0aClcblxuICBpZiAodHlwZW9mIGl2ID09PSAnc3RyaW5nJykgaXYgPSBCdWZmZXIuZnJvbShpdilcbiAgaWYgKGNvbmZpZy5tb2RlICE9PSAnR0NNJyAmJiBpdi5sZW5ndGggIT09IGNvbmZpZy5pdikgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBpdiBsZW5ndGggJyArIGl2Lmxlbmd0aClcblxuICBpZiAoY29uZmlnLnR5cGUgPT09ICdzdHJlYW0nKSB7XG4gICAgcmV0dXJuIG5ldyBTdHJlYW1DaXBoZXIoY29uZmlnLm1vZHVsZSwgcGFzc3dvcmQsIGl2KVxuICB9IGVsc2UgaWYgKGNvbmZpZy50eXBlID09PSAnYXV0aCcpIHtcbiAgICByZXR1cm4gbmV3IEF1dGhDaXBoZXIoY29uZmlnLm1vZHVsZSwgcGFzc3dvcmQsIGl2KVxuICB9XG5cbiAgcmV0dXJuIG5ldyBDaXBoZXIoY29uZmlnLm1vZHVsZSwgcGFzc3dvcmQsIGl2KVxufVxuXG5mdW5jdGlvbiBjcmVhdGVDaXBoZXIgKHN1aXRlLCBwYXNzd29yZCkge1xuICB2YXIgY29uZmlnID0gTU9ERVNbc3VpdGUudG9Mb3dlckNhc2UoKV1cbiAgaWYgKCFjb25maWcpIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG5cbiAgdmFyIGtleXMgPSBlYnRrKHBhc3N3b3JkLCBmYWxzZSwgY29uZmlnLmtleSwgY29uZmlnLml2KVxuICByZXR1cm4gY3JlYXRlQ2lwaGVyaXYoc3VpdGUsIGtleXMua2V5LCBrZXlzLml2KVxufVxuXG5leHBvcnRzLmNyZWF0ZUNpcGhlcml2ID0gY3JlYXRlQ2lwaGVyaXZcbmV4cG9ydHMuY3JlYXRlQ2lwaGVyID0gY3JlYXRlQ2lwaGVyXG4iLCJ2YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcbnZhciBaRVJPRVMgPSBCdWZmZXIuYWxsb2MoMTYsIDApXG5cbmZ1bmN0aW9uIHRvQXJyYXkgKGJ1Zikge1xuICByZXR1cm4gW1xuICAgIGJ1Zi5yZWFkVUludDMyQkUoMCksXG4gICAgYnVmLnJlYWRVSW50MzJCRSg0KSxcbiAgICBidWYucmVhZFVJbnQzMkJFKDgpLFxuICAgIGJ1Zi5yZWFkVUludDMyQkUoMTIpXG4gIF1cbn1cblxuZnVuY3Rpb24gZnJvbUFycmF5IChvdXQpIHtcbiAgdmFyIGJ1ZiA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSgxNilcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzBdID4+PiAwLCAwKVxuICBidWYud3JpdGVVSW50MzJCRShvdXRbMV0gPj4+IDAsIDQpXG4gIGJ1Zi53cml0ZVVJbnQzMkJFKG91dFsyXSA+Pj4gMCwgOClcbiAgYnVmLndyaXRlVUludDMyQkUob3V0WzNdID4+PiAwLCAxMilcbiAgcmV0dXJuIGJ1ZlxufVxuXG5mdW5jdGlvbiBHSEFTSCAoa2V5KSB7XG4gIHRoaXMuaCA9IGtleVxuICB0aGlzLnN0YXRlID0gQnVmZmVyLmFsbG9jKDE2LCAwKVxuICB0aGlzLmNhY2hlID0gQnVmZmVyLmFsbG9jVW5zYWZlKDApXG59XG5cbi8vIGZyb20gaHR0cDovL2JpdHdpc2VzaGlmdGxlZnQuZ2l0aHViLmlvL3NqY2wvZG9jL3N5bWJvbHMvc3JjL2NvcmVfZ2NtLmpzLmh0bWxcbi8vIGJ5IEp1aG8gVsOkaMOkLUhlcnR0dWFcbkdIQVNILnByb3RvdHlwZS5naGFzaCA9IGZ1bmN0aW9uIChibG9jaykge1xuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBibG9jay5sZW5ndGgpIHtcbiAgICB0aGlzLnN0YXRlW2ldIF49IGJsb2NrW2ldXG4gIH1cbiAgdGhpcy5fbXVsdGlwbHkoKVxufVxuXG5HSEFTSC5wcm90b3R5cGUuX211bHRpcGx5ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgVmkgPSB0b0FycmF5KHRoaXMuaClcbiAgdmFyIFppID0gWzAsIDAsIDAsIDBdXG4gIHZhciBqLCB4aSwgbHNiVmlcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgMTI4KSB7XG4gICAgeGkgPSAodGhpcy5zdGF0ZVt+fihpIC8gOCldICYgKDEgPDwgKDcgLSAoaSAlIDgpKSkpICE9PSAwXG4gICAgaWYgKHhpKSB7XG4gICAgICAvLyBaX2krMSA9IFpfaSBeIFZfaVxuICAgICAgWmlbMF0gXj0gVmlbMF1cbiAgICAgIFppWzFdIF49IFZpWzFdXG4gICAgICBaaVsyXSBePSBWaVsyXVxuICAgICAgWmlbM10gXj0gVmlbM11cbiAgICB9XG5cbiAgICAvLyBTdG9yZSB0aGUgdmFsdWUgb2YgTFNCKFZfaSlcbiAgICBsc2JWaSA9IChWaVszXSAmIDEpICE9PSAwXG5cbiAgICAvLyBWX2krMSA9IFZfaSA+PiAxXG4gICAgZm9yIChqID0gMzsgaiA+IDA7IGotLSkge1xuICAgICAgVmlbal0gPSAoVmlbal0gPj4+IDEpIHwgKChWaVtqIC0gMV0gJiAxKSA8PCAzMSlcbiAgICB9XG4gICAgVmlbMF0gPSBWaVswXSA+Pj4gMVxuXG4gICAgLy8gSWYgTFNCKFZfaSkgaXMgMSwgVl9pKzEgPSAoVl9pID4+IDEpIF4gUlxuICAgIGlmIChsc2JWaSkge1xuICAgICAgVmlbMF0gPSBWaVswXSBeICgweGUxIDw8IDI0KVxuICAgIH1cbiAgfVxuICB0aGlzLnN0YXRlID0gZnJvbUFycmF5KFppKVxufVxuXG5HSEFTSC5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKGJ1Zikge1xuICB0aGlzLmNhY2hlID0gQnVmZmVyLmNvbmNhdChbdGhpcy5jYWNoZSwgYnVmXSlcbiAgdmFyIGNodW5rXG4gIHdoaWxlICh0aGlzLmNhY2hlLmxlbmd0aCA+PSAxNikge1xuICAgIGNodW5rID0gdGhpcy5jYWNoZS5zbGljZSgwLCAxNilcbiAgICB0aGlzLmNhY2hlID0gdGhpcy5jYWNoZS5zbGljZSgxNilcbiAgICB0aGlzLmdoYXNoKGNodW5rKVxuICB9XG59XG5cbkdIQVNILnByb3RvdHlwZS5maW5hbCA9IGZ1bmN0aW9uIChhYmwsIGJsKSB7XG4gIGlmICh0aGlzLmNhY2hlLmxlbmd0aCkge1xuICAgIHRoaXMuZ2hhc2goQnVmZmVyLmNvbmNhdChbdGhpcy5jYWNoZSwgWkVST0VTXSwgMTYpKVxuICB9XG5cbiAgdGhpcy5naGFzaChmcm9tQXJyYXkoWzAsIGFibCwgMCwgYmxdKSlcbiAgcmV0dXJuIHRoaXMuc3RhdGVcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBHSEFTSFxuIiwiZnVuY3Rpb24gaW5jcjMyIChpdikge1xuICB2YXIgbGVuID0gaXYubGVuZ3RoXG4gIHZhciBpdGVtXG4gIHdoaWxlIChsZW4tLSkge1xuICAgIGl0ZW0gPSBpdi5yZWFkVUludDgobGVuKVxuICAgIGlmIChpdGVtID09PSAyNTUpIHtcbiAgICAgIGl2LndyaXRlVUludDgoMCwgbGVuKVxuICAgIH0gZWxzZSB7XG4gICAgICBpdGVtKytcbiAgICAgIGl2LndyaXRlVUludDgoaXRlbSwgbGVuKVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbn1cbm1vZHVsZS5leHBvcnRzID0gaW5jcjMyXG4iLCJ2YXIgeG9yID0gcmVxdWlyZSgnYnVmZmVyLXhvcicpXG5cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBibG9jaykge1xuICB2YXIgZGF0YSA9IHhvcihibG9jaywgc2VsZi5fcHJldilcblxuICBzZWxmLl9wcmV2ID0gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhkYXRhKVxuICByZXR1cm4gc2VsZi5fcHJldlxufVxuXG5leHBvcnRzLmRlY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgYmxvY2spIHtcbiAgdmFyIHBhZCA9IHNlbGYuX3ByZXZcblxuICBzZWxmLl9wcmV2ID0gYmxvY2tcbiAgdmFyIG91dCA9IHNlbGYuX2NpcGhlci5kZWNyeXB0QmxvY2soYmxvY2spXG5cbiAgcmV0dXJuIHhvcihvdXQsIHBhZClcbn1cbiIsInZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxudmFyIHhvciA9IHJlcXVpcmUoJ2J1ZmZlci14b3InKVxuXG5mdW5jdGlvbiBlbmNyeXB0U3RhcnQgKHNlbGYsIGRhdGEsIGRlY3J5cHQpIHtcbiAgdmFyIGxlbiA9IGRhdGEubGVuZ3RoXG4gIHZhciBvdXQgPSB4b3IoZGF0YSwgc2VsZi5fY2FjaGUpXG4gIHNlbGYuX2NhY2hlID0gc2VsZi5fY2FjaGUuc2xpY2UobGVuKVxuICBzZWxmLl9wcmV2ID0gQnVmZmVyLmNvbmNhdChbc2VsZi5fcHJldiwgZGVjcnlwdCA/IGRhdGEgOiBvdXRdKVxuICByZXR1cm4gb3V0XG59XG5cbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBkYXRhLCBkZWNyeXB0KSB7XG4gIHZhciBvdXQgPSBCdWZmZXIuYWxsb2NVbnNhZmUoMClcbiAgdmFyIGxlblxuXG4gIHdoaWxlIChkYXRhLmxlbmd0aCkge1xuICAgIGlmIChzZWxmLl9jYWNoZS5sZW5ndGggPT09IDApIHtcbiAgICAgIHNlbGYuX2NhY2hlID0gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhzZWxmLl9wcmV2KVxuICAgICAgc2VsZi5fcHJldiA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSgwKVxuICAgIH1cblxuICAgIGlmIChzZWxmLl9jYWNoZS5sZW5ndGggPD0gZGF0YS5sZW5ndGgpIHtcbiAgICAgIGxlbiA9IHNlbGYuX2NhY2hlLmxlbmd0aFxuICAgICAgb3V0ID0gQnVmZmVyLmNvbmNhdChbb3V0LCBlbmNyeXB0U3RhcnQoc2VsZiwgZGF0YS5zbGljZSgwLCBsZW4pLCBkZWNyeXB0KV0pXG4gICAgICBkYXRhID0gZGF0YS5zbGljZShsZW4pXG4gICAgfSBlbHNlIHtcbiAgICAgIG91dCA9IEJ1ZmZlci5jb25jYXQoW291dCwgZW5jcnlwdFN0YXJ0KHNlbGYsIGRhdGEsIGRlY3J5cHQpXSlcbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG91dFxufVxuIiwidmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG5cbmZ1bmN0aW9uIGVuY3J5cHRCeXRlIChzZWxmLCBieXRlUGFyYW0sIGRlY3J5cHQpIHtcbiAgdmFyIHBhZFxuICB2YXIgaSA9IC0xXG4gIHZhciBsZW4gPSA4XG4gIHZhciBvdXQgPSAwXG4gIHZhciBiaXQsIHZhbHVlXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBwYWQgPSBzZWxmLl9jaXBoZXIuZW5jcnlwdEJsb2NrKHNlbGYuX3ByZXYpXG4gICAgYml0ID0gKGJ5dGVQYXJhbSAmICgxIDw8ICg3IC0gaSkpKSA/IDB4ODAgOiAwXG4gICAgdmFsdWUgPSBwYWRbMF0gXiBiaXRcbiAgICBvdXQgKz0gKCh2YWx1ZSAmIDB4ODApID4+IChpICUgOCkpXG4gICAgc2VsZi5fcHJldiA9IHNoaWZ0SW4oc2VsZi5fcHJldiwgZGVjcnlwdCA/IGJpdCA6IHZhbHVlKVxuICB9XG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gc2hpZnRJbiAoYnVmZmVyLCB2YWx1ZSkge1xuICB2YXIgbGVuID0gYnVmZmVyLmxlbmd0aFxuICB2YXIgaSA9IC0xXG4gIHZhciBvdXQgPSBCdWZmZXIuYWxsb2NVbnNhZmUoYnVmZmVyLmxlbmd0aClcbiAgYnVmZmVyID0gQnVmZmVyLmNvbmNhdChbYnVmZmVyLCBCdWZmZXIuZnJvbShbdmFsdWVdKV0pXG5cbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIG91dFtpXSA9IGJ1ZmZlcltpXSA8PCAxIHwgYnVmZmVyW2kgKyAxXSA+PiAoNylcbiAgfVxuXG4gIHJldHVybiBvdXRcbn1cblxuZXhwb3J0cy5lbmNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGNodW5rLCBkZWNyeXB0KSB7XG4gIHZhciBsZW4gPSBjaHVuay5sZW5ndGhcbiAgdmFyIG91dCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShsZW4pXG4gIHZhciBpID0gLTFcblxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgb3V0W2ldID0gZW5jcnlwdEJ5dGUoc2VsZiwgY2h1bmtbaV0sIGRlY3J5cHQpXG4gIH1cblxuICByZXR1cm4gb3V0XG59XG4iLCJ2YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcblxuZnVuY3Rpb24gZW5jcnlwdEJ5dGUgKHNlbGYsIGJ5dGVQYXJhbSwgZGVjcnlwdCkge1xuICB2YXIgcGFkID0gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhzZWxmLl9wcmV2KVxuICB2YXIgb3V0ID0gcGFkWzBdIF4gYnl0ZVBhcmFtXG5cbiAgc2VsZi5fcHJldiA9IEJ1ZmZlci5jb25jYXQoW1xuICAgIHNlbGYuX3ByZXYuc2xpY2UoMSksXG4gICAgQnVmZmVyLmZyb20oW2RlY3J5cHQgPyBieXRlUGFyYW0gOiBvdXRdKVxuICBdKVxuXG4gIHJldHVybiBvdXRcbn1cblxuZXhwb3J0cy5lbmNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGNodW5rLCBkZWNyeXB0KSB7XG4gIHZhciBsZW4gPSBjaHVuay5sZW5ndGhcbiAgdmFyIG91dCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShsZW4pXG4gIHZhciBpID0gLTFcblxuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgb3V0W2ldID0gZW5jcnlwdEJ5dGUoc2VsZiwgY2h1bmtbaV0sIGRlY3J5cHQpXG4gIH1cblxuICByZXR1cm4gb3V0XG59XG4iLCJ2YXIgeG9yID0gcmVxdWlyZSgnYnVmZmVyLXhvcicpXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcbnZhciBpbmNyMzIgPSByZXF1aXJlKCcuLi9pbmNyMzInKVxuXG5mdW5jdGlvbiBnZXRCbG9jayAoc2VsZikge1xuICB2YXIgb3V0ID0gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9ja1JhdyhzZWxmLl9wcmV2KVxuICBpbmNyMzIoc2VsZi5fcHJldilcbiAgcmV0dXJuIG91dFxufVxuXG52YXIgYmxvY2tTaXplID0gMTZcbmV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBjaHVuaykge1xuICB2YXIgY2h1bmtOdW0gPSBNYXRoLmNlaWwoY2h1bmsubGVuZ3RoIC8gYmxvY2tTaXplKVxuICB2YXIgc3RhcnQgPSBzZWxmLl9jYWNoZS5sZW5ndGhcbiAgc2VsZi5fY2FjaGUgPSBCdWZmZXIuY29uY2F0KFtcbiAgICBzZWxmLl9jYWNoZSxcbiAgICBCdWZmZXIuYWxsb2NVbnNhZmUoY2h1bmtOdW0gKiBibG9ja1NpemUpXG4gIF0pXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgY2h1bmtOdW07IGkrKykge1xuICAgIHZhciBvdXQgPSBnZXRCbG9jayhzZWxmKVxuICAgIHZhciBvZmZzZXQgPSBzdGFydCArIGkgKiBibG9ja1NpemVcbiAgICBzZWxmLl9jYWNoZS53cml0ZVVJbnQzMkJFKG91dFswXSwgb2Zmc2V0ICsgMClcbiAgICBzZWxmLl9jYWNoZS53cml0ZVVJbnQzMkJFKG91dFsxXSwgb2Zmc2V0ICsgNClcbiAgICBzZWxmLl9jYWNoZS53cml0ZVVJbnQzMkJFKG91dFsyXSwgb2Zmc2V0ICsgOClcbiAgICBzZWxmLl9jYWNoZS53cml0ZVVJbnQzMkJFKG91dFszXSwgb2Zmc2V0ICsgMTIpXG4gIH1cbiAgdmFyIHBhZCA9IHNlbGYuX2NhY2hlLnNsaWNlKDAsIGNodW5rLmxlbmd0aClcbiAgc2VsZi5fY2FjaGUgPSBzZWxmLl9jYWNoZS5zbGljZShjaHVuay5sZW5ndGgpXG4gIHJldHVybiB4b3IoY2h1bmssIHBhZClcbn1cbiIsImV4cG9ydHMuZW5jcnlwdCA9IGZ1bmN0aW9uIChzZWxmLCBibG9jaykge1xuICByZXR1cm4gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhibG9jaylcbn1cblxuZXhwb3J0cy5kZWNyeXB0ID0gZnVuY3Rpb24gKHNlbGYsIGJsb2NrKSB7XG4gIHJldHVybiBzZWxmLl9jaXBoZXIuZGVjcnlwdEJsb2NrKGJsb2NrKVxufVxuIiwidmFyIG1vZGVNb2R1bGVzID0ge1xuICBFQ0I6IHJlcXVpcmUoJy4vZWNiJyksXG4gIENCQzogcmVxdWlyZSgnLi9jYmMnKSxcbiAgQ0ZCOiByZXF1aXJlKCcuL2NmYicpLFxuICBDRkI4OiByZXF1aXJlKCcuL2NmYjgnKSxcbiAgQ0ZCMTogcmVxdWlyZSgnLi9jZmIxJyksXG4gIE9GQjogcmVxdWlyZSgnLi9vZmInKSxcbiAgQ1RSOiByZXF1aXJlKCcuL2N0cicpLFxuICBHQ006IHJlcXVpcmUoJy4vY3RyJylcbn1cblxudmFyIG1vZGVzID0gcmVxdWlyZSgnLi9saXN0Lmpzb24nKVxuXG5mb3IgKHZhciBrZXkgaW4gbW9kZXMpIHtcbiAgbW9kZXNba2V5XS5tb2R1bGUgPSBtb2RlTW9kdWxlc1ttb2Rlc1trZXldLm1vZGVdXG59XG5cbm1vZHVsZS5leHBvcnRzID0gbW9kZXNcbiIsIm1vZHVsZS5leHBvcnRzPXtcbiAgXCJhZXMtMTI4LWVjYlwiOiB7XG4gICAgXCJjaXBoZXJcIjogXCJBRVNcIixcbiAgICBcImtleVwiOiAxMjgsXG4gICAgXCJpdlwiOiAwLFxuICAgIFwibW9kZVwiOiBcIkVDQlwiLFxuICAgIFwidHlwZVwiOiBcImJsb2NrXCJcbiAgfSxcbiAgXCJhZXMtMTkyLWVjYlwiOiB7XG4gICAgXCJjaXBoZXJcIjogXCJBRVNcIixcbiAgICBcImtleVwiOiAxOTIsXG4gICAgXCJpdlwiOiAwLFxuICAgIFwibW9kZVwiOiBcIkVDQlwiLFxuICAgIFwidHlwZVwiOiBcImJsb2NrXCJcbiAgfSxcbiAgXCJhZXMtMjU2LWVjYlwiOiB7XG4gICAgXCJjaXBoZXJcIjogXCJBRVNcIixcbiAgICBcImtleVwiOiAyNTYsXG4gICAgXCJpdlwiOiAwLFxuICAgIFwibW9kZVwiOiBcIkVDQlwiLFxuICAgIFwidHlwZVwiOiBcImJsb2NrXCJcbiAgfSxcbiAgXCJhZXMtMTI4LWNiY1wiOiB7XG4gICAgXCJjaXBoZXJcIjogXCJBRVNcIixcbiAgICBcImtleVwiOiAxMjgsXG4gICAgXCJpdlwiOiAxNixcbiAgICBcIm1vZGVcIjogXCJDQkNcIixcbiAgICBcInR5cGVcIjogXCJibG9ja1wiXG4gIH0sXG4gIFwiYWVzLTE5Mi1jYmNcIjoge1xuICAgIFwiY2lwaGVyXCI6IFwiQUVTXCIsXG4gICAgXCJrZXlcIjogMTkyLFxuICAgIFwiaXZcIjogMTYsXG4gICAgXCJtb2RlXCI6IFwiQ0JDXCIsXG4gICAgXCJ0eXBlXCI6IFwiYmxvY2tcIlxuICB9LFxuICBcImFlcy0yNTYtY2JjXCI6IHtcbiAgICBcImNpcGhlclwiOiBcIkFFU1wiLFxuICAgIFwia2V5XCI6IDI1NixcbiAgICBcIml2XCI6IDE2LFxuICAgIFwibW9kZVwiOiBcIkNCQ1wiLFxuICAgIFwidHlwZVwiOiBcImJsb2NrXCJcbiAgfSxcbiAgXCJhZXMxMjhcIjoge1xuICAgIFwiY2lwaGVyXCI6IFwiQUVTXCIsXG4gICAgXCJrZXlcIjogMTI4LFxuICAgIFwiaXZcIjogMTYsXG4gICAgXCJtb2RlXCI6IFwiQ0JDXCIsXG4gICAgXCJ0eXBlXCI6IFwiYmxvY2tcIlxuICB9LFxuICBcImFlczE5MlwiOiB7XG4gICAgXCJjaXBoZXJcIjogXCJBRVNcIixcbiAgICBcImtleVwiOiAxOTIsXG4gICAgXCJpdlwiOiAxNixcbiAgICBcIm1vZGVcIjogXCJDQkNcIixcbiAgICBcInR5cGVcIjogXCJibG9ja1wiXG4gIH0sXG4gIFwiYWVzMjU2XCI6IHtcbiAgICBcImNpcGhlclwiOiBcIkFFU1wiLFxuICAgIFwia2V5XCI6IDI1NixcbiAgICBcIml2XCI6IDE2LFxuICAgIFwibW9kZVwiOiBcIkNCQ1wiLFxuICAgIFwidHlwZVwiOiBcImJsb2NrXCJcbiAgfSxcbiAgXCJhZXMtMTI4LWNmYlwiOiB7XG4gICAgXCJjaXBoZXJcIjogXCJBRVNcIixcbiAgICBcImtleVwiOiAxMjgsXG4gICAgXCJpdlwiOiAxNixcbiAgICBcIm1vZGVcIjogXCJDRkJcIixcbiAgICBcInR5cGVcIjogXCJzdHJlYW1cIlxuICB9LFxuICBcImFlcy0xOTItY2ZiXCI6IHtcbiAgICBcImNpcGhlclwiOiBcIkFFU1wiLFxuICAgIFwia2V5XCI6IDE5MixcbiAgICBcIml2XCI6IDE2LFxuICAgIFwibW9kZVwiOiBcIkNGQlwiLFxuICAgIFwidHlwZVwiOiBcInN0cmVhbVwiXG4gIH0sXG4gIFwiYWVzLTI1Ni1jZmJcIjoge1xuICAgIFwiY2lwaGVyXCI6IFwiQUVTXCIsXG4gICAgXCJrZXlcIjogMjU2LFxuICAgIFwiaXZcIjogMTYsXG4gICAgXCJtb2RlXCI6IFwiQ0ZCXCIsXG4gICAgXCJ0eXBlXCI6IFwic3RyZWFtXCJcbiAgfSxcbiAgXCJhZXMtMTI4LWNmYjhcIjoge1xuICAgIFwiY2lwaGVyXCI6IFwiQUVTXCIsXG4gICAgXCJrZXlcIjogMTI4LFxuICAgIFwiaXZcIjogMTYsXG4gICAgXCJtb2RlXCI6IFwiQ0ZCOFwiLFxuICAgIFwidHlwZVwiOiBcInN0cmVhbVwiXG4gIH0sXG4gIFwiYWVzLTE5Mi1jZmI4XCI6IHtcbiAgICBcImNpcGhlclwiOiBcIkFFU1wiLFxuICAgIFwia2V5XCI6IDE5MixcbiAgICBcIml2XCI6IDE2LFxuICAgIFwibW9kZVwiOiBcIkNGQjhcIixcbiAgICBcInR5cGVcIjogXCJzdHJlYW1cIlxuICB9LFxuICBcImFlcy0yNTYtY2ZiOFwiOiB7XG4gICAgXCJjaXBoZXJcIjogXCJBRVNcIixcbiAgICBcImtleVwiOiAyNTYsXG4gICAgXCJpdlwiOiAxNixcbiAgICBcIm1vZGVcIjogXCJDRkI4XCIsXG4gICAgXCJ0eXBlXCI6IFwic3RyZWFtXCJcbiAgfSxcbiAgXCJhZXMtMTI4LWNmYjFcIjoge1xuICAgIFwiY2lwaGVyXCI6IFwiQUVTXCIsXG4gICAgXCJrZXlcIjogMTI4LFxuICAgIFwiaXZcIjogMTYsXG4gICAgXCJtb2RlXCI6IFwiQ0ZCMVwiLFxuICAgIFwidHlwZVwiOiBcInN0cmVhbVwiXG4gIH0sXG4gIFwiYWVzLTE5Mi1jZmIxXCI6IHtcbiAgICBcImNpcGhlclwiOiBcIkFFU1wiLFxuICAgIFwia2V5XCI6IDE5MixcbiAgICBcIml2XCI6IDE2LFxuICAgIFwibW9kZVwiOiBcIkNGQjFcIixcbiAgICBcInR5cGVcIjogXCJzdHJlYW1cIlxuICB9LFxuICBcImFlcy0yNTYtY2ZiMVwiOiB7XG4gICAgXCJjaXBoZXJcIjogXCJBRVNcIixcbiAgICBcImtleVwiOiAyNTYsXG4gICAgXCJpdlwiOiAxNixcbiAgICBcIm1vZGVcIjogXCJDRkIxXCIsXG4gICAgXCJ0eXBlXCI6IFwic3RyZWFtXCJcbiAgfSxcbiAgXCJhZXMtMTI4LW9mYlwiOiB7XG4gICAgXCJjaXBoZXJcIjogXCJBRVNcIixcbiAgICBcImtleVwiOiAxMjgsXG4gICAgXCJpdlwiOiAxNixcbiAgICBcIm1vZGVcIjogXCJPRkJcIixcbiAgICBcInR5cGVcIjogXCJzdHJlYW1cIlxuICB9LFxuICBcImFlcy0xOTItb2ZiXCI6IHtcbiAgICBcImNpcGhlclwiOiBcIkFFU1wiLFxuICAgIFwia2V5XCI6IDE5MixcbiAgICBcIml2XCI6IDE2LFxuICAgIFwibW9kZVwiOiBcIk9GQlwiLFxuICAgIFwidHlwZVwiOiBcInN0cmVhbVwiXG4gIH0sXG4gIFwiYWVzLTI1Ni1vZmJcIjoge1xuICAgIFwiY2lwaGVyXCI6IFwiQUVTXCIsXG4gICAgXCJrZXlcIjogMjU2LFxuICAgIFwiaXZcIjogMTYsXG4gICAgXCJtb2RlXCI6IFwiT0ZCXCIsXG4gICAgXCJ0eXBlXCI6IFwic3RyZWFtXCJcbiAgfSxcbiAgXCJhZXMtMTI4LWN0clwiOiB7XG4gICAgXCJjaXBoZXJcIjogXCJBRVNcIixcbiAgICBcImtleVwiOiAxMjgsXG4gICAgXCJpdlwiOiAxNixcbiAgICBcIm1vZGVcIjogXCJDVFJcIixcbiAgICBcInR5cGVcIjogXCJzdHJlYW1cIlxuICB9LFxuICBcImFlcy0xOTItY3RyXCI6IHtcbiAgICBcImNpcGhlclwiOiBcIkFFU1wiLFxuICAgIFwia2V5XCI6IDE5MixcbiAgICBcIml2XCI6IDE2LFxuICAgIFwibW9kZVwiOiBcIkNUUlwiLFxuICAgIFwidHlwZVwiOiBcInN0cmVhbVwiXG4gIH0sXG4gIFwiYWVzLTI1Ni1jdHJcIjoge1xuICAgIFwiY2lwaGVyXCI6IFwiQUVTXCIsXG4gICAgXCJrZXlcIjogMjU2LFxuICAgIFwiaXZcIjogMTYsXG4gICAgXCJtb2RlXCI6IFwiQ1RSXCIsXG4gICAgXCJ0eXBlXCI6IFwic3RyZWFtXCJcbiAgfSxcbiAgXCJhZXMtMTI4LWdjbVwiOiB7XG4gICAgXCJjaXBoZXJcIjogXCJBRVNcIixcbiAgICBcImtleVwiOiAxMjgsXG4gICAgXCJpdlwiOiAxMixcbiAgICBcIm1vZGVcIjogXCJHQ01cIixcbiAgICBcInR5cGVcIjogXCJhdXRoXCJcbiAgfSxcbiAgXCJhZXMtMTkyLWdjbVwiOiB7XG4gICAgXCJjaXBoZXJcIjogXCJBRVNcIixcbiAgICBcImtleVwiOiAxOTIsXG4gICAgXCJpdlwiOiAxMixcbiAgICBcIm1vZGVcIjogXCJHQ01cIixcbiAgICBcInR5cGVcIjogXCJhdXRoXCJcbiAgfSxcbiAgXCJhZXMtMjU2LWdjbVwiOiB7XG4gICAgXCJjaXBoZXJcIjogXCJBRVNcIixcbiAgICBcImtleVwiOiAyNTYsXG4gICAgXCJpdlwiOiAxMixcbiAgICBcIm1vZGVcIjogXCJHQ01cIixcbiAgICBcInR5cGVcIjogXCJhdXRoXCJcbiAgfVxufVxuIiwidmFyIHhvciA9IHJlcXVpcmUoJ2J1ZmZlci14b3InKVxuXG5mdW5jdGlvbiBnZXRCbG9jayAoc2VsZikge1xuICBzZWxmLl9wcmV2ID0gc2VsZi5fY2lwaGVyLmVuY3J5cHRCbG9jayhzZWxmLl9wcmV2KVxuICByZXR1cm4gc2VsZi5fcHJldlxufVxuXG5leHBvcnRzLmVuY3J5cHQgPSBmdW5jdGlvbiAoc2VsZiwgY2h1bmspIHtcbiAgd2hpbGUgKHNlbGYuX2NhY2hlLmxlbmd0aCA8IGNodW5rLmxlbmd0aCkge1xuICAgIHNlbGYuX2NhY2hlID0gQnVmZmVyLmNvbmNhdChbc2VsZi5fY2FjaGUsIGdldEJsb2NrKHNlbGYpXSlcbiAgfVxuXG4gIHZhciBwYWQgPSBzZWxmLl9jYWNoZS5zbGljZSgwLCBjaHVuay5sZW5ndGgpXG4gIHNlbGYuX2NhY2hlID0gc2VsZi5fY2FjaGUuc2xpY2UoY2h1bmsubGVuZ3RoKVxuICByZXR1cm4geG9yKGNodW5rLCBwYWQpXG59XG4iLCJ2YXIgYWVzID0gcmVxdWlyZSgnLi9hZXMnKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxuXG5mdW5jdGlvbiBTdHJlYW1DaXBoZXIgKG1vZGUsIGtleSwgaXYsIGRlY3J5cHQpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcblxuICB0aGlzLl9jaXBoZXIgPSBuZXcgYWVzLkFFUyhrZXkpXG4gIHRoaXMuX3ByZXYgPSBCdWZmZXIuZnJvbShpdilcbiAgdGhpcy5fY2FjaGUgPSBCdWZmZXIuYWxsb2NVbnNhZmUoMClcbiAgdGhpcy5fc2VjQ2FjaGUgPSBCdWZmZXIuYWxsb2NVbnNhZmUoMClcbiAgdGhpcy5fZGVjcnlwdCA9IGRlY3J5cHRcbiAgdGhpcy5fbW9kZSA9IG1vZGVcbn1cblxuaW5oZXJpdHMoU3RyZWFtQ2lwaGVyLCBUcmFuc2Zvcm0pXG5cblN0cmVhbUNpcGhlci5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChjaHVuaykge1xuICByZXR1cm4gdGhpcy5fbW9kZS5lbmNyeXB0KHRoaXMsIGNodW5rLCB0aGlzLl9kZWNyeXB0KVxufVxuXG5TdHJlYW1DaXBoZXIucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fY2lwaGVyLnNjcnViKClcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW1DaXBoZXJcbiIsInZhciBERVMgPSByZXF1aXJlKCdicm93c2VyaWZ5LWRlcycpXG52YXIgYWVzID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1hZXMvYnJvd3NlcicpXG52YXIgYWVzTW9kZXMgPSByZXF1aXJlKCdicm93c2VyaWZ5LWFlcy9tb2RlcycpXG52YXIgZGVzTW9kZXMgPSByZXF1aXJlKCdicm93c2VyaWZ5LWRlcy9tb2RlcycpXG52YXIgZWJ0ayA9IHJlcXVpcmUoJ2V2cF9ieXRlc3Rva2V5JylcblxuZnVuY3Rpb24gY3JlYXRlQ2lwaGVyIChzdWl0ZSwgcGFzc3dvcmQpIHtcbiAgc3VpdGUgPSBzdWl0ZS50b0xvd2VyQ2FzZSgpXG5cbiAgdmFyIGtleUxlbiwgaXZMZW5cbiAgaWYgKGFlc01vZGVzW3N1aXRlXSkge1xuICAgIGtleUxlbiA9IGFlc01vZGVzW3N1aXRlXS5rZXlcbiAgICBpdkxlbiA9IGFlc01vZGVzW3N1aXRlXS5pdlxuICB9IGVsc2UgaWYgKGRlc01vZGVzW3N1aXRlXSkge1xuICAgIGtleUxlbiA9IGRlc01vZGVzW3N1aXRlXS5rZXkgKiA4XG4gICAgaXZMZW4gPSBkZXNNb2Rlc1tzdWl0ZV0uaXZcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxuICB9XG5cbiAgdmFyIGtleXMgPSBlYnRrKHBhc3N3b3JkLCBmYWxzZSwga2V5TGVuLCBpdkxlbilcbiAgcmV0dXJuIGNyZWF0ZUNpcGhlcml2KHN1aXRlLCBrZXlzLmtleSwga2V5cy5pdilcbn1cblxuZnVuY3Rpb24gY3JlYXRlRGVjaXBoZXIgKHN1aXRlLCBwYXNzd29yZCkge1xuICBzdWl0ZSA9IHN1aXRlLnRvTG93ZXJDYXNlKClcblxuICB2YXIga2V5TGVuLCBpdkxlblxuICBpZiAoYWVzTW9kZXNbc3VpdGVdKSB7XG4gICAga2V5TGVuID0gYWVzTW9kZXNbc3VpdGVdLmtleVxuICAgIGl2TGVuID0gYWVzTW9kZXNbc3VpdGVdLml2XG4gIH0gZWxzZSBpZiAoZGVzTW9kZXNbc3VpdGVdKSB7XG4gICAga2V5TGVuID0gZGVzTW9kZXNbc3VpdGVdLmtleSAqIDhcbiAgICBpdkxlbiA9IGRlc01vZGVzW3N1aXRlXS5pdlxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG4gIH1cblxuICB2YXIga2V5cyA9IGVidGsocGFzc3dvcmQsIGZhbHNlLCBrZXlMZW4sIGl2TGVuKVxuICByZXR1cm4gY3JlYXRlRGVjaXBoZXJpdihzdWl0ZSwga2V5cy5rZXksIGtleXMuaXYpXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNpcGhlcml2IChzdWl0ZSwga2V5LCBpdikge1xuICBzdWl0ZSA9IHN1aXRlLnRvTG93ZXJDYXNlKClcbiAgaWYgKGFlc01vZGVzW3N1aXRlXSkgcmV0dXJuIGFlcy5jcmVhdGVDaXBoZXJpdihzdWl0ZSwga2V5LCBpdilcbiAgaWYgKGRlc01vZGVzW3N1aXRlXSkgcmV0dXJuIG5ldyBERVMoeyBrZXk6IGtleSwgaXY6IGl2LCBtb2RlOiBzdWl0ZSB9KVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ2ludmFsaWQgc3VpdGUgdHlwZScpXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZURlY2lwaGVyaXYgKHN1aXRlLCBrZXksIGl2KSB7XG4gIHN1aXRlID0gc3VpdGUudG9Mb3dlckNhc2UoKVxuICBpZiAoYWVzTW9kZXNbc3VpdGVdKSByZXR1cm4gYWVzLmNyZWF0ZURlY2lwaGVyaXYoc3VpdGUsIGtleSwgaXYpXG4gIGlmIChkZXNNb2Rlc1tzdWl0ZV0pIHJldHVybiBuZXcgREVTKHsga2V5OiBrZXksIGl2OiBpdiwgbW9kZTogc3VpdGUsIGRlY3J5cHQ6IHRydWUgfSlcblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIHN1aXRlIHR5cGUnKVxufVxuXG5mdW5jdGlvbiBnZXRDaXBoZXJzICgpIHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKGRlc01vZGVzKS5jb25jYXQoYWVzLmdldENpcGhlcnMoKSlcbn1cblxuZXhwb3J0cy5jcmVhdGVDaXBoZXIgPSBleHBvcnRzLkNpcGhlciA9IGNyZWF0ZUNpcGhlclxuZXhwb3J0cy5jcmVhdGVDaXBoZXJpdiA9IGV4cG9ydHMuQ2lwaGVyaXYgPSBjcmVhdGVDaXBoZXJpdlxuZXhwb3J0cy5jcmVhdGVEZWNpcGhlciA9IGV4cG9ydHMuRGVjaXBoZXIgPSBjcmVhdGVEZWNpcGhlclxuZXhwb3J0cy5jcmVhdGVEZWNpcGhlcml2ID0gZXhwb3J0cy5EZWNpcGhlcml2ID0gY3JlYXRlRGVjaXBoZXJpdlxuZXhwb3J0cy5saXN0Q2lwaGVycyA9IGV4cG9ydHMuZ2V0Q2lwaGVycyA9IGdldENpcGhlcnNcbiIsInZhciBDaXBoZXJCYXNlID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxudmFyIGRlcyA9IHJlcXVpcmUoJ2Rlcy5qcycpXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcblxudmFyIG1vZGVzID0ge1xuICAnZGVzLWVkZTMtY2JjJzogZGVzLkNCQy5pbnN0YW50aWF0ZShkZXMuRURFKSxcbiAgJ2Rlcy1lZGUzJzogZGVzLkVERSxcbiAgJ2Rlcy1lZGUtY2JjJzogZGVzLkNCQy5pbnN0YW50aWF0ZShkZXMuRURFKSxcbiAgJ2Rlcy1lZGUnOiBkZXMuRURFLFxuICAnZGVzLWNiYyc6IGRlcy5DQkMuaW5zdGFudGlhdGUoZGVzLkRFUyksXG4gICdkZXMtZWNiJzogZGVzLkRFU1xufVxubW9kZXMuZGVzID0gbW9kZXNbJ2Rlcy1jYmMnXVxubW9kZXMuZGVzMyA9IG1vZGVzWydkZXMtZWRlMy1jYmMnXVxubW9kdWxlLmV4cG9ydHMgPSBERVNcbmluaGVyaXRzKERFUywgQ2lwaGVyQmFzZSlcbmZ1bmN0aW9uIERFUyAob3B0cykge1xuICBDaXBoZXJCYXNlLmNhbGwodGhpcylcbiAgdmFyIG1vZGVOYW1lID0gb3B0cy5tb2RlLnRvTG93ZXJDYXNlKClcbiAgdmFyIG1vZGUgPSBtb2Rlc1ttb2RlTmFtZV1cbiAgdmFyIHR5cGVcbiAgaWYgKG9wdHMuZGVjcnlwdCkge1xuICAgIHR5cGUgPSAnZGVjcnlwdCdcbiAgfSBlbHNlIHtcbiAgICB0eXBlID0gJ2VuY3J5cHQnXG4gIH1cbiAgdmFyIGtleSA9IG9wdHMua2V5XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGtleSkpIHtcbiAgICBrZXkgPSBCdWZmZXIuZnJvbShrZXkpXG4gIH1cbiAgaWYgKG1vZGVOYW1lID09PSAnZGVzLWVkZScgfHwgbW9kZU5hbWUgPT09ICdkZXMtZWRlLWNiYycpIHtcbiAgICBrZXkgPSBCdWZmZXIuY29uY2F0KFtrZXksIGtleS5zbGljZSgwLCA4KV0pXG4gIH1cbiAgdmFyIGl2ID0gb3B0cy5pdlxuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihpdikpIHtcbiAgICBpdiA9IEJ1ZmZlci5mcm9tKGl2KVxuICB9XG4gIHRoaXMuX2RlcyA9IG1vZGUuY3JlYXRlKHtcbiAgICBrZXk6IGtleSxcbiAgICBpdjogaXYsXG4gICAgdHlwZTogdHlwZVxuICB9KVxufVxuREVTLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgcmV0dXJuIEJ1ZmZlci5mcm9tKHRoaXMuX2Rlcy51cGRhdGUoZGF0YSkpXG59XG5ERVMucHJvdG90eXBlLl9maW5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIEJ1ZmZlci5mcm9tKHRoaXMuX2Rlcy5maW5hbCgpKVxufVxuIiwiZXhwb3J0c1snZGVzLWVjYiddID0ge1xuICBrZXk6IDgsXG4gIGl2OiAwXG59XG5leHBvcnRzWydkZXMtY2JjJ10gPSBleHBvcnRzLmRlcyA9IHtcbiAga2V5OiA4LFxuICBpdjogOFxufVxuZXhwb3J0c1snZGVzLWVkZTMtY2JjJ10gPSBleHBvcnRzLmRlczMgPSB7XG4gIGtleTogMjQsXG4gIGl2OiA4XG59XG5leHBvcnRzWydkZXMtZWRlMyddID0ge1xuICBrZXk6IDI0LFxuICBpdjogMFxufVxuZXhwb3J0c1snZGVzLWVkZS1jYmMnXSA9IHtcbiAga2V5OiAxNixcbiAgaXY6IDhcbn1cbmV4cG9ydHNbJ2Rlcy1lZGUnXSA9IHtcbiAga2V5OiAxNixcbiAgaXY6IDBcbn1cbiIsIi8qIGVzbGludC1kaXNhYmxlIG5vZGUvbm8tZGVwcmVjYXRlZC1hcGkgKi9cbnZhciBidWZmZXIgPSByZXF1aXJlKCdidWZmZXInKVxudmFyIEJ1ZmZlciA9IGJ1ZmZlci5CdWZmZXJcblxuLy8gYWx0ZXJuYXRpdmUgdG8gdXNpbmcgT2JqZWN0LmtleXMgZm9yIG9sZCBicm93c2Vyc1xuZnVuY3Rpb24gY29weVByb3BzIChzcmMsIGRzdCkge1xuICBmb3IgKHZhciBrZXkgaW4gc3JjKSB7XG4gICAgZHN0W2tleV0gPSBzcmNba2V5XVxuICB9XG59XG5pZiAoQnVmZmVyLmZyb20gJiYgQnVmZmVyLmFsbG9jICYmIEJ1ZmZlci5hbGxvY1Vuc2FmZSAmJiBCdWZmZXIuYWxsb2NVbnNhZmVTbG93KSB7XG4gIG1vZHVsZS5leHBvcnRzID0gYnVmZmVyXG59IGVsc2Uge1xuICAvLyBDb3B5IHByb3BlcnRpZXMgZnJvbSByZXF1aXJlKCdidWZmZXInKVxuICBjb3B5UHJvcHMoYnVmZmVyLCBleHBvcnRzKVxuICBleHBvcnRzLkJ1ZmZlciA9IFNhZmVCdWZmZXJcbn1cblxuZnVuY3Rpb24gU2FmZUJ1ZmZlciAoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIEJ1ZmZlcihhcmcsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuLy8gQ29weSBzdGF0aWMgbWV0aG9kcyBmcm9tIEJ1ZmZlclxuY29weVByb3BzKEJ1ZmZlciwgU2FmZUJ1ZmZlcilcblxuU2FmZUJ1ZmZlci5mcm9tID0gZnVuY3Rpb24gKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICh0eXBlb2YgYXJnID09PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3Qgbm90IGJlIGEgbnVtYmVyJylcbiAgfVxuICByZXR1cm4gQnVmZmVyKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG5TYWZlQnVmZmVyLmFsbG9jID0gZnVuY3Rpb24gKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgbnVtYmVyJylcbiAgfVxuICB2YXIgYnVmID0gQnVmZmVyKHNpemUpXG4gIGlmIChmaWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJykge1xuICAgICAgYnVmLmZpbGwoZmlsbCwgZW5jb2RpbmcpXG4gICAgfSBlbHNlIHtcbiAgICAgIGJ1Zi5maWxsKGZpbGwpXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGJ1Zi5maWxsKDApXG4gIH1cbiAgcmV0dXJuIGJ1ZlxufVxuXG5TYWZlQnVmZmVyLmFsbG9jVW5zYWZlID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgaWYgKHR5cGVvZiBzaXplICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBudW1iZXInKVxuICB9XG4gIHJldHVybiBCdWZmZXIoc2l6ZSlcbn1cblxuU2FmZUJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3cgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpXG4gIH1cbiAgcmV0dXJuIGJ1ZmZlci5TbG93QnVmZmVyKHNpemUpXG59XG4iLCJ2YXIgYm4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIHJhbmRvbUJ5dGVzID0gcmVxdWlyZSgncmFuZG9tYnl0ZXMnKTtcbm1vZHVsZS5leHBvcnRzID0gY3J0O1xuZnVuY3Rpb24gYmxpbmQocHJpdikge1xuICB2YXIgciA9IGdldHIocHJpdik7XG4gIHZhciBibGluZGVyID0gci50b1JlZChibi5tb250KHByaXYubW9kdWx1cykpXG4gIC5yZWRQb3cobmV3IGJuKHByaXYucHVibGljRXhwb25lbnQpKS5mcm9tUmVkKCk7XG4gIHJldHVybiB7XG4gICAgYmxpbmRlcjogYmxpbmRlcixcbiAgICB1bmJsaW5kZXI6ci5pbnZtKHByaXYubW9kdWx1cylcbiAgfTtcbn1cbmZ1bmN0aW9uIGNydChtc2csIHByaXYpIHtcbiAgdmFyIGJsaW5kcyA9IGJsaW5kKHByaXYpO1xuICB2YXIgbGVuID0gcHJpdi5tb2R1bHVzLmJ5dGVMZW5ndGgoKTtcbiAgdmFyIG1vZCA9IGJuLm1vbnQocHJpdi5tb2R1bHVzKTtcbiAgdmFyIGJsaW5kZWQgPSBuZXcgYm4obXNnKS5tdWwoYmxpbmRzLmJsaW5kZXIpLnVtb2QocHJpdi5tb2R1bHVzKTtcbiAgdmFyIGMxID0gYmxpbmRlZC50b1JlZChibi5tb250KHByaXYucHJpbWUxKSk7XG4gIHZhciBjMiA9IGJsaW5kZWQudG9SZWQoYm4ubW9udChwcml2LnByaW1lMikpO1xuICB2YXIgcWludiA9IHByaXYuY29lZmZpY2llbnQ7XG4gIHZhciBwID0gcHJpdi5wcmltZTE7XG4gIHZhciBxID0gcHJpdi5wcmltZTI7XG4gIHZhciBtMSA9IGMxLnJlZFBvdyhwcml2LmV4cG9uZW50MSk7XG4gIHZhciBtMiA9IGMyLnJlZFBvdyhwcml2LmV4cG9uZW50Mik7XG4gIG0xID0gbTEuZnJvbVJlZCgpO1xuICBtMiA9IG0yLmZyb21SZWQoKTtcbiAgdmFyIGggPSBtMS5pc3ViKG0yKS5pbXVsKHFpbnYpLnVtb2QocCk7XG4gIGguaW11bChxKTtcbiAgbTIuaWFkZChoKTtcbiAgcmV0dXJuIG5ldyBCdWZmZXIobTIuaW11bChibGluZHMudW5ibGluZGVyKS51bW9kKHByaXYubW9kdWx1cykudG9BcnJheShmYWxzZSwgbGVuKSk7XG59XG5jcnQuZ2V0ciA9IGdldHI7XG5mdW5jdGlvbiBnZXRyKHByaXYpIHtcbiAgdmFyIGxlbiA9IHByaXYubW9kdWx1cy5ieXRlTGVuZ3RoKCk7XG4gIHZhciByID0gbmV3IGJuKHJhbmRvbUJ5dGVzKGxlbikpO1xuICB3aGlsZSAoci5jbXAocHJpdi5tb2R1bHVzKSA+PSAgMCB8fCAhci51bW9kKHByaXYucHJpbWUxKSB8fCAhci51bW9kKHByaXYucHJpbWUyKSkge1xuICAgIHIgPSBuZXcgYm4ocmFuZG9tQnl0ZXMobGVuKSk7XG4gIH1cbiAgcmV0dXJuIHI7XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vYnJvd3Nlci9hbGdvcml0aG1zLmpzb24nKVxuIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcInNoYTIyNFdpdGhSU0FFbmNyeXB0aW9uXCI6IHtcbiAgICBcInNpZ25cIjogXCJyc2FcIixcbiAgICBcImhhc2hcIjogXCJzaGEyMjRcIixcbiAgICBcImlkXCI6IFwiMzAyZDMwMGQwNjA5NjA4NjQ4MDE2NTAzMDQwMjA0MDUwMDA0MWNcIlxuICB9LFxuICBcIlJTQS1TSEEyMjRcIjoge1xuICAgIFwic2lnblwiOiBcImVjZHNhL3JzYVwiLFxuICAgIFwiaGFzaFwiOiBcInNoYTIyNFwiLFxuICAgIFwiaWRcIjogXCIzMDJkMzAwZDA2MDk2MDg2NDgwMTY1MDMwNDAyMDQwNTAwMDQxY1wiXG4gIH0sXG4gIFwic2hhMjU2V2l0aFJTQUVuY3J5cHRpb25cIjoge1xuICAgIFwic2lnblwiOiBcInJzYVwiLFxuICAgIFwiaGFzaFwiOiBcInNoYTI1NlwiLFxuICAgIFwiaWRcIjogXCIzMDMxMzAwZDA2MDk2MDg2NDgwMTY1MDMwNDAyMDEwNTAwMDQyMFwiXG4gIH0sXG4gIFwiUlNBLVNIQTI1NlwiOiB7XG4gICAgXCJzaWduXCI6IFwiZWNkc2EvcnNhXCIsXG4gICAgXCJoYXNoXCI6IFwic2hhMjU2XCIsXG4gICAgXCJpZFwiOiBcIjMwMzEzMDBkMDYwOTYwODY0ODAxNjUwMzA0MDIwMTA1MDAwNDIwXCJcbiAgfSxcbiAgXCJzaGEzODRXaXRoUlNBRW5jcnlwdGlvblwiOiB7XG4gICAgXCJzaWduXCI6IFwicnNhXCIsXG4gICAgXCJoYXNoXCI6IFwic2hhMzg0XCIsXG4gICAgXCJpZFwiOiBcIjMwNDEzMDBkMDYwOTYwODY0ODAxNjUwMzA0MDIwMjA1MDAwNDMwXCJcbiAgfSxcbiAgXCJSU0EtU0hBMzg0XCI6IHtcbiAgICBcInNpZ25cIjogXCJlY2RzYS9yc2FcIixcbiAgICBcImhhc2hcIjogXCJzaGEzODRcIixcbiAgICBcImlkXCI6IFwiMzA0MTMwMGQwNjA5NjA4NjQ4MDE2NTAzMDQwMjAyMDUwMDA0MzBcIlxuICB9LFxuICBcInNoYTUxMldpdGhSU0FFbmNyeXB0aW9uXCI6IHtcbiAgICBcInNpZ25cIjogXCJyc2FcIixcbiAgICBcImhhc2hcIjogXCJzaGE1MTJcIixcbiAgICBcImlkXCI6IFwiMzA1MTMwMGQwNjA5NjA4NjQ4MDE2NTAzMDQwMjAzMDUwMDA0NDBcIlxuICB9LFxuICBcIlJTQS1TSEE1MTJcIjoge1xuICAgIFwic2lnblwiOiBcImVjZHNhL3JzYVwiLFxuICAgIFwiaGFzaFwiOiBcInNoYTUxMlwiLFxuICAgIFwiaWRcIjogXCIzMDUxMzAwZDA2MDk2MDg2NDgwMTY1MDMwNDAyMDMwNTAwMDQ0MFwiXG4gIH0sXG4gIFwiUlNBLVNIQTFcIjoge1xuICAgIFwic2lnblwiOiBcInJzYVwiLFxuICAgIFwiaGFzaFwiOiBcInNoYTFcIixcbiAgICBcImlkXCI6IFwiMzAyMTMwMDkwNjA1MmIwZTAzMDIxYTA1MDAwNDE0XCJcbiAgfSxcbiAgXCJlY2RzYS13aXRoLVNIQTFcIjoge1xuICAgIFwic2lnblwiOiBcImVjZHNhXCIsXG4gICAgXCJoYXNoXCI6IFwic2hhMVwiLFxuICAgIFwiaWRcIjogXCJcIlxuICB9LFxuICBcInNoYTI1NlwiOiB7XG4gICAgXCJzaWduXCI6IFwiZWNkc2FcIixcbiAgICBcImhhc2hcIjogXCJzaGEyNTZcIixcbiAgICBcImlkXCI6IFwiXCJcbiAgfSxcbiAgXCJzaGEyMjRcIjoge1xuICAgIFwic2lnblwiOiBcImVjZHNhXCIsXG4gICAgXCJoYXNoXCI6IFwic2hhMjI0XCIsXG4gICAgXCJpZFwiOiBcIlwiXG4gIH0sXG4gIFwic2hhMzg0XCI6IHtcbiAgICBcInNpZ25cIjogXCJlY2RzYVwiLFxuICAgIFwiaGFzaFwiOiBcInNoYTM4NFwiLFxuICAgIFwiaWRcIjogXCJcIlxuICB9LFxuICBcInNoYTUxMlwiOiB7XG4gICAgXCJzaWduXCI6IFwiZWNkc2FcIixcbiAgICBcImhhc2hcIjogXCJzaGE1MTJcIixcbiAgICBcImlkXCI6IFwiXCJcbiAgfSxcbiAgXCJEU0EtU0hBXCI6IHtcbiAgICBcInNpZ25cIjogXCJkc2FcIixcbiAgICBcImhhc2hcIjogXCJzaGExXCIsXG4gICAgXCJpZFwiOiBcIlwiXG4gIH0sXG4gIFwiRFNBLVNIQTFcIjoge1xuICAgIFwic2lnblwiOiBcImRzYVwiLFxuICAgIFwiaGFzaFwiOiBcInNoYTFcIixcbiAgICBcImlkXCI6IFwiXCJcbiAgfSxcbiAgXCJEU0FcIjoge1xuICAgIFwic2lnblwiOiBcImRzYVwiLFxuICAgIFwiaGFzaFwiOiBcInNoYTFcIixcbiAgICBcImlkXCI6IFwiXCJcbiAgfSxcbiAgXCJEU0EtV0lUSC1TSEEyMjRcIjoge1xuICAgIFwic2lnblwiOiBcImRzYVwiLFxuICAgIFwiaGFzaFwiOiBcInNoYTIyNFwiLFxuICAgIFwiaWRcIjogXCJcIlxuICB9LFxuICBcIkRTQS1TSEEyMjRcIjoge1xuICAgIFwic2lnblwiOiBcImRzYVwiLFxuICAgIFwiaGFzaFwiOiBcInNoYTIyNFwiLFxuICAgIFwiaWRcIjogXCJcIlxuICB9LFxuICBcIkRTQS1XSVRILVNIQTI1NlwiOiB7XG4gICAgXCJzaWduXCI6IFwiZHNhXCIsXG4gICAgXCJoYXNoXCI6IFwic2hhMjU2XCIsXG4gICAgXCJpZFwiOiBcIlwiXG4gIH0sXG4gIFwiRFNBLVNIQTI1NlwiOiB7XG4gICAgXCJzaWduXCI6IFwiZHNhXCIsXG4gICAgXCJoYXNoXCI6IFwic2hhMjU2XCIsXG4gICAgXCJpZFwiOiBcIlwiXG4gIH0sXG4gIFwiRFNBLVdJVEgtU0hBMzg0XCI6IHtcbiAgICBcInNpZ25cIjogXCJkc2FcIixcbiAgICBcImhhc2hcIjogXCJzaGEzODRcIixcbiAgICBcImlkXCI6IFwiXCJcbiAgfSxcbiAgXCJEU0EtU0hBMzg0XCI6IHtcbiAgICBcInNpZ25cIjogXCJkc2FcIixcbiAgICBcImhhc2hcIjogXCJzaGEzODRcIixcbiAgICBcImlkXCI6IFwiXCJcbiAgfSxcbiAgXCJEU0EtV0lUSC1TSEE1MTJcIjoge1xuICAgIFwic2lnblwiOiBcImRzYVwiLFxuICAgIFwiaGFzaFwiOiBcInNoYTUxMlwiLFxuICAgIFwiaWRcIjogXCJcIlxuICB9LFxuICBcIkRTQS1TSEE1MTJcIjoge1xuICAgIFwic2lnblwiOiBcImRzYVwiLFxuICAgIFwiaGFzaFwiOiBcInNoYTUxMlwiLFxuICAgIFwiaWRcIjogXCJcIlxuICB9LFxuICBcIkRTQS1SSVBFTUQxNjBcIjoge1xuICAgIFwic2lnblwiOiBcImRzYVwiLFxuICAgIFwiaGFzaFwiOiBcInJtZDE2MFwiLFxuICAgIFwiaWRcIjogXCJcIlxuICB9LFxuICBcInJpcGVtZDE2MFdpdGhSU0FcIjoge1xuICAgIFwic2lnblwiOiBcInJzYVwiLFxuICAgIFwiaGFzaFwiOiBcInJtZDE2MFwiLFxuICAgIFwiaWRcIjogXCIzMDIxMzAwOTA2MDUyYjI0MDMwMjAxMDUwMDA0MTRcIlxuICB9LFxuICBcIlJTQS1SSVBFTUQxNjBcIjoge1xuICAgIFwic2lnblwiOiBcInJzYVwiLFxuICAgIFwiaGFzaFwiOiBcInJtZDE2MFwiLFxuICAgIFwiaWRcIjogXCIzMDIxMzAwOTA2MDUyYjI0MDMwMjAxMDUwMDA0MTRcIlxuICB9LFxuICBcIm1kNVdpdGhSU0FFbmNyeXB0aW9uXCI6IHtcbiAgICBcInNpZ25cIjogXCJyc2FcIixcbiAgICBcImhhc2hcIjogXCJtZDVcIixcbiAgICBcImlkXCI6IFwiMzAyMDMwMGMwNjA4MmE4NjQ4ODZmNzBkMDIwNTA1MDAwNDEwXCJcbiAgfSxcbiAgXCJSU0EtTUQ1XCI6IHtcbiAgICBcInNpZ25cIjogXCJyc2FcIixcbiAgICBcImhhc2hcIjogXCJtZDVcIixcbiAgICBcImlkXCI6IFwiMzAyMDMwMGMwNjA4MmE4NjQ4ODZmNzBkMDIwNTA1MDAwNDEwXCJcbiAgfVxufVxuIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcIjEuMy4xMzIuMC4xMFwiOiBcInNlY3AyNTZrMVwiLFxuICBcIjEuMy4xMzIuMC4zM1wiOiBcInAyMjRcIixcbiAgXCIxLjIuODQwLjEwMDQ1LjMuMS4xXCI6IFwicDE5MlwiLFxuICBcIjEuMi44NDAuMTAwNDUuMy4xLjdcIjogXCJwMjU2XCIsXG4gIFwiMS4zLjEzMi4wLjM0XCI6IFwicDM4NFwiLFxuICBcIjEuMy4xMzIuMC4zNVwiOiBcInA1MjFcIlxufVxuIiwidmFyIGNyZWF0ZUhhc2ggPSByZXF1aXJlKCdjcmVhdGUtaGFzaCcpXG52YXIgc3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJylcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBzaWduID0gcmVxdWlyZSgnLi9zaWduJylcbnZhciB2ZXJpZnkgPSByZXF1aXJlKCcuL3ZlcmlmeScpXG5cbnZhciBhbGdvcml0aG1zID0gcmVxdWlyZSgnLi9hbGdvcml0aG1zLmpzb24nKVxuT2JqZWN0LmtleXMoYWxnb3JpdGhtcykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gIGFsZ29yaXRobXNba2V5XS5pZCA9IG5ldyBCdWZmZXIoYWxnb3JpdGhtc1trZXldLmlkLCAnaGV4JylcbiAgYWxnb3JpdGhtc1trZXkudG9Mb3dlckNhc2UoKV0gPSBhbGdvcml0aG1zW2tleV1cbn0pXG5cbmZ1bmN0aW9uIFNpZ24gKGFsZ29yaXRobSkge1xuICBzdHJlYW0uV3JpdGFibGUuY2FsbCh0aGlzKVxuXG4gIHZhciBkYXRhID0gYWxnb3JpdGhtc1thbGdvcml0aG1dXG4gIGlmICghZGF0YSkgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIG1lc3NhZ2UgZGlnZXN0JylcblxuICB0aGlzLl9oYXNoVHlwZSA9IGRhdGEuaGFzaFxuICB0aGlzLl9oYXNoID0gY3JlYXRlSGFzaChkYXRhLmhhc2gpXG4gIHRoaXMuX3RhZyA9IGRhdGEuaWRcbiAgdGhpcy5fc2lnblR5cGUgPSBkYXRhLnNpZ25cbn1cbmluaGVyaXRzKFNpZ24sIHN0cmVhbS5Xcml0YWJsZSlcblxuU2lnbi5wcm90b3R5cGUuX3dyaXRlID0gZnVuY3Rpb24gX3dyaXRlIChkYXRhLCBfLCBkb25lKSB7XG4gIHRoaXMuX2hhc2gudXBkYXRlKGRhdGEpXG4gIGRvbmUoKVxufVxuXG5TaWduLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUgKGRhdGEsIGVuYykge1xuICBpZiAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSBkYXRhID0gbmV3IEJ1ZmZlcihkYXRhLCBlbmMpXG5cbiAgdGhpcy5faGFzaC51cGRhdGUoZGF0YSlcbiAgcmV0dXJuIHRoaXNcbn1cblxuU2lnbi5wcm90b3R5cGUuc2lnbiA9IGZ1bmN0aW9uIHNpZ25NZXRob2QgKGtleSwgZW5jKSB7XG4gIHRoaXMuZW5kKClcbiAgdmFyIGhhc2ggPSB0aGlzLl9oYXNoLmRpZ2VzdCgpXG4gIHZhciBzaWcgPSBzaWduKGhhc2gsIGtleSwgdGhpcy5faGFzaFR5cGUsIHRoaXMuX3NpZ25UeXBlLCB0aGlzLl90YWcpXG5cbiAgcmV0dXJuIGVuYyA/IHNpZy50b1N0cmluZyhlbmMpIDogc2lnXG59XG5cbmZ1bmN0aW9uIFZlcmlmeSAoYWxnb3JpdGhtKSB7XG4gIHN0cmVhbS5Xcml0YWJsZS5jYWxsKHRoaXMpXG5cbiAgdmFyIGRhdGEgPSBhbGdvcml0aG1zW2FsZ29yaXRobV1cbiAgaWYgKCFkYXRhKSB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gbWVzc2FnZSBkaWdlc3QnKVxuXG4gIHRoaXMuX2hhc2ggPSBjcmVhdGVIYXNoKGRhdGEuaGFzaClcbiAgdGhpcy5fdGFnID0gZGF0YS5pZFxuICB0aGlzLl9zaWduVHlwZSA9IGRhdGEuc2lnblxufVxuaW5oZXJpdHMoVmVyaWZ5LCBzdHJlYW0uV3JpdGFibGUpXG5cblZlcmlmeS5wcm90b3R5cGUuX3dyaXRlID0gZnVuY3Rpb24gX3dyaXRlIChkYXRhLCBfLCBkb25lKSB7XG4gIHRoaXMuX2hhc2gudXBkYXRlKGRhdGEpXG4gIGRvbmUoKVxufVxuXG5WZXJpZnkucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIHVwZGF0ZSAoZGF0YSwgZW5jKSB7XG4gIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIGRhdGEgPSBuZXcgQnVmZmVyKGRhdGEsIGVuYylcblxuICB0aGlzLl9oYXNoLnVwZGF0ZShkYXRhKVxuICByZXR1cm4gdGhpc1xufVxuXG5WZXJpZnkucHJvdG90eXBlLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeU1ldGhvZCAoa2V5LCBzaWcsIGVuYykge1xuICBpZiAodHlwZW9mIHNpZyA9PT0gJ3N0cmluZycpIHNpZyA9IG5ldyBCdWZmZXIoc2lnLCBlbmMpXG5cbiAgdGhpcy5lbmQoKVxuICB2YXIgaGFzaCA9IHRoaXMuX2hhc2guZGlnZXN0KClcbiAgcmV0dXJuIHZlcmlmeShzaWcsIGhhc2gsIGtleSwgdGhpcy5fc2lnblR5cGUsIHRoaXMuX3RhZylcbn1cblxuZnVuY3Rpb24gY3JlYXRlU2lnbiAoYWxnb3JpdGhtKSB7XG4gIHJldHVybiBuZXcgU2lnbihhbGdvcml0aG0pXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVZlcmlmeSAoYWxnb3JpdGhtKSB7XG4gIHJldHVybiBuZXcgVmVyaWZ5KGFsZ29yaXRobSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIFNpZ246IGNyZWF0ZVNpZ24sXG4gIFZlcmlmeTogY3JlYXRlVmVyaWZ5LFxuICBjcmVhdGVTaWduOiBjcmVhdGVTaWduLFxuICBjcmVhdGVWZXJpZnk6IGNyZWF0ZVZlcmlmeVxufVxuIiwiLy8gbXVjaCBvZiB0aGlzIGJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9pbmR1dG55L3NlbGYtc2lnbmVkL2Jsb2IvZ2gtcGFnZXMvbGliL3JzYS5qc1xudmFyIGNyZWF0ZUhtYWMgPSByZXF1aXJlKCdjcmVhdGUtaG1hYycpXG52YXIgY3J0ID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1yc2EnKVxudmFyIEVDID0gcmVxdWlyZSgnZWxsaXB0aWMnKS5lY1xudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKVxudmFyIHBhcnNlS2V5cyA9IHJlcXVpcmUoJ3BhcnNlLWFzbjEnKVxudmFyIGN1cnZlcyA9IHJlcXVpcmUoJy4vY3VydmVzLmpzb24nKVxuXG5mdW5jdGlvbiBzaWduIChoYXNoLCBrZXksIGhhc2hUeXBlLCBzaWduVHlwZSwgdGFnKSB7XG4gIHZhciBwcml2ID0gcGFyc2VLZXlzKGtleSlcbiAgaWYgKHByaXYuY3VydmUpIHtcbiAgICAvLyByc2Ega2V5cyBjYW4gYmUgaW50ZXJwcmV0ZWQgYXMgZWNkc2Egb25lcyBpbiBvcGVuc3NsXG4gICAgaWYgKHNpZ25UeXBlICE9PSAnZWNkc2EnICYmIHNpZ25UeXBlICE9PSAnZWNkc2EvcnNhJykgdGhyb3cgbmV3IEVycm9yKCd3cm9uZyBwcml2YXRlIGtleSB0eXBlJylcbiAgICByZXR1cm4gZWNTaWduKGhhc2gsIHByaXYpXG4gIH0gZWxzZSBpZiAocHJpdi50eXBlID09PSAnZHNhJykge1xuICAgIGlmIChzaWduVHlwZSAhPT0gJ2RzYScpIHRocm93IG5ldyBFcnJvcignd3JvbmcgcHJpdmF0ZSBrZXkgdHlwZScpXG4gICAgcmV0dXJuIGRzYVNpZ24oaGFzaCwgcHJpdiwgaGFzaFR5cGUpXG4gIH0gZWxzZSB7XG4gICAgaWYgKHNpZ25UeXBlICE9PSAncnNhJyAmJiBzaWduVHlwZSAhPT0gJ2VjZHNhL3JzYScpIHRocm93IG5ldyBFcnJvcignd3JvbmcgcHJpdmF0ZSBrZXkgdHlwZScpXG4gIH1cbiAgaGFzaCA9IEJ1ZmZlci5jb25jYXQoW3RhZywgaGFzaF0pXG4gIHZhciBsZW4gPSBwcml2Lm1vZHVsdXMuYnl0ZUxlbmd0aCgpXG4gIHZhciBwYWQgPSBbIDAsIDEgXVxuICB3aGlsZSAoaGFzaC5sZW5ndGggKyBwYWQubGVuZ3RoICsgMSA8IGxlbikgcGFkLnB1c2goMHhmZilcbiAgcGFkLnB1c2goMHgwMClcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgaGFzaC5sZW5ndGgpIHBhZC5wdXNoKGhhc2hbaV0pXG5cbiAgdmFyIG91dCA9IGNydChwYWQsIHByaXYpXG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gZWNTaWduIChoYXNoLCBwcml2KSB7XG4gIHZhciBjdXJ2ZUlkID0gY3VydmVzW3ByaXYuY3VydmUuam9pbignLicpXVxuICBpZiAoIWN1cnZlSWQpIHRocm93IG5ldyBFcnJvcigndW5rbm93biBjdXJ2ZSAnICsgcHJpdi5jdXJ2ZS5qb2luKCcuJykpXG5cbiAgdmFyIGN1cnZlID0gbmV3IEVDKGN1cnZlSWQpXG4gIHZhciBrZXkgPSBjdXJ2ZS5rZXlGcm9tUHJpdmF0ZShwcml2LnByaXZhdGVLZXkpXG4gIHZhciBvdXQgPSBrZXkuc2lnbihoYXNoKVxuXG4gIHJldHVybiBuZXcgQnVmZmVyKG91dC50b0RFUigpKVxufVxuXG5mdW5jdGlvbiBkc2FTaWduIChoYXNoLCBwcml2LCBhbGdvKSB7XG4gIHZhciB4ID0gcHJpdi5wYXJhbXMucHJpdl9rZXlcbiAgdmFyIHAgPSBwcml2LnBhcmFtcy5wXG4gIHZhciBxID0gcHJpdi5wYXJhbXMucVxuICB2YXIgZyA9IHByaXYucGFyYW1zLmdcbiAgdmFyIHIgPSBuZXcgQk4oMClcbiAgdmFyIGtcbiAgdmFyIEggPSBiaXRzMmludChoYXNoLCBxKS5tb2QocSlcbiAgdmFyIHMgPSBmYWxzZVxuICB2YXIga3YgPSBnZXRLZXkoeCwgcSwgaGFzaCwgYWxnbylcbiAgd2hpbGUgKHMgPT09IGZhbHNlKSB7XG4gICAgayA9IG1ha2VLZXkocSwga3YsIGFsZ28pXG4gICAgciA9IG1ha2VSKGcsIGssIHAsIHEpXG4gICAgcyA9IGsuaW52bShxKS5pbXVsKEguYWRkKHgubXVsKHIpKSkubW9kKHEpXG4gICAgaWYgKHMuY21wbigwKSA9PT0gMCkge1xuICAgICAgcyA9IGZhbHNlXG4gICAgICByID0gbmV3IEJOKDApXG4gICAgfVxuICB9XG4gIHJldHVybiB0b0RFUihyLCBzKVxufVxuXG5mdW5jdGlvbiB0b0RFUiAociwgcykge1xuICByID0gci50b0FycmF5KClcbiAgcyA9IHMudG9BcnJheSgpXG5cbiAgLy8gUGFkIHZhbHVlc1xuICBpZiAoclswXSAmIDB4ODApIHIgPSBbIDAgXS5jb25jYXQocilcbiAgaWYgKHNbMF0gJiAweDgwKSBzID0gWyAwIF0uY29uY2F0KHMpXG5cbiAgdmFyIHRvdGFsID0gci5sZW5ndGggKyBzLmxlbmd0aCArIDRcbiAgdmFyIHJlcyA9IFsgMHgzMCwgdG90YWwsIDB4MDIsIHIubGVuZ3RoIF1cbiAgcmVzID0gcmVzLmNvbmNhdChyLCBbIDB4MDIsIHMubGVuZ3RoIF0sIHMpXG4gIHJldHVybiBuZXcgQnVmZmVyKHJlcylcbn1cblxuZnVuY3Rpb24gZ2V0S2V5ICh4LCBxLCBoYXNoLCBhbGdvKSB7XG4gIHggPSBuZXcgQnVmZmVyKHgudG9BcnJheSgpKVxuICBpZiAoeC5sZW5ndGggPCBxLmJ5dGVMZW5ndGgoKSkge1xuICAgIHZhciB6ZXJvcyA9IG5ldyBCdWZmZXIocS5ieXRlTGVuZ3RoKCkgLSB4Lmxlbmd0aClcbiAgICB6ZXJvcy5maWxsKDApXG4gICAgeCA9IEJ1ZmZlci5jb25jYXQoWyB6ZXJvcywgeCBdKVxuICB9XG4gIHZhciBobGVuID0gaGFzaC5sZW5ndGhcbiAgdmFyIGhiaXRzID0gYml0czJvY3RldHMoaGFzaCwgcSlcbiAgdmFyIHYgPSBuZXcgQnVmZmVyKGhsZW4pXG4gIHYuZmlsbCgxKVxuICB2YXIgayA9IG5ldyBCdWZmZXIoaGxlbilcbiAgay5maWxsKDApXG4gIGsgPSBjcmVhdGVIbWFjKGFsZ28sIGspLnVwZGF0ZSh2KS51cGRhdGUobmV3IEJ1ZmZlcihbIDAgXSkpLnVwZGF0ZSh4KS51cGRhdGUoaGJpdHMpLmRpZ2VzdCgpXG4gIHYgPSBjcmVhdGVIbWFjKGFsZ28sIGspLnVwZGF0ZSh2KS5kaWdlc3QoKVxuICBrID0gY3JlYXRlSG1hYyhhbGdvLCBrKS51cGRhdGUodikudXBkYXRlKG5ldyBCdWZmZXIoWyAxIF0pKS51cGRhdGUoeCkudXBkYXRlKGhiaXRzKS5kaWdlc3QoKVxuICB2ID0gY3JlYXRlSG1hYyhhbGdvLCBrKS51cGRhdGUodikuZGlnZXN0KClcbiAgcmV0dXJuIHsgazogaywgdjogdiB9XG59XG5cbmZ1bmN0aW9uIGJpdHMyaW50IChvYml0cywgcSkge1xuICB2YXIgYml0cyA9IG5ldyBCTihvYml0cylcbiAgdmFyIHNoaWZ0ID0gKG9iaXRzLmxlbmd0aCA8PCAzKSAtIHEuYml0TGVuZ3RoKClcbiAgaWYgKHNoaWZ0ID4gMCkgYml0cy5pc2hybihzaGlmdClcbiAgcmV0dXJuIGJpdHNcbn1cblxuZnVuY3Rpb24gYml0czJvY3RldHMgKGJpdHMsIHEpIHtcbiAgYml0cyA9IGJpdHMyaW50KGJpdHMsIHEpXG4gIGJpdHMgPSBiaXRzLm1vZChxKVxuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcihiaXRzLnRvQXJyYXkoKSlcbiAgaWYgKG91dC5sZW5ndGggPCBxLmJ5dGVMZW5ndGgoKSkge1xuICAgIHZhciB6ZXJvcyA9IG5ldyBCdWZmZXIocS5ieXRlTGVuZ3RoKCkgLSBvdXQubGVuZ3RoKVxuICAgIHplcm9zLmZpbGwoMClcbiAgICBvdXQgPSBCdWZmZXIuY29uY2F0KFsgemVyb3MsIG91dCBdKVxuICB9XG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gbWFrZUtleSAocSwga3YsIGFsZ28pIHtcbiAgdmFyIHRcbiAgdmFyIGtcblxuICBkbyB7XG4gICAgdCA9IG5ldyBCdWZmZXIoMClcblxuICAgIHdoaWxlICh0Lmxlbmd0aCAqIDggPCBxLmJpdExlbmd0aCgpKSB7XG4gICAgICBrdi52ID0gY3JlYXRlSG1hYyhhbGdvLCBrdi5rKS51cGRhdGUoa3YudikuZGlnZXN0KClcbiAgICAgIHQgPSBCdWZmZXIuY29uY2F0KFsgdCwga3YudiBdKVxuICAgIH1cblxuICAgIGsgPSBiaXRzMmludCh0LCBxKVxuICAgIGt2LmsgPSBjcmVhdGVIbWFjKGFsZ28sIGt2LmspLnVwZGF0ZShrdi52KS51cGRhdGUobmV3IEJ1ZmZlcihbIDAgXSkpLmRpZ2VzdCgpXG4gICAga3YudiA9IGNyZWF0ZUhtYWMoYWxnbywga3YuaykudXBkYXRlKGt2LnYpLmRpZ2VzdCgpXG4gIH0gd2hpbGUgKGsuY21wKHEpICE9PSAtMSlcblxuICByZXR1cm4ga1xufVxuXG5mdW5jdGlvbiBtYWtlUiAoZywgaywgcCwgcSkge1xuICByZXR1cm4gZy50b1JlZChCTi5tb250KHApKS5yZWRQb3coaykuZnJvbVJlZCgpLm1vZChxKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNpZ25cbm1vZHVsZS5leHBvcnRzLmdldEtleSA9IGdldEtleVxubW9kdWxlLmV4cG9ydHMubWFrZUtleSA9IG1ha2VLZXlcbiIsIi8vIG11Y2ggb2YgdGhpcyBiYXNlZCBvbiBodHRwczovL2dpdGh1Yi5jb20vaW5kdXRueS9zZWxmLXNpZ25lZC9ibG9iL2doLXBhZ2VzL2xpYi9yc2EuanNcbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJylcbnZhciBFQyA9IHJlcXVpcmUoJ2VsbGlwdGljJykuZWNcbnZhciBwYXJzZUtleXMgPSByZXF1aXJlKCdwYXJzZS1hc24xJylcbnZhciBjdXJ2ZXMgPSByZXF1aXJlKCcuL2N1cnZlcy5qc29uJylcblxuZnVuY3Rpb24gdmVyaWZ5IChzaWcsIGhhc2gsIGtleSwgc2lnblR5cGUsIHRhZykge1xuICB2YXIgcHViID0gcGFyc2VLZXlzKGtleSlcbiAgaWYgKHB1Yi50eXBlID09PSAnZWMnKSB7XG4gICAgLy8gcnNhIGtleXMgY2FuIGJlIGludGVycHJldGVkIGFzIGVjZHNhIG9uZXMgaW4gb3BlbnNzbFxuICAgIGlmIChzaWduVHlwZSAhPT0gJ2VjZHNhJyAmJiBzaWduVHlwZSAhPT0gJ2VjZHNhL3JzYScpIHRocm93IG5ldyBFcnJvcignd3JvbmcgcHVibGljIGtleSB0eXBlJylcbiAgICByZXR1cm4gZWNWZXJpZnkoc2lnLCBoYXNoLCBwdWIpXG4gIH0gZWxzZSBpZiAocHViLnR5cGUgPT09ICdkc2EnKSB7XG4gICAgaWYgKHNpZ25UeXBlICE9PSAnZHNhJykgdGhyb3cgbmV3IEVycm9yKCd3cm9uZyBwdWJsaWMga2V5IHR5cGUnKVxuICAgIHJldHVybiBkc2FWZXJpZnkoc2lnLCBoYXNoLCBwdWIpXG4gIH0gZWxzZSB7XG4gICAgaWYgKHNpZ25UeXBlICE9PSAncnNhJyAmJiBzaWduVHlwZSAhPT0gJ2VjZHNhL3JzYScpIHRocm93IG5ldyBFcnJvcignd3JvbmcgcHVibGljIGtleSB0eXBlJylcbiAgfVxuICBoYXNoID0gQnVmZmVyLmNvbmNhdChbdGFnLCBoYXNoXSlcbiAgdmFyIGxlbiA9IHB1Yi5tb2R1bHVzLmJ5dGVMZW5ndGgoKVxuICB2YXIgcGFkID0gWyAxIF1cbiAgdmFyIHBhZE51bSA9IDBcbiAgd2hpbGUgKGhhc2gubGVuZ3RoICsgcGFkLmxlbmd0aCArIDIgPCBsZW4pIHtcbiAgICBwYWQucHVzaCgweGZmKVxuICAgIHBhZE51bSsrXG4gIH1cbiAgcGFkLnB1c2goMHgwMClcbiAgdmFyIGkgPSAtMVxuICB3aGlsZSAoKytpIDwgaGFzaC5sZW5ndGgpIHtcbiAgICBwYWQucHVzaChoYXNoW2ldKVxuICB9XG4gIHBhZCA9IG5ldyBCdWZmZXIocGFkKVxuICB2YXIgcmVkID0gQk4ubW9udChwdWIubW9kdWx1cylcbiAgc2lnID0gbmV3IEJOKHNpZykudG9SZWQocmVkKVxuXG4gIHNpZyA9IHNpZy5yZWRQb3cobmV3IEJOKHB1Yi5wdWJsaWNFeHBvbmVudCkpXG4gIHNpZyA9IG5ldyBCdWZmZXIoc2lnLmZyb21SZWQoKS50b0FycmF5KCkpXG4gIHZhciBvdXQgPSBwYWROdW0gPCA4ID8gMSA6IDBcbiAgbGVuID0gTWF0aC5taW4oc2lnLmxlbmd0aCwgcGFkLmxlbmd0aClcbiAgaWYgKHNpZy5sZW5ndGggIT09IHBhZC5sZW5ndGgpIG91dCA9IDFcblxuICBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikgb3V0IHw9IHNpZ1tpXSBeIHBhZFtpXVxuICByZXR1cm4gb3V0ID09PSAwXG59XG5cbmZ1bmN0aW9uIGVjVmVyaWZ5IChzaWcsIGhhc2gsIHB1Yikge1xuICB2YXIgY3VydmVJZCA9IGN1cnZlc1twdWIuZGF0YS5hbGdvcml0aG0uY3VydmUuam9pbignLicpXVxuICBpZiAoIWN1cnZlSWQpIHRocm93IG5ldyBFcnJvcigndW5rbm93biBjdXJ2ZSAnICsgcHViLmRhdGEuYWxnb3JpdGhtLmN1cnZlLmpvaW4oJy4nKSlcblxuICB2YXIgY3VydmUgPSBuZXcgRUMoY3VydmVJZClcbiAgdmFyIHB1YmtleSA9IHB1Yi5kYXRhLnN1YmplY3RQcml2YXRlS2V5LmRhdGFcblxuICByZXR1cm4gY3VydmUudmVyaWZ5KGhhc2gsIHNpZywgcHVia2V5KVxufVxuXG5mdW5jdGlvbiBkc2FWZXJpZnkgKHNpZywgaGFzaCwgcHViKSB7XG4gIHZhciBwID0gcHViLmRhdGEucFxuICB2YXIgcSA9IHB1Yi5kYXRhLnFcbiAgdmFyIGcgPSBwdWIuZGF0YS5nXG4gIHZhciB5ID0gcHViLmRhdGEucHViX2tleVxuICB2YXIgdW5wYWNrZWQgPSBwYXJzZUtleXMuc2lnbmF0dXJlLmRlY29kZShzaWcsICdkZXInKVxuICB2YXIgcyA9IHVucGFja2VkLnNcbiAgdmFyIHIgPSB1bnBhY2tlZC5yXG4gIGNoZWNrVmFsdWUocywgcSlcbiAgY2hlY2tWYWx1ZShyLCBxKVxuICB2YXIgbW9udHAgPSBCTi5tb250KHApXG4gIHZhciB3ID0gcy5pbnZtKHEpXG4gIHZhciB2ID0gZy50b1JlZChtb250cClcbiAgICAucmVkUG93KG5ldyBCTihoYXNoKS5tdWwodykubW9kKHEpKVxuICAgIC5mcm9tUmVkKClcbiAgICAubXVsKHkudG9SZWQobW9udHApLnJlZFBvdyhyLm11bCh3KS5tb2QocSkpLmZyb21SZWQoKSlcbiAgICAubW9kKHApXG4gICAgLm1vZChxKVxuICByZXR1cm4gdi5jbXAocikgPT09IDBcbn1cblxuZnVuY3Rpb24gY2hlY2tWYWx1ZSAoYiwgcSkge1xuICBpZiAoYi5jbXBuKDApIDw9IDApIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBzaWcnKVxuICBpZiAoYi5jbXAocSkgPj0gcSkgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHNpZycpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gdmVyaWZ5XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuJ3VzZSBzdHJpY3QnO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXI7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIGlzRW5jb2RpbmcgPSBCdWZmZXIuaXNFbmNvZGluZyB8fCBmdW5jdGlvbiAoZW5jb2RpbmcpIHtcbiAgZW5jb2RpbmcgPSAnJyArIGVuY29kaW5nO1xuICBzd2l0Y2ggKGVuY29kaW5nICYmIGVuY29kaW5nLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlICdoZXgnOmNhc2UgJ3V0ZjgnOmNhc2UgJ3V0Zi04JzpjYXNlICdhc2NpaSc6Y2FzZSAnYmluYXJ5JzpjYXNlICdiYXNlNjQnOmNhc2UgJ3VjczInOmNhc2UgJ3Vjcy0yJzpjYXNlICd1dGYxNmxlJzpjYXNlICd1dGYtMTZsZSc6Y2FzZSAncmF3JzpcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIF9ub3JtYWxpemVFbmNvZGluZyhlbmMpIHtcbiAgaWYgKCFlbmMpIHJldHVybiAndXRmOCc7XG4gIHZhciByZXRyaWVkO1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIHN3aXRjaCAoZW5jKSB7XG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuICd1dGY4JztcbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiAndXRmMTZsZSc7XG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuICdsYXRpbjEnO1xuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBlbmM7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAocmV0cmllZCkgcmV0dXJuOyAvLyB1bmRlZmluZWRcbiAgICAgICAgZW5jID0gKCcnICsgZW5jKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICByZXRyaWVkID0gdHJ1ZTtcbiAgICB9XG4gIH1cbn07XG5cbi8vIERvIG5vdCBjYWNoZSBgQnVmZmVyLmlzRW5jb2RpbmdgIHdoZW4gY2hlY2tpbmcgZW5jb2RpbmcgbmFtZXMgYXMgc29tZVxuLy8gbW9kdWxlcyBtb25rZXktcGF0Y2ggaXQgdG8gc3VwcG9ydCBhZGRpdGlvbmFsIGVuY29kaW5nc1xuZnVuY3Rpb24gbm9ybWFsaXplRW5jb2RpbmcoZW5jKSB7XG4gIHZhciBuZW5jID0gX25vcm1hbGl6ZUVuY29kaW5nKGVuYyk7XG4gIGlmICh0eXBlb2YgbmVuYyAhPT0gJ3N0cmluZycgJiYgKEJ1ZmZlci5pc0VuY29kaW5nID09PSBpc0VuY29kaW5nIHx8ICFpc0VuY29kaW5nKGVuYykpKSB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmMpO1xuICByZXR1cm4gbmVuYyB8fCBlbmM7XG59XG5cbi8vIFN0cmluZ0RlY29kZXIgcHJvdmlkZXMgYW4gaW50ZXJmYWNlIGZvciBlZmZpY2llbnRseSBzcGxpdHRpbmcgYSBzZXJpZXMgb2Zcbi8vIGJ1ZmZlcnMgaW50byBhIHNlcmllcyBvZiBKUyBzdHJpbmdzIHdpdGhvdXQgYnJlYWtpbmcgYXBhcnQgbXVsdGktYnl0ZVxuLy8gY2hhcmFjdGVycy5cbmV4cG9ydHMuU3RyaW5nRGVjb2RlciA9IFN0cmluZ0RlY29kZXI7XG5mdW5jdGlvbiBTdHJpbmdEZWNvZGVyKGVuY29kaW5nKSB7XG4gIHRoaXMuZW5jb2RpbmcgPSBub3JtYWxpemVFbmNvZGluZyhlbmNvZGluZyk7XG4gIHZhciBuYjtcbiAgc3dpdGNoICh0aGlzLmVuY29kaW5nKSB7XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICB0aGlzLnRleHQgPSB1dGYxNlRleHQ7XG4gICAgICB0aGlzLmVuZCA9IHV0ZjE2RW5kO1xuICAgICAgbmIgPSA0O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndXRmOCc6XG4gICAgICB0aGlzLmZpbGxMYXN0ID0gdXRmOEZpbGxMYXN0O1xuICAgICAgbmIgPSA0O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIHRoaXMudGV4dCA9IGJhc2U2NFRleHQ7XG4gICAgICB0aGlzLmVuZCA9IGJhc2U2NEVuZDtcbiAgICAgIG5iID0gMztcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aGlzLndyaXRlID0gc2ltcGxlV3JpdGU7XG4gICAgICB0aGlzLmVuZCA9IHNpbXBsZUVuZDtcbiAgICAgIHJldHVybjtcbiAgfVxuICB0aGlzLmxhc3ROZWVkID0gMDtcbiAgdGhpcy5sYXN0VG90YWwgPSAwO1xuICB0aGlzLmxhc3RDaGFyID0gQnVmZmVyLmFsbG9jVW5zYWZlKG5iKTtcbn1cblxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAoYnVmKSB7XG4gIGlmIChidWYubGVuZ3RoID09PSAwKSByZXR1cm4gJyc7XG4gIHZhciByO1xuICB2YXIgaTtcbiAgaWYgKHRoaXMubGFzdE5lZWQpIHtcbiAgICByID0gdGhpcy5maWxsTGFzdChidWYpO1xuICAgIGlmIChyID09PSB1bmRlZmluZWQpIHJldHVybiAnJztcbiAgICBpID0gdGhpcy5sYXN0TmVlZDtcbiAgICB0aGlzLmxhc3ROZWVkID0gMDtcbiAgfSBlbHNlIHtcbiAgICBpID0gMDtcbiAgfVxuICBpZiAoaSA8IGJ1Zi5sZW5ndGgpIHJldHVybiByID8gciArIHRoaXMudGV4dChidWYsIGkpIDogdGhpcy50ZXh0KGJ1ZiwgaSk7XG4gIHJldHVybiByIHx8ICcnO1xufTtcblxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZW5kID0gdXRmOEVuZDtcblxuLy8gUmV0dXJucyBvbmx5IGNvbXBsZXRlIGNoYXJhY3RlcnMgaW4gYSBCdWZmZXJcblN0cmluZ0RlY29kZXIucHJvdG90eXBlLnRleHQgPSB1dGY4VGV4dDtcblxuLy8gQXR0ZW1wdHMgdG8gY29tcGxldGUgYSBwYXJ0aWFsIG5vbi1VVEYtOCBjaGFyYWN0ZXIgdXNpbmcgYnl0ZXMgZnJvbSBhIEJ1ZmZlclxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZmlsbExhc3QgPSBmdW5jdGlvbiAoYnVmKSB7XG4gIGlmICh0aGlzLmxhc3ROZWVkIDw9IGJ1Zi5sZW5ndGgpIHtcbiAgICBidWYuY29weSh0aGlzLmxhc3RDaGFyLCB0aGlzLmxhc3RUb3RhbCAtIHRoaXMubGFzdE5lZWQsIDAsIHRoaXMubGFzdE5lZWQpO1xuICAgIHJldHVybiB0aGlzLmxhc3RDaGFyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcsIDAsIHRoaXMubGFzdFRvdGFsKTtcbiAgfVxuICBidWYuY29weSh0aGlzLmxhc3RDaGFyLCB0aGlzLmxhc3RUb3RhbCAtIHRoaXMubGFzdE5lZWQsIDAsIGJ1Zi5sZW5ndGgpO1xuICB0aGlzLmxhc3ROZWVkIC09IGJ1Zi5sZW5ndGg7XG59O1xuXG4vLyBDaGVja3MgdGhlIHR5cGUgb2YgYSBVVEYtOCBieXRlLCB3aGV0aGVyIGl0J3MgQVNDSUksIGEgbGVhZGluZyBieXRlLCBvciBhXG4vLyBjb250aW51YXRpb24gYnl0ZS4gSWYgYW4gaW52YWxpZCBieXRlIGlzIGRldGVjdGVkLCAtMiBpcyByZXR1cm5lZC5cbmZ1bmN0aW9uIHV0ZjhDaGVja0J5dGUoYnl0ZSkge1xuICBpZiAoYnl0ZSA8PSAweDdGKSByZXR1cm4gMDtlbHNlIGlmIChieXRlID4+IDUgPT09IDB4MDYpIHJldHVybiAyO2Vsc2UgaWYgKGJ5dGUgPj4gNCA9PT0gMHgwRSkgcmV0dXJuIDM7ZWxzZSBpZiAoYnl0ZSA+PiAzID09PSAweDFFKSByZXR1cm4gNDtcbiAgcmV0dXJuIGJ5dGUgPj4gNiA9PT0gMHgwMiA/IC0xIDogLTI7XG59XG5cbi8vIENoZWNrcyBhdCBtb3N0IDMgYnl0ZXMgYXQgdGhlIGVuZCBvZiBhIEJ1ZmZlciBpbiBvcmRlciB0byBkZXRlY3QgYW5cbi8vIGluY29tcGxldGUgbXVsdGktYnl0ZSBVVEYtOCBjaGFyYWN0ZXIuIFRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgKDIsIDMsIG9yIDQpXG4vLyBuZWVkZWQgdG8gY29tcGxldGUgdGhlIFVURi04IGNoYXJhY3RlciAoaWYgYXBwbGljYWJsZSkgYXJlIHJldHVybmVkLlxuZnVuY3Rpb24gdXRmOENoZWNrSW5jb21wbGV0ZShzZWxmLCBidWYsIGkpIHtcbiAgdmFyIGogPSBidWYubGVuZ3RoIC0gMTtcbiAgaWYgKGogPCBpKSByZXR1cm4gMDtcbiAgdmFyIG5iID0gdXRmOENoZWNrQnl0ZShidWZbal0pO1xuICBpZiAobmIgPj0gMCkge1xuICAgIGlmIChuYiA+IDApIHNlbGYubGFzdE5lZWQgPSBuYiAtIDE7XG4gICAgcmV0dXJuIG5iO1xuICB9XG4gIGlmICgtLWogPCBpIHx8IG5iID09PSAtMikgcmV0dXJuIDA7XG4gIG5iID0gdXRmOENoZWNrQnl0ZShidWZbal0pO1xuICBpZiAobmIgPj0gMCkge1xuICAgIGlmIChuYiA+IDApIHNlbGYubGFzdE5lZWQgPSBuYiAtIDI7XG4gICAgcmV0dXJuIG5iO1xuICB9XG4gIGlmICgtLWogPCBpIHx8IG5iID09PSAtMikgcmV0dXJuIDA7XG4gIG5iID0gdXRmOENoZWNrQnl0ZShidWZbal0pO1xuICBpZiAobmIgPj0gMCkge1xuICAgIGlmIChuYiA+IDApIHtcbiAgICAgIGlmIChuYiA9PT0gMikgbmIgPSAwO2Vsc2Ugc2VsZi5sYXN0TmVlZCA9IG5iIC0gMztcbiAgICB9XG4gICAgcmV0dXJuIG5iO1xuICB9XG4gIHJldHVybiAwO1xufVxuXG4vLyBWYWxpZGF0ZXMgYXMgbWFueSBjb250aW51YXRpb24gYnl0ZXMgZm9yIGEgbXVsdGktYnl0ZSBVVEYtOCBjaGFyYWN0ZXIgYXNcbi8vIG5lZWRlZCBvciBhcmUgYXZhaWxhYmxlLiBJZiB3ZSBzZWUgYSBub24tY29udGludWF0aW9uIGJ5dGUgd2hlcmUgd2UgZXhwZWN0XG4vLyBvbmUsIHdlIFwicmVwbGFjZVwiIHRoZSB2YWxpZGF0ZWQgY29udGludWF0aW9uIGJ5dGVzIHdlJ3ZlIHNlZW4gc28gZmFyIHdpdGhcbi8vIGEgc2luZ2xlIFVURi04IHJlcGxhY2VtZW50IGNoYXJhY3RlciAoJ1xcdWZmZmQnKSwgdG8gbWF0Y2ggdjgncyBVVEYtOCBkZWNvZGluZ1xuLy8gYmVoYXZpb3IuIFRoZSBjb250aW51YXRpb24gYnl0ZSBjaGVjayBpcyBpbmNsdWRlZCB0aHJlZSB0aW1lcyBpbiB0aGUgY2FzZVxuLy8gd2hlcmUgYWxsIG9mIHRoZSBjb250aW51YXRpb24gYnl0ZXMgZm9yIGEgY2hhcmFjdGVyIGV4aXN0IGluIHRoZSBzYW1lIGJ1ZmZlci5cbi8vIEl0IGlzIGFsc28gZG9uZSB0aGlzIHdheSBhcyBhIHNsaWdodCBwZXJmb3JtYW5jZSBpbmNyZWFzZSBpbnN0ZWFkIG9mIHVzaW5nIGFcbi8vIGxvb3AuXG5mdW5jdGlvbiB1dGY4Q2hlY2tFeHRyYUJ5dGVzKHNlbGYsIGJ1ZiwgcCkge1xuICBpZiAoKGJ1ZlswXSAmIDB4QzApICE9PSAweDgwKSB7XG4gICAgc2VsZi5sYXN0TmVlZCA9IDA7XG4gICAgcmV0dXJuICdcXHVmZmZkJztcbiAgfVxuICBpZiAoc2VsZi5sYXN0TmVlZCA+IDEgJiYgYnVmLmxlbmd0aCA+IDEpIHtcbiAgICBpZiAoKGJ1ZlsxXSAmIDB4QzApICE9PSAweDgwKSB7XG4gICAgICBzZWxmLmxhc3ROZWVkID0gMTtcbiAgICAgIHJldHVybiAnXFx1ZmZmZCc7XG4gICAgfVxuICAgIGlmIChzZWxmLmxhc3ROZWVkID4gMiAmJiBidWYubGVuZ3RoID4gMikge1xuICAgICAgaWYgKChidWZbMl0gJiAweEMwKSAhPT0gMHg4MCkge1xuICAgICAgICBzZWxmLmxhc3ROZWVkID0gMjtcbiAgICAgICAgcmV0dXJuICdcXHVmZmZkJztcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLy8gQXR0ZW1wdHMgdG8gY29tcGxldGUgYSBtdWx0aS1ieXRlIFVURi04IGNoYXJhY3RlciB1c2luZyBieXRlcyBmcm9tIGEgQnVmZmVyLlxuZnVuY3Rpb24gdXRmOEZpbGxMYXN0KGJ1Zikge1xuICB2YXIgcCA9IHRoaXMubGFzdFRvdGFsIC0gdGhpcy5sYXN0TmVlZDtcbiAgdmFyIHIgPSB1dGY4Q2hlY2tFeHRyYUJ5dGVzKHRoaXMsIGJ1ZiwgcCk7XG4gIGlmIChyICE9PSB1bmRlZmluZWQpIHJldHVybiByO1xuICBpZiAodGhpcy5sYXN0TmVlZCA8PSBidWYubGVuZ3RoKSB7XG4gICAgYnVmLmNvcHkodGhpcy5sYXN0Q2hhciwgcCwgMCwgdGhpcy5sYXN0TmVlZCk7XG4gICAgcmV0dXJuIHRoaXMubGFzdENoYXIudG9TdHJpbmcodGhpcy5lbmNvZGluZywgMCwgdGhpcy5sYXN0VG90YWwpO1xuICB9XG4gIGJ1Zi5jb3B5KHRoaXMubGFzdENoYXIsIHAsIDAsIGJ1Zi5sZW5ndGgpO1xuICB0aGlzLmxhc3ROZWVkIC09IGJ1Zi5sZW5ndGg7XG59XG5cbi8vIFJldHVybnMgYWxsIGNvbXBsZXRlIFVURi04IGNoYXJhY3RlcnMgaW4gYSBCdWZmZXIuIElmIHRoZSBCdWZmZXIgZW5kZWQgb24gYVxuLy8gcGFydGlhbCBjaGFyYWN0ZXIsIHRoZSBjaGFyYWN0ZXIncyBieXRlcyBhcmUgYnVmZmVyZWQgdW50aWwgdGhlIHJlcXVpcmVkXG4vLyBudW1iZXIgb2YgYnl0ZXMgYXJlIGF2YWlsYWJsZS5cbmZ1bmN0aW9uIHV0ZjhUZXh0KGJ1ZiwgaSkge1xuICB2YXIgdG90YWwgPSB1dGY4Q2hlY2tJbmNvbXBsZXRlKHRoaXMsIGJ1ZiwgaSk7XG4gIGlmICghdGhpcy5sYXN0TmVlZCkgcmV0dXJuIGJ1Zi50b1N0cmluZygndXRmOCcsIGkpO1xuICB0aGlzLmxhc3RUb3RhbCA9IHRvdGFsO1xuICB2YXIgZW5kID0gYnVmLmxlbmd0aCAtICh0b3RhbCAtIHRoaXMubGFzdE5lZWQpO1xuICBidWYuY29weSh0aGlzLmxhc3RDaGFyLCAwLCBlbmQpO1xuICByZXR1cm4gYnVmLnRvU3RyaW5nKCd1dGY4JywgaSwgZW5kKTtcbn1cblxuLy8gRm9yIFVURi04LCBhIHJlcGxhY2VtZW50IGNoYXJhY3RlciBpcyBhZGRlZCB3aGVuIGVuZGluZyBvbiBhIHBhcnRpYWxcbi8vIGNoYXJhY3Rlci5cbmZ1bmN0aW9uIHV0ZjhFbmQoYnVmKSB7XG4gIHZhciByID0gYnVmICYmIGJ1Zi5sZW5ndGggPyB0aGlzLndyaXRlKGJ1ZikgOiAnJztcbiAgaWYgKHRoaXMubGFzdE5lZWQpIHJldHVybiByICsgJ1xcdWZmZmQnO1xuICByZXR1cm4gcjtcbn1cblxuLy8gVVRGLTE2TEUgdHlwaWNhbGx5IG5lZWRzIHR3byBieXRlcyBwZXIgY2hhcmFjdGVyLCBidXQgZXZlbiBpZiB3ZSBoYXZlIGFuIGV2ZW5cbi8vIG51bWJlciBvZiBieXRlcyBhdmFpbGFibGUsIHdlIG5lZWQgdG8gY2hlY2sgaWYgd2UgZW5kIG9uIGEgbGVhZGluZy9oaWdoXG4vLyBzdXJyb2dhdGUuIEluIHRoYXQgY2FzZSwgd2UgbmVlZCB0byB3YWl0IGZvciB0aGUgbmV4dCB0d28gYnl0ZXMgaW4gb3JkZXIgdG9cbi8vIGRlY29kZSB0aGUgbGFzdCBjaGFyYWN0ZXIgcHJvcGVybHkuXG5mdW5jdGlvbiB1dGYxNlRleHQoYnVmLCBpKSB7XG4gIGlmICgoYnVmLmxlbmd0aCAtIGkpICUgMiA9PT0gMCkge1xuICAgIHZhciByID0gYnVmLnRvU3RyaW5nKCd1dGYxNmxlJywgaSk7XG4gICAgaWYgKHIpIHtcbiAgICAgIHZhciBjID0gci5jaGFyQ29kZUF0KHIubGVuZ3RoIC0gMSk7XG4gICAgICBpZiAoYyA+PSAweEQ4MDAgJiYgYyA8PSAweERCRkYpIHtcbiAgICAgICAgdGhpcy5sYXN0TmVlZCA9IDI7XG4gICAgICAgIHRoaXMubGFzdFRvdGFsID0gNDtcbiAgICAgICAgdGhpcy5sYXN0Q2hhclswXSA9IGJ1ZltidWYubGVuZ3RoIC0gMl07XG4gICAgICAgIHRoaXMubGFzdENoYXJbMV0gPSBidWZbYnVmLmxlbmd0aCAtIDFdO1xuICAgICAgICByZXR1cm4gci5zbGljZSgwLCAtMSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByO1xuICB9XG4gIHRoaXMubGFzdE5lZWQgPSAxO1xuICB0aGlzLmxhc3RUb3RhbCA9IDI7XG4gIHRoaXMubGFzdENoYXJbMF0gPSBidWZbYnVmLmxlbmd0aCAtIDFdO1xuICByZXR1cm4gYnVmLnRvU3RyaW5nKCd1dGYxNmxlJywgaSwgYnVmLmxlbmd0aCAtIDEpO1xufVxuXG4vLyBGb3IgVVRGLTE2TEUgd2UgZG8gbm90IGV4cGxpY2l0bHkgYXBwZW5kIHNwZWNpYWwgcmVwbGFjZW1lbnQgY2hhcmFjdGVycyBpZiB3ZVxuLy8gZW5kIG9uIGEgcGFydGlhbCBjaGFyYWN0ZXIsIHdlIHNpbXBseSBsZXQgdjggaGFuZGxlIHRoYXQuXG5mdW5jdGlvbiB1dGYxNkVuZChidWYpIHtcbiAgdmFyIHIgPSBidWYgJiYgYnVmLmxlbmd0aCA/IHRoaXMud3JpdGUoYnVmKSA6ICcnO1xuICBpZiAodGhpcy5sYXN0TmVlZCkge1xuICAgIHZhciBlbmQgPSB0aGlzLmxhc3RUb3RhbCAtIHRoaXMubGFzdE5lZWQ7XG4gICAgcmV0dXJuIHIgKyB0aGlzLmxhc3RDaGFyLnRvU3RyaW5nKCd1dGYxNmxlJywgMCwgZW5kKTtcbiAgfVxuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gYmFzZTY0VGV4dChidWYsIGkpIHtcbiAgdmFyIG4gPSAoYnVmLmxlbmd0aCAtIGkpICUgMztcbiAgaWYgKG4gPT09IDApIHJldHVybiBidWYudG9TdHJpbmcoJ2Jhc2U2NCcsIGkpO1xuICB0aGlzLmxhc3ROZWVkID0gMyAtIG47XG4gIHRoaXMubGFzdFRvdGFsID0gMztcbiAgaWYgKG4gPT09IDEpIHtcbiAgICB0aGlzLmxhc3RDaGFyWzBdID0gYnVmW2J1Zi5sZW5ndGggLSAxXTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmxhc3RDaGFyWzBdID0gYnVmW2J1Zi5sZW5ndGggLSAyXTtcbiAgICB0aGlzLmxhc3RDaGFyWzFdID0gYnVmW2J1Zi5sZW5ndGggLSAxXTtcbiAgfVxuICByZXR1cm4gYnVmLnRvU3RyaW5nKCdiYXNlNjQnLCBpLCBidWYubGVuZ3RoIC0gbik7XG59XG5cbmZ1bmN0aW9uIGJhc2U2NEVuZChidWYpIHtcbiAgdmFyIHIgPSBidWYgJiYgYnVmLmxlbmd0aCA/IHRoaXMud3JpdGUoYnVmKSA6ICcnO1xuICBpZiAodGhpcy5sYXN0TmVlZCkgcmV0dXJuIHIgKyB0aGlzLmxhc3RDaGFyLnRvU3RyaW5nKCdiYXNlNjQnLCAwLCAzIC0gdGhpcy5sYXN0TmVlZCk7XG4gIHJldHVybiByO1xufVxuXG4vLyBQYXNzIGJ5dGVzIG9uIHRocm91Z2ggZm9yIHNpbmdsZS1ieXRlIGVuY29kaW5ncyAoZS5nLiBhc2NpaSwgbGF0aW4xLCBoZXgpXG5mdW5jdGlvbiBzaW1wbGVXcml0ZShidWYpIHtcbiAgcmV0dXJuIGJ1Zi50b1N0cmluZyh0aGlzLmVuY29kaW5nKTtcbn1cblxuZnVuY3Rpb24gc2ltcGxlRW5kKGJ1Zikge1xuICByZXR1cm4gYnVmICYmIGJ1Zi5sZW5ndGggPyB0aGlzLndyaXRlKGJ1ZikgOiAnJztcbn0iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHhvciAoYSwgYikge1xuICB2YXIgbGVuZ3RoID0gTWF0aC5taW4oYS5sZW5ndGgsIGIubGVuZ3RoKVxuICB2YXIgYnVmZmVyID0gbmV3IEJ1ZmZlcihsZW5ndGgpXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGJ1ZmZlcltpXSA9IGFbaV0gXiBiW2ldXG4gIH1cblxuICByZXR1cm4gYnVmZmVyXG59XG4iLCIvKiFcbiAqIFRoZSBidWZmZXIgbW9kdWxlIGZyb20gbm9kZS5qcywgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxodHRwczovL2Zlcm9zcy5vcmc+XG4gKiBAbGljZW5zZSAgTUlUXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG5cbid1c2Ugc3RyaWN0J1xuXG52YXIgYmFzZTY0ID0gcmVxdWlyZSgnYmFzZTY0LWpzJylcbnZhciBpZWVlNzU0ID0gcmVxdWlyZSgnaWVlZTc1NCcpXG5cbmV4cG9ydHMuQnVmZmVyID0gQnVmZmVyXG5leHBvcnRzLlNsb3dCdWZmZXIgPSBTbG93QnVmZmVyXG5leHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTID0gNTBcblxudmFyIEtfTUFYX0xFTkdUSCA9IDB4N2ZmZmZmZmZcbmV4cG9ydHMua01heExlbmd0aCA9IEtfTUFYX0xFTkdUSFxuXG4vKipcbiAqIElmIGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGA6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBQcmludCB3YXJuaW5nIGFuZCByZWNvbW1lbmQgdXNpbmcgYGJ1ZmZlcmAgdjQueCB3aGljaCBoYXMgYW4gT2JqZWN0XG4gKiAgICAgICAgICAgICAgIGltcGxlbWVudGF0aW9uIChtb3N0IGNvbXBhdGlibGUsIGV2ZW4gSUU2KVxuICpcbiAqIEJyb3dzZXJzIHRoYXQgc3VwcG9ydCB0eXBlZCBhcnJheXMgYXJlIElFIDEwKywgRmlyZWZveCA0KywgQ2hyb21lIDcrLCBTYWZhcmkgNS4xKyxcbiAqIE9wZXJhIDExLjYrLCBpT1MgNC4yKy5cbiAqXG4gKiBXZSByZXBvcnQgdGhhdCB0aGUgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHR5cGVkIGFycmF5cyBpZiB0aGUgYXJlIG5vdCBzdWJjbGFzc2FibGVcbiAqIHVzaW5nIF9fcHJvdG9fXy4gRmlyZWZveCA0LTI5IGxhY2tzIHN1cHBvcnQgZm9yIGFkZGluZyBuZXcgcHJvcGVydGllcyB0byBgVWludDhBcnJheWBcbiAqIChTZWU6IGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTY5NTQzOCkuIElFIDEwIGxhY2tzIHN1cHBvcnRcbiAqIGZvciBfX3Byb3RvX18gYW5kIGhhcyBhIGJ1Z2d5IHR5cGVkIGFycmF5IGltcGxlbWVudGF0aW9uLlxuICovXG5CdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCA9IHR5cGVkQXJyYXlTdXBwb3J0KClcblxuaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJiB0eXBlb2YgY29uc29sZSAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICB0eXBlb2YgY29uc29sZS5lcnJvciA9PT0gJ2Z1bmN0aW9uJykge1xuICBjb25zb2xlLmVycm9yKFxuICAgICdUaGlzIGJyb3dzZXIgbGFja3MgdHlwZWQgYXJyYXkgKFVpbnQ4QXJyYXkpIHN1cHBvcnQgd2hpY2ggaXMgcmVxdWlyZWQgYnkgJyArXG4gICAgJ2BidWZmZXJgIHY1LnguIFVzZSBgYnVmZmVyYCB2NC54IGlmIHlvdSByZXF1aXJlIG9sZCBicm93c2VyIHN1cHBvcnQuJ1xuICApXG59XG5cbmZ1bmN0aW9uIHR5cGVkQXJyYXlTdXBwb3J0ICgpIHtcbiAgLy8gQ2FuIHR5cGVkIGFycmF5IGluc3RhbmNlcyBjYW4gYmUgYXVnbWVudGVkP1xuICB0cnkge1xuICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheSgxKVxuICAgIGFyci5fX3Byb3RvX18gPSB7IF9fcHJvdG9fXzogVWludDhBcnJheS5wcm90b3R5cGUsIGZvbzogZnVuY3Rpb24gKCkgeyByZXR1cm4gNDIgfSB9XG4gICAgcmV0dXJuIGFyci5mb28oKSA9PT0gNDJcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShCdWZmZXIucHJvdG90eXBlLCAncGFyZW50Jywge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcih0aGlzKSkgcmV0dXJuIHVuZGVmaW5lZFxuICAgIHJldHVybiB0aGlzLmJ1ZmZlclxuICB9XG59KVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoQnVmZmVyLnByb3RvdHlwZSwgJ29mZnNldCcsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIodGhpcykpIHJldHVybiB1bmRlZmluZWRcbiAgICByZXR1cm4gdGhpcy5ieXRlT2Zmc2V0XG4gIH1cbn0pXG5cbmZ1bmN0aW9uIGNyZWF0ZUJ1ZmZlciAobGVuZ3RoKSB7XG4gIGlmIChsZW5ndGggPiBLX01BWF9MRU5HVEgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVGhlIHZhbHVlIFwiJyArIGxlbmd0aCArICdcIiBpcyBpbnZhbGlkIGZvciBvcHRpb24gXCJzaXplXCInKVxuICB9XG4gIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlXG4gIHZhciBidWYgPSBuZXcgVWludDhBcnJheShsZW5ndGgpXG4gIGJ1Zi5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIHJldHVybiBidWZcbn1cblxuLyoqXG4gKiBUaGUgQnVmZmVyIGNvbnN0cnVjdG9yIHJldHVybnMgaW5zdGFuY2VzIG9mIGBVaW50OEFycmF5YCB0aGF0IGhhdmUgdGhlaXJcbiAqIHByb3RvdHlwZSBjaGFuZ2VkIHRvIGBCdWZmZXIucHJvdG90eXBlYC4gRnVydGhlcm1vcmUsIGBCdWZmZXJgIGlzIGEgc3ViY2xhc3Mgb2ZcbiAqIGBVaW50OEFycmF5YCwgc28gdGhlIHJldHVybmVkIGluc3RhbmNlcyB3aWxsIGhhdmUgYWxsIHRoZSBub2RlIGBCdWZmZXJgIG1ldGhvZHNcbiAqIGFuZCB0aGUgYFVpbnQ4QXJyYXlgIG1ldGhvZHMuIFNxdWFyZSBicmFja2V0IG5vdGF0aW9uIHdvcmtzIGFzIGV4cGVjdGVkIC0tIGl0XG4gKiByZXR1cm5zIGEgc2luZ2xlIG9jdGV0LlxuICpcbiAqIFRoZSBgVWludDhBcnJheWAgcHJvdG90eXBlIHJlbWFpbnMgdW5tb2RpZmllZC5cbiAqL1xuXG5mdW5jdGlvbiBCdWZmZXIgKGFyZywgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIC8vIENvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICBpZiAodHlwZW9mIGVuY29kaW5nT3JPZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAnVGhlIFwic3RyaW5nXCIgYXJndW1lbnQgbXVzdCBiZSBvZiB0eXBlIHN0cmluZy4gUmVjZWl2ZWQgdHlwZSBudW1iZXInXG4gICAgICApXG4gICAgfVxuICAgIHJldHVybiBhbGxvY1Vuc2FmZShhcmcpXG4gIH1cbiAgcmV0dXJuIGZyb20oYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbi8vIEZpeCBzdWJhcnJheSgpIGluIEVTMjAxNi4gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9wdWxsLzk3XG5pZiAodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnNwZWNpZXMgIT0gbnVsbCAmJlxuICAgIEJ1ZmZlcltTeW1ib2wuc3BlY2llc10gPT09IEJ1ZmZlcikge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQnVmZmVyLCBTeW1ib2wuc3BlY2llcywge1xuICAgIHZhbHVlOiBudWxsLFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICB3cml0YWJsZTogZmFsc2VcbiAgfSlcbn1cblxuQnVmZmVyLnBvb2xTaXplID0gODE5MiAvLyBub3QgdXNlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uXG5cbmZ1bmN0aW9uIGZyb20gKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldClcbiAgfVxuXG4gIGlmIChBcnJheUJ1ZmZlci5pc1ZpZXcodmFsdWUpKSB7XG4gICAgcmV0dXJuIGZyb21BcnJheUxpa2UodmFsdWUpXG4gIH1cblxuICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgIHRocm93IFR5cGVFcnJvcihcbiAgICAgICdUaGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBvbmUgb2YgdHlwZSBzdHJpbmcsIEJ1ZmZlciwgQXJyYXlCdWZmZXIsIEFycmF5LCAnICtcbiAgICAgICdvciBBcnJheS1saWtlIE9iamVjdC4gUmVjZWl2ZWQgdHlwZSAnICsgKHR5cGVvZiB2YWx1ZSlcbiAgICApXG4gIH1cblxuICBpZiAoaXNJbnN0YW5jZSh2YWx1ZSwgQXJyYXlCdWZmZXIpIHx8XG4gICAgICAodmFsdWUgJiYgaXNJbnN0YW5jZSh2YWx1ZS5idWZmZXIsIEFycmF5QnVmZmVyKSkpIHtcbiAgICByZXR1cm4gZnJvbUFycmF5QnVmZmVyKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAnVGhlIFwidmFsdWVcIiBhcmd1bWVudCBtdXN0IG5vdCBiZSBvZiB0eXBlIG51bWJlci4gUmVjZWl2ZWQgdHlwZSBudW1iZXInXG4gICAgKVxuICB9XG5cbiAgdmFyIHZhbHVlT2YgPSB2YWx1ZS52YWx1ZU9mICYmIHZhbHVlLnZhbHVlT2YoKVxuICBpZiAodmFsdWVPZiAhPSBudWxsICYmIHZhbHVlT2YgIT09IHZhbHVlKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHZhbHVlT2YsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIHZhciBiID0gZnJvbU9iamVjdCh2YWx1ZSlcbiAgaWYgKGIpIHJldHVybiBiXG5cbiAgaWYgKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1ByaW1pdGl2ZSAhPSBudWxsICYmXG4gICAgICB0eXBlb2YgdmFsdWVbU3ltYm9sLnRvUHJpbWl0aXZlXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBCdWZmZXIuZnJvbShcbiAgICAgIHZhbHVlW1N5bWJvbC50b1ByaW1pdGl2ZV0oJ3N0cmluZycpLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGhcbiAgICApXG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICdUaGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBvbmUgb2YgdHlwZSBzdHJpbmcsIEJ1ZmZlciwgQXJyYXlCdWZmZXIsIEFycmF5LCAnICtcbiAgICAnb3IgQXJyYXktbGlrZSBPYmplY3QuIFJlY2VpdmVkIHR5cGUgJyArICh0eXBlb2YgdmFsdWUpXG4gIClcbn1cblxuLyoqXG4gKiBGdW5jdGlvbmFsbHkgZXF1aXZhbGVudCB0byBCdWZmZXIoYXJnLCBlbmNvZGluZykgYnV0IHRocm93cyBhIFR5cGVFcnJvclxuICogaWYgdmFsdWUgaXMgYSBudW1iZXIuXG4gKiBCdWZmZXIuZnJvbShzdHJbLCBlbmNvZGluZ10pXG4gKiBCdWZmZXIuZnJvbShhcnJheSlcbiAqIEJ1ZmZlci5mcm9tKGJ1ZmZlcilcbiAqIEJ1ZmZlci5mcm9tKGFycmF5QnVmZmVyWywgYnl0ZU9mZnNldFssIGxlbmd0aF1dKVxuICoqL1xuQnVmZmVyLmZyb20gPSBmdW5jdGlvbiAodmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gZnJvbSh2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKVxufVxuXG4vLyBOb3RlOiBDaGFuZ2UgcHJvdG90eXBlICphZnRlciogQnVmZmVyLmZyb20gaXMgZGVmaW5lZCB0byB3b3JrYXJvdW5kIENocm9tZSBidWc6XG4vLyBodHRwczovL2dpdGh1Yi5jb20vZmVyb3NzL2J1ZmZlci9wdWxsLzE0OFxuQnVmZmVyLnByb3RvdHlwZS5fX3Byb3RvX18gPSBVaW50OEFycmF5LnByb3RvdHlwZVxuQnVmZmVyLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXlcblxuZnVuY3Rpb24gYXNzZXJ0U2l6ZSAoc2l6ZSkge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBiZSBvZiB0eXBlIG51bWJlcicpXG4gIH0gZWxzZSBpZiAoc2l6ZSA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVGhlIHZhbHVlIFwiJyArIHNpemUgKyAnXCIgaXMgaW52YWxpZCBmb3Igb3B0aW9uIFwic2l6ZVwiJylcbiAgfVxufVxuXG5mdW5jdGlvbiBhbGxvYyAoc2l6ZSwgZmlsbCwgZW5jb2RpbmcpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICBpZiAoc2l6ZSA8PSAwKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcihzaXplKVxuICB9XG4gIGlmIChmaWxsICE9PSB1bmRlZmluZWQpIHtcbiAgICAvLyBPbmx5IHBheSBhdHRlbnRpb24gdG8gZW5jb2RpbmcgaWYgaXQncyBhIHN0cmluZy4gVGhpc1xuICAgIC8vIHByZXZlbnRzIGFjY2lkZW50YWxseSBzZW5kaW5nIGluIGEgbnVtYmVyIHRoYXQgd291bGRcbiAgICAvLyBiZSBpbnRlcnByZXR0ZWQgYXMgYSBzdGFydCBvZmZzZXQuXG4gICAgcmV0dXJuIHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZydcbiAgICAgID8gY3JlYXRlQnVmZmVyKHNpemUpLmZpbGwoZmlsbCwgZW5jb2RpbmcpXG4gICAgICA6IGNyZWF0ZUJ1ZmZlcihzaXplKS5maWxsKGZpbGwpXG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcihzaXplKVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqIGFsbG9jKHNpemVbLCBmaWxsWywgZW5jb2RpbmddXSlcbiAqKi9cbkJ1ZmZlci5hbGxvYyA9IGZ1bmN0aW9uIChzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICByZXR1cm4gYWxsb2Moc2l6ZSwgZmlsbCwgZW5jb2RpbmcpXG59XG5cbmZ1bmN0aW9uIGFsbG9jVW5zYWZlIChzaXplKSB7XG4gIGFzc2VydFNpemUoc2l6ZSlcbiAgcmV0dXJuIGNyZWF0ZUJ1ZmZlcihzaXplIDwgMCA/IDAgOiBjaGVja2VkKHNpemUpIHwgMClcbn1cblxuLyoqXG4gKiBFcXVpdmFsZW50IHRvIEJ1ZmZlcihudW0pLCBieSBkZWZhdWx0IGNyZWF0ZXMgYSBub24temVyby1maWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICogKi9cbkJ1ZmZlci5hbGxvY1Vuc2FmZSA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIHJldHVybiBhbGxvY1Vuc2FmZShzaXplKVxufVxuLyoqXG4gKiBFcXVpdmFsZW50IHRvIFNsb3dCdWZmZXIobnVtKSwgYnkgZGVmYXVsdCBjcmVhdGVzIGEgbm9uLXplcm8tZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqL1xuQnVmZmVyLmFsbG9jVW5zYWZlU2xvdyA9IGZ1bmN0aW9uIChzaXplKSB7XG4gIHJldHVybiBhbGxvY1Vuc2FmZShzaXplKVxufVxuXG5mdW5jdGlvbiBmcm9tU3RyaW5nIChzdHJpbmcsIGVuY29kaW5nKSB7XG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnIHx8IGVuY29kaW5nID09PSAnJykge1xuICAgIGVuY29kaW5nID0gJ3V0ZjgnXG4gIH1cblxuICBpZiAoIUJ1ZmZlci5pc0VuY29kaW5nKGVuY29kaW5nKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgfVxuXG4gIHZhciBsZW5ndGggPSBieXRlTGVuZ3RoKHN0cmluZywgZW5jb2RpbmcpIHwgMFxuICB2YXIgYnVmID0gY3JlYXRlQnVmZmVyKGxlbmd0aClcblxuICB2YXIgYWN0dWFsID0gYnVmLndyaXRlKHN0cmluZywgZW5jb2RpbmcpXG5cbiAgaWYgKGFjdHVhbCAhPT0gbGVuZ3RoKSB7XG4gICAgLy8gV3JpdGluZyBhIGhleCBzdHJpbmcsIGZvciBleGFtcGxlLCB0aGF0IGNvbnRhaW5zIGludmFsaWQgY2hhcmFjdGVycyB3aWxsXG4gICAgLy8gY2F1c2UgZXZlcnl0aGluZyBhZnRlciB0aGUgZmlyc3QgaW52YWxpZCBjaGFyYWN0ZXIgdG8gYmUgaWdub3JlZC4gKGUuZy5cbiAgICAvLyAnYWJ4eGNkJyB3aWxsIGJlIHRyZWF0ZWQgYXMgJ2FiJylcbiAgICBidWYgPSBidWYuc2xpY2UoMCwgYWN0dWFsKVxuICB9XG5cbiAgcmV0dXJuIGJ1ZlxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlMaWtlIChhcnJheSkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoIDwgMCA/IDAgOiBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHZhciBidWYgPSBjcmVhdGVCdWZmZXIobGVuZ3RoKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgYnVmW2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gYnVmXG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUJ1ZmZlciAoYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICBpZiAoYnl0ZU9mZnNldCA8IDAgfHwgYXJyYXkuYnl0ZUxlbmd0aCA8IGJ5dGVPZmZzZXQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJvZmZzZXRcIiBpcyBvdXRzaWRlIG9mIGJ1ZmZlciBib3VuZHMnKVxuICB9XG5cbiAgaWYgKGFycmF5LmJ5dGVMZW5ndGggPCBieXRlT2Zmc2V0ICsgKGxlbmd0aCB8fCAwKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdcImxlbmd0aFwiIGlzIG91dHNpZGUgb2YgYnVmZmVyIGJvdW5kcycpXG4gIH1cblxuICB2YXIgYnVmXG4gIGlmIChieXRlT2Zmc2V0ID09PSB1bmRlZmluZWQgJiYgbGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBidWYgPSBuZXcgVWludDhBcnJheShhcnJheSlcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGJ1ZiA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0KVxuICB9IGVsc2Uge1xuICAgIGJ1ZiA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZVxuICBidWYuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICByZXR1cm4gYnVmXG59XG5cbmZ1bmN0aW9uIGZyb21PYmplY3QgKG9iaikge1xuICBpZiAoQnVmZmVyLmlzQnVmZmVyKG9iaikpIHtcbiAgICB2YXIgbGVuID0gY2hlY2tlZChvYmoubGVuZ3RoKSB8IDBcbiAgICB2YXIgYnVmID0gY3JlYXRlQnVmZmVyKGxlbilcblxuICAgIGlmIChidWYubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gYnVmXG4gICAgfVxuXG4gICAgb2JqLmNvcHkoYnVmLCAwLCAwLCBsZW4pXG4gICAgcmV0dXJuIGJ1ZlxuICB9XG5cbiAgaWYgKG9iai5sZW5ndGggIT09IHVuZGVmaW5lZCkge1xuICAgIGlmICh0eXBlb2Ygb2JqLmxlbmd0aCAhPT0gJ251bWJlcicgfHwgbnVtYmVySXNOYU4ob2JqLmxlbmd0aCkpIHtcbiAgICAgIHJldHVybiBjcmVhdGVCdWZmZXIoMClcbiAgICB9XG4gICAgcmV0dXJuIGZyb21BcnJheUxpa2Uob2JqKVxuICB9XG5cbiAgaWYgKG9iai50eXBlID09PSAnQnVmZmVyJyAmJiBBcnJheS5pc0FycmF5KG9iai5kYXRhKSkge1xuICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKG9iai5kYXRhKVxuICB9XG59XG5cbmZ1bmN0aW9uIGNoZWNrZWQgKGxlbmd0aCkge1xuICAvLyBOb3RlOiBjYW5ub3QgdXNlIGBsZW5ndGggPCBLX01BWF9MRU5HVEhgIGhlcmUgYmVjYXVzZSB0aGF0IGZhaWxzIHdoZW5cbiAgLy8gbGVuZ3RoIGlzIE5hTiAod2hpY2ggaXMgb3RoZXJ3aXNlIGNvZXJjZWQgdG8gemVyby4pXG4gIGlmIChsZW5ndGggPj0gS19NQVhfTEVOR1RIKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gYWxsb2NhdGUgQnVmZmVyIGxhcmdlciB0aGFuIG1heGltdW0gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgJ3NpemU6IDB4JyArIEtfTUFYX0xFTkdUSC50b1N0cmluZygxNikgKyAnIGJ5dGVzJylcbiAgfVxuICByZXR1cm4gbGVuZ3RoIHwgMFxufVxuXG5mdW5jdGlvbiBTbG93QnVmZmVyIChsZW5ndGgpIHtcbiAgaWYgKCtsZW5ndGggIT0gbGVuZ3RoKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZXFlcWVxXG4gICAgbGVuZ3RoID0gMFxuICB9XG4gIHJldHVybiBCdWZmZXIuYWxsb2MoK2xlbmd0aClcbn1cblxuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIgKGIpIHtcbiAgcmV0dXJuIGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlciA9PT0gdHJ1ZSAmJlxuICAgIGIgIT09IEJ1ZmZlci5wcm90b3R5cGUgLy8gc28gQnVmZmVyLmlzQnVmZmVyKEJ1ZmZlci5wcm90b3R5cGUpIHdpbGwgYmUgZmFsc2Vcbn1cblxuQnVmZmVyLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChhLCBiKSB7XG4gIGlmIChpc0luc3RhbmNlKGEsIFVpbnQ4QXJyYXkpKSBhID0gQnVmZmVyLmZyb20oYSwgYS5vZmZzZXQsIGEuYnl0ZUxlbmd0aClcbiAgaWYgKGlzSW5zdGFuY2UoYiwgVWludDhBcnJheSkpIGIgPSBCdWZmZXIuZnJvbShiLCBiLm9mZnNldCwgYi5ieXRlTGVuZ3RoKVxuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihhKSB8fCAhQnVmZmVyLmlzQnVmZmVyKGIpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICdUaGUgXCJidWYxXCIsIFwiYnVmMlwiIGFyZ3VtZW50cyBtdXN0IGJlIG9uZSBvZiB0eXBlIEJ1ZmZlciBvciBVaW50OEFycmF5J1xuICAgIClcbiAgfVxuXG4gIGlmIChhID09PSBiKSByZXR1cm4gMFxuXG4gIHZhciB4ID0gYS5sZW5ndGhcbiAgdmFyIHkgPSBiLmxlbmd0aFxuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBNYXRoLm1pbih4LCB5KTsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIHtcbiAgICAgIHggPSBhW2ldXG4gICAgICB5ID0gYltpXVxuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cblxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbkJ1ZmZlci5pc0VuY29kaW5nID0gZnVuY3Rpb24gaXNFbmNvZGluZyAoZW5jb2RpbmcpIHtcbiAgc3dpdGNoIChTdHJpbmcoZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnbGF0aW4xJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldHVybiB0cnVlXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5cbkJ1ZmZlci5jb25jYXQgPSBmdW5jdGlvbiBjb25jYXQgKGxpc3QsIGxlbmd0aCkge1xuICBpZiAoIUFycmF5LmlzQXJyYXkobGlzdCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RcIiBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5hbGxvYygwKVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbGVuZ3RoID0gMFxuICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgICBsZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmZmVyID0gQnVmZmVyLmFsbG9jVW5zYWZlKGxlbmd0aClcbiAgdmFyIHBvcyA9IDBcbiAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgYnVmID0gbGlzdFtpXVxuICAgIGlmIChpc0luc3RhbmNlKGJ1ZiwgVWludDhBcnJheSkpIHtcbiAgICAgIGJ1ZiA9IEJ1ZmZlci5mcm9tKGJ1ZilcbiAgICB9XG4gICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJylcbiAgICB9XG4gICAgYnVmLmNvcHkoYnVmZmVyLCBwb3MpXG4gICAgcG9zICs9IGJ1Zi5sZW5ndGhcbiAgfVxuICByZXR1cm4gYnVmZmVyXG59XG5cbmZ1bmN0aW9uIGJ5dGVMZW5ndGggKHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihzdHJpbmcpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5sZW5ndGhcbiAgfVxuICBpZiAoQXJyYXlCdWZmZXIuaXNWaWV3KHN0cmluZykgfHwgaXNJbnN0YW5jZShzdHJpbmcsIEFycmF5QnVmZmVyKSkge1xuICAgIHJldHVybiBzdHJpbmcuYnl0ZUxlbmd0aFxuICB9XG4gIGlmICh0eXBlb2Ygc3RyaW5nICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAnVGhlIFwic3RyaW5nXCIgYXJndW1lbnQgbXVzdCBiZSBvbmUgb2YgdHlwZSBzdHJpbmcsIEJ1ZmZlciwgb3IgQXJyYXlCdWZmZXIuICcgK1xuICAgICAgJ1JlY2VpdmVkIHR5cGUgJyArIHR5cGVvZiBzdHJpbmdcbiAgICApXG4gIH1cblxuICB2YXIgbGVuID0gc3RyaW5nLmxlbmd0aFxuICB2YXIgbXVzdE1hdGNoID0gKGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSA9PT0gdHJ1ZSlcbiAgaWYgKCFtdXN0TWF0Y2ggJiYgbGVuID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIFVzZSBhIGZvciBsb29wIHRvIGF2b2lkIHJlY3Vyc2lvblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsZW5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiBsZW4gKiAyXG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gbGVuID4+PiAxXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB7XG4gICAgICAgICAgcmV0dXJuIG11c3RNYXRjaCA/IC0xIDogdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGggLy8gYXNzdW1lIHV0ZjhcbiAgICAgICAgfVxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuQnVmZmVyLmJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoXG5cbmZ1bmN0aW9uIHNsb3dUb1N0cmluZyAoZW5jb2RpbmcsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcblxuICAvLyBObyBuZWVkIHRvIHZlcmlmeSB0aGF0IFwidGhpcy5sZW5ndGggPD0gTUFYX1VJTlQzMlwiIHNpbmNlIGl0J3MgYSByZWFkLW9ubHlcbiAgLy8gcHJvcGVydHkgb2YgYSB0eXBlZCBhcnJheS5cblxuICAvLyBUaGlzIGJlaGF2ZXMgbmVpdGhlciBsaWtlIFN0cmluZyBub3IgVWludDhBcnJheSBpbiB0aGF0IHdlIHNldCBzdGFydC9lbmRcbiAgLy8gdG8gdGhlaXIgdXBwZXIvbG93ZXIgYm91bmRzIGlmIHRoZSB2YWx1ZSBwYXNzZWQgaXMgb3V0IG9mIHJhbmdlLlxuICAvLyB1bmRlZmluZWQgaXMgaGFuZGxlZCBzcGVjaWFsbHkgYXMgcGVyIEVDTUEtMjYyIDZ0aCBFZGl0aW9uLFxuICAvLyBTZWN0aW9uIDEzLjMuMy43IFJ1bnRpbWUgU2VtYW50aWNzOiBLZXllZEJpbmRpbmdJbml0aWFsaXphdGlvbi5cbiAgaWYgKHN0YXJ0ID09PSB1bmRlZmluZWQgfHwgc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgPSAwXG4gIH1cbiAgLy8gUmV0dXJuIGVhcmx5IGlmIHN0YXJ0ID4gdGhpcy5sZW5ndGguIERvbmUgaGVyZSB0byBwcmV2ZW50IHBvdGVudGlhbCB1aW50MzJcbiAgLy8gY29lcmNpb24gZmFpbCBiZWxvdy5cbiAgaWYgKHN0YXJ0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCB8fCBlbmQgPiB0aGlzLmxlbmd0aCkge1xuICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gIH1cblxuICBpZiAoZW5kIDw9IDApIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIC8vIEZvcmNlIGNvZXJzaW9uIHRvIHVpbnQzMi4gVGhpcyB3aWxsIGFsc28gY29lcmNlIGZhbHNleS9OYU4gdmFsdWVzIHRvIDAuXG4gIGVuZCA+Pj49IDBcbiAgc3RhcnQgPj4+PSAwXG5cbiAgaWYgKGVuZCA8PSBzdGFydCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGF0aW4xU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1dGYxNmxlU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbi8vIFRoaXMgcHJvcGVydHkgaXMgdXNlZCBieSBgQnVmZmVyLmlzQnVmZmVyYCAoYW5kIHRoZSBgaXMtYnVmZmVyYCBucG0gcGFja2FnZSlcbi8vIHRvIGRldGVjdCBhIEJ1ZmZlciBpbnN0YW5jZS4gSXQncyBub3QgcG9zc2libGUgdG8gdXNlIGBpbnN0YW5jZW9mIEJ1ZmZlcmBcbi8vIHJlbGlhYmx5IGluIGEgYnJvd3NlcmlmeSBjb250ZXh0IGJlY2F1c2UgdGhlcmUgY291bGQgYmUgbXVsdGlwbGUgZGlmZmVyZW50XG4vLyBjb3BpZXMgb2YgdGhlICdidWZmZXInIHBhY2thZ2UgaW4gdXNlLiBUaGlzIG1ldGhvZCB3b3JrcyBldmVuIGZvciBCdWZmZXJcbi8vIGluc3RhbmNlcyB0aGF0IHdlcmUgY3JlYXRlZCBmcm9tIGFub3RoZXIgY29weSBvZiB0aGUgYGJ1ZmZlcmAgcGFja2FnZS5cbi8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvaXNzdWVzLzE1NFxuQnVmZmVyLnByb3RvdHlwZS5faXNCdWZmZXIgPSB0cnVlXG5cbmZ1bmN0aW9uIHN3YXAgKGIsIG4sIG0pIHtcbiAgdmFyIGkgPSBiW25dXG4gIGJbbl0gPSBiW21dXG4gIGJbbV0gPSBpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDE2ID0gZnVuY3Rpb24gc3dhcDE2ICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSAyICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAxNi1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSAyKSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgMSlcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXAzMiA9IGZ1bmN0aW9uIHN3YXAzMiAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgNCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgMzItYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gNCkge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDMpXG4gICAgc3dhcCh0aGlzLCBpICsgMSwgaSArIDIpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwNjQgPSBmdW5jdGlvbiBzd2FwNjQgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDggIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDY0LWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDgpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyA3KVxuICAgIHN3YXAodGhpcywgaSArIDEsIGkgKyA2KVxuICAgIHN3YXAodGhpcywgaSArIDIsIGkgKyA1KVxuICAgIHN3YXAodGhpcywgaSArIDMsIGkgKyA0KVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyAoKSB7XG4gIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuZ3RoID09PSAwKSByZXR1cm4gJydcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHJldHVybiB1dGY4U2xpY2UodGhpcywgMCwgbGVuZ3RoKVxuICByZXR1cm4gc2xvd1RvU3RyaW5nLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b0xvY2FsZVN0cmluZyA9IEJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmdcblxuQnVmZmVyLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiBlcXVhbHMgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIHRydWVcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpID09PSAwXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QgKCkge1xuICB2YXIgc3RyID0gJydcbiAgdmFyIG1heCA9IGV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVNcbiAgc3RyID0gdGhpcy50b1N0cmluZygnaGV4JywgMCwgbWF4KS5yZXBsYWNlKC8oLnsyfSkvZywgJyQxICcpLnRyaW0oKVxuICBpZiAodGhpcy5sZW5ndGggPiBtYXgpIHN0ciArPSAnIC4uLiAnXG4gIHJldHVybiAnPEJ1ZmZlciAnICsgc3RyICsgJz4nXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKHRhcmdldCwgc3RhcnQsIGVuZCwgdGhpc1N0YXJ0LCB0aGlzRW5kKSB7XG4gIGlmIChpc0luc3RhbmNlKHRhcmdldCwgVWludDhBcnJheSkpIHtcbiAgICB0YXJnZXQgPSBCdWZmZXIuZnJvbSh0YXJnZXQsIHRhcmdldC5vZmZzZXQsIHRhcmdldC5ieXRlTGVuZ3RoKVxuICB9XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHRhcmdldCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgJ1RoZSBcInRhcmdldFwiIGFyZ3VtZW50IG11c3QgYmUgb25lIG9mIHR5cGUgQnVmZmVyIG9yIFVpbnQ4QXJyYXkuICcgK1xuICAgICAgJ1JlY2VpdmVkIHR5cGUgJyArICh0eXBlb2YgdGFyZ2V0KVxuICAgIClcbiAgfVxuXG4gIGlmIChzdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgc3RhcnQgPSAwXG4gIH1cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5kID0gdGFyZ2V0ID8gdGFyZ2V0Lmxlbmd0aCA6IDBcbiAgfVxuICBpZiAodGhpc1N0YXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzU3RhcnQgPSAwXG4gIH1cbiAgaWYgKHRoaXNFbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRoaXNFbmQgPSB0aGlzLmxlbmd0aFxuICB9XG5cbiAgaWYgKHN0YXJ0IDwgMCB8fCBlbmQgPiB0YXJnZXQubGVuZ3RoIHx8IHRoaXNTdGFydCA8IDAgfHwgdGhpc0VuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ291dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAodGhpc1N0YXJ0ID49IHRoaXNFbmQgJiYgc3RhcnQgPj0gZW5kKSB7XG4gICAgcmV0dXJuIDBcbiAgfVxuICBpZiAodGhpc1N0YXJ0ID49IHRoaXNFbmQpIHtcbiAgICByZXR1cm4gLTFcbiAgfVxuICBpZiAoc3RhcnQgPj0gZW5kKSB7XG4gICAgcmV0dXJuIDFcbiAgfVxuXG4gIHN0YXJ0ID4+Pj0gMFxuICBlbmQgPj4+PSAwXG4gIHRoaXNTdGFydCA+Pj49IDBcbiAgdGhpc0VuZCA+Pj49IDBcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0KSByZXR1cm4gMFxuXG4gIHZhciB4ID0gdGhpc0VuZCAtIHRoaXNTdGFydFxuICB2YXIgeSA9IGVuZCAtIHN0YXJ0XG4gIHZhciBsZW4gPSBNYXRoLm1pbih4LCB5KVxuXG4gIHZhciB0aGlzQ29weSA9IHRoaXMuc2xpY2UodGhpc1N0YXJ0LCB0aGlzRW5kKVxuICB2YXIgdGFyZ2V0Q29weSA9IHRhcmdldC5zbGljZShzdGFydCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAodGhpc0NvcHlbaV0gIT09IHRhcmdldENvcHlbaV0pIHtcbiAgICAgIHggPSB0aGlzQ29weVtpXVxuICAgICAgeSA9IHRhcmdldENvcHlbaV1cbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgaWYgKHggPCB5KSByZXR1cm4gLTFcbiAgaWYgKHkgPCB4KSByZXR1cm4gMVxuICByZXR1cm4gMFxufVxuXG4vLyBGaW5kcyBlaXRoZXIgdGhlIGZpcnN0IGluZGV4IG9mIGB2YWxgIGluIGBidWZmZXJgIGF0IG9mZnNldCA+PSBgYnl0ZU9mZnNldGAsXG4vLyBPUiB0aGUgbGFzdCBpbmRleCBvZiBgdmFsYCBpbiBgYnVmZmVyYCBhdCBvZmZzZXQgPD0gYGJ5dGVPZmZzZXRgLlxuLy9cbi8vIEFyZ3VtZW50czpcbi8vIC0gYnVmZmVyIC0gYSBCdWZmZXIgdG8gc2VhcmNoXG4vLyAtIHZhbCAtIGEgc3RyaW5nLCBCdWZmZXIsIG9yIG51bWJlclxuLy8gLSBieXRlT2Zmc2V0IC0gYW4gaW5kZXggaW50byBgYnVmZmVyYDsgd2lsbCBiZSBjbGFtcGVkIHRvIGFuIGludDMyXG4vLyAtIGVuY29kaW5nIC0gYW4gb3B0aW9uYWwgZW5jb2RpbmcsIHJlbGV2YW50IGlzIHZhbCBpcyBhIHN0cmluZ1xuLy8gLSBkaXIgLSB0cnVlIGZvciBpbmRleE9mLCBmYWxzZSBmb3IgbGFzdEluZGV4T2ZcbmZ1bmN0aW9uIGJpZGlyZWN0aW9uYWxJbmRleE9mIChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcikge1xuICAvLyBFbXB0eSBidWZmZXIgbWVhbnMgbm8gbWF0Y2hcbiAgaWYgKGJ1ZmZlci5sZW5ndGggPT09IDApIHJldHVybiAtMVxuXG4gIC8vIE5vcm1hbGl6ZSBieXRlT2Zmc2V0XG4gIGlmICh0eXBlb2YgYnl0ZU9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IGJ5dGVPZmZzZXRcbiAgICBieXRlT2Zmc2V0ID0gMFxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPiAweDdmZmZmZmZmKSB7XG4gICAgYnl0ZU9mZnNldCA9IDB4N2ZmZmZmZmZcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0IDwgLTB4ODAwMDAwMDApIHtcbiAgICBieXRlT2Zmc2V0ID0gLTB4ODAwMDAwMDBcbiAgfVxuICBieXRlT2Zmc2V0ID0gK2J5dGVPZmZzZXQgLy8gQ29lcmNlIHRvIE51bWJlci5cbiAgaWYgKG51bWJlcklzTmFOKGJ5dGVPZmZzZXQpKSB7XG4gICAgLy8gYnl0ZU9mZnNldDogaXQgaXQncyB1bmRlZmluZWQsIG51bGwsIE5hTiwgXCJmb29cIiwgZXRjLCBzZWFyY2ggd2hvbGUgYnVmZmVyXG4gICAgYnl0ZU9mZnNldCA9IGRpciA/IDAgOiAoYnVmZmVyLmxlbmd0aCAtIDEpXG4gIH1cblxuICAvLyBOb3JtYWxpemUgYnl0ZU9mZnNldDogbmVnYXRpdmUgb2Zmc2V0cyBzdGFydCBmcm9tIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlclxuICBpZiAoYnl0ZU9mZnNldCA8IDApIGJ5dGVPZmZzZXQgPSBidWZmZXIubGVuZ3RoICsgYnl0ZU9mZnNldFxuICBpZiAoYnl0ZU9mZnNldCA+PSBidWZmZXIubGVuZ3RoKSB7XG4gICAgaWYgKGRpcikgcmV0dXJuIC0xXG4gICAgZWxzZSBieXRlT2Zmc2V0ID0gYnVmZmVyLmxlbmd0aCAtIDFcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0IDwgMCkge1xuICAgIGlmIChkaXIpIGJ5dGVPZmZzZXQgPSAwXG4gICAgZWxzZSByZXR1cm4gLTFcbiAgfVxuXG4gIC8vIE5vcm1hbGl6ZSB2YWxcbiAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFsID0gQnVmZmVyLmZyb20odmFsLCBlbmNvZGluZylcbiAgfVxuXG4gIC8vIEZpbmFsbHksIHNlYXJjaCBlaXRoZXIgaW5kZXhPZiAoaWYgZGlyIGlzIHRydWUpIG9yIGxhc3RJbmRleE9mXG4gIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsKSkge1xuICAgIC8vIFNwZWNpYWwgY2FzZTogbG9va2luZyBmb3IgZW1wdHkgc3RyaW5nL2J1ZmZlciBhbHdheXMgZmFpbHNcbiAgICBpZiAodmFsLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIC0xXG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpXG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICB2YWwgPSB2YWwgJiAweEZGIC8vIFNlYXJjaCBmb3IgYSBieXRlIHZhbHVlIFswLTI1NV1cbiAgICBpZiAodHlwZW9mIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGlmIChkaXIpIHtcbiAgICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YuY2FsbChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5sYXN0SW5kZXhPZi5jYWxsKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0KVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlciwgWyB2YWwgXSwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcilcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlRXJyb3IoJ3ZhbCBtdXN0IGJlIHN0cmluZywgbnVtYmVyIG9yIEJ1ZmZlcicpXG59XG5cbmZ1bmN0aW9uIGFycmF5SW5kZXhPZiAoYXJyLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpIHtcbiAgdmFyIGluZGV4U2l6ZSA9IDFcbiAgdmFyIGFyckxlbmd0aCA9IGFyci5sZW5ndGhcbiAgdmFyIHZhbExlbmd0aCA9IHZhbC5sZW5ndGhcblxuICBpZiAoZW5jb2RpbmcgIT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgaWYgKGVuY29kaW5nID09PSAndWNzMicgfHwgZW5jb2RpbmcgPT09ICd1Y3MtMicgfHxcbiAgICAgICAgZW5jb2RpbmcgPT09ICd1dGYxNmxlJyB8fCBlbmNvZGluZyA9PT0gJ3V0Zi0xNmxlJykge1xuICAgICAgaWYgKGFyci5sZW5ndGggPCAyIHx8IHZhbC5sZW5ndGggPCAyKSB7XG4gICAgICAgIHJldHVybiAtMVxuICAgICAgfVxuICAgICAgaW5kZXhTaXplID0gMlxuICAgICAgYXJyTGVuZ3RoIC89IDJcbiAgICAgIHZhbExlbmd0aCAvPSAyXG4gICAgICBieXRlT2Zmc2V0IC89IDJcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZWFkIChidWYsIGkpIHtcbiAgICBpZiAoaW5kZXhTaXplID09PSAxKSB7XG4gICAgICByZXR1cm4gYnVmW2ldXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBidWYucmVhZFVJbnQxNkJFKGkgKiBpbmRleFNpemUpXG4gICAgfVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGRpcikge1xuICAgIHZhciBmb3VuZEluZGV4ID0gLTFcbiAgICBmb3IgKGkgPSBieXRlT2Zmc2V0OyBpIDwgYXJyTGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChyZWFkKGFyciwgaSkgPT09IHJlYWQodmFsLCBmb3VuZEluZGV4ID09PSAtMSA/IDAgOiBpIC0gZm91bmRJbmRleCkpIHtcbiAgICAgICAgaWYgKGZvdW5kSW5kZXggPT09IC0xKSBmb3VuZEluZGV4ID0gaVxuICAgICAgICBpZiAoaSAtIGZvdW5kSW5kZXggKyAxID09PSB2YWxMZW5ndGgpIHJldHVybiBmb3VuZEluZGV4ICogaW5kZXhTaXplXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZm91bmRJbmRleCAhPT0gLTEpIGkgLT0gaSAtIGZvdW5kSW5kZXhcbiAgICAgICAgZm91bmRJbmRleCA9IC0xXG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChieXRlT2Zmc2V0ICsgdmFsTGVuZ3RoID4gYXJyTGVuZ3RoKSBieXRlT2Zmc2V0ID0gYXJyTGVuZ3RoIC0gdmFsTGVuZ3RoXG4gICAgZm9yIChpID0gYnl0ZU9mZnNldDsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHZhciBmb3VuZCA9IHRydWVcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdmFsTGVuZ3RoOyBqKyspIHtcbiAgICAgICAgaWYgKHJlYWQoYXJyLCBpICsgaikgIT09IHJlYWQodmFsLCBqKSkge1xuICAgICAgICAgIGZvdW5kID0gZmFsc2VcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZm91bmQpIHJldHVybiBpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIC0xXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5jbHVkZXMgPSBmdW5jdGlvbiBpbmNsdWRlcyAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gdGhpcy5pbmRleE9mKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpICE9PSAtMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluZGV4T2YgPSBmdW5jdGlvbiBpbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCB0cnVlKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmxhc3RJbmRleE9mID0gZnVuY3Rpb24gbGFzdEluZGV4T2YgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGJpZGlyZWN0aW9uYWxJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGZhbHNlKVxufVxuXG5mdW5jdGlvbiBoZXhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIG9mZnNldCA9IE51bWJlcihvZmZzZXQpIHx8IDBcbiAgdmFyIHJlbWFpbmluZyA9IGJ1Zi5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgfSBlbHNlIHtcbiAgICBsZW5ndGggPSBOdW1iZXIobGVuZ3RoKVxuICAgIGlmIChsZW5ndGggPiByZW1haW5pbmcpIHtcbiAgICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICAgIH1cbiAgfVxuXG4gIHZhciBzdHJMZW4gPSBzdHJpbmcubGVuZ3RoXG5cbiAgaWYgKGxlbmd0aCA+IHN0ckxlbiAvIDIpIHtcbiAgICBsZW5ndGggPSBzdHJMZW4gLyAyXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIHZhciBwYXJzZWQgPSBwYXJzZUludChzdHJpbmcuc3Vic3RyKGkgKiAyLCAyKSwgMTYpXG4gICAgaWYgKG51bWJlcklzTmFOKHBhcnNlZCkpIHJldHVybiBpXG4gICAgYnVmW29mZnNldCArIGldID0gcGFyc2VkXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gdXRmOFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmOFRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYXNjaWlXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGFzY2lpVG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBsYXRpbjFXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBhc2NpaVdyaXRlKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmFzZTY0V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIHVjczJXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjE2bGVUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiB3cml0ZSAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZylcbiAgaWYgKG9mZnNldCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5jb2RpbmcgPSAndXRmOCdcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgZW5jb2RpbmcpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIG9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBvZmZzZXRbLCBsZW5ndGhdWywgZW5jb2RpbmddKVxuICB9IGVsc2UgaWYgKGlzRmluaXRlKG9mZnNldCkpIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgICBpZiAoaXNGaW5pdGUobGVuZ3RoKSkge1xuICAgICAgbGVuZ3RoID0gbGVuZ3RoID4+PiAwXG4gICAgICBpZiAoZW5jb2RpbmcgPT09IHVuZGVmaW5lZCkgZW5jb2RpbmcgPSAndXRmOCdcbiAgICB9IGVsc2Uge1xuICAgICAgZW5jb2RpbmcgPSBsZW5ndGhcbiAgICAgIGxlbmd0aCA9IHVuZGVmaW5lZFxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnQnVmZmVyLndyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldFssIGxlbmd0aF0pIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQnXG4gICAgKVxuICB9XG5cbiAgdmFyIHJlbWFpbmluZyA9IHRoaXMubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCB8fCBsZW5ndGggPiByZW1haW5pbmcpIGxlbmd0aCA9IHJlbWFpbmluZ1xuXG4gIGlmICgoc3RyaW5nLmxlbmd0aCA+IDAgJiYgKGxlbmd0aCA8IDAgfHwgb2Zmc2V0IDwgMCkpIHx8IG9mZnNldCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gd3JpdGUgb3V0c2lkZSBidWZmZXIgYm91bmRzJylcbiAgfVxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGF0aW4xV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgLy8gV2FybmluZzogbWF4TGVuZ3RoIG5vdCB0YWtlbiBpbnRvIGFjY291bnQgaW4gYmFzZTY0V3JpdGVcbiAgICAgICAgcmV0dXJuIGJhc2U2NFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1Y3MyV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnQnVmZmVyJyxcbiAgICBkYXRhOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLl9hcnIgfHwgdGhpcywgMClcbiAgfVxufVxuXG5mdW5jdGlvbiBiYXNlNjRTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGlmIChzdGFydCA9PT0gMCAmJiBlbmQgPT09IGJ1Zi5sZW5ndGgpIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYuc2xpY2Uoc3RhcnQsIGVuZCkpXG4gIH1cbn1cblxuZnVuY3Rpb24gdXRmOFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuICB2YXIgcmVzID0gW11cblxuICB2YXIgaSA9IHN0YXJ0XG4gIHdoaWxlIChpIDwgZW5kKSB7XG4gICAgdmFyIGZpcnN0Qnl0ZSA9IGJ1ZltpXVxuICAgIHZhciBjb2RlUG9pbnQgPSBudWxsXG4gICAgdmFyIGJ5dGVzUGVyU2VxdWVuY2UgPSAoZmlyc3RCeXRlID4gMHhFRikgPyA0XG4gICAgICA6IChmaXJzdEJ5dGUgPiAweERGKSA/IDNcbiAgICAgICAgOiAoZmlyc3RCeXRlID4gMHhCRikgPyAyXG4gICAgICAgICAgOiAxXG5cbiAgICBpZiAoaSArIGJ5dGVzUGVyU2VxdWVuY2UgPD0gZW5kKSB7XG4gICAgICB2YXIgc2Vjb25kQnl0ZSwgdGhpcmRCeXRlLCBmb3VydGhCeXRlLCB0ZW1wQ29kZVBvaW50XG5cbiAgICAgIHN3aXRjaCAoYnl0ZXNQZXJTZXF1ZW5jZSkge1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgaWYgKGZpcnN0Qnl0ZSA8IDB4ODApIHtcbiAgICAgICAgICAgIGNvZGVQb2ludCA9IGZpcnN0Qnl0ZVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweDFGKSA8PCAweDYgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0YpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHhDIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAodGhpcmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3RkYgJiYgKHRlbXBDb2RlUG9pbnQgPCAweEQ4MDAgfHwgdGVtcENvZGVQb2ludCA+IDB4REZGRikpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgZm91cnRoQnl0ZSA9IGJ1ZltpICsgM11cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKGZvdXJ0aEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4MTIgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4QyB8ICh0aGlyZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAoZm91cnRoQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4RkZGRiAmJiB0ZW1wQ29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY29kZVBvaW50ID09PSBudWxsKSB7XG4gICAgICAvLyB3ZSBkaWQgbm90IGdlbmVyYXRlIGEgdmFsaWQgY29kZVBvaW50IHNvIGluc2VydCBhXG4gICAgICAvLyByZXBsYWNlbWVudCBjaGFyIChVK0ZGRkQpIGFuZCBhZHZhbmNlIG9ubHkgMSBieXRlXG4gICAgICBjb2RlUG9pbnQgPSAweEZGRkRcbiAgICAgIGJ5dGVzUGVyU2VxdWVuY2UgPSAxXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPiAweEZGRkYpIHtcbiAgICAgIC8vIGVuY29kZSB0byB1dGYxNiAoc3Vycm9nYXRlIHBhaXIgZGFuY2UpXG4gICAgICBjb2RlUG9pbnQgLT0gMHgxMDAwMFxuICAgICAgcmVzLnB1c2goY29kZVBvaW50ID4+PiAxMCAmIDB4M0ZGIHwgMHhEODAwKVxuICAgICAgY29kZVBvaW50ID0gMHhEQzAwIHwgY29kZVBvaW50ICYgMHgzRkZcbiAgICB9XG5cbiAgICByZXMucHVzaChjb2RlUG9pbnQpXG4gICAgaSArPSBieXRlc1BlclNlcXVlbmNlXG4gIH1cblxuICByZXR1cm4gZGVjb2RlQ29kZVBvaW50c0FycmF5KHJlcylcbn1cblxuLy8gQmFzZWQgb24gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjI3NDcyNzIvNjgwNzQyLCB0aGUgYnJvd3NlciB3aXRoXG4vLyB0aGUgbG93ZXN0IGxpbWl0IGlzIENocm9tZSwgd2l0aCAweDEwMDAwIGFyZ3MuXG4vLyBXZSBnbyAxIG1hZ25pdHVkZSBsZXNzLCBmb3Igc2FmZXR5XG52YXIgTUFYX0FSR1VNRU5UU19MRU5HVEggPSAweDEwMDBcblxuZnVuY3Rpb24gZGVjb2RlQ29kZVBvaW50c0FycmF5IChjb2RlUG9pbnRzKSB7XG4gIHZhciBsZW4gPSBjb2RlUG9pbnRzLmxlbmd0aFxuICBpZiAobGVuIDw9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjb2RlUG9pbnRzKSAvLyBhdm9pZCBleHRyYSBzbGljZSgpXG4gIH1cblxuICAvLyBEZWNvZGUgaW4gY2h1bmtzIHRvIGF2b2lkIFwiY2FsbCBzdGFjayBzaXplIGV4Y2VlZGVkXCIuXG4gIHZhciByZXMgPSAnJ1xuICB2YXIgaSA9IDBcbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShcbiAgICAgIFN0cmluZyxcbiAgICAgIGNvZGVQb2ludHMuc2xpY2UoaSwgaSArPSBNQVhfQVJHVU1FTlRTX0xFTkdUSClcbiAgICApXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSAmIDB4N0YpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBsYXRpbjFTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBoZXhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA8IDApIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCB8fCBlbmQgPCAwIHx8IGVuZCA+IGxlbikgZW5kID0gbGVuXG5cbiAgdmFyIG91dCA9ICcnXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgb3V0ICs9IHRvSGV4KGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IGJ1Zi5zbGljZShzdGFydCwgZW5kKVxuICB2YXIgcmVzID0gJydcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldICsgKGJ5dGVzW2kgKyAxXSAqIDI1NikpXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24gc2xpY2UgKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIHN0YXJ0ID0gfn5zdGFydFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IGxlbiA6IH5+ZW5kXG5cbiAgaWYgKHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ICs9IGxlblxuICAgIGlmIChzdGFydCA8IDApIHN0YXJ0ID0gMFxuICB9IGVsc2UgaWYgKHN0YXJ0ID4gbGVuKSB7XG4gICAgc3RhcnQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCAwKSB7XG4gICAgZW5kICs9IGxlblxuICAgIGlmIChlbmQgPCAwKSBlbmQgPSAwXG4gIH0gZWxzZSBpZiAoZW5kID4gbGVuKSB7XG4gICAgZW5kID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgdmFyIG5ld0J1ZiA9IHRoaXMuc3ViYXJyYXkoc3RhcnQsIGVuZClcbiAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2VcbiAgbmV3QnVmLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgcmV0dXJuIG5ld0J1ZlxufVxuXG4vKlxuICogTmVlZCB0byBtYWtlIHN1cmUgdGhhdCBidWZmZXIgaXNuJ3QgdHJ5aW5nIHRvIHdyaXRlIG91dCBvZiBib3VuZHMuXG4gKi9cbmZ1bmN0aW9uIGNoZWNrT2Zmc2V0IChvZmZzZXQsIGV4dCwgbGVuZ3RoKSB7XG4gIGlmICgob2Zmc2V0ICUgMSkgIT09IDAgfHwgb2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ29mZnNldCBpcyBub3QgdWludCcpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBsZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdUcnlpbmcgdG8gYWNjZXNzIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludExFID0gZnVuY3Rpb24gcmVhZFVJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRCRSA9IGZ1bmN0aW9uIHJlYWRVSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuICB9XG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXVxuICB2YXIgbXVsID0gMVxuICB3aGlsZSAoYnl0ZUxlbmd0aCA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gcmVhZFVJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2QkUgPSBmdW5jdGlvbiByZWFkVUludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDgpIHwgdGhpc1tvZmZzZXQgKyAxXVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKCh0aGlzW29mZnNldF0pIHxcbiAgICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSkgK1xuICAgICAgKHRoaXNbb2Zmc2V0ICsgM10gKiAweDEwMDAwMDApXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdICogMHgxMDAwMDAwKSArXG4gICAgKCh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgIHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludExFID0gZnVuY3Rpb24gcmVhZEludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRCRSA9IGZ1bmN0aW9uIHJlYWRJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgaSA9IGJ5dGVMZW5ndGhcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1pXVxuICB3aGlsZSAoaSA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uIHJlYWRJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICBpZiAoISh0aGlzW29mZnNldF0gJiAweDgwKSkgcmV0dXJuICh0aGlzW29mZnNldF0pXG4gIHJldHVybiAoKDB4ZmYgLSB0aGlzW29mZnNldF0gKyAxKSAqIC0xKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkxFID0gZnVuY3Rpb24gcmVhZEludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2QkUgPSBmdW5jdGlvbiByZWFkSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgMV0gfCAodGhpc1tvZmZzZXRdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdKSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgM10gPDwgMjQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyQkUgPSBmdW5jdGlvbiByZWFkSW50MzJCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCAyNCkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdExFID0gZnVuY3Rpb24gcmVhZEZsb2F0TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdEJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVMRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDUyLCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCA1MiwgOClcbn1cblxuZnVuY3Rpb24gY2hlY2tJbnQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImJ1ZmZlclwiIGFyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXIgaW5zdGFuY2UnKVxuICBpZiAodmFsdWUgPiBtYXggfHwgdmFsdWUgPCBtaW4pIHRocm93IG5ldyBSYW5nZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgaXMgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRMRSA9IGZ1bmN0aW9uIHdyaXRlVUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIHZhciBtYXhCeXRlcyA9IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSAtIDFcbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBtYXhCeXRlcywgMClcbiAgfVxuXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbWF4Qnl0ZXMgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCkgLSAxXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbWF4Qnl0ZXMsIDApXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDggPSBmdW5jdGlvbiB3cml0ZVVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHhmZiwgMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgPj4+IDI0KVxuICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludExFID0gZnVuY3Rpb24gd3JpdGVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCAoOCAqIGJ5dGVMZW5ndGgpIC0gMSlcblxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIGxpbWl0IC0gMSwgLWxpbWl0KVxuICB9XG5cbiAgdmFyIGkgPSAwXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSAwXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIGlmICh2YWx1ZSA8IDAgJiYgc3ViID09PSAwICYmIHRoaXNbb2Zmc2V0ICsgaSAtIDFdICE9PSAwKSB7XG4gICAgICBzdWIgPSAxXG4gICAgfVxuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRCRSA9IGZ1bmN0aW9uIHdyaXRlSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgKDggKiBieXRlTGVuZ3RoKSAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IDBcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICBpZiAodmFsdWUgPCAwICYmIHN1YiA9PT0gMCAmJiB0aGlzW29mZnNldCArIGkgKyAxXSAhPT0gMCkge1xuICAgICAgc3ViID0gMVxuICAgIH1cbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50OCA9IGZ1bmN0aW9uIHdyaXRlSW50OCAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4N2YsIC0weDgwKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmYgKyB2YWx1ZSArIDFcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZUludDE2TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgJiAweGZmKVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmZmZmZiArIHZhbHVlICsgMVxuICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbmZ1bmN0aW9uIGNoZWNrSUVFRTc1NCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbiAgaWYgKG9mZnNldCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxufVxuXG5mdW5jdGlvbiB3cml0ZUZsb2F0IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0lFRUU3NTQoYnVmLCB2YWx1ZSwgb2Zmc2V0LCA0LCAzLjQwMjgyMzQ2NjM4NTI4ODZlKzM4LCAtMy40MDI4MjM0NjYzODUyODg2ZSszOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCAyMywgNClcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0TEUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0TEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRCRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiB3cml0ZURvdWJsZSAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgOCwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbiAgcmV0dXJuIG9mZnNldCArIDhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiBjb3B5ICh0YXJnZXQsIHRhcmdldFN0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHRhcmdldCkpIHRocm93IG5ldyBUeXBlRXJyb3IoJ2FyZ3VtZW50IHNob3VsZCBiZSBhIEJ1ZmZlcicpXG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCAmJiBlbmQgIT09IDApIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXRTdGFydCA+PSB0YXJnZXQubGVuZ3RoKSB0YXJnZXRTdGFydCA9IHRhcmdldC5sZW5ndGhcbiAgaWYgKCF0YXJnZXRTdGFydCkgdGFyZ2V0U3RhcnQgPSAwXG4gIGlmIChlbmQgPiAwICYmIGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIC8vIENvcHkgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuIDBcbiAgaWYgKHRhcmdldC5sZW5ndGggPT09IDAgfHwgdGhpcy5sZW5ndGggPT09IDApIHJldHVybiAwXG5cbiAgLy8gRmF0YWwgZXJyb3IgY29uZGl0aW9uc1xuICBpZiAodGFyZ2V0U3RhcnQgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICB9XG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAoZW5kIDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3NvdXJjZUVuZCBvdXQgb2YgYm91bmRzJylcblxuICAvLyBBcmUgd2Ugb29iP1xuICBpZiAoZW5kID4gdGhpcy5sZW5ndGgpIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgPCBlbmQgLSBzdGFydCkge1xuICAgIGVuZCA9IHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCArIHN0YXJ0XG4gIH1cblxuICB2YXIgbGVuID0gZW5kIC0gc3RhcnRcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0ICYmIHR5cGVvZiBVaW50OEFycmF5LnByb3RvdHlwZS5jb3B5V2l0aGluID09PSAnZnVuY3Rpb24nKSB7XG4gICAgLy8gVXNlIGJ1aWx0LWluIHdoZW4gYXZhaWxhYmxlLCBtaXNzaW5nIGZyb20gSUUxMVxuICAgIHRoaXMuY29weVdpdGhpbih0YXJnZXRTdGFydCwgc3RhcnQsIGVuZClcbiAgfSBlbHNlIGlmICh0aGlzID09PSB0YXJnZXQgJiYgc3RhcnQgPCB0YXJnZXRTdGFydCAmJiB0YXJnZXRTdGFydCA8IGVuZCkge1xuICAgIC8vIGRlc2NlbmRpbmcgY29weSBmcm9tIGVuZFxuICAgIGZvciAodmFyIGkgPSBsZW4gLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgVWludDhBcnJheS5wcm90b3R5cGUuc2V0LmNhbGwoXG4gICAgICB0YXJnZXQsXG4gICAgICB0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpLFxuICAgICAgdGFyZ2V0U3RhcnRcbiAgICApXG4gIH1cblxuICByZXR1cm4gbGVuXG59XG5cbi8vIFVzYWdlOlxuLy8gICAgYnVmZmVyLmZpbGwobnVtYmVyWywgb2Zmc2V0WywgZW5kXV0pXG4vLyAgICBidWZmZXIuZmlsbChidWZmZXJbLCBvZmZzZXRbLCBlbmRdXSlcbi8vICAgIGJ1ZmZlci5maWxsKHN0cmluZ1ssIG9mZnNldFssIGVuZF1dWywgZW5jb2RpbmddKVxuQnVmZmVyLnByb3RvdHlwZS5maWxsID0gZnVuY3Rpb24gZmlsbCAodmFsLCBzdGFydCwgZW5kLCBlbmNvZGluZykge1xuICAvLyBIYW5kbGUgc3RyaW5nIGNhc2VzOlxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAodHlwZW9mIHN0YXJ0ID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBzdGFydFxuICAgICAgc3RhcnQgPSAwXG4gICAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGVuZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVuY29kaW5nID0gZW5kXG4gICAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICAgIH1cbiAgICBpZiAoZW5jb2RpbmcgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdlbmNvZGluZyBtdXN0IGJlIGEgc3RyaW5nJylcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZycgJiYgIUJ1ZmZlci5pc0VuY29kaW5nKGVuY29kaW5nKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgIH1cbiAgICBpZiAodmFsLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdmFyIGNvZGUgPSB2YWwuY2hhckNvZGVBdCgwKVxuICAgICAgaWYgKChlbmNvZGluZyA9PT0gJ3V0ZjgnICYmIGNvZGUgPCAxMjgpIHx8XG4gICAgICAgICAgZW5jb2RpbmcgPT09ICdsYXRpbjEnKSB7XG4gICAgICAgIC8vIEZhc3QgcGF0aDogSWYgYHZhbGAgZml0cyBpbnRvIGEgc2luZ2xlIGJ5dGUsIHVzZSB0aGF0IG51bWVyaWMgdmFsdWUuXG4gICAgICAgIHZhbCA9IGNvZGVcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICB2YWwgPSB2YWwgJiAyNTVcbiAgfVxuXG4gIC8vIEludmFsaWQgcmFuZ2VzIGFyZSBub3Qgc2V0IHRvIGEgZGVmYXVsdCwgc28gY2FuIHJhbmdlIGNoZWNrIGVhcmx5LlxuICBpZiAoc3RhcnQgPCAwIHx8IHRoaXMubGVuZ3RoIDwgc3RhcnQgfHwgdGhpcy5sZW5ndGggPCBlbmQpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignT3V0IG9mIHJhbmdlIGluZGV4JylcbiAgfVxuXG4gIGlmIChlbmQgPD0gc3RhcnQpIHtcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgc3RhcnQgPSBzdGFydCA+Pj4gMFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IHRoaXMubGVuZ3RoIDogZW5kID4+PiAwXG5cbiAgaWYgKCF2YWwpIHZhbCA9IDBcblxuICB2YXIgaVxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgICB0aGlzW2ldID0gdmFsXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBieXRlcyA9IEJ1ZmZlci5pc0J1ZmZlcih2YWwpXG4gICAgICA/IHZhbFxuICAgICAgOiBCdWZmZXIuZnJvbSh2YWwsIGVuY29kaW5nKVxuICAgIHZhciBsZW4gPSBieXRlcy5sZW5ndGhcbiAgICBpZiAobGVuID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgdmFsdWUgXCInICsgdmFsICtcbiAgICAgICAgJ1wiIGlzIGludmFsaWQgZm9yIGFyZ3VtZW50IFwidmFsdWVcIicpXG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCBlbmQgLSBzdGFydDsgKytpKSB7XG4gICAgICB0aGlzW2kgKyBzdGFydF0gPSBieXRlc1tpICUgbGVuXVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzXG59XG5cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT1cblxudmFyIElOVkFMSURfQkFTRTY0X1JFID0gL1teKy8wLTlBLVphLXotX10vZ1xuXG5mdW5jdGlvbiBiYXNlNjRjbGVhbiAoc3RyKSB7XG4gIC8vIE5vZGUgdGFrZXMgZXF1YWwgc2lnbnMgYXMgZW5kIG9mIHRoZSBCYXNlNjQgZW5jb2RpbmdcbiAgc3RyID0gc3RyLnNwbGl0KCc9JylbMF1cbiAgLy8gTm9kZSBzdHJpcHMgb3V0IGludmFsaWQgY2hhcmFjdGVycyBsaWtlIFxcbiBhbmQgXFx0IGZyb20gdGhlIHN0cmluZywgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHN0ciA9IHN0ci50cmltKCkucmVwbGFjZShJTlZBTElEX0JBU0U2NF9SRSwgJycpXG4gIC8vIE5vZGUgY29udmVydHMgc3RyaW5ncyB3aXRoIGxlbmd0aCA8IDIgdG8gJydcbiAgaWYgKHN0ci5sZW5ndGggPCAyKSByZXR1cm4gJydcbiAgLy8gTm9kZSBhbGxvd3MgZm9yIG5vbi1wYWRkZWQgYmFzZTY0IHN0cmluZ3MgKG1pc3NpbmcgdHJhaWxpbmcgPT09KSwgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHdoaWxlIChzdHIubGVuZ3RoICUgNCAhPT0gMCkge1xuICAgIHN0ciA9IHN0ciArICc9J1xuICB9XG4gIHJldHVybiBzdHJcbn1cblxuZnVuY3Rpb24gdG9IZXggKG4pIHtcbiAgaWYgKG4gPCAxNikgcmV0dXJuICcwJyArIG4udG9TdHJpbmcoMTYpXG4gIHJldHVybiBuLnRvU3RyaW5nKDE2KVxufVxuXG5mdW5jdGlvbiB1dGY4VG9CeXRlcyAoc3RyaW5nLCB1bml0cykge1xuICB1bml0cyA9IHVuaXRzIHx8IEluZmluaXR5XG4gIHZhciBjb2RlUG9pbnRcbiAgdmFyIGxlbmd0aCA9IHN0cmluZy5sZW5ndGhcbiAgdmFyIGxlYWRTdXJyb2dhdGUgPSBudWxsXG4gIHZhciBieXRlcyA9IFtdXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGNvZGVQb2ludCA9IHN0cmluZy5jaGFyQ29kZUF0KGkpXG5cbiAgICAvLyBpcyBzdXJyb2dhdGUgY29tcG9uZW50XG4gICAgaWYgKGNvZGVQb2ludCA+IDB4RDdGRiAmJiBjb2RlUG9pbnQgPCAweEUwMDApIHtcbiAgICAgIC8vIGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoIWxlYWRTdXJyb2dhdGUpIHtcbiAgICAgICAgLy8gbm8gbGVhZCB5ZXRcbiAgICAgICAgaWYgKGNvZGVQb2ludCA+IDB4REJGRikge1xuICAgICAgICAgIC8vIHVuZXhwZWN0ZWQgdHJhaWxcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9IGVsc2UgaWYgKGkgKyAxID09PSBsZW5ndGgpIHtcbiAgICAgICAgICAvLyB1bnBhaXJlZCBsZWFkXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHZhbGlkIGxlYWRcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIDIgbGVhZHMgaW4gYSByb3dcbiAgICAgIGlmIChjb2RlUG9pbnQgPCAweERDMDApIHtcbiAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gdmFsaWQgc3Vycm9nYXRlIHBhaXJcbiAgICAgIGNvZGVQb2ludCA9IChsZWFkU3Vycm9nYXRlIC0gMHhEODAwIDw8IDEwIHwgY29kZVBvaW50IC0gMHhEQzAwKSArIDB4MTAwMDBcbiAgICB9IGVsc2UgaWYgKGxlYWRTdXJyb2dhdGUpIHtcbiAgICAgIC8vIHZhbGlkIGJtcCBjaGFyLCBidXQgbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgIH1cblxuICAgIGxlYWRTdXJyb2dhdGUgPSBudWxsXG5cbiAgICAvLyBlbmNvZGUgdXRmOFxuICAgIGlmIChjb2RlUG9pbnQgPCAweDgwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDEpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goY29kZVBvaW50KVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHg4MDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiB8IDB4QzAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDMpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgfCAweEUwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSA0KSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHgxMiB8IDB4RjAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29kZSBwb2ludCcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIsIHVuaXRzKSB7XG4gIHZhciBjLCBoaSwgbG9cbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG5cbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBoaSA9IGMgPj4gOFxuICAgIGxvID0gYyAlIDI1NlxuICAgIGJ5dGVBcnJheS5wdXNoKGxvKVxuICAgIGJ5dGVBcnJheS5wdXNoKGhpKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzIChzdHIpIHtcbiAgcmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShiYXNlNjRjbGVhbihzdHIpKVxufVxuXG5mdW5jdGlvbiBibGl0QnVmZmVyIChzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGlmICgoaSArIG9mZnNldCA+PSBkc3QubGVuZ3RoKSB8fCAoaSA+PSBzcmMubGVuZ3RoKSkgYnJlYWtcbiAgICBkc3RbaSArIG9mZnNldF0gPSBzcmNbaV1cbiAgfVxuICByZXR1cm4gaVxufVxuXG4vLyBBcnJheUJ1ZmZlciBvciBVaW50OEFycmF5IG9iamVjdHMgZnJvbSBvdGhlciBjb250ZXh0cyAoaS5lLiBpZnJhbWVzKSBkbyBub3QgcGFzc1xuLy8gdGhlIGBpbnN0YW5jZW9mYCBjaGVjayBidXQgdGhleSBzaG91bGQgYmUgdHJlYXRlZCBhcyBvZiB0aGF0IHR5cGUuXG4vLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyL2lzc3Vlcy8xNjZcbmZ1bmN0aW9uIGlzSW5zdGFuY2UgKG9iaiwgdHlwZSkge1xuICByZXR1cm4gb2JqIGluc3RhbmNlb2YgdHlwZSB8fFxuICAgIChvYmogIT0gbnVsbCAmJiBvYmouY29uc3RydWN0b3IgIT0gbnVsbCAmJiBvYmouY29uc3RydWN0b3IubmFtZSAhPSBudWxsICYmXG4gICAgICBvYmouY29uc3RydWN0b3IubmFtZSA9PT0gdHlwZS5uYW1lKVxufVxuZnVuY3Rpb24gbnVtYmVySXNOYU4gKG9iaikge1xuICAvLyBGb3IgSUUxMSBzdXBwb3J0XG4gIHJldHVybiBvYmogIT09IG9iaiAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNlbGYtY29tcGFyZVxufVxuIiwiLyogY2ZiLmpzIChDKSAyMDEzLXByZXNlbnQgU2hlZXRKUyAtLSBodHRwOi8vc2hlZXRqcy5jb20gKi9cbi8qIHZpbTogc2V0IHRzPTI6ICovXG4vKmpzaGludCBlcW51bGw6dHJ1ZSAqL1xuLypleHBvcnRlZCBDRkIgKi9cbi8qZ2xvYmFsIG1vZHVsZSwgcmVxdWlyZTpmYWxzZSwgcHJvY2VzczpmYWxzZSwgQnVmZmVyOmZhbHNlLCBVaW50OEFycmF5OmZhbHNlLCBVaW50MTZBcnJheTpmYWxzZSAqL1xuXG52YXIgQmFzZTY0ID0gKGZ1bmN0aW9uIG1ha2VfYjY0KCl7XG5cdHZhciBtYXAgPSBcIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky89XCI7XG5cdHJldHVybiB7XG5cdFx0ZW5jb2RlOiBmdW5jdGlvbihpbnB1dCkge1xuXHRcdFx0dmFyIG8gPSBcIlwiO1xuXHRcdFx0dmFyIGMxPTAsIGMyPTAsIGMzPTAsIGUxPTAsIGUyPTAsIGUzPTAsIGU0PTA7XG5cdFx0XHRmb3IodmFyIGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoOyApIHtcblx0XHRcdFx0YzEgPSBpbnB1dC5jaGFyQ29kZUF0KGkrKyk7XG5cdFx0XHRcdGUxID0gKGMxID4+IDIpO1xuXG5cdFx0XHRcdGMyID0gaW5wdXQuY2hhckNvZGVBdChpKyspO1xuXHRcdFx0XHRlMiA9ICgoYzEgJiAzKSA8PCA0KSB8IChjMiA+PiA0KTtcblxuXHRcdFx0XHRjMyA9IGlucHV0LmNoYXJDb2RlQXQoaSsrKTtcblx0XHRcdFx0ZTMgPSAoKGMyICYgMTUpIDw8IDIpIHwgKGMzID4+IDYpO1xuXHRcdFx0XHRlNCA9IChjMyAmIDYzKTtcblx0XHRcdFx0aWYgKGlzTmFOKGMyKSkgeyBlMyA9IGU0ID0gNjQ7IH1cblx0XHRcdFx0ZWxzZSBpZiAoaXNOYU4oYzMpKSB7IGU0ID0gNjQ7IH1cblx0XHRcdFx0byArPSBtYXAuY2hhckF0KGUxKSArIG1hcC5jaGFyQXQoZTIpICsgbWFwLmNoYXJBdChlMykgKyBtYXAuY2hhckF0KGU0KTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBvO1xuXHRcdH0sXG5cdFx0ZGVjb2RlOiBmdW5jdGlvbiBiNjRfZGVjb2RlKGlucHV0KSB7XG5cdFx0XHR2YXIgbyA9IFwiXCI7XG5cdFx0XHR2YXIgYzE9MCwgYzI9MCwgYzM9MCwgZTE9MCwgZTI9MCwgZTM9MCwgZTQ9MDtcblx0XHRcdGlucHV0ID0gaW5wdXQucmVwbGFjZSgvW15cXHdcXCtcXC9cXD1dL2csIFwiXCIpO1xuXHRcdFx0Zm9yKHZhciBpID0gMDsgaSA8IGlucHV0Lmxlbmd0aDspIHtcblx0XHRcdFx0ZTEgPSBtYXAuaW5kZXhPZihpbnB1dC5jaGFyQXQoaSsrKSk7XG5cdFx0XHRcdGUyID0gbWFwLmluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpO1xuXHRcdFx0XHRjMSA9IChlMSA8PCAyKSB8IChlMiA+PiA0KTtcblx0XHRcdFx0byArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGMxKTtcblxuXHRcdFx0XHRlMyA9IG1hcC5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTtcblx0XHRcdFx0YzIgPSAoKGUyICYgMTUpIDw8IDQpIHwgKGUzID4+IDIpO1xuXHRcdFx0XHRpZiAoZTMgIT09IDY0KSB7IG8gKz0gU3RyaW5nLmZyb21DaGFyQ29kZShjMik7IH1cblxuXHRcdFx0XHRlNCA9IG1hcC5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTtcblx0XHRcdFx0YzMgPSAoKGUzICYgMykgPDwgNikgfCBlNDtcblx0XHRcdFx0aWYgKGU0ICE9PSA2NCkgeyBvICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYzMpOyB9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbztcblx0XHR9XG5cdH07XG59KSgpO1xudmFyIGhhc19idWYgPSAodHlwZW9mIEJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHByb2Nlc3MgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBwcm9jZXNzLnZlcnNpb25zICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLnZlcnNpb25zLm5vZGUpO1xuXG52YXIgQnVmZmVyX2Zyb20gPSBmdW5jdGlvbigpe307XG5cbmlmKHR5cGVvZiBCdWZmZXIgIT09ICd1bmRlZmluZWQnKSB7XG5cdHZhciBuYmZzID0gIUJ1ZmZlci5mcm9tO1xuXHRpZighbmJmcykgdHJ5IHsgQnVmZmVyLmZyb20oXCJmb29cIiwgXCJ1dGY4XCIpOyB9IGNhdGNoKGUpIHsgbmJmcyA9IHRydWU7IH1cblx0QnVmZmVyX2Zyb20gPSBuYmZzID8gZnVuY3Rpb24oYnVmLCBlbmMpIHsgcmV0dXJuIChlbmMpID8gbmV3IEJ1ZmZlcihidWYsIGVuYykgOiBuZXcgQnVmZmVyKGJ1Zik7IH0gOiBCdWZmZXIuZnJvbS5iaW5kKEJ1ZmZlcik7XG5cdC8vICRGbG93SWdub3JlXG5cdGlmKCFCdWZmZXIuYWxsb2MpIEJ1ZmZlci5hbGxvYyA9IGZ1bmN0aW9uKG4pIHsgcmV0dXJuIG5ldyBCdWZmZXIobik7IH07XG5cdC8vICRGbG93SWdub3JlXG5cdGlmKCFCdWZmZXIuYWxsb2NVbnNhZmUpIEJ1ZmZlci5hbGxvY1Vuc2FmZSA9IGZ1bmN0aW9uKG4pIHsgcmV0dXJuIG5ldyBCdWZmZXIobik7IH07XG59XG5cbmZ1bmN0aW9uIG5ld19yYXdfYnVmKGxlbikge1xuXHQvKiBqc2hpbnQgLVcwNTYgKi9cblx0cmV0dXJuIGhhc19idWYgPyBCdWZmZXIuYWxsb2MobGVuKSA6IG5ldyBBcnJheShsZW4pO1xuXHQvKiBqc2hpbnQgK1cwNTYgKi9cbn1cblxuZnVuY3Rpb24gbmV3X3Vuc2FmZV9idWYobGVuKSB7XG5cdC8qIGpzaGludCAtVzA1NiAqL1xuXHRyZXR1cm4gaGFzX2J1ZiA/IEJ1ZmZlci5hbGxvY1Vuc2FmZShsZW4pIDogbmV3IEFycmF5KGxlbik7XG5cdC8qIGpzaGludCArVzA1NiAqL1xufVxuXG52YXIgczJhID0gZnVuY3Rpb24gczJhKHMpIHtcblx0aWYoaGFzX2J1ZikgcmV0dXJuIEJ1ZmZlcl9mcm9tKHMsIFwiYmluYXJ5XCIpO1xuXHRyZXR1cm4gcy5zcGxpdChcIlwiKS5tYXAoZnVuY3Rpb24oeCl7IHJldHVybiB4LmNoYXJDb2RlQXQoMCkgJiAweGZmOyB9KTtcbn07XG5cbnZhciBjaHIwID0gL1xcdTAwMDAvZywgY2hyMSA9IC9bXFx1MDAwMS1cXHUwMDA2XS9nO1xudmFyIF9fdG9CdWZmZXIgPSBmdW5jdGlvbihidWZzKSB7IHZhciB4ID0gW107IGZvcih2YXIgaSA9IDA7IGkgPCBidWZzWzBdLmxlbmd0aDsgKytpKSB7IHgucHVzaC5hcHBseSh4LCBidWZzWzBdW2ldKTsgfSByZXR1cm4geDsgfTtcbnZhciBfX190b0J1ZmZlciA9IF9fdG9CdWZmZXI7XG52YXIgX191dGYxNmxlID0gZnVuY3Rpb24oYixzLGUpIHsgdmFyIHNzPVtdOyBmb3IodmFyIGk9czsgaTxlOyBpKz0yKSBzcy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoX19yZWFkVUludDE2TEUoYixpKSkpOyByZXR1cm4gc3Muam9pbihcIlwiKS5yZXBsYWNlKGNocjAsJycpOyB9O1xudmFyIF9fX3V0ZjE2bGUgPSBfX3V0ZjE2bGU7XG52YXIgX19oZXhsaWZ5ID0gZnVuY3Rpb24oYixzLGwpIHsgdmFyIHNzPVtdOyBmb3IodmFyIGk9czsgaTxzK2w7ICsraSkgc3MucHVzaCgoXCIwXCIgKyBiW2ldLnRvU3RyaW5nKDE2KSkuc2xpY2UoLTIpKTsgcmV0dXJuIHNzLmpvaW4oXCJcIik7IH07XG52YXIgX19faGV4bGlmeSA9IF9faGV4bGlmeTtcbnZhciBfX2Jjb25jYXQgPSBmdW5jdGlvbihidWZzKSB7XG5cdGlmKEFycmF5LmlzQXJyYXkoYnVmc1swXSkpIHJldHVybiBbXS5jb25jYXQuYXBwbHkoW10sIGJ1ZnMpO1xuXHR2YXIgbWF4bGVuID0gMCwgaSA9IDA7XG5cdGZvcihpID0gMDsgaSA8IGJ1ZnMubGVuZ3RoOyArK2kpIG1heGxlbiArPSBidWZzW2ldLmxlbmd0aDtcblx0dmFyIG8gPSBuZXcgVWludDhBcnJheShtYXhsZW4pO1xuXHRmb3IoaSA9IDAsIG1heGxlbiA9IDA7IGkgPCBidWZzLmxlbmd0aDsgbWF4bGVuICs9IGJ1ZnNbaV0ubGVuZ3RoLCArK2kpIG8uc2V0KGJ1ZnNbaV0sIG1heGxlbik7XG5cdHJldHVybiBvO1xufTtcbnZhciBiY29uY2F0ID0gX19iY29uY2F0O1xuXG5cbmlmKGhhc19idWYpIHtcblx0X191dGYxNmxlID0gZnVuY3Rpb24oYixzLGUpIHtcblx0XHRpZighQnVmZmVyLmlzQnVmZmVyKGIpKSByZXR1cm4gX19fdXRmMTZsZShiLHMsZSk7XG5cdFx0cmV0dXJuIGIudG9TdHJpbmcoJ3V0ZjE2bGUnLHMsZSkucmVwbGFjZShjaHIwLCcnKS8qLnJlcGxhY2UoY2hyMSwnIScpKi87XG5cdH07XG5cdF9faGV4bGlmeSA9IGZ1bmN0aW9uKGIscyxsKSB7IHJldHVybiBCdWZmZXIuaXNCdWZmZXIoYikgPyBiLnRvU3RyaW5nKCdoZXgnLHMscytsKSA6IF9fX2hleGxpZnkoYixzLGwpOyB9O1xuXHRfX3RvQnVmZmVyID0gZnVuY3Rpb24oYnVmcykgeyByZXR1cm4gKGJ1ZnNbMF0ubGVuZ3RoID4gMCAmJiBCdWZmZXIuaXNCdWZmZXIoYnVmc1swXVswXSkpID8gQnVmZmVyLmNvbmNhdCgoYnVmc1swXSkpIDogX19fdG9CdWZmZXIoYnVmcyk7fTtcblx0czJhID0gZnVuY3Rpb24ocykgeyByZXR1cm4gQnVmZmVyX2Zyb20ocywgXCJiaW5hcnlcIik7IH07XG5cdGJjb25jYXQgPSBmdW5jdGlvbihidWZzKSB7IHJldHVybiBCdWZmZXIuaXNCdWZmZXIoYnVmc1swXSkgPyBCdWZmZXIuY29uY2F0KGJ1ZnMpIDogX19iY29uY2F0KGJ1ZnMpOyB9O1xufVxuXG5cbnZhciBfX3JlYWRVSW50OCA9IGZ1bmN0aW9uKGIsIGlkeCkgeyByZXR1cm4gYltpZHhdOyB9O1xudmFyIF9fcmVhZFVJbnQxNkxFID0gZnVuY3Rpb24oYiwgaWR4KSB7IHJldHVybiBiW2lkeCsxXSooMTw8OCkrYltpZHhdOyB9O1xudmFyIF9fcmVhZEludDE2TEUgPSBmdW5jdGlvbihiLCBpZHgpIHsgdmFyIHUgPSBiW2lkeCsxXSooMTw8OCkrYltpZHhdOyByZXR1cm4gKHUgPCAweDgwMDApID8gdSA6ICgweGZmZmYgLSB1ICsgMSkgKiAtMTsgfTtcbnZhciBfX3JlYWRVSW50MzJMRSA9IGZ1bmN0aW9uKGIsIGlkeCkgeyByZXR1cm4gYltpZHgrM10qKDE8PDI0KSsoYltpZHgrMl08PDE2KSsoYltpZHgrMV08PDgpK2JbaWR4XTsgfTtcbnZhciBfX3JlYWRJbnQzMkxFID0gZnVuY3Rpb24oYiwgaWR4KSB7IHJldHVybiAoYltpZHgrM108PDI0KSsoYltpZHgrMl08PDE2KSsoYltpZHgrMV08PDgpK2JbaWR4XTsgfTtcblxuZnVuY3Rpb24gUmVhZFNoaWZ0KHNpemUsIHQpIHtcblx0dmFyIG9JLCBvUywgdHlwZSA9IDA7XG5cdHN3aXRjaChzaXplKSB7XG5cdFx0Y2FzZSAxOiBvSSA9IF9fcmVhZFVJbnQ4KHRoaXMsIHRoaXMubCk7IGJyZWFrO1xuXHRcdGNhc2UgMjogb0kgPSAodCAhPT0gJ2knID8gX19yZWFkVUludDE2TEUgOiBfX3JlYWRJbnQxNkxFKSh0aGlzLCB0aGlzLmwpOyBicmVhaztcblx0XHRjYXNlIDQ6IG9JID0gX19yZWFkSW50MzJMRSh0aGlzLCB0aGlzLmwpOyBicmVhaztcblx0XHRjYXNlIDE2OiB0eXBlID0gMjsgb1MgPSBfX2hleGxpZnkodGhpcywgdGhpcy5sLCBzaXplKTtcblx0fVxuXHR0aGlzLmwgKz0gc2l6ZTsgaWYodHlwZSA9PT0gMCkgcmV0dXJuIG9JOyByZXR1cm4gb1M7XG59XG5cbnZhciBfX3dyaXRlVUludDMyTEUgPSBmdW5jdGlvbihiLCB2YWwsIGlkeCkgeyBiW2lkeF0gPSAodmFsICYgMHhGRik7IGJbaWR4KzFdID0gKCh2YWwgPj4+IDgpICYgMHhGRik7IGJbaWR4KzJdID0gKCh2YWwgPj4+IDE2KSAmIDB4RkYpOyBiW2lkeCszXSA9ICgodmFsID4+PiAyNCkgJiAweEZGKTsgfTtcbnZhciBfX3dyaXRlSW50MzJMRSAgPSBmdW5jdGlvbihiLCB2YWwsIGlkeCkgeyBiW2lkeF0gPSAodmFsICYgMHhGRik7IGJbaWR4KzFdID0gKCh2YWwgPj4gOCkgJiAweEZGKTsgYltpZHgrMl0gPSAoKHZhbCA+PiAxNikgJiAweEZGKTsgYltpZHgrM10gPSAoKHZhbCA+PiAyNCkgJiAweEZGKTsgfTtcblxuZnVuY3Rpb24gV3JpdGVTaGlmdCh0LCB2YWwsIGYpIHtcblx0dmFyIHNpemUgPSAwLCBpID0gMDtcblx0c3dpdGNoKGYpIHtcblx0XHRjYXNlIFwiaGV4XCI6IGZvcig7IGkgPCB0OyArK2kpIHtcbnRoaXNbdGhpcy5sKytdID0gcGFyc2VJbnQodmFsLnNsaWNlKDIqaSwgMippKzIpLCAxNil8fDA7XG5cdFx0fSByZXR1cm4gdGhpcztcblx0XHRjYXNlIFwidXRmMTZsZVwiOlxudmFyIGVuZCA9IHRoaXMubCArIHQ7XG5cdFx0XHRmb3IoaSA9IDA7IGkgPCBNYXRoLm1pbih2YWwubGVuZ3RoLCB0KTsgKytpKSB7XG5cdFx0XHRcdHZhciBjYyA9IHZhbC5jaGFyQ29kZUF0KGkpO1xuXHRcdFx0XHR0aGlzW3RoaXMubCsrXSA9IGNjICYgMHhmZjtcblx0XHRcdFx0dGhpc1t0aGlzLmwrK10gPSBjYyA+PiA4O1xuXHRcdFx0fVxuXHRcdFx0d2hpbGUodGhpcy5sIDwgZW5kKSB0aGlzW3RoaXMubCsrXSA9IDA7XG5cdFx0XHRyZXR1cm4gdGhpcztcblx0fVxuc3dpdGNoKHQpIHtcblx0XHRjYXNlICAxOiBzaXplID0gMTsgdGhpc1t0aGlzLmxdID0gdmFsJjB4RkY7IGJyZWFrO1xuXHRcdGNhc2UgIDI6IHNpemUgPSAyOyB0aGlzW3RoaXMubF0gPSB2YWwmMHhGRjsgdmFsID4+Pj0gODsgdGhpc1t0aGlzLmwrMV0gPSB2YWwmMHhGRjsgYnJlYWs7XG5cdFx0Y2FzZSAgNDogc2l6ZSA9IDQ7IF9fd3JpdGVVSW50MzJMRSh0aGlzLCB2YWwsIHRoaXMubCk7IGJyZWFrO1xuXHRcdGNhc2UgLTQ6IHNpemUgPSA0OyBfX3dyaXRlSW50MzJMRSh0aGlzLCB2YWwsIHRoaXMubCk7IGJyZWFrO1xuXHR9XG5cdHRoaXMubCArPSBzaXplOyByZXR1cm4gdGhpcztcbn1cblxuZnVuY3Rpb24gQ2hlY2tGaWVsZChoZXhzdHIsIGZsZCkge1xuXHR2YXIgbSA9IF9faGV4bGlmeSh0aGlzLHRoaXMubCxoZXhzdHIubGVuZ3RoPj4xKTtcblx0aWYobSAhPT0gaGV4c3RyKSB0aHJvdyBuZXcgRXJyb3IoZmxkICsgJ0V4cGVjdGVkICcgKyBoZXhzdHIgKyAnIHNhdyAnICsgbSk7XG5cdHRoaXMubCArPSBoZXhzdHIubGVuZ3RoPj4xO1xufVxuXG5mdW5jdGlvbiBwcmVwX2Jsb2IoYmxvYiwgcG9zKSB7XG5cdGJsb2IubCA9IHBvcztcblx0YmxvYi5yZWFkX3NoaWZ0ID0gUmVhZFNoaWZ0O1xuXHRibG9iLmNoayA9IENoZWNrRmllbGQ7XG5cdGJsb2Iud3JpdGVfc2hpZnQgPSBXcml0ZVNoaWZ0O1xufVxuXG5mdW5jdGlvbiBuZXdfYnVmKHN6KSB7XG5cdHZhciBvID0gKG5ld19yYXdfYnVmKHN6KSk7XG5cdHByZXBfYmxvYihvLCAwKTtcblx0cmV0dXJuIG87XG59XG5cbi8qIGNyYzMyLmpzIChDKSAyMDE0LXByZXNlbnQgU2hlZXRKUyAtLSBodHRwOi8vc2hlZXRqcy5jb20gKi9cbi8qIHZpbTogc2V0IHRzPTI6ICovXG4vKmV4cG9ydGVkIENSQzMyICovXG52YXIgQ1JDMzI7XG4oZnVuY3Rpb24gKGZhY3RvcnkpIHtcblx0Lypqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG5cdC8qZXNsaW50LWRpc2FibGUgKi9cblx0ZmFjdG9yeShDUkMzMiA9IHt9KTtcblx0Lyplc2xpbnQtZW5hYmxlICovXG5cdC8qanNoaW50IGlnbm9yZTplbmQgKi9cbn0oZnVuY3Rpb24oQ1JDMzIpIHtcbkNSQzMyLnZlcnNpb24gPSAnMS4yLjAnO1xuLyogc2VlIHBlcmYvY3JjMzJ0YWJsZS5qcyAqL1xuLypnbG9iYWwgSW50MzJBcnJheSAqL1xuZnVuY3Rpb24gc2lnbmVkX2NyY190YWJsZSgpIHtcblx0dmFyIGMgPSAwLCB0YWJsZSA9IG5ldyBBcnJheSgyNTYpO1xuXG5cdGZvcih2YXIgbiA9MDsgbiAhPSAyNTY7ICsrbil7XG5cdFx0YyA9IG47XG5cdFx0YyA9ICgoYyYxKSA/ICgtMzA2Njc0OTEyIF4gKGMgPj4+IDEpKSA6IChjID4+PiAxKSk7XG5cdFx0YyA9ICgoYyYxKSA/ICgtMzA2Njc0OTEyIF4gKGMgPj4+IDEpKSA6IChjID4+PiAxKSk7XG5cdFx0YyA9ICgoYyYxKSA/ICgtMzA2Njc0OTEyIF4gKGMgPj4+IDEpKSA6IChjID4+PiAxKSk7XG5cdFx0YyA9ICgoYyYxKSA/ICgtMzA2Njc0OTEyIF4gKGMgPj4+IDEpKSA6IChjID4+PiAxKSk7XG5cdFx0YyA9ICgoYyYxKSA/ICgtMzA2Njc0OTEyIF4gKGMgPj4+IDEpKSA6IChjID4+PiAxKSk7XG5cdFx0YyA9ICgoYyYxKSA/ICgtMzA2Njc0OTEyIF4gKGMgPj4+IDEpKSA6IChjID4+PiAxKSk7XG5cdFx0YyA9ICgoYyYxKSA/ICgtMzA2Njc0OTEyIF4gKGMgPj4+IDEpKSA6IChjID4+PiAxKSk7XG5cdFx0YyA9ICgoYyYxKSA/ICgtMzA2Njc0OTEyIF4gKGMgPj4+IDEpKSA6IChjID4+PiAxKSk7XG5cdFx0dGFibGVbbl0gPSBjO1xuXHR9XG5cblx0cmV0dXJuIHR5cGVvZiBJbnQzMkFycmF5ICE9PSAndW5kZWZpbmVkJyA/IG5ldyBJbnQzMkFycmF5KHRhYmxlKSA6IHRhYmxlO1xufVxuXG52YXIgVCA9IHNpZ25lZF9jcmNfdGFibGUoKTtcbmZ1bmN0aW9uIGNyYzMyX2JzdHIoYnN0ciwgc2VlZCkge1xuXHR2YXIgQyA9IHNlZWQgXiAtMSwgTCA9IGJzdHIubGVuZ3RoIC0gMTtcblx0Zm9yKHZhciBpID0gMDsgaSA8IEw7KSB7XG5cdFx0QyA9IChDPj4+OCkgXiBUWyhDXmJzdHIuY2hhckNvZGVBdChpKyspKSYweEZGXTtcblx0XHRDID0gKEM+Pj44KSBeIFRbKENeYnN0ci5jaGFyQ29kZUF0KGkrKykpJjB4RkZdO1xuXHR9XG5cdGlmKGkgPT09IEwpIEMgPSAoQz4+PjgpIF4gVFsoQyBeIGJzdHIuY2hhckNvZGVBdChpKSkmMHhGRl07XG5cdHJldHVybiBDIF4gLTE7XG59XG5cbmZ1bmN0aW9uIGNyYzMyX2J1ZihidWYsIHNlZWQpIHtcblx0aWYoYnVmLmxlbmd0aCA+IDEwMDAwKSByZXR1cm4gY3JjMzJfYnVmXzgoYnVmLCBzZWVkKTtcblx0dmFyIEMgPSBzZWVkIF4gLTEsIEwgPSBidWYubGVuZ3RoIC0gMztcblx0Zm9yKHZhciBpID0gMDsgaSA8IEw7KSB7XG5cdFx0QyA9IChDPj4+OCkgXiBUWyhDXmJ1ZltpKytdKSYweEZGXTtcblx0XHRDID0gKEM+Pj44KSBeIFRbKENeYnVmW2krK10pJjB4RkZdO1xuXHRcdEMgPSAoQz4+PjgpIF4gVFsoQ15idWZbaSsrXSkmMHhGRl07XG5cdFx0QyA9IChDPj4+OCkgXiBUWyhDXmJ1ZltpKytdKSYweEZGXTtcblx0fVxuXHR3aGlsZShpIDwgTCszKSBDID0gKEM+Pj44KSBeIFRbKENeYnVmW2krK10pJjB4RkZdO1xuXHRyZXR1cm4gQyBeIC0xO1xufVxuXG5mdW5jdGlvbiBjcmMzMl9idWZfOChidWYsIHNlZWQpIHtcblx0dmFyIEMgPSBzZWVkIF4gLTEsIEwgPSBidWYubGVuZ3RoIC0gNztcblx0Zm9yKHZhciBpID0gMDsgaSA8IEw7KSB7XG5cdFx0QyA9IChDPj4+OCkgXiBUWyhDXmJ1ZltpKytdKSYweEZGXTtcblx0XHRDID0gKEM+Pj44KSBeIFRbKENeYnVmW2krK10pJjB4RkZdO1xuXHRcdEMgPSAoQz4+PjgpIF4gVFsoQ15idWZbaSsrXSkmMHhGRl07XG5cdFx0QyA9IChDPj4+OCkgXiBUWyhDXmJ1ZltpKytdKSYweEZGXTtcblx0XHRDID0gKEM+Pj44KSBeIFRbKENeYnVmW2krK10pJjB4RkZdO1xuXHRcdEMgPSAoQz4+PjgpIF4gVFsoQ15idWZbaSsrXSkmMHhGRl07XG5cdFx0QyA9IChDPj4+OCkgXiBUWyhDXmJ1ZltpKytdKSYweEZGXTtcblx0XHRDID0gKEM+Pj44KSBeIFRbKENeYnVmW2krK10pJjB4RkZdO1xuXHR9XG5cdHdoaWxlKGkgPCBMKzcpIEMgPSAoQz4+PjgpIF4gVFsoQ15idWZbaSsrXSkmMHhGRl07XG5cdHJldHVybiBDIF4gLTE7XG59XG5cbmZ1bmN0aW9uIGNyYzMyX3N0cihzdHIsIHNlZWQpIHtcblx0dmFyIEMgPSBzZWVkIF4gLTE7XG5cdGZvcih2YXIgaSA9IDAsIEw9c3RyLmxlbmd0aCwgYywgZDsgaSA8IEw7KSB7XG5cdFx0YyA9IHN0ci5jaGFyQ29kZUF0KGkrKyk7XG5cdFx0aWYoYyA8IDB4ODApIHtcblx0XHRcdEMgPSAoQz4+PjgpIF4gVFsoQyBeIGMpJjB4RkZdO1xuXHRcdH0gZWxzZSBpZihjIDwgMHg4MDApIHtcblx0XHRcdEMgPSAoQz4+PjgpIF4gVFsoQyBeICgxOTJ8KChjPj42KSYzMSkpKSYweEZGXTtcblx0XHRcdEMgPSAoQz4+PjgpIF4gVFsoQyBeICgxMjh8KGMmNjMpKSkmMHhGRl07XG5cdFx0fSBlbHNlIGlmKGMgPj0gMHhEODAwICYmIGMgPCAweEUwMDApIHtcblx0XHRcdGMgPSAoYyYxMDIzKSs2NDsgZCA9IHN0ci5jaGFyQ29kZUF0KGkrKykmMTAyMztcblx0XHRcdEMgPSAoQz4+PjgpIF4gVFsoQyBeICgyNDB8KChjPj44KSY3KSkpJjB4RkZdO1xuXHRcdFx0QyA9IChDPj4+OCkgXiBUWyhDIF4gKDEyOHwoKGM+PjIpJjYzKSkpJjB4RkZdO1xuXHRcdFx0QyA9IChDPj4+OCkgXiBUWyhDIF4gKDEyOHwoKGQ+PjYpJjE1KXwoKGMmMyk8PDQpKSkmMHhGRl07XG5cdFx0XHRDID0gKEM+Pj44KSBeIFRbKEMgXiAoMTI4fChkJjYzKSkpJjB4RkZdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRDID0gKEM+Pj44KSBeIFRbKEMgXiAoMjI0fCgoYz4+MTIpJjE1KSkpJjB4RkZdO1xuXHRcdFx0QyA9IChDPj4+OCkgXiBUWyhDIF4gKDEyOHwoKGM+PjYpJjYzKSkpJjB4RkZdO1xuXHRcdFx0QyA9IChDPj4+OCkgXiBUWyhDIF4gKDEyOHwoYyY2MykpKSYweEZGXTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIEMgXiAtMTtcbn1cbkNSQzMyLnRhYmxlID0gVDtcbkNSQzMyLmJzdHIgPSBjcmMzMl9ic3RyO1xuQ1JDMzIuYnVmID0gY3JjMzJfYnVmO1xuQ1JDMzIuc3RyID0gY3JjMzJfc3RyO1xufSkpO1xuLyogW01TLUNGQl0gdjIwMTcxMjAxICovXG52YXIgQ0ZCID0gKGZ1bmN0aW9uIF9DRkIoKXtcbnZhciBleHBvcnRzID0ge307XG5leHBvcnRzLnZlcnNpb24gPSAnMS4xLjAnO1xuLyogW01TLUNGQl0gMi42LjQgKi9cbmZ1bmN0aW9uIG5hbWVjbXAobCwgcikge1xuXHR2YXIgTCA9IGwuc3BsaXQoXCIvXCIpLCBSID0gci5zcGxpdChcIi9cIik7XG5cdGZvcih2YXIgaSA9IDAsIGMgPSAwLCBaID0gTWF0aC5taW4oTC5sZW5ndGgsIFIubGVuZ3RoKTsgaSA8IFo7ICsraSkge1xuXHRcdGlmKChjID0gTFtpXS5sZW5ndGggLSBSW2ldLmxlbmd0aCkpIHJldHVybiBjO1xuXHRcdGlmKExbaV0gIT0gUltpXSkgcmV0dXJuIExbaV0gPCBSW2ldID8gLTEgOiAxO1xuXHR9XG5cdHJldHVybiBMLmxlbmd0aCAtIFIubGVuZ3RoO1xufVxuZnVuY3Rpb24gZGlybmFtZShwKSB7XG5cdGlmKHAuY2hhckF0KHAubGVuZ3RoIC0gMSkgPT0gXCIvXCIpIHJldHVybiAocC5zbGljZSgwLC0xKS5pbmRleE9mKFwiL1wiKSA9PT0gLTEpID8gcCA6IGRpcm5hbWUocC5zbGljZSgwLCAtMSkpO1xuXHR2YXIgYyA9IHAubGFzdEluZGV4T2YoXCIvXCIpO1xuXHRyZXR1cm4gKGMgPT09IC0xKSA/IHAgOiBwLnNsaWNlKDAsIGMrMSk7XG59XG5cbmZ1bmN0aW9uIGZpbGVuYW1lKHApIHtcblx0aWYocC5jaGFyQXQocC5sZW5ndGggLSAxKSA9PSBcIi9cIikgcmV0dXJuIGZpbGVuYW1lKHAuc2xpY2UoMCwgLTEpKTtcblx0dmFyIGMgPSBwLmxhc3RJbmRleE9mKFwiL1wiKTtcblx0cmV0dXJuIChjID09PSAtMSkgPyBwIDogcC5zbGljZShjKzEpO1xufVxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbi8qIERPUyBEYXRlIGZvcm1hdDpcbiAgIGhpZ2h8WVlZWVlZWW0ubW1tZGRkZGQuSEhISEhNTU0uTU1NU1NTU1N8bG93XG4gICBhZGQgMTk4MCB0byBzdG9yZWQgeWVhclxuICAgc3RvcmVkIHNlY29uZCBzaG91bGQgYmUgZG91YmxlZFxuKi9cblxuLyogd3JpdGUgSlMgZGF0ZSB0byBidWYgYXMgYSBET1MgZGF0ZSAqL1xuZnVuY3Rpb24gd3JpdGVfZG9zX2RhdGUoYnVmLCBkYXRlKSB7XG5cdGlmKHR5cGVvZiBkYXRlID09PSBcInN0cmluZ1wiKSBkYXRlID0gbmV3IERhdGUoZGF0ZSk7XG5cdHZhciBobXMgPSBkYXRlLmdldEhvdXJzKCk7XG5cdGhtcyA9IGhtcyA8PCA2IHwgZGF0ZS5nZXRNaW51dGVzKCk7XG5cdGhtcyA9IGhtcyA8PCA1IHwgKGRhdGUuZ2V0U2Vjb25kcygpPj4+MSk7XG5cdGJ1Zi53cml0ZV9zaGlmdCgyLCBobXMpO1xuXHR2YXIgeW1kID0gKGRhdGUuZ2V0RnVsbFllYXIoKSAtIDE5ODApO1xuXHR5bWQgPSB5bWQgPDwgNCB8IChkYXRlLmdldE1vbnRoKCkrMSk7XG5cdHltZCA9IHltZCA8PCA1IHwgZGF0ZS5nZXREYXRlKCk7XG5cdGJ1Zi53cml0ZV9zaGlmdCgyLCB5bWQpO1xufVxuXG4vKiByZWFkIGZvdXIgYnl0ZXMgZnJvbSBidWYgYW5kIGludGVycHJldCBhcyBhIERPUyBkYXRlICovXG5mdW5jdGlvbiBwYXJzZV9kb3NfZGF0ZShidWYpIHtcblx0dmFyIGhtcyA9IGJ1Zi5yZWFkX3NoaWZ0KDIpICYgMHhGRkZGO1xuXHR2YXIgeW1kID0gYnVmLnJlYWRfc2hpZnQoMikgJiAweEZGRkY7XG5cdHZhciB2YWwgPSBuZXcgRGF0ZSgpO1xuXHR2YXIgZCA9IHltZCAmIDB4MUY7IHltZCA+Pj49IDU7XG5cdHZhciBtID0geW1kICYgMHgwRjsgeW1kID4+Pj0gNDtcblx0dmFsLnNldE1pbGxpc2Vjb25kcygwKTtcblx0dmFsLnNldEZ1bGxZZWFyKHltZCArIDE5ODApO1xuXHR2YWwuc2V0TW9udGgobS0xKTtcblx0dmFsLnNldERhdGUoZCk7XG5cdHZhciBTID0gaG1zICYgMHgxRjsgaG1zID4+Pj0gNTtcblx0dmFyIE0gPSBobXMgJiAweDNGOyBobXMgPj4+PSA2O1xuXHR2YWwuc2V0SG91cnMoaG1zKTtcblx0dmFsLnNldE1pbnV0ZXMoTSk7XG5cdHZhbC5zZXRTZWNvbmRzKFM8PDEpO1xuXHRyZXR1cm4gdmFsO1xufVxuZnVuY3Rpb24gcGFyc2VfZXh0cmFfZmllbGQoYmxvYikge1xuXHRwcmVwX2Jsb2IoYmxvYiwgMCk7XG5cdHZhciBvID0ge307XG5cdHZhciBmbGFncyA9IDA7XG5cdHdoaWxlKGJsb2IubCA8PSBibG9iLmxlbmd0aCAtIDQpIHtcblx0XHR2YXIgdHlwZSA9IGJsb2IucmVhZF9zaGlmdCgyKTtcblx0XHR2YXIgc3ogPSBibG9iLnJlYWRfc2hpZnQoMiksIHRndCA9IGJsb2IubCArIHN6O1xuXHRcdHZhciBwID0ge307XG5cdFx0c3dpdGNoKHR5cGUpIHtcblx0XHRcdC8qIFVOSVgtc3R5bGUgVGltZXN0YW1wcyAqL1xuXHRcdFx0Y2FzZSAweDU0NTU6IHtcblx0XHRcdFx0ZmxhZ3MgPSBibG9iLnJlYWRfc2hpZnQoMSk7XG5cdFx0XHRcdGlmKGZsYWdzICYgMSkgcC5tdGltZSA9IGJsb2IucmVhZF9zaGlmdCg0KTtcblx0XHRcdFx0LyogZm9yIHNvbWUgcmVhc29uLCBDRCBmbGFnIGNvcnJlc3BvbmRzIHRvIExGSCAqL1xuXHRcdFx0XHRpZihzeiA+IDUpIHtcblx0XHRcdFx0XHRpZihmbGFncyAmIDIpIHAuYXRpbWUgPSBibG9iLnJlYWRfc2hpZnQoNCk7XG5cdFx0XHRcdFx0aWYoZmxhZ3MgJiA0KSBwLmN0aW1lID0gYmxvYi5yZWFkX3NoaWZ0KDQpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmKHAubXRpbWUpIHAubXQgPSBuZXcgRGF0ZShwLm10aW1lKjEwMDApO1xuXHRcdFx0fVxuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXHRcdGJsb2IubCA9IHRndDtcblx0XHRvW3R5cGVdID0gcDtcblx0fVxuXHRyZXR1cm4gbztcbn1cbnZhciBmcztcbmZ1bmN0aW9uIGdldF9mcygpIHsgcmV0dXJuIGZzIHx8IChmcyA9IHJlcXVpcmUoJ2ZzJykpOyB9XG5mdW5jdGlvbiBwYXJzZShmaWxlLCBvcHRpb25zKSB7XG5pZihmaWxlWzBdID09IDB4NTAgJiYgZmlsZVsxXSA9PSAweDRiKSByZXR1cm4gcGFyc2VfemlwKGZpbGUsIG9wdGlvbnMpO1xuaWYoZmlsZS5sZW5ndGggPCA1MTIpIHRocm93IG5ldyBFcnJvcihcIkNGQiBmaWxlIHNpemUgXCIgKyBmaWxlLmxlbmd0aCArIFwiIDwgNTEyXCIpO1xudmFyIG12ZXIgPSAzO1xudmFyIHNzeiA9IDUxMjtcbnZhciBubWZzID0gMDsgLy8gbnVtYmVyIG9mIG1pbmkgRkFUIHNlY3RvcnNcbnZhciBkaWZhdF9zZWNfY250ID0gMDtcbnZhciBkaXJfc3RhcnQgPSAwO1xudmFyIG1pbmlmYXRfc3RhcnQgPSAwO1xudmFyIGRpZmF0X3N0YXJ0ID0gMDtcblxudmFyIGZhdF9hZGRycyA9IFtdOyAvLyBsb2NhdGlvbnMgb2YgRkFUIHNlY3RvcnNcblxuLyogW01TLUNGQl0gMi4yIENvbXBvdW5kIEZpbGUgSGVhZGVyICovXG52YXIgYmxvYiA9IGZpbGUuc2xpY2UoMCw1MTIpO1xucHJlcF9ibG9iKGJsb2IsIDApO1xuXG4vKiBtYWpvciB2ZXJzaW9uICovXG52YXIgbXYgPSBjaGVja19nZXRfbXZlcihibG9iKTtcbm12ZXIgPSBtdlswXTtcbnN3aXRjaChtdmVyKSB7XG5cdGNhc2UgMzogc3N6ID0gNTEyOyBicmVhazsgY2FzZSA0OiBzc3ogPSA0MDk2OyBicmVhaztcblx0Y2FzZSAwOiBpZihtdlsxXSA9PSAwKSByZXR1cm4gcGFyc2VfemlwKGZpbGUsIG9wdGlvbnMpO1xuXHQvKiBmYWxscyB0aHJvdWdoICovXG5cdGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcihcIk1ham9yIFZlcnNpb246IEV4cGVjdGVkIDMgb3IgNCBzYXcgXCIgKyBtdmVyKTtcbn1cblxuLyogcmVwcm9jZXNzIGhlYWRlciAqL1xuaWYoc3N6ICE9PSA1MTIpIHsgYmxvYiA9IGZpbGUuc2xpY2UoMCxzc3opOyBwcmVwX2Jsb2IoYmxvYiwgMjggLyogYmxvYi5sICovKTsgfVxuLyogU2F2ZSBoZWFkZXIgZm9yIGZpbmFsIG9iamVjdCAqL1xudmFyIGhlYWRlciA9IGZpbGUuc2xpY2UoMCxzc3opO1xuXG5jaGVja19zaGlmdHMoYmxvYiwgbXZlcik7XG5cbi8vIE51bWJlciBvZiBEaXJlY3RvcnkgU2VjdG9yc1xudmFyIGRpcl9jbnQgPSBibG9iLnJlYWRfc2hpZnQoNCwgJ2knKTtcbmlmKG12ZXIgPT09IDMgJiYgZGlyX2NudCAhPT0gMCkgdGhyb3cgbmV3IEVycm9yKCcjIERpcmVjdG9yeSBTZWN0b3JzOiBFeHBlY3RlZCAwIHNhdyAnICsgZGlyX2NudCk7XG5cbi8vIE51bWJlciBvZiBGQVQgU2VjdG9yc1xuYmxvYi5sICs9IDQ7XG5cbi8vIEZpcnN0IERpcmVjdG9yeSBTZWN0b3IgTG9jYXRpb25cbmRpcl9zdGFydCA9IGJsb2IucmVhZF9zaGlmdCg0LCAnaScpO1xuXG4vLyBUcmFuc2FjdGlvbiBTaWduYXR1cmVcbmJsb2IubCArPSA0O1xuXG4vLyBNaW5pIFN0cmVhbSBDdXRvZmYgU2l6ZVxuYmxvYi5jaGsoJzAwMTAwMDAwJywgJ01pbmkgU3RyZWFtIEN1dG9mZiBTaXplOiAnKTtcblxuLy8gRmlyc3QgTWluaSBGQVQgU2VjdG9yIExvY2F0aW9uXG5taW5pZmF0X3N0YXJ0ID0gYmxvYi5yZWFkX3NoaWZ0KDQsICdpJyk7XG5cbi8vIE51bWJlciBvZiBNaW5pIEZBVCBTZWN0b3JzXG5ubWZzID0gYmxvYi5yZWFkX3NoaWZ0KDQsICdpJyk7XG5cbi8vIEZpcnN0IERJRkFUIHNlY3RvciBsb2NhdGlvblxuZGlmYXRfc3RhcnQgPSBibG9iLnJlYWRfc2hpZnQoNCwgJ2knKTtcblxuLy8gTnVtYmVyIG9mIERJRkFUIFNlY3RvcnNcbmRpZmF0X3NlY19jbnQgPSBibG9iLnJlYWRfc2hpZnQoNCwgJ2knKTtcblxuLy8gR3JhYiBGQVQgU2VjdG9yIExvY2F0aW9uc1xuZm9yKHZhciBxID0gLTEsIGogPSAwOyBqIDwgMTA5OyArK2opIHsgLyogMTA5ID0gKDUxMiAtIGJsb2IubCk+Pj4yOyAqL1xuXHRxID0gYmxvYi5yZWFkX3NoaWZ0KDQsICdpJyk7XG5cdGlmKHE8MCkgYnJlYWs7XG5cdGZhdF9hZGRyc1tqXSA9IHE7XG59XG5cbi8qKiBCcmVhayB0aGUgZmlsZSB1cCBpbnRvIHNlY3RvcnMgKi9cbnZhciBzZWN0b3JzID0gc2VjdG9yaWZ5KGZpbGUsIHNzeik7XG5cbnNsZXV0aF9mYXQoZGlmYXRfc3RhcnQsIGRpZmF0X3NlY19jbnQsIHNlY3RvcnMsIHNzeiwgZmF0X2FkZHJzKTtcblxuLyoqIENoYWlucyAqL1xudmFyIHNlY3Rvcl9saXN0ID0gbWFrZV9zZWN0b3JfbGlzdChzZWN0b3JzLCBkaXJfc3RhcnQsIGZhdF9hZGRycywgc3N6KTtcblxuc2VjdG9yX2xpc3RbZGlyX3N0YXJ0XS5uYW1lID0gXCIhRGlyZWN0b3J5XCI7XG5pZihubWZzID4gMCAmJiBtaW5pZmF0X3N0YXJ0ICE9PSBFTkRPRkNIQUlOKSBzZWN0b3JfbGlzdFttaW5pZmF0X3N0YXJ0XS5uYW1lID0gXCIhTWluaUZBVFwiO1xuc2VjdG9yX2xpc3RbZmF0X2FkZHJzWzBdXS5uYW1lID0gXCIhRkFUXCI7XG5zZWN0b3JfbGlzdC5mYXRfYWRkcnMgPSBmYXRfYWRkcnM7XG5zZWN0b3JfbGlzdC5zc3ogPSBzc3o7XG5cbi8qIFtNUy1DRkJdIDIuNi4xIENvbXBvdW5kIEZpbGUgRGlyZWN0b3J5IEVudHJ5ICovXG52YXIgZmlsZXMgPSB7fSwgUGF0aHMgPSBbXSwgRmlsZUluZGV4ID0gW10sIEZ1bGxQYXRocyA9IFtdO1xucmVhZF9kaXJlY3RvcnkoZGlyX3N0YXJ0LCBzZWN0b3JfbGlzdCwgc2VjdG9ycywgUGF0aHMsIG5tZnMsIGZpbGVzLCBGaWxlSW5kZXgsIG1pbmlmYXRfc3RhcnQpO1xuXG5idWlsZF9mdWxsX3BhdGhzKEZpbGVJbmRleCwgRnVsbFBhdGhzLCBQYXRocyk7XG5QYXRocy5zaGlmdCgpO1xuXG52YXIgbyA9IHtcblx0RmlsZUluZGV4OiBGaWxlSW5kZXgsXG5cdEZ1bGxQYXRoczogRnVsbFBhdGhzXG59O1xuXG4vLyAkRmxvd0lnbm9yZVxuaWYob3B0aW9ucyAmJiBvcHRpb25zLnJhdykgby5yYXcgPSB7aGVhZGVyOiBoZWFkZXIsIHNlY3RvcnM6IHNlY3RvcnN9O1xucmV0dXJuIG87XG59IC8vIHBhcnNlXG5cbi8qIFtNUy1DRkJdIDIuMiBDb21wb3VuZCBGaWxlIEhlYWRlciAtLSByZWFkIHVwIHRvIG1ham9yIHZlcnNpb24gKi9cbmZ1bmN0aW9uIGNoZWNrX2dldF9tdmVyKGJsb2IpIHtcblx0aWYoYmxvYltibG9iLmxdID09IDB4NTAgJiYgYmxvYltibG9iLmwgKyAxXSA9PSAweDRiKSByZXR1cm4gWzAsIDBdO1xuXHQvLyBoZWFkZXIgc2lnbmF0dXJlIDhcblx0YmxvYi5jaGsoSEVBREVSX1NJR05BVFVSRSwgJ0hlYWRlciBTaWduYXR1cmU6ICcpO1xuXG5cdC8vIGNsc2lkIDE2XG5cdGJsb2IuY2hrKEhFQURFUl9DTFNJRCwgJ0NMU0lEOiAnKTtcblxuXHQvLyBtaW5vciB2ZXJzaW9uIDJcblx0dmFyIG12ZXIgPSBibG9iLnJlYWRfc2hpZnQoMiwgJ3UnKTtcblxuXHRyZXR1cm4gW2Jsb2IucmVhZF9zaGlmdCgyLCd1JyksIG12ZXJdO1xufVxuZnVuY3Rpb24gY2hlY2tfc2hpZnRzKGJsb2IsIG12ZXIpIHtcblx0dmFyIHNoaWZ0ID0gMHgwOTtcblxuXHQvLyBCeXRlIE9yZGVyXG5cdC8vYmxvYi5jaGsoJ2ZlZmYnLCAnQnl0ZSBPcmRlcjogJyk7IC8vIG5vdGU6IHNvbWUgd3JpdGVycyBwdXQgMHhmZmZmXG5cdGJsb2IubCArPSAyO1xuXG5cdC8vIFNlY3RvciBTaGlmdFxuXHRzd2l0Y2goKHNoaWZ0ID0gYmxvYi5yZWFkX3NoaWZ0KDIpKSkge1xuXHRcdGNhc2UgMHgwOTogaWYobXZlciAhPSAzKSB0aHJvdyBuZXcgRXJyb3IoJ1NlY3RvciBTaGlmdDogRXhwZWN0ZWQgOSBzYXcgJyArIHNoaWZ0KTsgYnJlYWs7XG5cdFx0Y2FzZSAweDBjOiBpZihtdmVyICE9IDQpIHRocm93IG5ldyBFcnJvcignU2VjdG9yIFNoaWZ0OiBFeHBlY3RlZCAxMiBzYXcgJyArIHNoaWZ0KTsgYnJlYWs7XG5cdFx0ZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCdTZWN0b3IgU2hpZnQ6IEV4cGVjdGVkIDkgb3IgMTIgc2F3ICcgKyBzaGlmdCk7XG5cdH1cblxuXHQvLyBNaW5pIFNlY3RvciBTaGlmdFxuXHRibG9iLmNoaygnMDYwMCcsICdNaW5pIFNlY3RvciBTaGlmdDogJyk7XG5cblx0Ly8gUmVzZXJ2ZWRcblx0YmxvYi5jaGsoJzAwMDAwMDAwMDAwMCcsICdSZXNlcnZlZDogJyk7XG59XG5cbi8qKiBCcmVhayB0aGUgZmlsZSB1cCBpbnRvIHNlY3RvcnMgKi9cbmZ1bmN0aW9uIHNlY3RvcmlmeShmaWxlLCBzc3opIHtcblx0dmFyIG5zZWN0b3JzID0gTWF0aC5jZWlsKGZpbGUubGVuZ3RoL3NzeiktMTtcblx0dmFyIHNlY3RvcnMgPSBbXTtcblx0Zm9yKHZhciBpPTE7IGkgPCBuc2VjdG9yczsgKytpKSBzZWN0b3JzW2ktMV0gPSBmaWxlLnNsaWNlKGkqc3N6LChpKzEpKnNzeik7XG5cdHNlY3RvcnNbbnNlY3RvcnMtMV0gPSBmaWxlLnNsaWNlKG5zZWN0b3JzKnNzeik7XG5cdHJldHVybiBzZWN0b3JzO1xufVxuXG4vKiBbTVMtQ0ZCXSAyLjYuNCBSZWQtQmxhY2sgVHJlZSAqL1xuZnVuY3Rpb24gYnVpbGRfZnVsbF9wYXRocyhGSSwgRlAsIFBhdGhzKSB7XG5cdHZhciBpID0gMCwgTCA9IDAsIFIgPSAwLCBDID0gMCwgaiA9IDAsIHBsID0gUGF0aHMubGVuZ3RoO1xuXHR2YXIgZGFkID0gW10sIHEgPSBbXTtcblxuXHRmb3IoOyBpIDwgcGw7ICsraSkgeyBkYWRbaV09cVtpXT1pOyBGUFtpXT1QYXRoc1tpXTsgfVxuXG5cdGZvcig7IGogPCBxLmxlbmd0aDsgKytqKSB7XG5cdFx0aSA9IHFbal07XG5cdFx0TCA9IEZJW2ldLkw7IFIgPSBGSVtpXS5SOyBDID0gRklbaV0uQztcblx0XHRpZihkYWRbaV0gPT09IGkpIHtcblx0XHRcdGlmKEwgIT09IC0xIC8qTk9TVFJFQU0qLyAmJiBkYWRbTF0gIT09IEwpIGRhZFtpXSA9IGRhZFtMXTtcblx0XHRcdGlmKFIgIT09IC0xICYmIGRhZFtSXSAhPT0gUikgZGFkW2ldID0gZGFkW1JdO1xuXHRcdH1cblx0XHRpZihDICE9PSAtMSAvKk5PU1RSRUFNKi8pIGRhZFtDXSA9IGk7XG5cdFx0aWYoTCAhPT0gLTEpIHsgZGFkW0xdID0gZGFkW2ldOyBpZihxLmxhc3RJbmRleE9mKEwpIDwgaikgcS5wdXNoKEwpOyB9XG5cdFx0aWYoUiAhPT0gLTEpIHsgZGFkW1JdID0gZGFkW2ldOyBpZihxLmxhc3RJbmRleE9mKFIpIDwgaikgcS5wdXNoKFIpOyB9XG5cdH1cblx0Zm9yKGk9MTsgaSA8IHBsOyArK2kpIGlmKGRhZFtpXSA9PT0gaSkge1xuXHRcdGlmKFIgIT09IC0xIC8qTk9TVFJFQU0qLyAmJiBkYWRbUl0gIT09IFIpIGRhZFtpXSA9IGRhZFtSXTtcblx0XHRlbHNlIGlmKEwgIT09IC0xICYmIGRhZFtMXSAhPT0gTCkgZGFkW2ldID0gZGFkW0xdO1xuXHR9XG5cblx0Zm9yKGk9MTsgaSA8IHBsOyArK2kpIHtcblx0XHRpZihGSVtpXS50eXBlID09PSAwIC8qIHVua25vd24gKi8pIGNvbnRpbnVlO1xuXHRcdGogPSBkYWRbaV07XG5cdFx0aWYoaiA9PT0gMCkgRlBbaV0gPSBGUFswXSArIFwiL1wiICsgRlBbaV07XG5cdFx0ZWxzZSB3aGlsZShqICE9PSAwICYmIGogIT09IGRhZFtqXSkge1xuXHRcdFx0RlBbaV0gPSBGUFtqXSArIFwiL1wiICsgRlBbaV07XG5cdFx0XHRqID0gZGFkW2pdO1xuXHRcdH1cblx0XHRkYWRbaV0gPSAwO1xuXHR9XG5cblx0RlBbMF0gKz0gXCIvXCI7XG5cdGZvcihpPTE7IGkgPCBwbDsgKytpKSB7XG5cdFx0aWYoRklbaV0udHlwZSAhPT0gMiAvKiBzdHJlYW0gKi8pIEZQW2ldICs9IFwiL1wiO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGdldF9tZmF0X2VudHJ5KGVudHJ5LCBwYXlsb2FkLCBtaW5pKSB7XG5cdHZhciBzdGFydCA9IGVudHJ5LnN0YXJ0LCBzaXplID0gZW50cnkuc2l6ZTtcblx0Ly9yZXR1cm4gKHBheWxvYWQuc2xpY2Uoc3RhcnQqTVNTWiwgc3RhcnQqTVNTWiArIHNpemUpKTtcblx0dmFyIG8gPSBbXTtcblx0dmFyIGlkeCA9IHN0YXJ0O1xuXHR3aGlsZShtaW5pICYmIHNpemUgPiAwICYmIGlkeCA+PSAwKSB7XG5cdFx0by5wdXNoKHBheWxvYWQuc2xpY2UoaWR4ICogTVNTWiwgaWR4ICogTVNTWiArIE1TU1opKTtcblx0XHRzaXplIC09IE1TU1o7XG5cdFx0aWR4ID0gX19yZWFkSW50MzJMRShtaW5pLCBpZHggKiA0KTtcblx0fVxuXHRpZihvLmxlbmd0aCA9PT0gMCkgcmV0dXJuIChuZXdfYnVmKDApKTtcblx0cmV0dXJuIChiY29uY2F0KG8pLnNsaWNlKDAsIGVudHJ5LnNpemUpKTtcbn1cblxuLyoqIENoYXNlIGRvd24gdGhlIHJlc3Qgb2YgdGhlIERJRkFUIGNoYWluIHRvIGJ1aWxkIGEgY29tcHJlaGVuc2l2ZSBsaXN0XG4gICAgRElGQVQgY2hhaW5zIGJ5IHN0b3JpbmcgdGhlIG5leHQgc2VjdG9yIG51bWJlciBhcyB0aGUgbGFzdCAzMiBiaXRzICovXG5mdW5jdGlvbiBzbGV1dGhfZmF0KGlkeCwgY250LCBzZWN0b3JzLCBzc3osIGZhdF9hZGRycykge1xuXHR2YXIgcSA9IEVORE9GQ0hBSU47XG5cdGlmKGlkeCA9PT0gRU5ET0ZDSEFJTikge1xuXHRcdGlmKGNudCAhPT0gMCkgdGhyb3cgbmV3IEVycm9yKFwiRElGQVQgY2hhaW4gc2hvcnRlciB0aGFuIGV4cGVjdGVkXCIpO1xuXHR9IGVsc2UgaWYoaWR4ICE9PSAtMSAvKkZSRUVTRUNUKi8pIHtcblx0XHR2YXIgc2VjdG9yID0gc2VjdG9yc1tpZHhdLCBtID0gKHNzej4+PjIpLTE7XG5cdFx0aWYoIXNlY3RvcikgcmV0dXJuO1xuXHRcdGZvcih2YXIgaSA9IDA7IGkgPCBtOyArK2kpIHtcblx0XHRcdGlmKChxID0gX19yZWFkSW50MzJMRShzZWN0b3IsaSo0KSkgPT09IEVORE9GQ0hBSU4pIGJyZWFrO1xuXHRcdFx0ZmF0X2FkZHJzLnB1c2gocSk7XG5cdFx0fVxuXHRcdHNsZXV0aF9mYXQoX19yZWFkSW50MzJMRShzZWN0b3Isc3N6LTQpLGNudCAtIDEsIHNlY3RvcnMsIHNzeiwgZmF0X2FkZHJzKTtcblx0fVxufVxuXG4vKiogRm9sbG93IHRoZSBsaW5rZWQgbGlzdCBvZiBzZWN0b3JzIGZvciBhIGdpdmVuIHN0YXJ0aW5nIHBvaW50ICovXG5mdW5jdGlvbiBnZXRfc2VjdG9yX2xpc3Qoc2VjdG9ycywgc3RhcnQsIGZhdF9hZGRycywgc3N6LCBjaGtkKSB7XG5cdHZhciBidWYgPSBbXSwgYnVmX2NoYWluID0gW107XG5cdGlmKCFjaGtkKSBjaGtkID0gW107XG5cdHZhciBtb2R1bHVzID0gc3N6IC0gMSwgaiA9IDAsIGpqID0gMDtcblx0Zm9yKGo9c3RhcnQ7IGo+PTA7KSB7XG5cdFx0Y2hrZFtqXSA9IHRydWU7XG5cdFx0YnVmW2J1Zi5sZW5ndGhdID0gajtcblx0XHRidWZfY2hhaW4ucHVzaChzZWN0b3JzW2pdKTtcblx0XHR2YXIgYWRkciA9IGZhdF9hZGRyc1tNYXRoLmZsb29yKGoqNC9zc3opXTtcblx0XHRqaiA9ICgoaio0KSAmIG1vZHVsdXMpO1xuXHRcdGlmKHNzeiA8IDQgKyBqaikgdGhyb3cgbmV3IEVycm9yKFwiRkFUIGJvdW5kYXJ5IGNyb3NzZWQ6IFwiICsgaiArIFwiIDQgXCIrc3N6KTtcblx0XHRpZighc2VjdG9yc1thZGRyXSkgYnJlYWs7XG5cdFx0aiA9IF9fcmVhZEludDMyTEUoc2VjdG9yc1thZGRyXSwgamopO1xuXHR9XG5cdHJldHVybiB7bm9kZXM6IGJ1ZiwgZGF0YTpfX3RvQnVmZmVyKFtidWZfY2hhaW5dKX07XG59XG5cbi8qKiBDaGFzZSBkb3duIHRoZSBzZWN0b3IgbGlua2VkIGxpc3RzICovXG5mdW5jdGlvbiBtYWtlX3NlY3Rvcl9saXN0KHNlY3RvcnMsIGRpcl9zdGFydCwgZmF0X2FkZHJzLCBzc3opIHtcblx0dmFyIHNsID0gc2VjdG9ycy5sZW5ndGgsIHNlY3Rvcl9saXN0ID0gKFtdKTtcblx0dmFyIGNoa2QgPSBbXSwgYnVmID0gW10sIGJ1Zl9jaGFpbiA9IFtdO1xuXHR2YXIgbW9kdWx1cyA9IHNzeiAtIDEsIGk9MCwgaj0wLCBrPTAsIGpqPTA7XG5cdGZvcihpPTA7IGkgPCBzbDsgKytpKSB7XG5cdFx0YnVmID0gKFtdKTtcblx0XHRrID0gKGkgKyBkaXJfc3RhcnQpOyBpZihrID49IHNsKSBrLT1zbDtcblx0XHRpZihjaGtkW2tdKSBjb250aW51ZTtcblx0XHRidWZfY2hhaW4gPSBbXTtcblx0XHRmb3Ioaj1rOyBqPj0wOykge1xuXHRcdFx0Y2hrZFtqXSA9IHRydWU7XG5cdFx0XHRidWZbYnVmLmxlbmd0aF0gPSBqO1xuXHRcdFx0YnVmX2NoYWluLnB1c2goc2VjdG9yc1tqXSk7XG5cdFx0XHR2YXIgYWRkciA9IGZhdF9hZGRyc1tNYXRoLmZsb29yKGoqNC9zc3opXTtcblx0XHRcdGpqID0gKChqKjQpICYgbW9kdWx1cyk7XG5cdFx0XHRpZihzc3ogPCA0ICsgamopIHRocm93IG5ldyBFcnJvcihcIkZBVCBib3VuZGFyeSBjcm9zc2VkOiBcIiArIGogKyBcIiA0IFwiK3Nzeik7XG5cdFx0XHRpZighc2VjdG9yc1thZGRyXSkgYnJlYWs7XG5cdFx0XHRqID0gX19yZWFkSW50MzJMRShzZWN0b3JzW2FkZHJdLCBqaik7XG5cdFx0fVxuXHRcdHNlY3Rvcl9saXN0W2tdID0gKHtub2RlczogYnVmLCBkYXRhOl9fdG9CdWZmZXIoW2J1Zl9jaGFpbl0pfSk7XG5cdH1cblx0cmV0dXJuIHNlY3Rvcl9saXN0O1xufVxuXG4vKiBbTVMtQ0ZCXSAyLjYuMSBDb21wb3VuZCBGaWxlIERpcmVjdG9yeSBFbnRyeSAqL1xuZnVuY3Rpb24gcmVhZF9kaXJlY3RvcnkoZGlyX3N0YXJ0LCBzZWN0b3JfbGlzdCwgc2VjdG9ycywgUGF0aHMsIG5tZnMsIGZpbGVzLCBGaWxlSW5kZXgsIG1pbmkpIHtcblx0dmFyIG1pbmlmYXRfc3RvcmUgPSAwLCBwbCA9IChQYXRocy5sZW5ndGg/MjowKTtcblx0dmFyIHNlY3RvciA9IHNlY3Rvcl9saXN0W2Rpcl9zdGFydF0uZGF0YTtcblx0dmFyIGkgPSAwLCBuYW1lbGVuID0gMCwgbmFtZTtcblx0Zm9yKDsgaSA8IHNlY3Rvci5sZW5ndGg7IGkrPSAxMjgpIHtcblx0XHR2YXIgYmxvYiA9IHNlY3Rvci5zbGljZShpLCBpKzEyOCk7XG5cdFx0cHJlcF9ibG9iKGJsb2IsIDY0KTtcblx0XHRuYW1lbGVuID0gYmxvYi5yZWFkX3NoaWZ0KDIpO1xuXHRcdG5hbWUgPSBfX3V0ZjE2bGUoYmxvYiwwLG5hbWVsZW4tcGwpO1xuXHRcdFBhdGhzLnB1c2gobmFtZSk7XG5cdFx0dmFyIG8gPSAoe1xuXHRcdFx0bmFtZTogIG5hbWUsXG5cdFx0XHR0eXBlOiAgYmxvYi5yZWFkX3NoaWZ0KDEpLFxuXHRcdFx0Y29sb3I6IGJsb2IucmVhZF9zaGlmdCgxKSxcblx0XHRcdEw6ICAgICBibG9iLnJlYWRfc2hpZnQoNCwgJ2knKSxcblx0XHRcdFI6ICAgICBibG9iLnJlYWRfc2hpZnQoNCwgJ2knKSxcblx0XHRcdEM6ICAgICBibG9iLnJlYWRfc2hpZnQoNCwgJ2knKSxcblx0XHRcdGNsc2lkOiBibG9iLnJlYWRfc2hpZnQoMTYpLFxuXHRcdFx0c3RhdGU6IGJsb2IucmVhZF9zaGlmdCg0LCAnaScpLFxuXHRcdFx0c3RhcnQ6IDAsXG5cdFx0XHRzaXplOiAwXG5cdFx0fSk7XG5cdFx0dmFyIGN0aW1lID0gYmxvYi5yZWFkX3NoaWZ0KDIpICsgYmxvYi5yZWFkX3NoaWZ0KDIpICsgYmxvYi5yZWFkX3NoaWZ0KDIpICsgYmxvYi5yZWFkX3NoaWZ0KDIpO1xuXHRcdGlmKGN0aW1lICE9PSAwKSBvLmN0ID0gcmVhZF9kYXRlKGJsb2IsIGJsb2IubC04KTtcblx0XHR2YXIgbXRpbWUgPSBibG9iLnJlYWRfc2hpZnQoMikgKyBibG9iLnJlYWRfc2hpZnQoMikgKyBibG9iLnJlYWRfc2hpZnQoMikgKyBibG9iLnJlYWRfc2hpZnQoMik7XG5cdFx0aWYobXRpbWUgIT09IDApIG8ubXQgPSByZWFkX2RhdGUoYmxvYiwgYmxvYi5sLTgpO1xuXHRcdG8uc3RhcnQgPSBibG9iLnJlYWRfc2hpZnQoNCwgJ2knKTtcblx0XHRvLnNpemUgPSBibG9iLnJlYWRfc2hpZnQoNCwgJ2knKTtcblx0XHRpZihvLnNpemUgPCAwICYmIG8uc3RhcnQgPCAwKSB7IG8uc2l6ZSA9IG8udHlwZSA9IDA7IG8uc3RhcnQgPSBFTkRPRkNIQUlOOyBvLm5hbWUgPSBcIlwiOyB9XG5cdFx0aWYoby50eXBlID09PSA1KSB7IC8qIHJvb3QgKi9cblx0XHRcdG1pbmlmYXRfc3RvcmUgPSBvLnN0YXJ0O1xuXHRcdFx0aWYobm1mcyA+IDAgJiYgbWluaWZhdF9zdG9yZSAhPT0gRU5ET0ZDSEFJTikgc2VjdG9yX2xpc3RbbWluaWZhdF9zdG9yZV0ubmFtZSA9IFwiIVN0cmVhbURhdGFcIjtcblx0XHRcdC8qbWluaWZhdF9zaXplID0gby5zaXplOyovXG5cdFx0fSBlbHNlIGlmKG8uc2l6ZSA+PSA0MDk2IC8qIE1TQ1NaICovKSB7XG5cdFx0XHRvLnN0b3JhZ2UgPSAnZmF0Jztcblx0XHRcdGlmKHNlY3Rvcl9saXN0W28uc3RhcnRdID09PSB1bmRlZmluZWQpIHNlY3Rvcl9saXN0W28uc3RhcnRdID0gZ2V0X3NlY3Rvcl9saXN0KHNlY3RvcnMsIG8uc3RhcnQsIHNlY3Rvcl9saXN0LmZhdF9hZGRycywgc2VjdG9yX2xpc3Quc3N6KTtcblx0XHRcdHNlY3Rvcl9saXN0W28uc3RhcnRdLm5hbWUgPSBvLm5hbWU7XG5cdFx0XHRvLmNvbnRlbnQgPSAoc2VjdG9yX2xpc3Rbby5zdGFydF0uZGF0YS5zbGljZSgwLG8uc2l6ZSkpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRvLnN0b3JhZ2UgPSAnbWluaWZhdCc7XG5cdFx0XHRpZihvLnNpemUgPCAwKSBvLnNpemUgPSAwO1xuXHRcdFx0ZWxzZSBpZihtaW5pZmF0X3N0b3JlICE9PSBFTkRPRkNIQUlOICYmIG8uc3RhcnQgIT09IEVORE9GQ0hBSU4gJiYgc2VjdG9yX2xpc3RbbWluaWZhdF9zdG9yZV0pIHtcblx0XHRcdFx0by5jb250ZW50ID0gZ2V0X21mYXRfZW50cnkobywgc2VjdG9yX2xpc3RbbWluaWZhdF9zdG9yZV0uZGF0YSwgKHNlY3Rvcl9saXN0W21pbmldfHx7fSkuZGF0YSk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmKG8uY29udGVudCkgcHJlcF9ibG9iKG8uY29udGVudCwgMCk7XG5cdFx0ZmlsZXNbbmFtZV0gPSBvO1xuXHRcdEZpbGVJbmRleC5wdXNoKG8pO1xuXHR9XG59XG5cbmZ1bmN0aW9uIHJlYWRfZGF0ZShibG9iLCBvZmZzZXQpIHtcblx0cmV0dXJuIG5ldyBEYXRlKCggKCAoX19yZWFkVUludDMyTEUoYmxvYixvZmZzZXQrNCkvMWU3KSpNYXRoLnBvdygyLDMyKStfX3JlYWRVSW50MzJMRShibG9iLG9mZnNldCkvMWU3ICkgLSAxMTY0NDQ3MzYwMCkqMTAwMCk7XG59XG5cbmZ1bmN0aW9uIHJlYWRfZmlsZShmaWxlbmFtZSwgb3B0aW9ucykge1xuXHRnZXRfZnMoKTtcblx0cmV0dXJuIHBhcnNlKGZzLnJlYWRGaWxlU3luYyhmaWxlbmFtZSksIG9wdGlvbnMpO1xufVxuXG5mdW5jdGlvbiByZWFkKGJsb2IsIG9wdGlvbnMpIHtcblx0c3dpdGNoKG9wdGlvbnMgJiYgb3B0aW9ucy50eXBlIHx8IFwiYmFzZTY0XCIpIHtcblx0XHRjYXNlIFwiZmlsZVwiOiByZXR1cm4gcmVhZF9maWxlKGJsb2IsIG9wdGlvbnMpO1xuXHRcdGNhc2UgXCJiYXNlNjRcIjogcmV0dXJuIHBhcnNlKHMyYShCYXNlNjQuZGVjb2RlKGJsb2IpKSwgb3B0aW9ucyk7XG5cdFx0Y2FzZSBcImJpbmFyeVwiOiByZXR1cm4gcGFyc2UoczJhKGJsb2IpLCBvcHRpb25zKTtcblx0fVxuXHRyZXR1cm4gcGFyc2UoYmxvYiwgb3B0aW9ucyk7XG59XG5cbmZ1bmN0aW9uIGluaXRfY2ZiKGNmYiwgb3B0cykge1xuXHR2YXIgbyA9IG9wdHMgfHwge30sIHJvb3QgPSBvLnJvb3QgfHwgXCJSb290IEVudHJ5XCI7XG5cdGlmKCFjZmIuRnVsbFBhdGhzKSBjZmIuRnVsbFBhdGhzID0gW107XG5cdGlmKCFjZmIuRmlsZUluZGV4KSBjZmIuRmlsZUluZGV4ID0gW107XG5cdGlmKGNmYi5GdWxsUGF0aHMubGVuZ3RoICE9PSBjZmIuRmlsZUluZGV4Lmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKFwiaW5jb25zaXN0ZW50IENGQiBzdHJ1Y3R1cmVcIik7XG5cdGlmKGNmYi5GdWxsUGF0aHMubGVuZ3RoID09PSAwKSB7XG5cdFx0Y2ZiLkZ1bGxQYXRoc1swXSA9IHJvb3QgKyBcIi9cIjtcblx0XHRjZmIuRmlsZUluZGV4WzBdID0gKHsgbmFtZTogcm9vdCwgdHlwZTogNSB9KTtcblx0fVxuXHRpZihvLkNMU0lEKSBjZmIuRmlsZUluZGV4WzBdLmNsc2lkID0gby5DTFNJRDtcblx0c2VlZF9jZmIoY2ZiKTtcbn1cbmZ1bmN0aW9uIHNlZWRfY2ZiKGNmYikge1xuXHR2YXIgbm0gPSBcIlxcdTAwMDFTaDMzdEo1XCI7XG5cdGlmKENGQi5maW5kKGNmYiwgXCIvXCIgKyBubSkpIHJldHVybjtcblx0dmFyIHAgPSBuZXdfYnVmKDQpOyBwWzBdID0gNTU7IHBbMV0gPSBwWzNdID0gNTA7IHBbMl0gPSA1NDtcblx0Y2ZiLkZpbGVJbmRleC5wdXNoKCh7IG5hbWU6IG5tLCB0eXBlOiAyLCBjb250ZW50OnAsIHNpemU6NCwgTDo2OSwgUjo2OSwgQzo2OSB9KSk7XG5cdGNmYi5GdWxsUGF0aHMucHVzaChjZmIuRnVsbFBhdGhzWzBdICsgbm0pO1xuXHRyZWJ1aWxkX2NmYihjZmIpO1xufVxuZnVuY3Rpb24gcmVidWlsZF9jZmIoY2ZiLCBmKSB7XG5cdGluaXRfY2ZiKGNmYik7XG5cdHZhciBnYyA9IGZhbHNlLCBzID0gZmFsc2U7XG5cdGZvcih2YXIgaSA9IGNmYi5GdWxsUGF0aHMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcblx0XHR2YXIgX2ZpbGUgPSBjZmIuRmlsZUluZGV4W2ldO1xuXHRcdHN3aXRjaChfZmlsZS50eXBlKSB7XG5cdFx0XHRjYXNlIDA6XG5cdFx0XHRcdGlmKHMpIGdjID0gdHJ1ZTtcblx0XHRcdFx0ZWxzZSB7IGNmYi5GaWxlSW5kZXgucG9wKCk7IGNmYi5GdWxsUGF0aHMucG9wKCk7IH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIDE6IGNhc2UgMjogY2FzZSA1OlxuXHRcdFx0XHRzID0gdHJ1ZTtcblx0XHRcdFx0aWYoaXNOYU4oX2ZpbGUuUiAqIF9maWxlLkwgKiBfZmlsZS5DKSkgZ2MgPSB0cnVlO1xuXHRcdFx0XHRpZihfZmlsZS5SID4gLTEgJiYgX2ZpbGUuTCA+IC0xICYmIF9maWxlLlIgPT0gX2ZpbGUuTCkgZ2MgPSB0cnVlO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGRlZmF1bHQ6IGdjID0gdHJ1ZTsgYnJlYWs7XG5cdFx0fVxuXHR9XG5cdGlmKCFnYyAmJiAhZikgcmV0dXJuO1xuXG5cdHZhciBub3cgPSBuZXcgRGF0ZSgxOTg3LCAxLCAxOSksIGogPSAwO1xuXHR2YXIgZGF0YSA9IFtdO1xuXHRmb3IoaSA9IDA7IGkgPCBjZmIuRnVsbFBhdGhzLmxlbmd0aDsgKytpKSB7XG5cdFx0aWYoY2ZiLkZpbGVJbmRleFtpXS50eXBlID09PSAwKSBjb250aW51ZTtcblx0XHRkYXRhLnB1c2goW2NmYi5GdWxsUGF0aHNbaV0sIGNmYi5GaWxlSW5kZXhbaV1dKTtcblx0fVxuXHRmb3IoaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgKytpKSB7XG5cdFx0dmFyIGRhZCA9IGRpcm5hbWUoZGF0YVtpXVswXSk7XG5cdFx0cyA9IGZhbHNlO1xuXHRcdGZvcihqID0gMDsgaiA8IGRhdGEubGVuZ3RoOyArK2opIGlmKGRhdGFbal1bMF0gPT09IGRhZCkgcyA9IHRydWU7XG5cdFx0aWYoIXMpIGRhdGEucHVzaChbZGFkLCAoe1xuXHRcdFx0bmFtZTogZmlsZW5hbWUoZGFkKS5yZXBsYWNlKFwiL1wiLFwiXCIpLFxuXHRcdFx0dHlwZTogMSxcblx0XHRcdGNsc2lkOiBIRUFERVJfQ0xTSUQsXG5cdFx0XHRjdDogbm93LCBtdDogbm93LFxuXHRcdFx0Y29udGVudDogbnVsbFxuXHRcdH0pXSk7XG5cdH1cblxuXHRkYXRhLnNvcnQoZnVuY3Rpb24oeCx5KSB7IHJldHVybiBuYW1lY21wKHhbMF0sIHlbMF0pOyB9KTtcblx0Y2ZiLkZ1bGxQYXRocyA9IFtdOyBjZmIuRmlsZUluZGV4ID0gW107XG5cdGZvcihpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyArK2kpIHsgY2ZiLkZ1bGxQYXRoc1tpXSA9IGRhdGFbaV1bMF07IGNmYi5GaWxlSW5kZXhbaV0gPSBkYXRhW2ldWzFdOyB9XG5cdGZvcihpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyArK2kpIHtcblx0XHR2YXIgZWx0ID0gY2ZiLkZpbGVJbmRleFtpXTtcblx0XHR2YXIgbm0gPSBjZmIuRnVsbFBhdGhzW2ldO1xuXG5cdFx0ZWx0Lm5hbWUgPSAgZmlsZW5hbWUobm0pLnJlcGxhY2UoXCIvXCIsXCJcIik7XG5cdFx0ZWx0LkwgPSBlbHQuUiA9IGVsdC5DID0gLShlbHQuY29sb3IgPSAxKTtcblx0XHRlbHQuc2l6ZSA9IGVsdC5jb250ZW50ID8gZWx0LmNvbnRlbnQubGVuZ3RoIDogMDtcblx0XHRlbHQuc3RhcnQgPSAwO1xuXHRcdGVsdC5jbHNpZCA9IChlbHQuY2xzaWQgfHwgSEVBREVSX0NMU0lEKTtcblx0XHRpZihpID09PSAwKSB7XG5cdFx0XHRlbHQuQyA9IGRhdGEubGVuZ3RoID4gMSA/IDEgOiAtMTtcblx0XHRcdGVsdC5zaXplID0gMDtcblx0XHRcdGVsdC50eXBlID0gNTtcblx0XHR9IGVsc2UgaWYobm0uc2xpY2UoLTEpID09IFwiL1wiKSB7XG5cdFx0XHRmb3Ioaj1pKzE7aiA8IGRhdGEubGVuZ3RoOyArK2opIGlmKGRpcm5hbWUoY2ZiLkZ1bGxQYXRoc1tqXSk9PW5tKSBicmVhaztcblx0XHRcdGVsdC5DID0gaiA+PSBkYXRhLmxlbmd0aCA/IC0xIDogajtcblx0XHRcdGZvcihqPWkrMTtqIDwgZGF0YS5sZW5ndGg7ICsraikgaWYoZGlybmFtZShjZmIuRnVsbFBhdGhzW2pdKT09ZGlybmFtZShubSkpIGJyZWFrO1xuXHRcdFx0ZWx0LlIgPSBqID49IGRhdGEubGVuZ3RoID8gLTEgOiBqO1xuXHRcdFx0ZWx0LnR5cGUgPSAxO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZihkaXJuYW1lKGNmYi5GdWxsUGF0aHNbaSsxXXx8XCJcIikgPT0gZGlybmFtZShubSkpIGVsdC5SID0gaSArIDE7XG5cdFx0XHRlbHQudHlwZSA9IDI7XG5cdFx0fVxuXHR9XG5cbn1cblxuZnVuY3Rpb24gX3dyaXRlKGNmYiwgb3B0aW9ucykge1xuXHR2YXIgX29wdHMgPSBvcHRpb25zIHx8IHt9O1xuXHRyZWJ1aWxkX2NmYihjZmIpO1xuXHRpZihfb3B0cy5maWxlVHlwZSA9PSAnemlwJykgcmV0dXJuIHdyaXRlX3ppcChjZmIsIF9vcHRzKTtcblx0dmFyIEwgPSAoZnVuY3Rpb24oY2ZiKXtcblx0XHR2YXIgbWluaV9zaXplID0gMCwgZmF0X3NpemUgPSAwO1xuXHRcdGZvcih2YXIgaSA9IDA7IGkgPCBjZmIuRmlsZUluZGV4Lmxlbmd0aDsgKytpKSB7XG5cdFx0XHR2YXIgZmlsZSA9IGNmYi5GaWxlSW5kZXhbaV07XG5cdFx0XHRpZighZmlsZS5jb250ZW50KSBjb250aW51ZTtcbnZhciBmbGVuID0gZmlsZS5jb250ZW50Lmxlbmd0aDtcblx0XHRcdGlmKGZsZW4gPiAwKXtcblx0XHRcdFx0aWYoZmxlbiA8IDB4MTAwMCkgbWluaV9zaXplICs9IChmbGVuICsgMHgzRikgPj4gNjtcblx0XHRcdFx0ZWxzZSBmYXRfc2l6ZSArPSAoZmxlbiArIDB4MDFGRikgPj4gOTtcblx0XHRcdH1cblx0XHR9XG5cdFx0dmFyIGRpcl9jbnQgPSAoY2ZiLkZ1bGxQYXRocy5sZW5ndGggKzMpID4+IDI7XG5cdFx0dmFyIG1pbmlfY250ID0gKG1pbmlfc2l6ZSArIDcpID4+IDM7XG5cdFx0dmFyIG1mYXRfY250ID0gKG1pbmlfc2l6ZSArIDB4N0YpID4+IDc7XG5cdFx0dmFyIGZhdF9iYXNlID0gbWluaV9jbnQgKyBmYXRfc2l6ZSArIGRpcl9jbnQgKyBtZmF0X2NudDtcblx0XHR2YXIgZmF0X2NudCA9IChmYXRfYmFzZSArIDB4N0YpID4+IDc7XG5cdFx0dmFyIGRpZmF0X2NudCA9IGZhdF9jbnQgPD0gMTA5ID8gMCA6IE1hdGguY2VpbCgoZmF0X2NudC0xMDkpLzB4N0YpO1xuXHRcdHdoaWxlKCgoZmF0X2Jhc2UgKyBmYXRfY250ICsgZGlmYXRfY250ICsgMHg3RikgPj4gNykgPiBmYXRfY250KSBkaWZhdF9jbnQgPSArK2ZhdF9jbnQgPD0gMTA5ID8gMCA6IE1hdGguY2VpbCgoZmF0X2NudC0xMDkpLzB4N0YpO1xuXHRcdHZhciBMID0gIFsxLCBkaWZhdF9jbnQsIGZhdF9jbnQsIG1mYXRfY250LCBkaXJfY250LCBmYXRfc2l6ZSwgbWluaV9zaXplLCAwXTtcblx0XHRjZmIuRmlsZUluZGV4WzBdLnNpemUgPSBtaW5pX3NpemUgPDwgNjtcblx0XHRMWzddID0gKGNmYi5GaWxlSW5kZXhbMF0uc3RhcnQ9TFswXStMWzFdK0xbMl0rTFszXStMWzRdK0xbNV0pKygoTFs2XSs3KSA+PiAzKTtcblx0XHRyZXR1cm4gTDtcblx0fSkoY2ZiKTtcblx0dmFyIG8gPSBuZXdfYnVmKExbN10gPDwgOSk7XG5cdHZhciBpID0gMCwgVCA9IDA7XG5cdHtcblx0XHRmb3IoaSA9IDA7IGkgPCA4OyArK2kpIG8ud3JpdGVfc2hpZnQoMSwgSEVBREVSX1NJR1tpXSk7XG5cdFx0Zm9yKGkgPSAwOyBpIDwgODsgKytpKSBvLndyaXRlX3NoaWZ0KDIsIDApO1xuXHRcdG8ud3JpdGVfc2hpZnQoMiwgMHgwMDNFKTtcblx0XHRvLndyaXRlX3NoaWZ0KDIsIDB4MDAwMyk7XG5cdFx0by53cml0ZV9zaGlmdCgyLCAweEZGRkUpO1xuXHRcdG8ud3JpdGVfc2hpZnQoMiwgMHgwMDA5KTtcblx0XHRvLndyaXRlX3NoaWZ0KDIsIDB4MDAwNik7XG5cdFx0Zm9yKGkgPSAwOyBpIDwgMzsgKytpKSBvLndyaXRlX3NoaWZ0KDIsIDApO1xuXHRcdG8ud3JpdGVfc2hpZnQoNCwgMCk7XG5cdFx0by53cml0ZV9zaGlmdCg0LCBMWzJdKTtcblx0XHRvLndyaXRlX3NoaWZ0KDQsIExbMF0gKyBMWzFdICsgTFsyXSArIExbM10gLSAxKTtcblx0XHRvLndyaXRlX3NoaWZ0KDQsIDApO1xuXHRcdG8ud3JpdGVfc2hpZnQoNCwgMTw8MTIpO1xuXHRcdG8ud3JpdGVfc2hpZnQoNCwgTFszXSA/IExbMF0gKyBMWzFdICsgTFsyXSAtIDE6IEVORE9GQ0hBSU4pO1xuXHRcdG8ud3JpdGVfc2hpZnQoNCwgTFszXSk7XG5cdFx0by53cml0ZV9zaGlmdCgtNCwgTFsxXSA/IExbMF0gLSAxOiBFTkRPRkNIQUlOKTtcblx0XHRvLndyaXRlX3NoaWZ0KDQsIExbMV0pO1xuXHRcdGZvcihpID0gMDsgaSA8IDEwOTsgKytpKSBvLndyaXRlX3NoaWZ0KC00LCBpIDwgTFsyXSA/IExbMV0gKyBpIDogLTEpO1xuXHR9XG5cdGlmKExbMV0pIHtcblx0XHRmb3IoVCA9IDA7IFQgPCBMWzFdOyArK1QpIHtcblx0XHRcdGZvcig7IGkgPCAyMzYgKyBUICogMTI3OyArK2kpIG8ud3JpdGVfc2hpZnQoLTQsIGkgPCBMWzJdID8gTFsxXSArIGkgOiAtMSk7XG5cdFx0XHRvLndyaXRlX3NoaWZ0KC00LCBUID09PSBMWzFdIC0gMSA/IEVORE9GQ0hBSU4gOiBUICsgMSk7XG5cdFx0fVxuXHR9XG5cdHZhciBjaGFpbml0ID0gZnVuY3Rpb24odykge1xuXHRcdGZvcihUICs9IHc7IGk8VC0xOyArK2kpIG8ud3JpdGVfc2hpZnQoLTQsIGkrMSk7XG5cdFx0aWYodykgeyArK2k7IG8ud3JpdGVfc2hpZnQoLTQsIEVORE9GQ0hBSU4pOyB9XG5cdH07XG5cdFQgPSBpID0gMDtcblx0Zm9yKFQrPUxbMV07IGk8VDsgKytpKSBvLndyaXRlX3NoaWZ0KC00LCBjb25zdHMuRElGU0VDVCk7XG5cdGZvcihUKz1MWzJdOyBpPFQ7ICsraSkgby53cml0ZV9zaGlmdCgtNCwgY29uc3RzLkZBVFNFQ1QpO1xuXHRjaGFpbml0KExbM10pO1xuXHRjaGFpbml0KExbNF0pO1xuXHR2YXIgaiA9IDAsIGZsZW4gPSAwO1xuXHR2YXIgZmlsZSA9IGNmYi5GaWxlSW5kZXhbMF07XG5cdGZvcig7IGogPCBjZmIuRmlsZUluZGV4Lmxlbmd0aDsgKytqKSB7XG5cdFx0ZmlsZSA9IGNmYi5GaWxlSW5kZXhbal07XG5cdFx0aWYoIWZpbGUuY29udGVudCkgY29udGludWU7XG5mbGVuID0gZmlsZS5jb250ZW50Lmxlbmd0aDtcblx0XHRpZihmbGVuIDwgMHgxMDAwKSBjb250aW51ZTtcblx0XHRmaWxlLnN0YXJ0ID0gVDtcblx0XHRjaGFpbml0KChmbGVuICsgMHgwMUZGKSA+PiA5KTtcblx0fVxuXHRjaGFpbml0KChMWzZdICsgNykgPj4gMyk7XG5cdHdoaWxlKG8ubCAmIDB4MUZGKSBvLndyaXRlX3NoaWZ0KC00LCBjb25zdHMuRU5ET0ZDSEFJTik7XG5cdFQgPSBpID0gMDtcblx0Zm9yKGogPSAwOyBqIDwgY2ZiLkZpbGVJbmRleC5sZW5ndGg7ICsraikge1xuXHRcdGZpbGUgPSBjZmIuRmlsZUluZGV4W2pdO1xuXHRcdGlmKCFmaWxlLmNvbnRlbnQpIGNvbnRpbnVlO1xuZmxlbiA9IGZpbGUuY29udGVudC5sZW5ndGg7XG5cdFx0aWYoIWZsZW4gfHwgZmxlbiA+PSAweDEwMDApIGNvbnRpbnVlO1xuXHRcdGZpbGUuc3RhcnQgPSBUO1xuXHRcdGNoYWluaXQoKGZsZW4gKyAweDNGKSA+PiA2KTtcblx0fVxuXHR3aGlsZShvLmwgJiAweDFGRikgby53cml0ZV9zaGlmdCgtNCwgY29uc3RzLkVORE9GQ0hBSU4pO1xuXHRmb3IoaSA9IDA7IGkgPCBMWzRdPDwyOyArK2kpIHtcblx0XHR2YXIgbm0gPSBjZmIuRnVsbFBhdGhzW2ldO1xuXHRcdGlmKCFubSB8fCBubS5sZW5ndGggPT09IDApIHtcblx0XHRcdGZvcihqID0gMDsgaiA8IDE3OyArK2opIG8ud3JpdGVfc2hpZnQoNCwgMCk7XG5cdFx0XHRmb3IoaiA9IDA7IGogPCAzOyArK2opIG8ud3JpdGVfc2hpZnQoNCwgLTEpO1xuXHRcdFx0Zm9yKGogPSAwOyBqIDwgMTI7ICsraikgby53cml0ZV9zaGlmdCg0LCAwKTtcblx0XHRcdGNvbnRpbnVlO1xuXHRcdH1cblx0XHRmaWxlID0gY2ZiLkZpbGVJbmRleFtpXTtcblx0XHRpZihpID09PSAwKSBmaWxlLnN0YXJ0ID0gZmlsZS5zaXplID8gZmlsZS5zdGFydCAtIDEgOiBFTkRPRkNIQUlOO1xuXHRcdHZhciBfbm0gPSAoaSA9PT0gMCAmJiBfb3B0cy5yb290KSB8fCBmaWxlLm5hbWU7XG5cdFx0ZmxlbiA9IDIqKF9ubS5sZW5ndGgrMSk7XG5cdFx0by53cml0ZV9zaGlmdCg2NCwgX25tLCBcInV0ZjE2bGVcIik7XG5cdFx0by53cml0ZV9zaGlmdCgyLCBmbGVuKTtcblx0XHRvLndyaXRlX3NoaWZ0KDEsIGZpbGUudHlwZSk7XG5cdFx0by53cml0ZV9zaGlmdCgxLCBmaWxlLmNvbG9yKTtcblx0XHRvLndyaXRlX3NoaWZ0KC00LCBmaWxlLkwpO1xuXHRcdG8ud3JpdGVfc2hpZnQoLTQsIGZpbGUuUik7XG5cdFx0by53cml0ZV9zaGlmdCgtNCwgZmlsZS5DKTtcblx0XHRpZighZmlsZS5jbHNpZCkgZm9yKGogPSAwOyBqIDwgNDsgKytqKSBvLndyaXRlX3NoaWZ0KDQsIDApO1xuXHRcdGVsc2Ugby53cml0ZV9zaGlmdCgxNiwgZmlsZS5jbHNpZCwgXCJoZXhcIik7XG5cdFx0by53cml0ZV9zaGlmdCg0LCBmaWxlLnN0YXRlIHx8IDApO1xuXHRcdG8ud3JpdGVfc2hpZnQoNCwgMCk7IG8ud3JpdGVfc2hpZnQoNCwgMCk7XG5cdFx0by53cml0ZV9zaGlmdCg0LCAwKTsgby53cml0ZV9zaGlmdCg0LCAwKTtcblx0XHRvLndyaXRlX3NoaWZ0KDQsIGZpbGUuc3RhcnQpO1xuXHRcdG8ud3JpdGVfc2hpZnQoNCwgZmlsZS5zaXplKTsgby53cml0ZV9zaGlmdCg0LCAwKTtcblx0fVxuXHRmb3IoaSA9IDE7IGkgPCBjZmIuRmlsZUluZGV4Lmxlbmd0aDsgKytpKSB7XG5cdFx0ZmlsZSA9IGNmYi5GaWxlSW5kZXhbaV07XG5pZihmaWxlLnNpemUgPj0gMHgxMDAwKSB7XG5cdFx0XHRvLmwgPSAoZmlsZS5zdGFydCsxKSA8PCA5O1xuXHRcdFx0Zm9yKGogPSAwOyBqIDwgZmlsZS5zaXplOyArK2opIG8ud3JpdGVfc2hpZnQoMSwgZmlsZS5jb250ZW50W2pdKTtcblx0XHRcdGZvcig7IGogJiAweDFGRjsgKytqKSBvLndyaXRlX3NoaWZ0KDEsIDApO1xuXHRcdH1cblx0fVxuXHRmb3IoaSA9IDE7IGkgPCBjZmIuRmlsZUluZGV4Lmxlbmd0aDsgKytpKSB7XG5cdFx0ZmlsZSA9IGNmYi5GaWxlSW5kZXhbaV07XG5pZihmaWxlLnNpemUgPiAwICYmIGZpbGUuc2l6ZSA8IDB4MTAwMCkge1xuXHRcdFx0Zm9yKGogPSAwOyBqIDwgZmlsZS5zaXplOyArK2opIG8ud3JpdGVfc2hpZnQoMSwgZmlsZS5jb250ZW50W2pdKTtcblx0XHRcdGZvcig7IGogJiAweDNGOyArK2opIG8ud3JpdGVfc2hpZnQoMSwgMCk7XG5cdFx0fVxuXHR9XG5cdHdoaWxlKG8ubCA8IG8ubGVuZ3RoKSBvLndyaXRlX3NoaWZ0KDEsIDApO1xuXHRyZXR1cm4gbztcbn1cbi8qIFtNUy1DRkJdIDIuNi40IChVbmljb2RlIDMuMC4xIGNhc2UgY29udmVyc2lvbikgKi9cbmZ1bmN0aW9uIGZpbmQoY2ZiLCBwYXRoKSB7XG5cdHZhciBVQ0Z1bGxQYXRocyA9IGNmYi5GdWxsUGF0aHMubWFwKGZ1bmN0aW9uKHgpIHsgcmV0dXJuIHgudG9VcHBlckNhc2UoKTsgfSk7XG5cdHZhciBVQ1BhdGhzID0gVUNGdWxsUGF0aHMubWFwKGZ1bmN0aW9uKHgpIHsgdmFyIHkgPSB4LnNwbGl0KFwiL1wiKTsgcmV0dXJuIHlbeS5sZW5ndGggLSAoeC5zbGljZSgtMSkgPT0gXCIvXCIgPyAyIDogMSldOyB9KTtcblx0dmFyIGsgPSBmYWxzZTtcblx0aWYocGF0aC5jaGFyQ29kZUF0KDApID09PSA0NyAvKiBcIi9cIiAqLykgeyBrID0gdHJ1ZTsgcGF0aCA9IFVDRnVsbFBhdGhzWzBdLnNsaWNlKDAsIC0xKSArIHBhdGg7IH1cblx0ZWxzZSBrID0gcGF0aC5pbmRleE9mKFwiL1wiKSAhPT0gLTE7XG5cdHZhciBVQ1BhdGggPSBwYXRoLnRvVXBwZXJDYXNlKCk7XG5cdHZhciB3ID0gayA9PT0gdHJ1ZSA/IFVDRnVsbFBhdGhzLmluZGV4T2YoVUNQYXRoKSA6IFVDUGF0aHMuaW5kZXhPZihVQ1BhdGgpO1xuXHRpZih3ICE9PSAtMSkgcmV0dXJuIGNmYi5GaWxlSW5kZXhbd107XG5cblx0dmFyIG0gPSAhVUNQYXRoLm1hdGNoKGNocjEpO1xuXHRVQ1BhdGggPSBVQ1BhdGgucmVwbGFjZShjaHIwLCcnKTtcblx0aWYobSkgVUNQYXRoID0gVUNQYXRoLnJlcGxhY2UoY2hyMSwnIScpO1xuXHRmb3IodyA9IDA7IHcgPCBVQ0Z1bGxQYXRocy5sZW5ndGg7ICsrdykge1xuXHRcdGlmKChtID8gVUNGdWxsUGF0aHNbd10ucmVwbGFjZShjaHIxLCchJykgOiBVQ0Z1bGxQYXRoc1t3XSkucmVwbGFjZShjaHIwLCcnKSA9PSBVQ1BhdGgpIHJldHVybiBjZmIuRmlsZUluZGV4W3ddO1xuXHRcdGlmKChtID8gVUNQYXRoc1t3XS5yZXBsYWNlKGNocjEsJyEnKSA6IFVDUGF0aHNbd10pLnJlcGxhY2UoY2hyMCwnJykgPT0gVUNQYXRoKSByZXR1cm4gY2ZiLkZpbGVJbmRleFt3XTtcblx0fVxuXHRyZXR1cm4gbnVsbDtcbn1cbi8qKiBDRkIgQ29uc3RhbnRzICovXG52YXIgTVNTWiA9IDY0OyAvKiBNaW5pIFNlY3RvciBTaXplID0gMTw8NiAqL1xuLy92YXIgTVNDU1ogPSA0MDk2OyAvKiBNaW5pIFN0cmVhbSBDdXRvZmYgU2l6ZSAqL1xuLyogMi4xIENvbXBvdW5kIEZpbGUgU2VjdG9yIE51bWJlcnMgYW5kIFR5cGVzICovXG52YXIgRU5ET0ZDSEFJTiA9IC0yO1xuLyogMi4yIENvbXBvdW5kIEZpbGUgSGVhZGVyICovXG52YXIgSEVBREVSX1NJR05BVFVSRSA9ICdkMGNmMTFlMGExYjExYWUxJztcbnZhciBIRUFERVJfU0lHID0gWzB4RDAsIDB4Q0YsIDB4MTEsIDB4RTAsIDB4QTEsIDB4QjEsIDB4MUEsIDB4RTFdO1xudmFyIEhFQURFUl9DTFNJRCA9ICcwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCc7XG52YXIgY29uc3RzID0ge1xuXHQvKiAyLjEgQ29tcHVuZCBGaWxlIFNlY3RvciBOdW1iZXJzIGFuZCBUeXBlcyAqL1xuXHRNQVhSRUdTRUNUOiAtNixcblx0RElGU0VDVDogLTQsXG5cdEZBVFNFQ1Q6IC0zLFxuXHRFTkRPRkNIQUlOOiBFTkRPRkNIQUlOLFxuXHRGUkVFU0VDVDogLTEsXG5cdC8qIDIuMiBDb21wb3VuZCBGaWxlIEhlYWRlciAqL1xuXHRIRUFERVJfU0lHTkFUVVJFOiBIRUFERVJfU0lHTkFUVVJFLFxuXHRIRUFERVJfTUlOT1JfVkVSU0lPTjogJzNlMDAnLFxuXHRNQVhSRUdTSUQ6IC02LFxuXHROT1NUUkVBTTogLTEsXG5cdEhFQURFUl9DTFNJRDogSEVBREVSX0NMU0lELFxuXHQvKiAyLjYuMSBDb21wb3VuZCBGaWxlIERpcmVjdG9yeSBFbnRyeSAqL1xuXHRFbnRyeVR5cGVzOiBbJ3Vua25vd24nLCdzdG9yYWdlJywnc3RyZWFtJywnbG9ja2J5dGVzJywncHJvcGVydHknLCdyb290J11cbn07XG5cbmZ1bmN0aW9uIHdyaXRlX2ZpbGUoY2ZiLCBmaWxlbmFtZSwgb3B0aW9ucykge1xuXHRnZXRfZnMoKTtcblx0dmFyIG8gPSBfd3JpdGUoY2ZiLCBvcHRpb25zKTtcbmZzLndyaXRlRmlsZVN5bmMoZmlsZW5hbWUsIG8pO1xufVxuXG5mdW5jdGlvbiBhMnMobykge1xuXHR2YXIgb3V0ID0gbmV3IEFycmF5KG8ubGVuZ3RoKTtcblx0Zm9yKHZhciBpID0gMDsgaSA8IG8ubGVuZ3RoOyArK2kpIG91dFtpXSA9IFN0cmluZy5mcm9tQ2hhckNvZGUob1tpXSk7XG5cdHJldHVybiBvdXQuam9pbihcIlwiKTtcbn1cblxuZnVuY3Rpb24gd3JpdGUoY2ZiLCBvcHRpb25zKSB7XG5cdHZhciBvID0gX3dyaXRlKGNmYiwgb3B0aW9ucyk7XG5cdHN3aXRjaChvcHRpb25zICYmIG9wdGlvbnMudHlwZSkge1xuXHRcdGNhc2UgXCJmaWxlXCI6IGdldF9mcygpOyBmcy53cml0ZUZpbGVTeW5jKG9wdGlvbnMuZmlsZW5hbWUsIChvKSk7IHJldHVybiBvO1xuXHRcdGNhc2UgXCJiaW5hcnlcIjogcmV0dXJuIGEycyhvKTtcblx0XHRjYXNlIFwiYmFzZTY0XCI6IHJldHVybiBCYXNlNjQuZW5jb2RlKGEycyhvKSk7XG5cdH1cblx0cmV0dXJuIG87XG59XG4vKiBub2RlIDwgOC4xIHpsaWIgZG9lcyBub3QgZXhwb3NlIGJ5dGVzUmVhZCwgc28gZGVmYXVsdCB0byBwdXJlIEpTICovXG52YXIgX3psaWI7XG5mdW5jdGlvbiB1c2VfemxpYih6bGliKSB7IHRyeSB7XG5cdHZhciBJbmZsYXRlUmF3ID0gemxpYi5JbmZsYXRlUmF3O1xuXHR2YXIgSW5mbFJhdyA9IG5ldyBJbmZsYXRlUmF3KCk7XG5cdEluZmxSYXcuX3Byb2Nlc3NDaHVuayhuZXcgVWludDhBcnJheShbMywgMF0pLCBJbmZsUmF3Ll9maW5pc2hGbHVzaEZsYWcpO1xuXHRpZihJbmZsUmF3LmJ5dGVzUmVhZCkgX3psaWIgPSB6bGliO1xuXHRlbHNlIHRocm93IG5ldyBFcnJvcihcInpsaWIgZG9lcyBub3QgZXhwb3NlIGJ5dGVzUmVhZFwiKTtcbn0gY2F0Y2goZSkge2NvbnNvbGUuZXJyb3IoXCJjYW5ub3QgdXNlIG5hdGl2ZSB6bGliOiBcIiArIChlLm1lc3NhZ2UgfHwgZSkpOyB9IH1cblxuZnVuY3Rpb24gX2luZmxhdGVSYXdTeW5jKHBheWxvYWQsIHVzeikge1xuXHRpZighX3psaWIpIHJldHVybiBfaW5mbGF0ZShwYXlsb2FkLCB1c3opO1xuXHR2YXIgSW5mbGF0ZVJhdyA9IF96bGliLkluZmxhdGVSYXc7XG5cdHZhciBJbmZsUmF3ID0gbmV3IEluZmxhdGVSYXcoKTtcblx0dmFyIG91dCA9IEluZmxSYXcuX3Byb2Nlc3NDaHVuayhwYXlsb2FkLnNsaWNlKHBheWxvYWQubCksIEluZmxSYXcuX2ZpbmlzaEZsdXNoRmxhZyk7XG5cdHBheWxvYWQubCArPSBJbmZsUmF3LmJ5dGVzUmVhZDtcblx0cmV0dXJuIG91dDtcbn1cblxuZnVuY3Rpb24gX2RlZmxhdGVSYXdTeW5jKHBheWxvYWQpIHtcblx0cmV0dXJuIF96bGliID8gX3psaWIuZGVmbGF0ZVJhd1N5bmMocGF5bG9hZCkgOiBfZGVmbGF0ZShwYXlsb2FkKTtcbn1cbnZhciBDTEVOX09SREVSID0gWyAxNiwgMTcsIDE4LCAwLCA4LCA3LCA5LCA2LCAxMCwgNSwgMTEsIDQsIDEyLCAzLCAxMywgMiwgMTQsIDEsIDE1IF07XG5cbi8qICBMRU5fSUQgPSBbIDI1NywgMjU4LCAyNTksIDI2MCwgMjYxLCAyNjIsIDI2MywgMjY0LCAyNjUsIDI2NiwgMjY3LCAyNjgsIDI2OSwgMjcwLCAyNzEsIDI3MiwgMjczLCAyNzQsIDI3NSwgMjc2LCAyNzcsIDI3OCwgMjc5LCAyODAsIDI4MSwgMjgyLCAyODMsIDI4NCwgMjg1IF07ICovXG52YXIgTEVOX0xOID0gWyAgIDMsICAgNCwgICA1LCAgIDYsICAgNywgICA4LCAgIDksICAxMCwgIDExLCAgMTMgLCAxNSwgIDE3LCAgMTksICAyMywgIDI3LCAgMzEsICAzNSwgIDQzLCAgNTEsICA1OSwgIDY3LCAgODMsICA5OSwgMTE1LCAxMzEsIDE2MywgMTk1LCAyMjcsIDI1OCBdO1xuXG4vKiAgRFNUX0lEID0gWyAgMCwgIDEsICAyLCAgMywgIDQsICA1LCAgNiwgIDcsICA4LCAgOSwgMTAsIDExLCAxMiwgMTMsICAxNCwgIDE1LCAgMTYsICAxNywgIDE4LCAgMTksICAgMjAsICAgMjEsICAgMjIsICAgMjMsICAgMjQsICAgMjUsICAgMjYsICAgIDI3LCAgICAyOCwgICAgMjkgXTsgKi9cbnZhciBEU1RfTE4gPSBbICAxLCAgMiwgIDMsICA0LCAgNSwgIDcsICA5LCAxMywgMTcsIDI1LCAzMywgNDksIDY1LCA5NywgMTI5LCAxOTMsIDI1NywgMzg1LCA1MTMsIDc2OSwgMTAyNSwgMTUzNywgMjA0OSwgMzA3MywgNDA5NywgNjE0NSwgODE5MywgMTIyODksIDE2Mzg1LCAyNDU3NyBdO1xuXG5mdW5jdGlvbiBiaXRfc3dhcF84KG4pIHsgdmFyIHQgPSAoKCgoKG48PDEpfChuPDwxMSkpICYgMHgyMjExMCkgfCAoKChuPDw1KXwobjw8MTUpKSAmIDB4ODg0NDApKSk7IHJldHVybiAoKHQ+PjE2KSB8ICh0Pj44KSB8dCkmMHhGRjsgfVxuXG52YXIgdXNlX3R5cGVkX2FycmF5cyA9IHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJztcblxudmFyIGJpdHN3YXA4ID0gdXNlX3R5cGVkX2FycmF5cyA/IG5ldyBVaW50OEFycmF5KDE8PDgpIDogW107XG5mb3IodmFyIHEgPSAwOyBxIDwgKDE8PDgpOyArK3EpIGJpdHN3YXA4W3FdID0gYml0X3N3YXBfOChxKTtcblxuZnVuY3Rpb24gYml0X3N3YXBfbihuLCBiKSB7XG5cdHZhciByZXYgPSBiaXRzd2FwOFtuICYgMHhGRl07XG5cdGlmKGIgPD0gOCkgcmV0dXJuIHJldiA+Pj4gKDgtYik7XG5cdHJldiA9IChyZXYgPDwgOCkgfCBiaXRzd2FwOFsobj4+OCkmMHhGRl07XG5cdGlmKGIgPD0gMTYpIHJldHVybiByZXYgPj4+ICgxNi1iKTtcblx0cmV2ID0gKHJldiA8PCA4KSB8IGJpdHN3YXA4WyhuPj4xNikmMHhGRl07XG5cdHJldHVybiByZXYgPj4+ICgyNC1iKTtcbn1cblxuLyogaGVscGVycyBmb3IgdW5hbGlnbmVkIGJpdCByZWFkcyAqL1xuZnVuY3Rpb24gcmVhZF9iaXRzXzIoYnVmLCBibCkgeyB2YXIgdyA9IChibCY3KSwgaCA9IChibD4+PjMpOyByZXR1cm4gKChidWZbaF18KHcgPD0gNiA/IDAgOiBidWZbaCsxXTw8OCkpPj4+dykmIDB4MDM7IH1cbmZ1bmN0aW9uIHJlYWRfYml0c18zKGJ1ZiwgYmwpIHsgdmFyIHcgPSAoYmwmNyksIGggPSAoYmw+Pj4zKTsgcmV0dXJuICgoYnVmW2hdfCh3IDw9IDUgPyAwIDogYnVmW2grMV08PDgpKT4+PncpJiAweDA3OyB9XG5mdW5jdGlvbiByZWFkX2JpdHNfNChidWYsIGJsKSB7IHZhciB3ID0gKGJsJjcpLCBoID0gKGJsPj4+Myk7IHJldHVybiAoKGJ1ZltoXXwodyA8PSA0ID8gMCA6IGJ1ZltoKzFdPDw4KSk+Pj53KSYgMHgwRjsgfVxuZnVuY3Rpb24gcmVhZF9iaXRzXzUoYnVmLCBibCkgeyB2YXIgdyA9IChibCY3KSwgaCA9IChibD4+PjMpOyByZXR1cm4gKChidWZbaF18KHcgPD0gMyA/IDAgOiBidWZbaCsxXTw8OCkpPj4+dykmIDB4MUY7IH1cbmZ1bmN0aW9uIHJlYWRfYml0c183KGJ1ZiwgYmwpIHsgdmFyIHcgPSAoYmwmNyksIGggPSAoYmw+Pj4zKTsgcmV0dXJuICgoYnVmW2hdfCh3IDw9IDEgPyAwIDogYnVmW2grMV08PDgpKT4+PncpJiAweDdGOyB9XG5cbi8qIHdvcmtzIHVwIHRvIG4gPSAzICogOCArIDEgPSAyNSAqL1xuZnVuY3Rpb24gcmVhZF9iaXRzX24oYnVmLCBibCwgbikge1xuXHR2YXIgdyA9IChibCY3KSwgaCA9IChibD4+PjMpLCBmID0gKCgxPDxuKS0xKTtcblx0dmFyIHYgPSBidWZbaF0gPj4+IHc7XG5cdGlmKG4gPCA4IC0gdykgcmV0dXJuIHYgJiBmO1xuXHR2IHw9IGJ1ZltoKzFdPDwoOC13KTtcblx0aWYobiA8IDE2IC0gdykgcmV0dXJuIHYgJiBmO1xuXHR2IHw9IGJ1ZltoKzJdPDwoMTYtdyk7XG5cdGlmKG4gPCAyNCAtIHcpIHJldHVybiB2ICYgZjtcblx0diB8PSBidWZbaCszXTw8KDI0LXcpO1xuXHRyZXR1cm4gdiAmIGY7XG59XG5cbi8qIHVudGlsIEFycmF5QnVmZmVyI3JlYWxsb2MgaXMgYSB0aGluZywgZmFrZSBhIHJlYWxsb2MgKi9cbmZ1bmN0aW9uIHJlYWxsb2MoYiwgc3opIHtcblx0dmFyIEwgPSBiLmxlbmd0aCwgTSA9IDIqTCA+IHN6ID8gMipMIDogc3ogKyA1LCBpID0gMDtcblx0aWYoTCA+PSBzeikgcmV0dXJuIGI7XG5cdGlmKGhhc19idWYpIHtcblx0XHR2YXIgbyA9IG5ld191bnNhZmVfYnVmKE0pO1xuXHRcdC8vICRGbG93SWdub3JlXG5cdFx0aWYoYi5jb3B5KSBiLmNvcHkobyk7XG5cdFx0ZWxzZSBmb3IoOyBpIDwgYi5sZW5ndGg7ICsraSkgb1tpXSA9IGJbaV07XG5cdFx0cmV0dXJuIG87XG5cdH0gZWxzZSBpZih1c2VfdHlwZWRfYXJyYXlzKSB7XG5cdFx0dmFyIGEgPSBuZXcgVWludDhBcnJheShNKTtcblx0XHRpZihhLnNldCkgYS5zZXQoYik7XG5cdFx0ZWxzZSBmb3IoOyBpIDwgYi5sZW5ndGg7ICsraSkgYVtpXSA9IGJbaV07XG5cdFx0cmV0dXJuIGE7XG5cdH1cblx0Yi5sZW5ndGggPSBNO1xuXHRyZXR1cm4gYjtcbn1cblxuLyogemVyby1maWxsZWQgYXJyYXlzIGZvciBvbGRlciBicm93c2VycyAqL1xuZnVuY3Rpb24gemVyb19maWxsX2FycmF5KG4pIHtcblx0dmFyIG8gPSBuZXcgQXJyYXkobik7XG5cdGZvcih2YXIgaSA9IDA7IGkgPCBuOyArK2kpIG9baV0gPSAwO1xuXHRyZXR1cm4gbztcbn12YXIgX2RlZmxhdGUgPSAoZnVuY3Rpb24oKSB7XG52YXIgX2RlZmxhdGVSYXcgPSAoZnVuY3Rpb24oKSB7XG5cdHJldHVybiBmdW5jdGlvbiBkZWZsYXRlUmF3KGRhdGEsIG91dCkge1xuXHRcdHZhciBib2ZmID0gMDtcblx0XHR3aGlsZShib2ZmIDwgZGF0YS5sZW5ndGgpIHtcblx0XHRcdHZhciBMID0gTWF0aC5taW4oMHhGRkZGLCBkYXRhLmxlbmd0aCAtIGJvZmYpO1xuXHRcdFx0dmFyIGggPSBib2ZmICsgTCA9PSBkYXRhLmxlbmd0aDtcblx0XHRcdC8qIFRPRE86IHRoaXMgaXMgb25seSB0eXBlIDAgc3RvcmVkICovXG5cdFx0XHRvdXQud3JpdGVfc2hpZnQoMSwgK2gpO1xuXHRcdFx0b3V0LndyaXRlX3NoaWZ0KDIsIEwpO1xuXHRcdFx0b3V0LndyaXRlX3NoaWZ0KDIsICh+TCkgJiAweEZGRkYpO1xuXHRcdFx0d2hpbGUoTC0tID4gMCkgb3V0W291dC5sKytdID0gZGF0YVtib2ZmKytdO1xuXHRcdH1cblx0XHRyZXR1cm4gb3V0Lmw7XG5cdH07XG59KSgpO1xuXG5yZXR1cm4gZnVuY3Rpb24oZGF0YSkge1xuXHR2YXIgYnVmID0gbmV3X2J1Zig1MCtNYXRoLmZsb29yKGRhdGEubGVuZ3RoKjEuMSkpO1xuXHR2YXIgb2ZmID0gX2RlZmxhdGVSYXcoZGF0YSwgYnVmKTtcblx0cmV0dXJuIGJ1Zi5zbGljZSgwLCBvZmYpO1xufTtcbn0pKCk7XG4vKiBtb2RpZmllZCBpbmZsYXRlIGZ1bmN0aW9uIGFsc28gbW92ZXMgb3JpZ2luYWwgcmVhZCBoZWFkICovXG5cbi8qIGJ1aWxkIHRyZWUgKHVzZWQgZm9yIGxpdGVyYWxzIGFuZCBsZW5ndGhzKSAqL1xuZnVuY3Rpb24gYnVpbGRfdHJlZShjbGVucywgY21hcCwgTUFYKSB7XG5cdHZhciBtYXhsZW4gPSAxLCB3ID0gMCwgaSA9IDAsIGogPSAwLCBjY29kZSA9IDAsIEwgPSBjbGVucy5sZW5ndGg7XG5cblx0dmFyIGJsX2NvdW50ICA9IHVzZV90eXBlZF9hcnJheXMgPyBuZXcgVWludDE2QXJyYXkoMzIpIDogemVyb19maWxsX2FycmF5KDMyKTtcblx0Zm9yKGkgPSAwOyBpIDwgMzI7ICsraSkgYmxfY291bnRbaV0gPSAwO1xuXG5cdGZvcihpID0gTDsgaSA8IE1BWDsgKytpKSBjbGVuc1tpXSA9IDA7XG5cdEwgPSBjbGVucy5sZW5ndGg7XG5cblx0dmFyIGN0cmVlID0gdXNlX3R5cGVkX2FycmF5cyA/IG5ldyBVaW50MTZBcnJheShMKSA6IHplcm9fZmlsbF9hcnJheShMKTsgLy8gW11cblxuXHQvKiBidWlsZCBjb2RlIHRyZWUgKi9cblx0Zm9yKGkgPSAwOyBpIDwgTDsgKytpKSB7XG5cdFx0YmxfY291bnRbKHcgPSBjbGVuc1tpXSldKys7XG5cdFx0aWYobWF4bGVuIDwgdykgbWF4bGVuID0gdztcblx0XHRjdHJlZVtpXSA9IDA7XG5cdH1cblx0YmxfY291bnRbMF0gPSAwO1xuXHRmb3IoaSA9IDE7IGkgPD0gbWF4bGVuOyArK2kpIGJsX2NvdW50W2krMTZdID0gKGNjb2RlID0gKGNjb2RlICsgYmxfY291bnRbaS0xXSk8PDEpO1xuXHRmb3IoaSA9IDA7IGkgPCBMOyArK2kpIHtcblx0XHRjY29kZSA9IGNsZW5zW2ldO1xuXHRcdGlmKGNjb2RlICE9IDApIGN0cmVlW2ldID0gYmxfY291bnRbY2NvZGUrMTZdKys7XG5cdH1cblxuXHQvKiBjbWFwW21heGxlbiArIDQgYml0c10gPSAob2ZmJjE1KSArIChsaXQ8PDQpIHJldmVyc2UgbWFwcGluZyAqL1xuXHR2YXIgY2xlbmkgPSAwO1xuXHRmb3IoaSA9IDA7IGkgPCBMOyArK2kpIHtcblx0XHRjbGVuaSA9IGNsZW5zW2ldO1xuXHRcdGlmKGNsZW5pICE9IDApIHtcblx0XHRcdGNjb2RlID0gYml0X3N3YXBfbihjdHJlZVtpXSwgbWF4bGVuKT4+KG1heGxlbi1jbGVuaSk7XG5cdFx0XHRmb3IoaiA9ICgxPDwobWF4bGVuICsgNCAtIGNsZW5pKSkgLSAxOyBqPj0wOyAtLWopXG5cdFx0XHRcdGNtYXBbY2NvZGV8KGo8PGNsZW5pKV0gPSAoY2xlbmkmMTUpIHwgKGk8PDQpO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gbWF4bGVuO1xufVxuXG52YXIgZml4X2xtYXAgPSB1c2VfdHlwZWRfYXJyYXlzID8gbmV3IFVpbnQxNkFycmF5KDUxMikgOiB6ZXJvX2ZpbGxfYXJyYXkoNTEyKTtcbnZhciBmaXhfZG1hcCA9IHVzZV90eXBlZF9hcnJheXMgPyBuZXcgVWludDE2QXJyYXkoMzIpICA6IHplcm9fZmlsbF9hcnJheSgzMik7XG5pZighdXNlX3R5cGVkX2FycmF5cykge1xuXHRmb3IodmFyIGkgPSAwOyBpIDwgNTEyOyArK2kpIGZpeF9sbWFwW2ldID0gMDtcblx0Zm9yKGkgPSAwOyBpIDwgMzI7ICsraSkgZml4X2RtYXBbaV0gPSAwO1xufVxuKGZ1bmN0aW9uKCkge1xuXHR2YXIgZGxlbnMgPSBbXTtcblx0dmFyIGkgPSAwO1xuXHRmb3IoO2k8MzI7IGkrKykgZGxlbnMucHVzaCg1KTtcblx0YnVpbGRfdHJlZShkbGVucywgZml4X2RtYXAsIDMyKTtcblxuXHR2YXIgY2xlbnMgPSBbXTtcblx0aSA9IDA7XG5cdGZvcig7IGk8PTE0MzsgaSsrKSBjbGVucy5wdXNoKDgpO1xuXHRmb3IoOyBpPD0yNTU7IGkrKykgY2xlbnMucHVzaCg5KTtcblx0Zm9yKDsgaTw9Mjc5OyBpKyspIGNsZW5zLnB1c2goNyk7XG5cdGZvcig7IGk8PTI4NzsgaSsrKSBjbGVucy5wdXNoKDgpO1xuXHRidWlsZF90cmVlKGNsZW5zLCBmaXhfbG1hcCwgMjg4KTtcbn0pKCk7XG5cbnZhciBkeW5fbG1hcCA9IHVzZV90eXBlZF9hcnJheXMgPyBuZXcgVWludDE2QXJyYXkoMzI3NjgpIDogemVyb19maWxsX2FycmF5KDMyNzY4KTtcbnZhciBkeW5fZG1hcCA9IHVzZV90eXBlZF9hcnJheXMgPyBuZXcgVWludDE2QXJyYXkoMzI3NjgpIDogemVyb19maWxsX2FycmF5KDMyNzY4KTtcbnZhciBkeW5fY21hcCA9IHVzZV90eXBlZF9hcnJheXMgPyBuZXcgVWludDE2QXJyYXkoMTI4KSAgIDogemVyb19maWxsX2FycmF5KDEyOCk7XG52YXIgZHluX2xlbl8xID0gMSwgZHluX2xlbl8yID0gMTtcblxuLyogNS41LjMgRXhwYW5kaW5nIEh1ZmZtYW4gQ29kZXMgKi9cbmZ1bmN0aW9uIGR5bihkYXRhLCBib2ZmKSB7XG5cdC8qIG5vbWVuY2xhdHVyZSBmcm9tIFJGQzE5NTEgcmVmZXJzIHRvIGJpdCB2YWx1ZXM7IHRoZXNlIGFyZSBvZmZzZXQgYnkgdGhlIGltcGxpY2l0IGNvbnN0YW50ICovXG5cdHZhciBfSExJVCA9IHJlYWRfYml0c181KGRhdGEsIGJvZmYpICsgMjU3OyBib2ZmICs9IDU7XG5cdHZhciBfSERJU1QgPSByZWFkX2JpdHNfNShkYXRhLCBib2ZmKSArIDE7IGJvZmYgKz0gNTtcblx0dmFyIF9IQ0xFTiA9IHJlYWRfYml0c180KGRhdGEsIGJvZmYpICsgNDsgYm9mZiArPSA0O1xuXHR2YXIgdyA9IDA7XG5cblx0LyogZ3JhYiBhbmQgc3RvcmUgY29kZSBsZW5ndGhzICovXG5cdHZhciBjbGVucyA9IHVzZV90eXBlZF9hcnJheXMgPyBuZXcgVWludDhBcnJheSgxOSkgOiB6ZXJvX2ZpbGxfYXJyYXkoMTkpO1xuXHR2YXIgY3RyZWUgPSBbIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAgXTtcblx0dmFyIG1heGxlbiA9IDE7XG5cdHZhciBibF9jb3VudCA9ICB1c2VfdHlwZWRfYXJyYXlzID8gbmV3IFVpbnQ4QXJyYXkoOCkgOiB6ZXJvX2ZpbGxfYXJyYXkoOCk7XG5cdHZhciBuZXh0X2NvZGUgPSB1c2VfdHlwZWRfYXJyYXlzID8gbmV3IFVpbnQ4QXJyYXkoOCkgOiB6ZXJvX2ZpbGxfYXJyYXkoOCk7XG5cdHZhciBMID0gY2xlbnMubGVuZ3RoOyAvKiAxOSAqL1xuXHRmb3IodmFyIGkgPSAwOyBpIDwgX0hDTEVOOyArK2kpIHtcblx0XHRjbGVuc1tDTEVOX09SREVSW2ldXSA9IHcgPSByZWFkX2JpdHNfMyhkYXRhLCBib2ZmKTtcblx0XHRpZihtYXhsZW4gPCB3KSBtYXhsZW4gPSB3O1xuXHRcdGJsX2NvdW50W3ddKys7XG5cdFx0Ym9mZiArPSAzO1xuXHR9XG5cblx0LyogYnVpbGQgY29kZSB0cmVlICovXG5cdHZhciBjY29kZSA9IDA7XG5cdGJsX2NvdW50WzBdID0gMDtcblx0Zm9yKGkgPSAxOyBpIDw9IG1heGxlbjsgKytpKSBuZXh0X2NvZGVbaV0gPSBjY29kZSA9IChjY29kZSArIGJsX2NvdW50W2ktMV0pPDwxO1xuXHRmb3IoaSA9IDA7IGkgPCBMOyArK2kpIGlmKChjY29kZSA9IGNsZW5zW2ldKSAhPSAwKSBjdHJlZVtpXSA9IG5leHRfY29kZVtjY29kZV0rKztcblx0LyogY21hcFs3IGJpdHMgZnJvbSBzdHJlYW1dID0gKG9mZiY3KSArIChsaXQ8PDMpICovXG5cdHZhciBjbGVuaSA9IDA7XG5cdGZvcihpID0gMDsgaSA8IEw7ICsraSkge1xuXHRcdGNsZW5pID0gY2xlbnNbaV07XG5cdFx0aWYoY2xlbmkgIT0gMCkge1xuXHRcdFx0Y2NvZGUgPSBiaXRzd2FwOFtjdHJlZVtpXV0+Pig4LWNsZW5pKTtcblx0XHRcdGZvcih2YXIgaiA9ICgxPDwoNy1jbGVuaSkpLTE7IGo+PTA7IC0taikgZHluX2NtYXBbY2NvZGV8KGo8PGNsZW5pKV0gPSAoY2xlbmkmNykgfCAoaTw8Myk7XG5cdFx0fVxuXHR9XG5cblx0LyogcmVhZCBsaXRlcmFsIGFuZCBkaXN0IGNvZGVzIGF0IG9uY2UgKi9cblx0dmFyIGhjb2RlcyA9IFtdO1xuXHRtYXhsZW4gPSAxO1xuXHRmb3IoOyBoY29kZXMubGVuZ3RoIDwgX0hMSVQgKyBfSERJU1Q7KSB7XG5cdFx0Y2NvZGUgPSBkeW5fY21hcFtyZWFkX2JpdHNfNyhkYXRhLCBib2ZmKV07XG5cdFx0Ym9mZiArPSBjY29kZSAmIDc7XG5cdFx0c3dpdGNoKChjY29kZSA+Pj49IDMpKSB7XG5cdFx0XHRjYXNlIDE2OlxuXHRcdFx0XHR3ID0gMyArIHJlYWRfYml0c18yKGRhdGEsIGJvZmYpOyBib2ZmICs9IDI7XG5cdFx0XHRcdGNjb2RlID0gaGNvZGVzW2hjb2Rlcy5sZW5ndGggLSAxXTtcblx0XHRcdFx0d2hpbGUody0tID4gMCkgaGNvZGVzLnB1c2goY2NvZGUpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMTc6XG5cdFx0XHRcdHcgPSAzICsgcmVhZF9iaXRzXzMoZGF0YSwgYm9mZik7IGJvZmYgKz0gMztcblx0XHRcdFx0d2hpbGUody0tID4gMCkgaGNvZGVzLnB1c2goMCk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAxODpcblx0XHRcdFx0dyA9IDExICsgcmVhZF9iaXRzXzcoZGF0YSwgYm9mZik7IGJvZmYgKz0gNztcblx0XHRcdFx0d2hpbGUodyAtLSA+IDApIGhjb2Rlcy5wdXNoKDApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdGhjb2Rlcy5wdXNoKGNjb2RlKTtcblx0XHRcdFx0aWYobWF4bGVuIDwgY2NvZGUpIG1heGxlbiA9IGNjb2RlO1xuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cdH1cblxuXHQvKiBidWlsZCBsaXRlcmFsIC8gbGVuZ3RoIHRyZWVzICovXG5cdHZhciBoMSA9IGhjb2Rlcy5zbGljZSgwLCBfSExJVCksIGgyID0gaGNvZGVzLnNsaWNlKF9ITElUKTtcblx0Zm9yKGkgPSBfSExJVDsgaSA8IDI4NjsgKytpKSBoMVtpXSA9IDA7XG5cdGZvcihpID0gX0hESVNUOyBpIDwgMzA7ICsraSkgaDJbaV0gPSAwO1xuXHRkeW5fbGVuXzEgPSBidWlsZF90cmVlKGgxLCBkeW5fbG1hcCwgMjg2KTtcblx0ZHluX2xlbl8yID0gYnVpbGRfdHJlZShoMiwgZHluX2RtYXAsIDMwKTtcblx0cmV0dXJuIGJvZmY7XG59XG5cbi8qIHJldHVybiBbIGRhdGEsIGJ5dGVzUmVhZCBdICovXG5mdW5jdGlvbiBpbmZsYXRlKGRhdGEsIHVzeikge1xuXHQvKiBzaG9ydGNpcmN1aXQgZm9yIGVtcHR5IGJ1ZmZlciBbMHgwMywgMHgwMF0gKi9cblx0aWYoZGF0YVswXSA9PSAzICYmICEoZGF0YVsxXSAmIDB4MykpIHsgcmV0dXJuIFtuZXdfcmF3X2J1Zih1c3opLCAyXTsgfVxuXG5cdC8qIGJpdCBvZmZzZXQgKi9cblx0dmFyIGJvZmYgPSAwO1xuXG5cdC8qIGhlYWRlciBpbmNsdWRlcyBmaW5hbCBiaXQgYW5kIHR5cGUgYml0cyAqL1xuXHR2YXIgaGVhZGVyID0gMDtcblxuXHR2YXIgb3V0YnVmID0gbmV3X3Vuc2FmZV9idWYodXN6ID8gdXN6IDogKDE8PDE4KSk7XG5cdHZhciB3b2ZmID0gMDtcblx0dmFyIE9MID0gb3V0YnVmLmxlbmd0aD4+PjA7XG5cdHZhciBtYXhfbGVuXzEgPSAwLCBtYXhfbGVuXzIgPSAwO1xuXG5cdHdoaWxlKChoZWFkZXImMSkgPT0gMCkge1xuXHRcdGhlYWRlciA9IHJlYWRfYml0c18zKGRhdGEsIGJvZmYpOyBib2ZmICs9IDM7XG5cdFx0aWYoKGhlYWRlciA+Pj4gMSkgPT0gMCkge1xuXHRcdFx0LyogU3RvcmVkIGJsb2NrICovXG5cdFx0XHRpZihib2ZmICYgNykgYm9mZiArPSA4IC0gKGJvZmYmNyk7XG5cdFx0XHQvKiAyIGJ5dGVzIHN6LCAyIGJ5dGVzIGJpdCBpbnZlcnNlICovXG5cdFx0XHR2YXIgc3ogPSBkYXRhW2JvZmY+Pj4zXSB8IGRhdGFbKGJvZmY+Pj4zKSsxXTw8ODtcblx0XHRcdGJvZmYgKz0gMzI7XG5cdFx0XHQvKiBwdXNoIHN6IGJ5dGVzICovXG5cdFx0XHRpZighdXN6ICYmIE9MIDwgd29mZiArIHN6KSB7IG91dGJ1ZiA9IHJlYWxsb2Mob3V0YnVmLCB3b2ZmICsgc3opOyBPTCA9IG91dGJ1Zi5sZW5ndGg7IH1cblx0XHRcdGlmKHR5cGVvZiBkYXRhLmNvcHkgPT09ICdmdW5jdGlvbicpIHtcblx0XHRcdFx0Ly8gJEZsb3dJZ25vcmVcblx0XHRcdFx0ZGF0YS5jb3B5KG91dGJ1Ziwgd29mZiwgYm9mZj4+PjMsIChib2ZmPj4+Mykrc3opO1xuXHRcdFx0XHR3b2ZmICs9IHN6OyBib2ZmICs9IDgqc3o7XG5cdFx0XHR9IGVsc2Ugd2hpbGUoc3otLSA+IDApIHsgb3V0YnVmW3dvZmYrK10gPSBkYXRhW2JvZmY+Pj4zXTsgYm9mZiArPSA4OyB9XG5cdFx0XHRjb250aW51ZTtcblx0XHR9IGVsc2UgaWYoKGhlYWRlciA+Pj4gMSkgPT0gMSkge1xuXHRcdFx0LyogRml4ZWQgSHVmZm1hbiAqL1xuXHRcdFx0bWF4X2xlbl8xID0gOTsgbWF4X2xlbl8yID0gNTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0LyogRHluYW1pYyBIdWZmbWFuICovXG5cdFx0XHRib2ZmID0gZHluKGRhdGEsIGJvZmYpO1xuXHRcdFx0bWF4X2xlbl8xID0gZHluX2xlbl8xOyBtYXhfbGVuXzIgPSBkeW5fbGVuXzI7XG5cdFx0fVxuXHRcdGlmKCF1c3ogJiYgKE9MIDwgd29mZiArIDMyNzY3KSkgeyBvdXRidWYgPSByZWFsbG9jKG91dGJ1Ziwgd29mZiArIDMyNzY3KTsgT0wgPSBvdXRidWYubGVuZ3RoOyB9XG5cdFx0Zm9yKDs7KSB7IC8vIHdoaWxlKHRydWUpIGlzIGFwcGFyZW50bHkgb3V0IG9mIHZvZ3VlIGluIG1vZGVybiBKUyBjaXJjbGVzXG5cdFx0XHQvKiBpbmdlc3QgY29kZSBhbmQgbW92ZSByZWFkIGhlYWQgKi9cblx0XHRcdHZhciBiaXRzID0gcmVhZF9iaXRzX24oZGF0YSwgYm9mZiwgbWF4X2xlbl8xKTtcblx0XHRcdHZhciBjb2RlID0gKGhlYWRlcj4+PjEpID09IDEgPyBmaXhfbG1hcFtiaXRzXSA6IGR5bl9sbWFwW2JpdHNdO1xuXHRcdFx0Ym9mZiArPSBjb2RlICYgMTU7IGNvZGUgPj4+PSA0O1xuXHRcdFx0LyogMC0yNTUgYXJlIGxpdGVyYWxzLCAyNTYgaXMgZW5kIG9mIGJsb2NrIHRva2VuLCAyNTcrIGFyZSBjb3B5IHRva2VucyAqL1xuXHRcdFx0aWYoKChjb2RlPj4+OCkmMHhGRikgPT09IDApIG91dGJ1Zlt3b2ZmKytdID0gY29kZTtcblx0XHRcdGVsc2UgaWYoY29kZSA9PSAyNTYpIGJyZWFrO1xuXHRcdFx0ZWxzZSB7XG5cdFx0XHRcdGNvZGUgLT0gMjU3O1xuXHRcdFx0XHR2YXIgbGVuX2ViID0gKGNvZGUgPCA4KSA/IDAgOiAoKGNvZGUtNCk+PjIpOyBpZihsZW5fZWIgPiA1KSBsZW5fZWIgPSAwO1xuXHRcdFx0XHR2YXIgdGd0ID0gd29mZiArIExFTl9MTltjb2RlXTtcblx0XHRcdFx0LyogbGVuZ3RoIGV4dHJhIGJpdHMgKi9cblx0XHRcdFx0aWYobGVuX2ViID4gMCkge1xuXHRcdFx0XHRcdHRndCArPSByZWFkX2JpdHNfbihkYXRhLCBib2ZmLCBsZW5fZWIpO1xuXHRcdFx0XHRcdGJvZmYgKz0gbGVuX2ViO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0LyogZGlzdCBjb2RlICovXG5cdFx0XHRcdGJpdHMgPSByZWFkX2JpdHNfbihkYXRhLCBib2ZmLCBtYXhfbGVuXzIpO1xuXHRcdFx0XHRjb2RlID0gKGhlYWRlcj4+PjEpID09IDEgPyBmaXhfZG1hcFtiaXRzXSA6IGR5bl9kbWFwW2JpdHNdO1xuXHRcdFx0XHRib2ZmICs9IGNvZGUgJiAxNTsgY29kZSA+Pj49IDQ7XG5cdFx0XHRcdHZhciBkc3RfZWIgPSAoY29kZSA8IDQgPyAwIDogKGNvZGUtMik+PjEpO1xuXHRcdFx0XHR2YXIgZHN0ID0gRFNUX0xOW2NvZGVdO1xuXHRcdFx0XHQvKiBkaXN0IGV4dHJhIGJpdHMgKi9cblx0XHRcdFx0aWYoZHN0X2ViID4gMCkge1xuXHRcdFx0XHRcdGRzdCArPSByZWFkX2JpdHNfbihkYXRhLCBib2ZmLCBkc3RfZWIpO1xuXHRcdFx0XHRcdGJvZmYgKz0gZHN0X2ViO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0LyogaW4gdGhlIGNvbW1vbiBjYXNlLCBtYW51YWwgYnl0ZSBjb3B5IGlzIGZhc3RlciB0aGFuIFRBIHNldCAvIEJ1ZmZlciBjb3B5ICovXG5cdFx0XHRcdGlmKCF1c3ogJiYgT0wgPCB0Z3QpIHsgb3V0YnVmID0gcmVhbGxvYyhvdXRidWYsIHRndCk7IE9MID0gb3V0YnVmLmxlbmd0aDsgfVxuXHRcdFx0XHR3aGlsZSh3b2ZmIDwgdGd0KSB7IG91dGJ1Zlt3b2ZmXSA9IG91dGJ1Zlt3b2ZmIC0gZHN0XTsgKyt3b2ZmOyB9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdHJldHVybiBbdXN6ID8gb3V0YnVmIDogb3V0YnVmLnNsaWNlKDAsIHdvZmYpLCAoYm9mZis3KT4+PjNdO1xufVxuXG5mdW5jdGlvbiBfaW5mbGF0ZShwYXlsb2FkLCB1c3opIHtcblx0dmFyIGRhdGEgPSBwYXlsb2FkLnNsaWNlKHBheWxvYWQubHx8MCk7XG5cdHZhciBvdXQgPSBpbmZsYXRlKGRhdGEsIHVzeik7XG5cdHBheWxvYWQubCArPSBvdXRbMV07XG5cdHJldHVybiBvdXRbMF07XG59XG5cbmZ1bmN0aW9uIHdhcm5fb3JfdGhyb3cod3JuLCBtc2cpIHtcblx0aWYod3JuKSB7IGlmKHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJykgY29uc29sZS5lcnJvcihtc2cpOyB9XG5cdGVsc2UgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlX3ppcChmaWxlLCBvcHRpb25zKSB7XG5cdHZhciBibG9iID0gZmlsZTtcblx0cHJlcF9ibG9iKGJsb2IsIDApO1xuXG5cdHZhciBGaWxlSW5kZXggPSBbXSwgRnVsbFBhdGhzID0gW107XG5cdHZhciBvID0ge1xuXHRcdEZpbGVJbmRleDogRmlsZUluZGV4LFxuXHRcdEZ1bGxQYXRoczogRnVsbFBhdGhzXG5cdH07XG5cdGluaXRfY2ZiKG8sIHsgcm9vdDogb3B0aW9ucy5yb290IH0pO1xuXG5cdC8qIGZpbmQgZW5kIG9mIGNlbnRyYWwgZGlyZWN0b3J5LCBzdGFydCBqdXN0IGFmdGVyIHNpZ25hdHVyZSAqL1xuXHR2YXIgaSA9IGJsb2IubGVuZ3RoIC0gNDtcblx0d2hpbGUoKGJsb2JbaV0gIT0gMHg1MCB8fCBibG9iW2krMV0gIT0gMHg0YiB8fCBibG9iW2krMl0gIT0gMHgwNSB8fCBibG9iW2krM10gIT0gMHgwNikgJiYgaSA+PSAwKSAtLWk7XG5cdGJsb2IubCA9IGkgKyA0O1xuXG5cdC8qIHBhcnNlIGVuZCBvZiBjZW50cmFsIGRpcmVjdG9yeSAqL1xuXHRibG9iLmwgKz0gNDtcblx0dmFyIGZjbnQgPSBibG9iLnJlYWRfc2hpZnQoMik7XG5cdGJsb2IubCArPSA2O1xuXHR2YXIgc3RhcnRfY2QgPSBibG9iLnJlYWRfc2hpZnQoNCk7XG5cblx0LyogcGFyc2UgY2VudHJhbCBkaXJlY3RvcnkgKi9cblx0YmxvYi5sID0gc3RhcnRfY2Q7XG5cblx0Zm9yKGkgPSAwOyBpIDwgZmNudDsgKytpKSB7XG5cdFx0LyogdHJ1c3QgbG9jYWwgZmlsZSBoZWFkZXIgaW5zdGVhZCBvZiBDRCBlbnRyeSAqL1xuXHRcdGJsb2IubCArPSAyMDtcblx0XHR2YXIgY3N6ID0gYmxvYi5yZWFkX3NoaWZ0KDQpO1xuXHRcdHZhciB1c3ogPSBibG9iLnJlYWRfc2hpZnQoNCk7XG5cdFx0dmFyIG5hbWVsZW4gPSBibG9iLnJlYWRfc2hpZnQoMik7XG5cdFx0dmFyIGVmc3ogPSBibG9iLnJlYWRfc2hpZnQoMik7XG5cdFx0dmFyIGZjc3ogPSBibG9iLnJlYWRfc2hpZnQoMik7XG5cdFx0YmxvYi5sICs9IDg7XG5cdFx0dmFyIG9mZnNldCA9IGJsb2IucmVhZF9zaGlmdCg0KTtcblx0XHR2YXIgRUYgPSBwYXJzZV9leHRyYV9maWVsZChibG9iLnNsaWNlKGJsb2IubCtuYW1lbGVuLCBibG9iLmwrbmFtZWxlbitlZnN6KSk7XG5cdFx0YmxvYi5sICs9IG5hbWVsZW4gKyBlZnN6ICsgZmNzejtcblxuXHRcdHZhciBMID0gYmxvYi5sO1xuXHRcdGJsb2IubCA9IG9mZnNldCArIDQ7XG5cdFx0cGFyc2VfbG9jYWxfZmlsZShibG9iLCBjc3osIHVzeiwgbywgRUYpO1xuXHRcdGJsb2IubCA9IEw7XG5cdH1cblxuXHRyZXR1cm4gbztcbn1cblxuXG4vKiBoZWFkIHN0YXJ0cyBqdXN0IGFmdGVyIGxvY2FsIGZpbGUgaGVhZGVyIHNpZ25hdHVyZSAqL1xuZnVuY3Rpb24gcGFyc2VfbG9jYWxfZmlsZShibG9iLCBjc3osIHVzeiwgbywgRUYpIHtcblx0LyogW2xvY2FsIGZpbGUgaGVhZGVyXSAqL1xuXHRibG9iLmwgKz0gMjtcblx0dmFyIGZsYWdzID0gYmxvYi5yZWFkX3NoaWZ0KDIpO1xuXHR2YXIgbWV0aCA9IGJsb2IucmVhZF9zaGlmdCgyKTtcblx0dmFyIGRhdGUgPSBwYXJzZV9kb3NfZGF0ZShibG9iKTtcblxuXHRpZihmbGFncyAmIDB4MjA0MSkgdGhyb3cgbmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgWklQIGVuY3J5cHRpb25cIik7XG5cdHZhciBjcmMzMiA9IGJsb2IucmVhZF9zaGlmdCg0KTtcblx0dmFyIF9jc3ogPSBibG9iLnJlYWRfc2hpZnQoNCk7XG5cdHZhciBfdXN6ID0gYmxvYi5yZWFkX3NoaWZ0KDQpO1xuXG5cdHZhciBuYW1lbGVuID0gYmxvYi5yZWFkX3NoaWZ0KDIpO1xuXHR2YXIgZWZzeiA9IGJsb2IucmVhZF9zaGlmdCgyKTtcblxuXHQvLyBUT0RPOiBmbGFncyAmICgxPDwxMSkgLy8gVVRGOFxuXHR2YXIgbmFtZSA9IFwiXCI7IGZvcih2YXIgaSA9IDA7IGkgPCBuYW1lbGVuOyArK2kpIG5hbWUgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShibG9iW2Jsb2IubCsrXSk7XG5cdGlmKGVmc3opIHtcblx0XHR2YXIgZWYgPSBwYXJzZV9leHRyYV9maWVsZChibG9iLnNsaWNlKGJsb2IubCwgYmxvYi5sICsgZWZzeikpO1xuXHRcdGlmKChlZlsweDU0NTVdfHx7fSkubXQpIGRhdGUgPSBlZlsweDU0NTVdLm10O1xuXHRcdGlmKCgoRUZ8fHt9KVsweDU0NTVdfHx7fSkubXQpIGRhdGUgPSBFRlsweDU0NTVdLm10O1xuXHR9XG5cdGJsb2IubCArPSBlZnN6O1xuXG5cdC8qIFtlbmNyeXB0aW9uIGhlYWRlcl0gKi9cblxuXHQvKiBbZmlsZSBkYXRhXSAqL1xuXHR2YXIgZGF0YSA9IGJsb2Iuc2xpY2UoYmxvYi5sLCBibG9iLmwgKyBfY3N6KTtcblx0c3dpdGNoKG1ldGgpIHtcblx0XHRjYXNlIDg6IGRhdGEgPSBfaW5mbGF0ZVJhd1N5bmMoYmxvYiwgX3Vzeik7IGJyZWFrO1xuXHRcdGNhc2UgMDogYnJlYWs7XG5cdFx0ZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgWklQIENvbXByZXNzaW9uIG1ldGhvZCBcIiArIG1ldGgpO1xuXHR9XG5cblx0LyogW2RhdGEgZGVzY3JpcHRvcl0gKi9cblx0dmFyIHdybiA9IGZhbHNlO1xuXHRpZihmbGFncyAmIDgpIHtcblx0XHRjcmMzMiA9IGJsb2IucmVhZF9zaGlmdCg0KTtcblx0XHRpZihjcmMzMiA9PSAweDA4MDc0YjUwKSB7IGNyYzMyID0gYmxvYi5yZWFkX3NoaWZ0KDQpOyB3cm4gPSB0cnVlOyB9XG5cdFx0X2NzeiA9IGJsb2IucmVhZF9zaGlmdCg0KTtcblx0XHRfdXN6ID0gYmxvYi5yZWFkX3NoaWZ0KDQpO1xuXHR9XG5cblx0aWYoX2NzeiAhPSBjc3opIHdhcm5fb3JfdGhyb3cod3JuLCBcIkJhZCBjb21wcmVzc2VkIHNpemU6IFwiICsgY3N6ICsgXCIgIT0gXCIgKyBfY3N6KTtcblx0aWYoX3VzeiAhPSB1c3opIHdhcm5fb3JfdGhyb3cod3JuLCBcIkJhZCB1bmNvbXByZXNzZWQgc2l6ZTogXCIgKyB1c3ogKyBcIiAhPSBcIiArIF91c3opO1xuXHR2YXIgX2NyYzMyID0gQ1JDMzIuYnVmKGRhdGEsIDApO1xuXHRpZihjcmMzMiAhPSBfY3JjMzIpIHdhcm5fb3JfdGhyb3cod3JuLCBcIkJhZCBDUkMzMiBjaGVja3N1bTogXCIgKyBjcmMzMiArIFwiICE9IFwiICsgX2NyYzMyKTtcblx0Y2ZiX2FkZChvLCBuYW1lLCBkYXRhLCB7dW5zYWZlOiB0cnVlLCBtdDogZGF0ZX0pO1xufVxuZnVuY3Rpb24gd3JpdGVfemlwKGNmYiwgb3B0aW9ucykge1xuXHR2YXIgX29wdHMgPSBvcHRpb25zIHx8IHt9O1xuXHR2YXIgb3V0ID0gW10sIGNkaXJzID0gW107XG5cdHZhciBvID0gbmV3X2J1ZigxKTtcblx0dmFyIG1ldGhvZCA9IChfb3B0cy5jb21wcmVzc2lvbiA/IDggOiAwKSwgZmxhZ3MgPSAwO1xuXHR2YXIgZGVzYyA9IGZhbHNlO1xuXHRpZihkZXNjKSBmbGFncyB8PSA4O1xuXHR2YXIgaSA9IDAsIGogPSAwO1xuXG5cdHZhciBzdGFydF9jZCA9IDAsIGZjbnQgPSAwO1xuXHR2YXIgcm9vdCA9IGNmYi5GdWxsUGF0aHNbMF0sIGZwID0gcm9vdCwgZmkgPSBjZmIuRmlsZUluZGV4WzBdO1xuXHR2YXIgY3JjcyA9IFtdO1xuXHR2YXIgc3pfY2QgPSAwO1xuXG5cdGZvcihpID0gMTsgaSA8IGNmYi5GdWxsUGF0aHMubGVuZ3RoOyArK2kpIHtcblx0XHRmcCA9IGNmYi5GdWxsUGF0aHNbaV0uc2xpY2Uocm9vdC5sZW5ndGgpOyBmaSA9IGNmYi5GaWxlSW5kZXhbaV07XG5cdFx0aWYoIWZpLnNpemUgfHwgIWZpLmNvbnRlbnQgfHwgZnAgPT0gXCJcXHUwMDAxU2gzM3RKNVwiKSBjb250aW51ZTtcblx0XHR2YXIgc3RhcnQgPSBzdGFydF9jZDtcblxuXHRcdC8qIFRPRE86IENQNDM3IGZpbGVuYW1lICovXG5cdFx0dmFyIG5hbWVidWYgPSBuZXdfYnVmKGZwLmxlbmd0aCk7XG5cdFx0Zm9yKGogPSAwOyBqIDwgZnAubGVuZ3RoOyArK2opIG5hbWVidWYud3JpdGVfc2hpZnQoMSwgZnAuY2hhckNvZGVBdChqKSAmIDB4N0YpO1xuXHRcdG5hbWVidWYgPSBuYW1lYnVmLnNsaWNlKDAsIG5hbWVidWYubCk7XG5cdFx0Y3Jjc1tmY250XSA9IENSQzMyLmJ1ZihmaS5jb250ZW50LCAwKTtcblxuXHRcdHZhciBvdXRidWYgPSBmaS5jb250ZW50O1xuXHRcdGlmKG1ldGhvZCA9PSA4KSBvdXRidWYgPSBfZGVmbGF0ZVJhd1N5bmMob3V0YnVmKTtcblxuXHRcdC8qIGxvY2FsIGZpbGUgaGVhZGVyICovXG5cdFx0byA9IG5ld19idWYoMzApO1xuXHRcdG8ud3JpdGVfc2hpZnQoNCwgMHgwNDAzNGI1MCk7XG5cdFx0by53cml0ZV9zaGlmdCgyLCAyMCk7XG5cdFx0by53cml0ZV9zaGlmdCgyLCBmbGFncyk7XG5cdFx0by53cml0ZV9zaGlmdCgyLCBtZXRob2QpO1xuXHRcdC8qIFRPRE86IGxhc3QgbW9kIGZpbGUgdGltZS9kYXRlICovXG5cdFx0aWYoZmkubXQpIHdyaXRlX2Rvc19kYXRlKG8sIGZpLm10KTtcblx0XHRlbHNlIG8ud3JpdGVfc2hpZnQoNCwgMCk7XG5cdFx0by53cml0ZV9zaGlmdCgtNCwgKGZsYWdzICYgOCkgPyAwIDogY3Jjc1tmY250XSk7XG5cdFx0by53cml0ZV9zaGlmdCg0LCAgKGZsYWdzICYgOCkgPyAwIDogb3V0YnVmLmxlbmd0aCk7XG5cdFx0by53cml0ZV9zaGlmdCg0LCAgKGZsYWdzICYgOCkgPyAwIDogZmkuY29udGVudC5sZW5ndGgpO1xuXHRcdG8ud3JpdGVfc2hpZnQoMiwgbmFtZWJ1Zi5sZW5ndGgpO1xuXHRcdG8ud3JpdGVfc2hpZnQoMiwgMCk7XG5cblx0XHRzdGFydF9jZCArPSBvLmxlbmd0aDtcblx0XHRvdXQucHVzaChvKTtcblx0XHRzdGFydF9jZCArPSBuYW1lYnVmLmxlbmd0aDtcblx0XHRvdXQucHVzaChuYW1lYnVmKTtcblxuXHRcdC8qIFRPRE86IGVuY3J5cHRpb24gaGVhZGVyID8gKi9cblx0XHRzdGFydF9jZCArPSBvdXRidWYubGVuZ3RoO1xuXHRcdG91dC5wdXNoKG91dGJ1Zik7XG5cblx0XHQvKiBkYXRhIGRlc2NyaXB0b3IgKi9cblx0XHRpZihmbGFncyAmIDgpIHtcblx0XHRcdG8gPSBuZXdfYnVmKDEyKTtcblx0XHRcdG8ud3JpdGVfc2hpZnQoLTQsIGNyY3NbZmNudF0pO1xuXHRcdFx0by53cml0ZV9zaGlmdCg0LCBvdXRidWYubGVuZ3RoKTtcblx0XHRcdG8ud3JpdGVfc2hpZnQoNCwgZmkuY29udGVudC5sZW5ndGgpO1xuXHRcdFx0c3RhcnRfY2QgKz0gby5sO1xuXHRcdFx0b3V0LnB1c2gobyk7XG5cdFx0fVxuXG5cdFx0LyogY2VudHJhbCBkaXJlY3RvcnkgKi9cblx0XHRvID0gbmV3X2J1Zig0Nik7XG5cdFx0by53cml0ZV9zaGlmdCg0LCAweDAyMDE0YjUwKTtcblx0XHRvLndyaXRlX3NoaWZ0KDIsIDApO1xuXHRcdG8ud3JpdGVfc2hpZnQoMiwgMjApO1xuXHRcdG8ud3JpdGVfc2hpZnQoMiwgZmxhZ3MpO1xuXHRcdG8ud3JpdGVfc2hpZnQoMiwgbWV0aG9kKTtcblx0XHRvLndyaXRlX3NoaWZ0KDQsIDApOyAvKiBUT0RPOiBsYXN0IG1vZCBmaWxlIHRpbWUvZGF0ZSAqL1xuXHRcdG8ud3JpdGVfc2hpZnQoLTQsIGNyY3NbZmNudF0pO1xuXG5cdFx0by53cml0ZV9zaGlmdCg0LCBvdXRidWYubGVuZ3RoKTtcblx0XHRvLndyaXRlX3NoaWZ0KDQsIGZpLmNvbnRlbnQubGVuZ3RoKTtcblx0XHRvLndyaXRlX3NoaWZ0KDIsIG5hbWVidWYubGVuZ3RoKTtcblx0XHRvLndyaXRlX3NoaWZ0KDIsIDApO1xuXHRcdG8ud3JpdGVfc2hpZnQoMiwgMCk7XG5cdFx0by53cml0ZV9zaGlmdCgyLCAwKTtcblx0XHRvLndyaXRlX3NoaWZ0KDIsIDApO1xuXHRcdG8ud3JpdGVfc2hpZnQoNCwgMCk7XG5cdFx0by53cml0ZV9zaGlmdCg0LCBzdGFydCk7XG5cblx0XHRzel9jZCArPSBvLmw7XG5cdFx0Y2RpcnMucHVzaChvKTtcblx0XHRzel9jZCArPSBuYW1lYnVmLmxlbmd0aDtcblx0XHRjZGlycy5wdXNoKG5hbWVidWYpO1xuXHRcdCsrZmNudDtcblx0fVxuXG5cdC8qIGVuZCBvZiBjZW50cmFsIGRpcmVjdG9yeSAqL1xuXHRvID0gbmV3X2J1ZigyMik7XG5cdG8ud3JpdGVfc2hpZnQoNCwgMHgwNjA1NGI1MCk7XG5cdG8ud3JpdGVfc2hpZnQoMiwgMCk7XG5cdG8ud3JpdGVfc2hpZnQoMiwgMCk7XG5cdG8ud3JpdGVfc2hpZnQoMiwgZmNudCk7XG5cdG8ud3JpdGVfc2hpZnQoMiwgZmNudCk7XG5cdG8ud3JpdGVfc2hpZnQoNCwgc3pfY2QpO1xuXHRvLndyaXRlX3NoaWZ0KDQsIHN0YXJ0X2NkKTtcblx0by53cml0ZV9zaGlmdCgyLCAwKTtcblxuXHRyZXR1cm4gYmNvbmNhdCgoW2Jjb25jYXQoKG91dCkpLCBiY29uY2F0KGNkaXJzKSwgb10pKTtcbn1cbmZ1bmN0aW9uIGNmYl9uZXcob3B0cykge1xuXHR2YXIgbyA9ICh7fSk7XG5cdGluaXRfY2ZiKG8sIG9wdHMpO1xuXHRyZXR1cm4gbztcbn1cblxuZnVuY3Rpb24gY2ZiX2FkZChjZmIsIG5hbWUsIGNvbnRlbnQsIG9wdHMpIHtcblx0dmFyIHVuc2FmZSA9IG9wdHMgJiYgb3B0cy51bnNhZmU7XG5cdGlmKCF1bnNhZmUpIGluaXRfY2ZiKGNmYik7XG5cdHZhciBmaWxlID0gIXVuc2FmZSAmJiBDRkIuZmluZChjZmIsIG5hbWUpO1xuXHRpZighZmlsZSkge1xuXHRcdHZhciBmcGF0aCA9IGNmYi5GdWxsUGF0aHNbMF07XG5cdFx0aWYobmFtZS5zbGljZSgwLCBmcGF0aC5sZW5ndGgpID09IGZwYXRoKSBmcGF0aCA9IG5hbWU7XG5cdFx0ZWxzZSB7XG5cdFx0XHRpZihmcGF0aC5zbGljZSgtMSkgIT0gXCIvXCIpIGZwYXRoICs9IFwiL1wiO1xuXHRcdFx0ZnBhdGggPSAoZnBhdGggKyBuYW1lKS5yZXBsYWNlKFwiLy9cIixcIi9cIik7XG5cdFx0fVxuXHRcdGZpbGUgPSAoe25hbWU6IGZpbGVuYW1lKG5hbWUpLCB0eXBlOiAyfSk7XG5cdFx0Y2ZiLkZpbGVJbmRleC5wdXNoKGZpbGUpO1xuXHRcdGNmYi5GdWxsUGF0aHMucHVzaChmcGF0aCk7XG5cdFx0aWYoIXVuc2FmZSkgQ0ZCLnV0aWxzLmNmYl9nYyhjZmIpO1xuXHR9XG5maWxlLmNvbnRlbnQgPSAoY29udGVudCk7XG5cdGZpbGUuc2l6ZSA9IGNvbnRlbnQgPyBjb250ZW50Lmxlbmd0aCA6IDA7XG5cdGlmKG9wdHMpIHtcblx0XHRpZihvcHRzLkNMU0lEKSBmaWxlLmNsc2lkID0gb3B0cy5DTFNJRDtcblx0XHRpZihvcHRzLm10KSBmaWxlLm10ID0gb3B0cy5tdDtcblx0XHRpZihvcHRzLmN0KSBmaWxlLmN0ID0gb3B0cy5jdDtcblx0fVxuXHRyZXR1cm4gZmlsZTtcbn1cblxuZnVuY3Rpb24gY2ZiX2RlbChjZmIsIG5hbWUpIHtcblx0aW5pdF9jZmIoY2ZiKTtcblx0dmFyIGZpbGUgPSBDRkIuZmluZChjZmIsIG5hbWUpO1xuXHRpZihmaWxlKSBmb3IodmFyIGogPSAwOyBqIDwgY2ZiLkZpbGVJbmRleC5sZW5ndGg7ICsraikgaWYoY2ZiLkZpbGVJbmRleFtqXSA9PSBmaWxlKSB7XG5cdFx0Y2ZiLkZpbGVJbmRleC5zcGxpY2UoaiwgMSk7XG5cdFx0Y2ZiLkZ1bGxQYXRocy5zcGxpY2UoaiwgMSk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblx0cmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBjZmJfbW92KGNmYiwgb2xkX25hbWUsIG5ld19uYW1lKSB7XG5cdGluaXRfY2ZiKGNmYik7XG5cdHZhciBmaWxlID0gQ0ZCLmZpbmQoY2ZiLCBvbGRfbmFtZSk7XG5cdGlmKGZpbGUpIGZvcih2YXIgaiA9IDA7IGogPCBjZmIuRmlsZUluZGV4Lmxlbmd0aDsgKytqKSBpZihjZmIuRmlsZUluZGV4W2pdID09IGZpbGUpIHtcblx0XHRjZmIuRmlsZUluZGV4W2pdLm5hbWUgPSBmaWxlbmFtZShuZXdfbmFtZSk7XG5cdFx0Y2ZiLkZ1bGxQYXRoc1tqXSA9IG5ld19uYW1lO1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gY2ZiX2djKGNmYikgeyByZWJ1aWxkX2NmYihjZmIsIHRydWUpOyB9XG5cbmV4cG9ydHMuZmluZCA9IGZpbmQ7XG5leHBvcnRzLnJlYWQgPSByZWFkO1xuZXhwb3J0cy5wYXJzZSA9IHBhcnNlO1xuZXhwb3J0cy53cml0ZSA9IHdyaXRlO1xuZXhwb3J0cy53cml0ZUZpbGUgPSB3cml0ZV9maWxlO1xuZXhwb3J0cy51dGlscyA9IHtcblx0Y2ZiX25ldzogY2ZiX25ldyxcblx0Y2ZiX2FkZDogY2ZiX2FkZCxcblx0Y2ZiX2RlbDogY2ZiX2RlbCxcblx0Y2ZiX21vdjogY2ZiX21vdixcblx0Y2ZiX2djOiBjZmJfZ2MsXG5cdFJlYWRTaGlmdDogUmVhZFNoaWZ0LFxuXHRDaGVja0ZpZWxkOiBDaGVja0ZpZWxkLFxuXHRwcmVwX2Jsb2I6IHByZXBfYmxvYixcblx0YmNvbmNhdDogYmNvbmNhdCxcblx0dXNlX3psaWI6IHVzZV96bGliLFxuXHRfZGVmbGF0ZVJhdzogX2RlZmxhdGUsXG5cdF9pbmZsYXRlUmF3OiBfaW5mbGF0ZSxcblx0Y29uc3RzOiBjb25zdHNcbn07XG5cbnJldHVybiBleHBvcnRzO1xufSkoKTtcblxuaWYodHlwZW9mIHJlcXVpcmUgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBET19OT1RfRVhQT1JUX0NGQiA9PT0gJ3VuZGVmaW5lZCcpIHsgbW9kdWxlLmV4cG9ydHMgPSBDRkI7IH1cbiIsInZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxudmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ3N0cmVhbScpLlRyYW5zZm9ybVxudmFyIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2RlcicpLlN0cmluZ0RlY29kZXJcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcblxuZnVuY3Rpb24gQ2lwaGVyQmFzZSAoaGFzaE1vZGUpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcylcbiAgdGhpcy5oYXNoTW9kZSA9IHR5cGVvZiBoYXNoTW9kZSA9PT0gJ3N0cmluZydcbiAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICB0aGlzW2hhc2hNb2RlXSA9IHRoaXMuX2ZpbmFsT3JEaWdlc3RcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmZpbmFsID0gdGhpcy5fZmluYWxPckRpZ2VzdFxuICB9XG4gIGlmICh0aGlzLl9maW5hbCkge1xuICAgIHRoaXMuX19maW5hbCA9IHRoaXMuX2ZpbmFsXG4gICAgdGhpcy5fZmluYWwgPSBudWxsXG4gIH1cbiAgdGhpcy5fZGVjb2RlciA9IG51bGxcbiAgdGhpcy5fZW5jb2RpbmcgPSBudWxsXG59XG5pbmhlcml0cyhDaXBoZXJCYXNlLCBUcmFuc2Zvcm0pXG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhLCBpbnB1dEVuYywgb3V0cHV0RW5jKSB7XG4gIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICBkYXRhID0gQnVmZmVyLmZyb20oZGF0YSwgaW5wdXRFbmMpXG4gIH1cblxuICB2YXIgb3V0RGF0YSA9IHRoaXMuX3VwZGF0ZShkYXRhKVxuICBpZiAodGhpcy5oYXNoTW9kZSkgcmV0dXJuIHRoaXNcblxuICBpZiAob3V0cHV0RW5jKSB7XG4gICAgb3V0RGF0YSA9IHRoaXMuX3RvU3RyaW5nKG91dERhdGEsIG91dHB1dEVuYylcbiAgfVxuXG4gIHJldHVybiBvdXREYXRhXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEF1dG9QYWRkaW5nID0gZnVuY3Rpb24gKCkge31cbkNpcGhlckJhc2UucHJvdG90eXBlLmdldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIGdldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEF1dGhUYWcgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcigndHJ5aW5nIHRvIHNldCBhdXRoIHRhZyBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLnNldEFBRCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCd0cnlpbmcgdG8gc2V0IGFhZCBpbiB1bnN1cHBvcnRlZCBzdGF0ZScpXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoZGF0YSwgXywgbmV4dCkge1xuICB2YXIgZXJyXG4gIHRyeSB7XG4gICAgaWYgKHRoaXMuaGFzaE1vZGUpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZShkYXRhKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnB1c2godGhpcy5fdXBkYXRlKGRhdGEpKVxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGVyciA9IGVcbiAgfSBmaW5hbGx5IHtcbiAgICBuZXh0KGVycilcbiAgfVxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX2ZsdXNoID0gZnVuY3Rpb24gKGRvbmUpIHtcbiAgdmFyIGVyclxuICB0cnkge1xuICAgIHRoaXMucHVzaCh0aGlzLl9fZmluYWwoKSlcbiAgfSBjYXRjaCAoZSkge1xuICAgIGVyciA9IGVcbiAgfVxuXG4gIGRvbmUoZXJyKVxufVxuQ2lwaGVyQmFzZS5wcm90b3R5cGUuX2ZpbmFsT3JEaWdlc3QgPSBmdW5jdGlvbiAob3V0cHV0RW5jKSB7XG4gIHZhciBvdXREYXRhID0gdGhpcy5fX2ZpbmFsKCkgfHwgQnVmZmVyLmFsbG9jKDApXG4gIGlmIChvdXRwdXRFbmMpIHtcbiAgICBvdXREYXRhID0gdGhpcy5fdG9TdHJpbmcob3V0RGF0YSwgb3V0cHV0RW5jLCB0cnVlKVxuICB9XG4gIHJldHVybiBvdXREYXRhXG59XG5cbkNpcGhlckJhc2UucHJvdG90eXBlLl90b1N0cmluZyA9IGZ1bmN0aW9uICh2YWx1ZSwgZW5jLCBmaW4pIHtcbiAgaWYgKCF0aGlzLl9kZWNvZGVyKSB7XG4gICAgdGhpcy5fZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKGVuYylcbiAgICB0aGlzLl9lbmNvZGluZyA9IGVuY1xuICB9XG5cbiAgaWYgKHRoaXMuX2VuY29kaW5nICE9PSBlbmMpIHRocm93IG5ldyBFcnJvcignY2FuXFwndCBzd2l0Y2ggZW5jb2RpbmdzJylcblxuICB2YXIgb3V0ID0gdGhpcy5fZGVjb2Rlci53cml0ZSh2YWx1ZSlcbiAgaWYgKGZpbikge1xuICAgIG91dCArPSB0aGlzLl9kZWNvZGVyLmVuZCgpXG4gIH1cblxuICByZXR1cm4gb3V0XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQ2lwaGVyQmFzZVxuIiwicmVxdWlyZSgnLi4vbW9kdWxlcy93ZWIuaW1tZWRpYXRlJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uL21vZHVsZXMvX2NvcmUnKS5zZXRJbW1lZGlhdGU7IiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIGlmKHR5cGVvZiBpdCAhPSAnZnVuY3Rpb24nKXRocm93IFR5cGVFcnJvcihpdCArICcgaXMgbm90IGEgZnVuY3Rpb24hJyk7XG4gIHJldHVybiBpdDtcbn07IiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgaWYoIWlzT2JqZWN0KGl0KSl0aHJvdyBUeXBlRXJyb3IoaXQgKyAnIGlzIG5vdCBhbiBvYmplY3QhJyk7XG4gIHJldHVybiBpdDtcbn07IiwidmFyIHRvU3RyaW5nID0ge30udG9TdHJpbmc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChpdCkuc2xpY2UoOCwgLTEpO1xufTsiLCJ2YXIgY29yZSA9IG1vZHVsZS5leHBvcnRzID0ge3ZlcnNpb246ICcyLjMuMCd9O1xuaWYodHlwZW9mIF9fZSA9PSAnbnVtYmVyJylfX2UgPSBjb3JlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmIiwiLy8gb3B0aW9uYWwgLyBzaW1wbGUgY29udGV4dCBiaW5kaW5nXG52YXIgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmbiwgdGhhdCwgbGVuZ3RoKXtcbiAgYUZ1bmN0aW9uKGZuKTtcbiAgaWYodGhhdCA9PT0gdW5kZWZpbmVkKXJldHVybiBmbjtcbiAgc3dpdGNoKGxlbmd0aCl7XG4gICAgY2FzZSAxOiByZXR1cm4gZnVuY3Rpb24oYSl7XG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhKTtcbiAgICB9O1xuICAgIGNhc2UgMjogcmV0dXJuIGZ1bmN0aW9uKGEsIGIpe1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYik7XG4gICAgfTtcbiAgICBjYXNlIDM6IHJldHVybiBmdW5jdGlvbihhLCBiLCBjKXtcbiAgICAgIHJldHVybiBmbi5jYWxsKHRoYXQsIGEsIGIsIGMpO1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKC8qIC4uLmFyZ3MgKi8pe1xuICAgIHJldHVybiBmbi5hcHBseSh0aGF0LCBhcmd1bWVudHMpO1xuICB9O1xufTsiLCIvLyBUaGFuaydzIElFOCBmb3IgaGlzIGZ1bm55IGRlZmluZVByb3BlcnR5XG5tb2R1bGUuZXhwb3J0cyA9ICFyZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uKCl7XG4gIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdhJywge2dldDogZnVuY3Rpb24oKXsgcmV0dXJuIDc7IH19KS5hICE9IDc7XG59KTsiLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKVxuICAsIGRvY3VtZW50ID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykuZG9jdW1lbnRcbiAgLy8gaW4gb2xkIElFIHR5cGVvZiBkb2N1bWVudC5jcmVhdGVFbGVtZW50IGlzICdvYmplY3QnXG4gICwgaXMgPSBpc09iamVjdChkb2N1bWVudCkgJiYgaXNPYmplY3QoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIGlzID8gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChpdCkgOiB7fTtcbn07IiwidmFyIGdsb2JhbCAgICA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpXG4gICwgY29yZSAgICAgID0gcmVxdWlyZSgnLi9fY29yZScpXG4gICwgY3R4ICAgICAgID0gcmVxdWlyZSgnLi9fY3R4JylcbiAgLCBoaWRlICAgICAgPSByZXF1aXJlKCcuL19oaWRlJylcbiAgLCBQUk9UT1RZUEUgPSAncHJvdG90eXBlJztcblxudmFyICRleHBvcnQgPSBmdW5jdGlvbih0eXBlLCBuYW1lLCBzb3VyY2Upe1xuICB2YXIgSVNfRk9SQ0VEID0gdHlwZSAmICRleHBvcnQuRlxuICAgICwgSVNfR0xPQkFMID0gdHlwZSAmICRleHBvcnQuR1xuICAgICwgSVNfU1RBVElDID0gdHlwZSAmICRleHBvcnQuU1xuICAgICwgSVNfUFJPVE8gID0gdHlwZSAmICRleHBvcnQuUFxuICAgICwgSVNfQklORCAgID0gdHlwZSAmICRleHBvcnQuQlxuICAgICwgSVNfV1JBUCAgID0gdHlwZSAmICRleHBvcnQuV1xuICAgICwgZXhwb3J0cyAgID0gSVNfR0xPQkFMID8gY29yZSA6IGNvcmVbbmFtZV0gfHwgKGNvcmVbbmFtZV0gPSB7fSlcbiAgICAsIGV4cFByb3RvICA9IGV4cG9ydHNbUFJPVE9UWVBFXVxuICAgICwgdGFyZ2V0ICAgID0gSVNfR0xPQkFMID8gZ2xvYmFsIDogSVNfU1RBVElDID8gZ2xvYmFsW25hbWVdIDogKGdsb2JhbFtuYW1lXSB8fCB7fSlbUFJPVE9UWVBFXVxuICAgICwga2V5LCBvd24sIG91dDtcbiAgaWYoSVNfR0xPQkFMKXNvdXJjZSA9IG5hbWU7XG4gIGZvcihrZXkgaW4gc291cmNlKXtcbiAgICAvLyBjb250YWlucyBpbiBuYXRpdmVcbiAgICBvd24gPSAhSVNfRk9SQ0VEICYmIHRhcmdldCAmJiB0YXJnZXRba2V5XSAhPT0gdW5kZWZpbmVkO1xuICAgIGlmKG93biAmJiBrZXkgaW4gZXhwb3J0cyljb250aW51ZTtcbiAgICAvLyBleHBvcnQgbmF0aXZlIG9yIHBhc3NlZFxuICAgIG91dCA9IG93biA/IHRhcmdldFtrZXldIDogc291cmNlW2tleV07XG4gICAgLy8gcHJldmVudCBnbG9iYWwgcG9sbHV0aW9uIGZvciBuYW1lc3BhY2VzXG4gICAgZXhwb3J0c1trZXldID0gSVNfR0xPQkFMICYmIHR5cGVvZiB0YXJnZXRba2V5XSAhPSAnZnVuY3Rpb24nID8gc291cmNlW2tleV1cbiAgICAvLyBiaW5kIHRpbWVycyB0byBnbG9iYWwgZm9yIGNhbGwgZnJvbSBleHBvcnQgY29udGV4dFxuICAgIDogSVNfQklORCAmJiBvd24gPyBjdHgob3V0LCBnbG9iYWwpXG4gICAgLy8gd3JhcCBnbG9iYWwgY29uc3RydWN0b3JzIGZvciBwcmV2ZW50IGNoYW5nZSB0aGVtIGluIGxpYnJhcnlcbiAgICA6IElTX1dSQVAgJiYgdGFyZ2V0W2tleV0gPT0gb3V0ID8gKGZ1bmN0aW9uKEMpe1xuICAgICAgdmFyIEYgPSBmdW5jdGlvbihhLCBiLCBjKXtcbiAgICAgICAgaWYodGhpcyBpbnN0YW5jZW9mIEMpe1xuICAgICAgICAgIHN3aXRjaChhcmd1bWVudHMubGVuZ3RoKXtcbiAgICAgICAgICAgIGNhc2UgMDogcmV0dXJuIG5ldyBDO1xuICAgICAgICAgICAgY2FzZSAxOiByZXR1cm4gbmV3IEMoYSk7XG4gICAgICAgICAgICBjYXNlIDI6IHJldHVybiBuZXcgQyhhLCBiKTtcbiAgICAgICAgICB9IHJldHVybiBuZXcgQyhhLCBiLCBjKTtcbiAgICAgICAgfSByZXR1cm4gQy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICAgIEZbUFJPVE9UWVBFXSA9IENbUFJPVE9UWVBFXTtcbiAgICAgIHJldHVybiBGO1xuICAgIC8vIG1ha2Ugc3RhdGljIHZlcnNpb25zIGZvciBwcm90b3R5cGUgbWV0aG9kc1xuICAgIH0pKG91dCkgOiBJU19QUk9UTyAmJiB0eXBlb2Ygb3V0ID09ICdmdW5jdGlvbicgPyBjdHgoRnVuY3Rpb24uY2FsbCwgb3V0KSA6IG91dDtcbiAgICAvLyBleHBvcnQgcHJvdG8gbWV0aG9kcyB0byBjb3JlLiVDT05TVFJVQ1RPUiUubWV0aG9kcy4lTkFNRSVcbiAgICBpZihJU19QUk9UTyl7XG4gICAgICAoZXhwb3J0cy52aXJ0dWFsIHx8IChleHBvcnRzLnZpcnR1YWwgPSB7fSkpW2tleV0gPSBvdXQ7XG4gICAgICAvLyBleHBvcnQgcHJvdG8gbWV0aG9kcyB0byBjb3JlLiVDT05TVFJVQ1RPUiUucHJvdG90eXBlLiVOQU1FJVxuICAgICAgaWYodHlwZSAmICRleHBvcnQuUiAmJiBleHBQcm90byAmJiAhZXhwUHJvdG9ba2V5XSloaWRlKGV4cFByb3RvLCBrZXksIG91dCk7XG4gICAgfVxuICB9XG59O1xuLy8gdHlwZSBiaXRtYXBcbiRleHBvcnQuRiA9IDE7ICAgLy8gZm9yY2VkXG4kZXhwb3J0LkcgPSAyOyAgIC8vIGdsb2JhbFxuJGV4cG9ydC5TID0gNDsgICAvLyBzdGF0aWNcbiRleHBvcnQuUCA9IDg7ICAgLy8gcHJvdG9cbiRleHBvcnQuQiA9IDE2OyAgLy8gYmluZFxuJGV4cG9ydC5XID0gMzI7ICAvLyB3cmFwXG4kZXhwb3J0LlUgPSA2NDsgIC8vIHNhZmVcbiRleHBvcnQuUiA9IDEyODsgLy8gcmVhbCBwcm90byBtZXRob2QgZm9yIGBsaWJyYXJ5YCBcbm1vZHVsZS5leHBvcnRzID0gJGV4cG9ydDsiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGV4ZWMpe1xuICB0cnkge1xuICAgIHJldHVybiAhIWV4ZWMoKTtcbiAgfSBjYXRjaChlKXtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufTsiLCIvLyBodHRwczovL2dpdGh1Yi5jb20vemxvaXJvY2svY29yZS1qcy9pc3N1ZXMvODYjaXNzdWVjb21tZW50LTExNTc1OTAyOFxudmFyIGdsb2JhbCA9IG1vZHVsZS5leHBvcnRzID0gdHlwZW9mIHdpbmRvdyAhPSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuTWF0aCA9PSBNYXRoXG4gID8gd2luZG93IDogdHlwZW9mIHNlbGYgIT0gJ3VuZGVmaW5lZCcgJiYgc2VsZi5NYXRoID09IE1hdGggPyBzZWxmIDogRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcbmlmKHR5cGVvZiBfX2cgPT0gJ251bWJlcicpX19nID0gZ2xvYmFsOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmIiwidmFyIGRQICAgICAgICAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKVxuICAsIGNyZWF0ZURlc2MgPSByZXF1aXJlKCcuL19wcm9wZXJ0eS1kZXNjJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBmdW5jdGlvbihvYmplY3QsIGtleSwgdmFsdWUpe1xuICByZXR1cm4gZFAuZihvYmplY3QsIGtleSwgY3JlYXRlRGVzYygxLCB2YWx1ZSkpO1xufSA6IGZ1bmN0aW9uKG9iamVjdCwga2V5LCB2YWx1ZSl7XG4gIG9iamVjdFtrZXldID0gdmFsdWU7XG4gIHJldHVybiBvYmplY3Q7XG59OyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykuZG9jdW1lbnQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50OyIsIm1vZHVsZS5leHBvcnRzID0gIXJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgJiYgIXJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24oKXtcclxuICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KHJlcXVpcmUoJy4vX2RvbS1jcmVhdGUnKSgnZGl2JyksICdhJywge2dldDogZnVuY3Rpb24oKXsgcmV0dXJuIDc7IH19KS5hICE9IDc7XHJcbn0pOyIsIi8vIGZhc3QgYXBwbHksIGh0dHA6Ly9qc3BlcmYubG5raXQuY29tL2Zhc3QtYXBwbHkvNVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmbiwgYXJncywgdGhhdCl7XG4gIHZhciB1biA9IHRoYXQgPT09IHVuZGVmaW5lZDtcbiAgc3dpdGNoKGFyZ3MubGVuZ3RoKXtcbiAgICBjYXNlIDA6IHJldHVybiB1biA/IGZuKClcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCk7XG4gICAgY2FzZSAxOiByZXR1cm4gdW4gPyBmbihhcmdzWzBdKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0LCBhcmdzWzBdKTtcbiAgICBjYXNlIDI6IHJldHVybiB1biA/IGZuKGFyZ3NbMF0sIGFyZ3NbMV0pXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgIGNhc2UgMzogcmV0dXJuIHVuID8gZm4oYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSlcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCwgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgY2FzZSA0OiByZXR1cm4gdW4gPyBmbihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0LCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdKTtcbiAgfSByZXR1cm4gICAgICAgICAgICAgIGZuLmFwcGx5KHRoYXQsIGFyZ3MpO1xufTsiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIHR5cGVvZiBpdCA9PT0gJ29iamVjdCcgPyBpdCAhPT0gbnVsbCA6IHR5cGVvZiBpdCA9PT0gJ2Z1bmN0aW9uJztcbn07IiwidmFyIGFuT2JqZWN0ICAgICAgID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0JylcbiAgLCBJRThfRE9NX0RFRklORSA9IHJlcXVpcmUoJy4vX2llOC1kb20tZGVmaW5lJylcbiAgLCB0b1ByaW1pdGl2ZSAgICA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpXG4gICwgZFAgICAgICAgICAgICAgPSBPYmplY3QuZGVmaW5lUHJvcGVydHk7XG5cbmV4cG9ydHMuZiA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBPYmplY3QuZGVmaW5lUHJvcGVydHkgOiBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0eShPLCBQLCBBdHRyaWJ1dGVzKXtcbiAgYW5PYmplY3QoTyk7XG4gIFAgPSB0b1ByaW1pdGl2ZShQLCB0cnVlKTtcbiAgYW5PYmplY3QoQXR0cmlidXRlcyk7XG4gIGlmKElFOF9ET01fREVGSU5FKXRyeSB7XG4gICAgcmV0dXJuIGRQKE8sIFAsIEF0dHJpYnV0ZXMpO1xuICB9IGNhdGNoKGUpeyAvKiBlbXB0eSAqLyB9XG4gIGlmKCdnZXQnIGluIEF0dHJpYnV0ZXMgfHwgJ3NldCcgaW4gQXR0cmlidXRlcyl0aHJvdyBUeXBlRXJyb3IoJ0FjY2Vzc29ycyBub3Qgc3VwcG9ydGVkIScpO1xuICBpZigndmFsdWUnIGluIEF0dHJpYnV0ZXMpT1tQXSA9IEF0dHJpYnV0ZXMudmFsdWU7XG4gIHJldHVybiBPO1xufTsiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGJpdG1hcCwgdmFsdWUpe1xuICByZXR1cm4ge1xuICAgIGVudW1lcmFibGUgIDogIShiaXRtYXAgJiAxKSxcbiAgICBjb25maWd1cmFibGU6ICEoYml0bWFwICYgMiksXG4gICAgd3JpdGFibGUgICAgOiAhKGJpdG1hcCAmIDQpLFxuICAgIHZhbHVlICAgICAgIDogdmFsdWVcbiAgfTtcbn07IiwidmFyIGN0eCAgICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vX2N0eCcpXG4gICwgaW52b2tlICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9faW52b2tlJylcbiAgLCBodG1sICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19odG1sJylcbiAgLCBjZWwgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19kb20tY3JlYXRlJylcbiAgLCBnbG9iYWwgICAgICAgICAgICAgPSByZXF1aXJlKCcuL19nbG9iYWwnKVxuICAsIHByb2Nlc3MgICAgICAgICAgICA9IGdsb2JhbC5wcm9jZXNzXG4gICwgc2V0VGFzayAgICAgICAgICAgID0gZ2xvYmFsLnNldEltbWVkaWF0ZVxuICAsIGNsZWFyVGFzayAgICAgICAgICA9IGdsb2JhbC5jbGVhckltbWVkaWF0ZVxuICAsIE1lc3NhZ2VDaGFubmVsICAgICA9IGdsb2JhbC5NZXNzYWdlQ2hhbm5lbFxuICAsIGNvdW50ZXIgICAgICAgICAgICA9IDBcbiAgLCBxdWV1ZSAgICAgICAgICAgICAgPSB7fVxuICAsIE9OUkVBRFlTVEFURUNIQU5HRSA9ICdvbnJlYWR5c3RhdGVjaGFuZ2UnXG4gICwgZGVmZXIsIGNoYW5uZWwsIHBvcnQ7XG52YXIgcnVuID0gZnVuY3Rpb24oKXtcbiAgdmFyIGlkID0gK3RoaXM7XG4gIGlmKHF1ZXVlLmhhc093blByb3BlcnR5KGlkKSl7XG4gICAgdmFyIGZuID0gcXVldWVbaWRdO1xuICAgIGRlbGV0ZSBxdWV1ZVtpZF07XG4gICAgZm4oKTtcbiAgfVxufTtcbnZhciBsaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgcnVuLmNhbGwoZXZlbnQuZGF0YSk7XG59O1xuLy8gTm9kZS5qcyAwLjkrICYgSUUxMCsgaGFzIHNldEltbWVkaWF0ZSwgb3RoZXJ3aXNlOlxuaWYoIXNldFRhc2sgfHwgIWNsZWFyVGFzayl7XG4gIHNldFRhc2sgPSBmdW5jdGlvbiBzZXRJbW1lZGlhdGUoZm4pe1xuICAgIHZhciBhcmdzID0gW10sIGkgPSAxO1xuICAgIHdoaWxlKGFyZ3VtZW50cy5sZW5ndGggPiBpKWFyZ3MucHVzaChhcmd1bWVudHNbaSsrXSk7XG4gICAgcXVldWVbKytjb3VudGVyXSA9IGZ1bmN0aW9uKCl7XG4gICAgICBpbnZva2UodHlwZW9mIGZuID09ICdmdW5jdGlvbicgPyBmbiA6IEZ1bmN0aW9uKGZuKSwgYXJncyk7XG4gICAgfTtcbiAgICBkZWZlcihjb3VudGVyKTtcbiAgICByZXR1cm4gY291bnRlcjtcbiAgfTtcbiAgY2xlYXJUYXNrID0gZnVuY3Rpb24gY2xlYXJJbW1lZGlhdGUoaWQpe1xuICAgIGRlbGV0ZSBxdWV1ZVtpZF07XG4gIH07XG4gIC8vIE5vZGUuanMgMC44LVxuICBpZihyZXF1aXJlKCcuL19jb2YnKShwcm9jZXNzKSA9PSAncHJvY2Vzcycpe1xuICAgIGRlZmVyID0gZnVuY3Rpb24oaWQpe1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhjdHgocnVuLCBpZCwgMSkpO1xuICAgIH07XG4gIC8vIEJyb3dzZXJzIHdpdGggTWVzc2FnZUNoYW5uZWwsIGluY2x1ZGVzIFdlYldvcmtlcnNcbiAgfSBlbHNlIGlmKE1lc3NhZ2VDaGFubmVsKXtcbiAgICBjaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsO1xuICAgIHBvcnQgICAgPSBjaGFubmVsLnBvcnQyO1xuICAgIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gbGlzdGVuZXI7XG4gICAgZGVmZXIgPSBjdHgocG9ydC5wb3N0TWVzc2FnZSwgcG9ydCwgMSk7XG4gIC8vIEJyb3dzZXJzIHdpdGggcG9zdE1lc3NhZ2UsIHNraXAgV2ViV29ya2Vyc1xuICAvLyBJRTggaGFzIHBvc3RNZXNzYWdlLCBidXQgaXQncyBzeW5jICYgdHlwZW9mIGl0cyBwb3N0TWVzc2FnZSBpcyAnb2JqZWN0J1xuICB9IGVsc2UgaWYoZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIgJiYgdHlwZW9mIHBvc3RNZXNzYWdlID09ICdmdW5jdGlvbicgJiYgIWdsb2JhbC5pbXBvcnRTY3JpcHRzKXtcbiAgICBkZWZlciA9IGZ1bmN0aW9uKGlkKXtcbiAgICAgIGdsb2JhbC5wb3N0TWVzc2FnZShpZCArICcnLCAnKicpO1xuICAgIH07XG4gICAgZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBsaXN0ZW5lciwgZmFsc2UpO1xuICAvLyBJRTgtXG4gIH0gZWxzZSBpZihPTlJFQURZU1RBVEVDSEFOR0UgaW4gY2VsKCdzY3JpcHQnKSl7XG4gICAgZGVmZXIgPSBmdW5jdGlvbihpZCl7XG4gICAgICBodG1sLmFwcGVuZENoaWxkKGNlbCgnc2NyaXB0JykpW09OUkVBRFlTVEFURUNIQU5HRV0gPSBmdW5jdGlvbigpe1xuICAgICAgICBodG1sLnJlbW92ZUNoaWxkKHRoaXMpO1xuICAgICAgICBydW4uY2FsbChpZCk7XG4gICAgICB9O1xuICAgIH07XG4gIC8vIFJlc3Qgb2xkIGJyb3dzZXJzXG4gIH0gZWxzZSB7XG4gICAgZGVmZXIgPSBmdW5jdGlvbihpZCl7XG4gICAgICBzZXRUaW1lb3V0KGN0eChydW4sIGlkLCAxKSwgMCk7XG4gICAgfTtcbiAgfVxufVxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNldDogICBzZXRUYXNrLFxuICBjbGVhcjogY2xlYXJUYXNrXG59OyIsIi8vIDcuMS4xIFRvUHJpbWl0aXZlKGlucHV0IFssIFByZWZlcnJlZFR5cGVdKVxudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG4vLyBpbnN0ZWFkIG9mIHRoZSBFUzYgc3BlYyB2ZXJzaW9uLCB3ZSBkaWRuJ3QgaW1wbGVtZW50IEBAdG9QcmltaXRpdmUgY2FzZVxuLy8gYW5kIHRoZSBzZWNvbmQgYXJndW1lbnQgLSBmbGFnIC0gcHJlZmVycmVkIHR5cGUgaXMgYSBzdHJpbmdcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQsIFMpe1xuICBpZighaXNPYmplY3QoaXQpKXJldHVybiBpdDtcbiAgdmFyIGZuLCB2YWw7XG4gIGlmKFMgJiYgdHlwZW9mIChmbiA9IGl0LnRvU3RyaW5nKSA9PSAnZnVuY3Rpb24nICYmICFpc09iamVjdCh2YWwgPSBmbi5jYWxsKGl0KSkpcmV0dXJuIHZhbDtcbiAgaWYodHlwZW9mIChmbiA9IGl0LnZhbHVlT2YpID09ICdmdW5jdGlvbicgJiYgIWlzT2JqZWN0KHZhbCA9IGZuLmNhbGwoaXQpKSlyZXR1cm4gdmFsO1xuICBpZighUyAmJiB0eXBlb2YgKGZuID0gaXQudG9TdHJpbmcpID09ICdmdW5jdGlvbicgJiYgIWlzT2JqZWN0KHZhbCA9IGZuLmNhbGwoaXQpKSlyZXR1cm4gdmFsO1xuICB0aHJvdyBUeXBlRXJyb3IoXCJDYW4ndCBjb252ZXJ0IG9iamVjdCB0byBwcmltaXRpdmUgdmFsdWVcIik7XG59OyIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0JylcbiAgLCAkdGFzayAgID0gcmVxdWlyZSgnLi9fdGFzaycpO1xuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LkIsIHtcbiAgc2V0SW1tZWRpYXRlOiAgICR0YXNrLnNldCxcbiAgY2xlYXJJbW1lZGlhdGU6ICR0YXNrLmNsZWFyXG59KTsiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gTk9URTogVGhlc2UgdHlwZSBjaGVja2luZyBmdW5jdGlvbnMgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYGluc3RhbmNlb2ZgXG4vLyBiZWNhdXNlIGl0IGlzIGZyYWdpbGUgYW5kIGNhbiBiZSBlYXNpbHkgZmFrZWQgd2l0aCBgT2JqZWN0LmNyZWF0ZSgpYC5cblxuZnVuY3Rpb24gaXNBcnJheShhcmcpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkpIHtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheShhcmcpO1xuICB9XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhhcmcpID09PSAnW29iamVjdCBBcnJheV0nO1xufVxuZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTtcblxuZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nO1xufVxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBpc0Jvb2xlYW47XG5cbmZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsID0gaXNOdWxsO1xuXG5mdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGxPclVuZGVmaW5lZCA9IGlzTnVsbE9yVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuZXhwb3J0cy5pc051bWJlciA9IGlzTnVtYmVyO1xuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuZXhwb3J0cy5pc1N0cmluZyA9IGlzU3RyaW5nO1xuXG5mdW5jdGlvbiBpc1N5bWJvbChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnO1xufVxuZXhwb3J0cy5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuZXhwb3J0cy5pc1VuZGVmaW5lZCA9IGlzVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gb2JqZWN0VG9TdHJpbmcocmUpID09PSAnW29iamVjdCBSZWdFeHBdJztcbn1cbmV4cG9ydHMuaXNSZWdFeHAgPSBpc1JlZ0V4cDtcblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5leHBvcnRzLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG5cbmZ1bmN0aW9uIGlzRGF0ZShkKSB7XG4gIHJldHVybiBvYmplY3RUb1N0cmluZyhkKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufVxuZXhwb3J0cy5pc0RhdGUgPSBpc0RhdGU7XG5cbmZ1bmN0aW9uIGlzRXJyb3IoZSkge1xuICByZXR1cm4gKG9iamVjdFRvU3RyaW5nKGUpID09PSAnW29iamVjdCBFcnJvcl0nIHx8IGUgaW5zdGFuY2VvZiBFcnJvcik7XG59XG5leHBvcnRzLmlzRXJyb3IgPSBpc0Vycm9yO1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnYm9vbGVhbicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdudW1iZXInIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCcgfHwgIC8vIEVTNiBzeW1ib2xcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICd1bmRlZmluZWQnO1xufVxuZXhwb3J0cy5pc1ByaW1pdGl2ZSA9IGlzUHJpbWl0aXZlO1xuXG5leHBvcnRzLmlzQnVmZmVyID0gQnVmZmVyLmlzQnVmZmVyO1xuXG5mdW5jdGlvbiBvYmplY3RUb1N0cmluZyhvKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7XG59XG4iLCJ2YXIgZWxsaXB0aWMgPSByZXF1aXJlKCdlbGxpcHRpYycpXG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY3JlYXRlRUNESCAoY3VydmUpIHtcbiAgcmV0dXJuIG5ldyBFQ0RIKGN1cnZlKVxufVxuXG52YXIgYWxpYXNlcyA9IHtcbiAgc2VjcDI1NmsxOiB7XG4gICAgbmFtZTogJ3NlY3AyNTZrMScsXG4gICAgYnl0ZUxlbmd0aDogMzJcbiAgfSxcbiAgc2VjcDIyNHIxOiB7XG4gICAgbmFtZTogJ3AyMjQnLFxuICAgIGJ5dGVMZW5ndGg6IDI4XG4gIH0sXG4gIHByaW1lMjU2djE6IHtcbiAgICBuYW1lOiAncDI1NicsXG4gICAgYnl0ZUxlbmd0aDogMzJcbiAgfSxcbiAgcHJpbWUxOTJ2MToge1xuICAgIG5hbWU6ICdwMTkyJyxcbiAgICBieXRlTGVuZ3RoOiAyNFxuICB9LFxuICBlZDI1NTE5OiB7XG4gICAgbmFtZTogJ2VkMjU1MTknLFxuICAgIGJ5dGVMZW5ndGg6IDMyXG4gIH0sXG4gIHNlY3AzODRyMToge1xuICAgIG5hbWU6ICdwMzg0JyxcbiAgICBieXRlTGVuZ3RoOiA0OFxuICB9LFxuICBzZWNwNTIxcjE6IHtcbiAgICBuYW1lOiAncDUyMScsXG4gICAgYnl0ZUxlbmd0aDogNjZcbiAgfVxufVxuXG5hbGlhc2VzLnAyMjQgPSBhbGlhc2VzLnNlY3AyMjRyMVxuYWxpYXNlcy5wMjU2ID0gYWxpYXNlcy5zZWNwMjU2cjEgPSBhbGlhc2VzLnByaW1lMjU2djFcbmFsaWFzZXMucDE5MiA9IGFsaWFzZXMuc2VjcDE5MnIxID0gYWxpYXNlcy5wcmltZTE5MnYxXG5hbGlhc2VzLnAzODQgPSBhbGlhc2VzLnNlY3AzODRyMVxuYWxpYXNlcy5wNTIxID0gYWxpYXNlcy5zZWNwNTIxcjFcblxuZnVuY3Rpb24gRUNESCAoY3VydmUpIHtcbiAgdGhpcy5jdXJ2ZVR5cGUgPSBhbGlhc2VzW2N1cnZlXVxuICBpZiAoIXRoaXMuY3VydmVUeXBlKSB7XG4gICAgdGhpcy5jdXJ2ZVR5cGUgPSB7XG4gICAgICBuYW1lOiBjdXJ2ZVxuICAgIH1cbiAgfVxuICB0aGlzLmN1cnZlID0gbmV3IGVsbGlwdGljLmVjKHRoaXMuY3VydmVUeXBlLm5hbWUpIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbmV3LWNhcFxuICB0aGlzLmtleXMgPSB2b2lkIDBcbn1cblxuRUNESC5wcm90b3R5cGUuZ2VuZXJhdGVLZXlzID0gZnVuY3Rpb24gKGVuYywgZm9ybWF0KSB7XG4gIHRoaXMua2V5cyA9IHRoaXMuY3VydmUuZ2VuS2V5UGFpcigpXG4gIHJldHVybiB0aGlzLmdldFB1YmxpY0tleShlbmMsIGZvcm1hdClcbn1cblxuRUNESC5wcm90b3R5cGUuY29tcHV0ZVNlY3JldCA9IGZ1bmN0aW9uIChvdGhlciwgaW5lbmMsIGVuYykge1xuICBpbmVuYyA9IGluZW5jIHx8ICd1dGY4J1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihvdGhlcikpIHtcbiAgICBvdGhlciA9IG5ldyBCdWZmZXIob3RoZXIsIGluZW5jKVxuICB9XG4gIHZhciBvdGhlclB1YiA9IHRoaXMuY3VydmUua2V5RnJvbVB1YmxpYyhvdGhlcikuZ2V0UHVibGljKClcbiAgdmFyIG91dCA9IG90aGVyUHViLm11bCh0aGlzLmtleXMuZ2V0UHJpdmF0ZSgpKS5nZXRYKClcbiAgcmV0dXJuIGZvcm1hdFJldHVyblZhbHVlKG91dCwgZW5jLCB0aGlzLmN1cnZlVHlwZS5ieXRlTGVuZ3RoKVxufVxuXG5FQ0RILnByb3RvdHlwZS5nZXRQdWJsaWNLZXkgPSBmdW5jdGlvbiAoZW5jLCBmb3JtYXQpIHtcbiAgdmFyIGtleSA9IHRoaXMua2V5cy5nZXRQdWJsaWMoZm9ybWF0ID09PSAnY29tcHJlc3NlZCcsIHRydWUpXG4gIGlmIChmb3JtYXQgPT09ICdoeWJyaWQnKSB7XG4gICAgaWYgKGtleVtrZXkubGVuZ3RoIC0gMV0gJSAyKSB7XG4gICAgICBrZXlbMF0gPSA3XG4gICAgfSBlbHNlIHtcbiAgICAgIGtleVswXSA9IDZcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZvcm1hdFJldHVyblZhbHVlKGtleSwgZW5jKVxufVxuXG5FQ0RILnByb3RvdHlwZS5nZXRQcml2YXRlS2V5ID0gZnVuY3Rpb24gKGVuYykge1xuICByZXR1cm4gZm9ybWF0UmV0dXJuVmFsdWUodGhpcy5rZXlzLmdldFByaXZhdGUoKSwgZW5jKVxufVxuXG5FQ0RILnByb3RvdHlwZS5zZXRQdWJsaWNLZXkgPSBmdW5jdGlvbiAocHViLCBlbmMpIHtcbiAgZW5jID0gZW5jIHx8ICd1dGY4J1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihwdWIpKSB7XG4gICAgcHViID0gbmV3IEJ1ZmZlcihwdWIsIGVuYylcbiAgfVxuICB0aGlzLmtleXMuX2ltcG9ydFB1YmxpYyhwdWIpXG4gIHJldHVybiB0aGlzXG59XG5cbkVDREgucHJvdG90eXBlLnNldFByaXZhdGVLZXkgPSBmdW5jdGlvbiAocHJpdiwgZW5jKSB7XG4gIGVuYyA9IGVuYyB8fCAndXRmOCdcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIocHJpdikpIHtcbiAgICBwcml2ID0gbmV3IEJ1ZmZlcihwcml2LCBlbmMpXG4gIH1cblxuICB2YXIgX3ByaXYgPSBuZXcgQk4ocHJpdilcbiAgX3ByaXYgPSBfcHJpdi50b1N0cmluZygxNilcbiAgdGhpcy5rZXlzID0gdGhpcy5jdXJ2ZS5nZW5LZXlQYWlyKClcbiAgdGhpcy5rZXlzLl9pbXBvcnRQcml2YXRlKF9wcml2KVxuICByZXR1cm4gdGhpc1xufVxuXG5mdW5jdGlvbiBmb3JtYXRSZXR1cm5WYWx1ZSAoYm4sIGVuYywgbGVuKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShibikpIHtcbiAgICBibiA9IGJuLnRvQXJyYXkoKVxuICB9XG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKGJuKVxuICBpZiAobGVuICYmIGJ1Zi5sZW5ndGggPCBsZW4pIHtcbiAgICB2YXIgemVyb3MgPSBuZXcgQnVmZmVyKGxlbiAtIGJ1Zi5sZW5ndGgpXG4gICAgemVyb3MuZmlsbCgwKVxuICAgIGJ1ZiA9IEJ1ZmZlci5jb25jYXQoW3plcm9zLCBidWZdKVxuICB9XG4gIGlmICghZW5jKSB7XG4gICAgcmV0dXJuIGJ1ZlxuICB9IGVsc2Uge1xuICAgIHJldHVybiBidWYudG9TdHJpbmcoZW5jKVxuICB9XG59XG4iLCIndXNlIHN0cmljdCdcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBNRDUgPSByZXF1aXJlKCdtZDUuanMnKVxudmFyIFJJUEVNRDE2MCA9IHJlcXVpcmUoJ3JpcGVtZDE2MCcpXG52YXIgc2hhID0gcmVxdWlyZSgnc2hhLmpzJylcbnZhciBCYXNlID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxuXG5mdW5jdGlvbiBIYXNoIChoYXNoKSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnZGlnZXN0JylcblxuICB0aGlzLl9oYXNoID0gaGFzaFxufVxuXG5pbmhlcml0cyhIYXNoLCBCYXNlKVxuXG5IYXNoLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5faGFzaC51cGRhdGUoZGF0YSlcbn1cblxuSGFzaC5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5faGFzaC5kaWdlc3QoKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNyZWF0ZUhhc2ggKGFsZykge1xuICBhbGcgPSBhbGcudG9Mb3dlckNhc2UoKVxuICBpZiAoYWxnID09PSAnbWQ1JykgcmV0dXJuIG5ldyBNRDUoKVxuICBpZiAoYWxnID09PSAncm1kMTYwJyB8fCBhbGcgPT09ICdyaXBlbWQxNjAnKSByZXR1cm4gbmV3IFJJUEVNRDE2MCgpXG5cbiAgcmV0dXJuIG5ldyBIYXNoKHNoYShhbGcpKVxufVxuIiwidmFyIE1ENSA9IHJlcXVpcmUoJ21kNS5qcycpXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGJ1ZmZlcikge1xuICByZXR1cm4gbmV3IE1ENSgpLnVwZGF0ZShidWZmZXIpLmRpZ2VzdCgpXG59XG4iLCIndXNlIHN0cmljdCdcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBMZWdhY3kgPSByZXF1aXJlKCcuL2xlZ2FjeScpXG52YXIgQmFzZSA9IHJlcXVpcmUoJ2NpcGhlci1iYXNlJylcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxudmFyIG1kNSA9IHJlcXVpcmUoJ2NyZWF0ZS1oYXNoL21kNScpXG52YXIgUklQRU1EMTYwID0gcmVxdWlyZSgncmlwZW1kMTYwJylcblxudmFyIHNoYSA9IHJlcXVpcmUoJ3NoYS5qcycpXG5cbnZhciBaRVJPUyA9IEJ1ZmZlci5hbGxvYygxMjgpXG5cbmZ1bmN0aW9uIEhtYWMgKGFsZywga2V5KSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnZGlnZXN0JylcbiAgaWYgKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnKSB7XG4gICAga2V5ID0gQnVmZmVyLmZyb20oa2V5KVxuICB9XG5cbiAgdmFyIGJsb2Nrc2l6ZSA9IChhbGcgPT09ICdzaGE1MTInIHx8IGFsZyA9PT0gJ3NoYTM4NCcpID8gMTI4IDogNjRcblxuICB0aGlzLl9hbGcgPSBhbGdcbiAgdGhpcy5fa2V5ID0ga2V5XG4gIGlmIChrZXkubGVuZ3RoID4gYmxvY2tzaXplKSB7XG4gICAgdmFyIGhhc2ggPSBhbGcgPT09ICdybWQxNjAnID8gbmV3IFJJUEVNRDE2MCgpIDogc2hhKGFsZylcbiAgICBrZXkgPSBoYXNoLnVwZGF0ZShrZXkpLmRpZ2VzdCgpXG4gIH0gZWxzZSBpZiAoa2V5Lmxlbmd0aCA8IGJsb2Nrc2l6ZSkge1xuICAgIGtleSA9IEJ1ZmZlci5jb25jYXQoW2tleSwgWkVST1NdLCBibG9ja3NpemUpXG4gIH1cblxuICB2YXIgaXBhZCA9IHRoaXMuX2lwYWQgPSBCdWZmZXIuYWxsb2NVbnNhZmUoYmxvY2tzaXplKVxuICB2YXIgb3BhZCA9IHRoaXMuX29wYWQgPSBCdWZmZXIuYWxsb2NVbnNhZmUoYmxvY2tzaXplKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tzaXplOyBpKyspIHtcbiAgICBpcGFkW2ldID0ga2V5W2ldIF4gMHgzNlxuICAgIG9wYWRbaV0gPSBrZXlbaV0gXiAweDVDXG4gIH1cbiAgdGhpcy5faGFzaCA9IGFsZyA9PT0gJ3JtZDE2MCcgPyBuZXcgUklQRU1EMTYwKCkgOiBzaGEoYWxnKVxuICB0aGlzLl9oYXNoLnVwZGF0ZShpcGFkKVxufVxuXG5pbmhlcml0cyhIbWFjLCBCYXNlKVxuXG5IbWFjLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5faGFzaC51cGRhdGUoZGF0YSlcbn1cblxuSG1hYy5wcm90b3R5cGUuX2ZpbmFsID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaCA9IHRoaXMuX2hhc2guZGlnZXN0KClcbiAgdmFyIGhhc2ggPSB0aGlzLl9hbGcgPT09ICdybWQxNjAnID8gbmV3IFJJUEVNRDE2MCgpIDogc2hhKHRoaXMuX2FsZylcbiAgcmV0dXJuIGhhc2gudXBkYXRlKHRoaXMuX29wYWQpLnVwZGF0ZShoKS5kaWdlc3QoKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNyZWF0ZUhtYWMgKGFsZywga2V5KSB7XG4gIGFsZyA9IGFsZy50b0xvd2VyQ2FzZSgpXG4gIGlmIChhbGcgPT09ICdybWQxNjAnIHx8IGFsZyA9PT0gJ3JpcGVtZDE2MCcpIHtcbiAgICByZXR1cm4gbmV3IEhtYWMoJ3JtZDE2MCcsIGtleSlcbiAgfVxuICBpZiAoYWxnID09PSAnbWQ1Jykge1xuICAgIHJldHVybiBuZXcgTGVnYWN5KG1kNSwga2V5KVxuICB9XG4gIHJldHVybiBuZXcgSG1hYyhhbGcsIGtleSlcbn1cbiIsIid1c2Ugc3RyaWN0J1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG5cbnZhciBCYXNlID0gcmVxdWlyZSgnY2lwaGVyLWJhc2UnKVxuXG52YXIgWkVST1MgPSBCdWZmZXIuYWxsb2MoMTI4KVxudmFyIGJsb2Nrc2l6ZSA9IDY0XG5cbmZ1bmN0aW9uIEhtYWMgKGFsZywga2V5KSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnZGlnZXN0JylcbiAgaWYgKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnKSB7XG4gICAga2V5ID0gQnVmZmVyLmZyb20oa2V5KVxuICB9XG5cbiAgdGhpcy5fYWxnID0gYWxnXG4gIHRoaXMuX2tleSA9IGtleVxuXG4gIGlmIChrZXkubGVuZ3RoID4gYmxvY2tzaXplKSB7XG4gICAga2V5ID0gYWxnKGtleSlcbiAgfSBlbHNlIGlmIChrZXkubGVuZ3RoIDwgYmxvY2tzaXplKSB7XG4gICAga2V5ID0gQnVmZmVyLmNvbmNhdChba2V5LCBaRVJPU10sIGJsb2Nrc2l6ZSlcbiAgfVxuXG4gIHZhciBpcGFkID0gdGhpcy5faXBhZCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShibG9ja3NpemUpXG4gIHZhciBvcGFkID0gdGhpcy5fb3BhZCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShibG9ja3NpemUpXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja3NpemU7IGkrKykge1xuICAgIGlwYWRbaV0gPSBrZXlbaV0gXiAweDM2XG4gICAgb3BhZFtpXSA9IGtleVtpXSBeIDB4NUNcbiAgfVxuXG4gIHRoaXMuX2hhc2ggPSBbaXBhZF1cbn1cblxuaW5oZXJpdHMoSG1hYywgQmFzZSlcblxuSG1hYy5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gIHRoaXMuX2hhc2gucHVzaChkYXRhKVxufVxuXG5IbWFjLnByb3RvdHlwZS5fZmluYWwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBoID0gdGhpcy5fYWxnKEJ1ZmZlci5jb25jYXQodGhpcy5faGFzaCkpXG4gIHJldHVybiB0aGlzLl9hbGcoQnVmZmVyLmNvbmNhdChbdGhpcy5fb3BhZCwgaF0pKVxufVxubW9kdWxlLmV4cG9ydHMgPSBIbWFjXG4iLCIndXNlIHN0cmljdCdcblxuZXhwb3J0cy5yYW5kb21CeXRlcyA9IGV4cG9ydHMucm5nID0gZXhwb3J0cy5wc2V1ZG9SYW5kb21CeXRlcyA9IGV4cG9ydHMucHJuZyA9IHJlcXVpcmUoJ3JhbmRvbWJ5dGVzJylcbmV4cG9ydHMuY3JlYXRlSGFzaCA9IGV4cG9ydHMuSGFzaCA9IHJlcXVpcmUoJ2NyZWF0ZS1oYXNoJylcbmV4cG9ydHMuY3JlYXRlSG1hYyA9IGV4cG9ydHMuSG1hYyA9IHJlcXVpcmUoJ2NyZWF0ZS1obWFjJylcblxudmFyIGFsZ29zID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1zaWduL2FsZ29zJylcbnZhciBhbGdvS2V5cyA9IE9iamVjdC5rZXlzKGFsZ29zKVxudmFyIGhhc2hlcyA9IFsnc2hhMScsICdzaGEyMjQnLCAnc2hhMjU2JywgJ3NoYTM4NCcsICdzaGE1MTInLCAnbWQ1JywgJ3JtZDE2MCddLmNvbmNhdChhbGdvS2V5cylcbmV4cG9ydHMuZ2V0SGFzaGVzID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gaGFzaGVzXG59XG5cbnZhciBwID0gcmVxdWlyZSgncGJrZGYyJylcbmV4cG9ydHMucGJrZGYyID0gcC5wYmtkZjJcbmV4cG9ydHMucGJrZGYyU3luYyA9IHAucGJrZGYyU3luY1xuXG52YXIgYWVzID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1jaXBoZXInKVxuXG5leHBvcnRzLkNpcGhlciA9IGFlcy5DaXBoZXJcbmV4cG9ydHMuY3JlYXRlQ2lwaGVyID0gYWVzLmNyZWF0ZUNpcGhlclxuZXhwb3J0cy5DaXBoZXJpdiA9IGFlcy5DaXBoZXJpdlxuZXhwb3J0cy5jcmVhdGVDaXBoZXJpdiA9IGFlcy5jcmVhdGVDaXBoZXJpdlxuZXhwb3J0cy5EZWNpcGhlciA9IGFlcy5EZWNpcGhlclxuZXhwb3J0cy5jcmVhdGVEZWNpcGhlciA9IGFlcy5jcmVhdGVEZWNpcGhlclxuZXhwb3J0cy5EZWNpcGhlcml2ID0gYWVzLkRlY2lwaGVyaXZcbmV4cG9ydHMuY3JlYXRlRGVjaXBoZXJpdiA9IGFlcy5jcmVhdGVEZWNpcGhlcml2XG5leHBvcnRzLmdldENpcGhlcnMgPSBhZXMuZ2V0Q2lwaGVyc1xuZXhwb3J0cy5saXN0Q2lwaGVycyA9IGFlcy5saXN0Q2lwaGVyc1xuXG52YXIgZGggPSByZXF1aXJlKCdkaWZmaWUtaGVsbG1hbicpXG5cbmV4cG9ydHMuRGlmZmllSGVsbG1hbkdyb3VwID0gZGguRGlmZmllSGVsbG1hbkdyb3VwXG5leHBvcnRzLmNyZWF0ZURpZmZpZUhlbGxtYW5Hcm91cCA9IGRoLmNyZWF0ZURpZmZpZUhlbGxtYW5Hcm91cFxuZXhwb3J0cy5nZXREaWZmaWVIZWxsbWFuID0gZGguZ2V0RGlmZmllSGVsbG1hblxuZXhwb3J0cy5jcmVhdGVEaWZmaWVIZWxsbWFuID0gZGguY3JlYXRlRGlmZmllSGVsbG1hblxuZXhwb3J0cy5EaWZmaWVIZWxsbWFuID0gZGguRGlmZmllSGVsbG1hblxuXG52YXIgc2lnbiA9IHJlcXVpcmUoJ2Jyb3dzZXJpZnktc2lnbicpXG5cbmV4cG9ydHMuY3JlYXRlU2lnbiA9IHNpZ24uY3JlYXRlU2lnblxuZXhwb3J0cy5TaWduID0gc2lnbi5TaWduXG5leHBvcnRzLmNyZWF0ZVZlcmlmeSA9IHNpZ24uY3JlYXRlVmVyaWZ5XG5leHBvcnRzLlZlcmlmeSA9IHNpZ24uVmVyaWZ5XG5cbmV4cG9ydHMuY3JlYXRlRUNESCA9IHJlcXVpcmUoJ2NyZWF0ZS1lY2RoJylcblxudmFyIHB1YmxpY0VuY3J5cHQgPSByZXF1aXJlKCdwdWJsaWMtZW5jcnlwdCcpXG5cbmV4cG9ydHMucHVibGljRW5jcnlwdCA9IHB1YmxpY0VuY3J5cHQucHVibGljRW5jcnlwdFxuZXhwb3J0cy5wcml2YXRlRW5jcnlwdCA9IHB1YmxpY0VuY3J5cHQucHJpdmF0ZUVuY3J5cHRcbmV4cG9ydHMucHVibGljRGVjcnlwdCA9IHB1YmxpY0VuY3J5cHQucHVibGljRGVjcnlwdFxuZXhwb3J0cy5wcml2YXRlRGVjcnlwdCA9IHB1YmxpY0VuY3J5cHQucHJpdmF0ZURlY3J5cHRcblxuLy8gdGhlIGxlYXN0IEkgY2FuIGRvIGlzIG1ha2UgZXJyb3IgbWVzc2FnZXMgZm9yIHRoZSByZXN0IG9mIHRoZSBub2RlLmpzL2NyeXB0byBhcGkuXG4vLyA7W1xuLy8gICAnY3JlYXRlQ3JlZGVudGlhbHMnXG4vLyBdLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbi8vICAgZXhwb3J0c1tuYW1lXSA9IGZ1bmN0aW9uICgpIHtcbi8vICAgICB0aHJvdyBuZXcgRXJyb3IoW1xuLy8gICAgICAgJ3NvcnJ5LCAnICsgbmFtZSArICcgaXMgbm90IGltcGxlbWVudGVkIHlldCcsXG4vLyAgICAgICAnd2UgYWNjZXB0IHB1bGwgcmVxdWVzdHMnLFxuLy8gICAgICAgJ2h0dHBzOi8vZ2l0aHViLmNvbS9jcnlwdG8tYnJvd3NlcmlmeS9jcnlwdG8tYnJvd3NlcmlmeSdcbi8vICAgICBdLmpvaW4oJ1xcbicpKVxuLy8gICB9XG4vLyB9KVxuXG52YXIgcmYgPSByZXF1aXJlKCdyYW5kb21maWxsJylcblxuZXhwb3J0cy5yYW5kb21GaWxsID0gcmYucmFuZG9tRmlsbFxuZXhwb3J0cy5yYW5kb21GaWxsU3luYyA9IHJmLnJhbmRvbUZpbGxTeW5jXG5cbmV4cG9ydHMuY3JlYXRlQ3JlZGVudGlhbHMgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcihbXG4gICAgJ3NvcnJ5LCBjcmVhdGVDcmVkZW50aWFscyBpcyBub3QgaW1wbGVtZW50ZWQgeWV0JyxcbiAgICAnd2UgYWNjZXB0IHB1bGwgcmVxdWVzdHMnLFxuICAgICdodHRwczovL2dpdGh1Yi5jb20vY3J5cHRvLWJyb3dzZXJpZnkvY3J5cHRvLWJyb3dzZXJpZnknXG4gIF0uam9pbignXFxuJykpXG59XG5cbmV4cG9ydHMuY29uc3RhbnRzID0ge1xuICAnREhfQ0hFQ0tfUF9OT1RfU0FGRV9QUklNRSc6IDIsXG4gICdESF9DSEVDS19QX05PVF9QUklNRSc6IDEsXG4gICdESF9VTkFCTEVfVE9fQ0hFQ0tfR0VORVJBVE9SJzogNCxcbiAgJ0RIX05PVF9TVUlUQUJMRV9HRU5FUkFUT1InOiA4LFxuICAnTlBOX0VOQUJMRUQnOiAxLFxuICAnQUxQTl9FTkFCTEVEJzogMSxcbiAgJ1JTQV9QS0NTMV9QQURESU5HJzogMSxcbiAgJ1JTQV9TU0xWMjNfUEFERElORyc6IDIsXG4gICdSU0FfTk9fUEFERElORyc6IDMsXG4gICdSU0FfUEtDUzFfT0FFUF9QQURESU5HJzogNCxcbiAgJ1JTQV9YOTMxX1BBRERJTkcnOiA1LFxuICAnUlNBX1BLQ1MxX1BTU19QQURESU5HJzogNixcbiAgJ1BPSU5UX0NPTlZFUlNJT05fQ09NUFJFU1NFRCc6IDIsXG4gICdQT0lOVF9DT05WRVJTSU9OX1VOQ09NUFJFU1NFRCc6IDQsXG4gICdQT0lOVF9DT05WRVJTSU9OX0hZQlJJRCc6IDZcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy51dGlscyA9IHJlcXVpcmUoJy4vZGVzL3V0aWxzJyk7XG5leHBvcnRzLkNpcGhlciA9IHJlcXVpcmUoJy4vZGVzL2NpcGhlcicpO1xuZXhwb3J0cy5ERVMgPSByZXF1aXJlKCcuL2Rlcy9kZXMnKTtcbmV4cG9ydHMuQ0JDID0gcmVxdWlyZSgnLi9kZXMvY2JjJyk7XG5leHBvcnRzLkVERSA9IHJlcXVpcmUoJy4vZGVzL2VkZScpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxudmFyIHByb3RvID0ge307XG5cbmZ1bmN0aW9uIENCQ1N0YXRlKGl2KSB7XG4gIGFzc2VydC5lcXVhbChpdi5sZW5ndGgsIDgsICdJbnZhbGlkIElWIGxlbmd0aCcpO1xuXG4gIHRoaXMuaXYgPSBuZXcgQXJyYXkoOCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5pdi5sZW5ndGg7IGkrKylcbiAgICB0aGlzLml2W2ldID0gaXZbaV07XG59XG5cbmZ1bmN0aW9uIGluc3RhbnRpYXRlKEJhc2UpIHtcbiAgZnVuY3Rpb24gQ0JDKG9wdGlvbnMpIHtcbiAgICBCYXNlLmNhbGwodGhpcywgb3B0aW9ucyk7XG4gICAgdGhpcy5fY2JjSW5pdCgpO1xuICB9XG4gIGluaGVyaXRzKENCQywgQmFzZSk7XG5cbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm90byk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgIENCQy5wcm90b3R5cGVba2V5XSA9IHByb3RvW2tleV07XG4gIH1cblxuICBDQkMuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKG9wdGlvbnMpIHtcbiAgICByZXR1cm4gbmV3IENCQyhvcHRpb25zKTtcbiAgfTtcblxuICByZXR1cm4gQ0JDO1xufVxuXG5leHBvcnRzLmluc3RhbnRpYXRlID0gaW5zdGFudGlhdGU7XG5cbnByb3RvLl9jYmNJbml0ID0gZnVuY3Rpb24gX2NiY0luaXQoKSB7XG4gIHZhciBzdGF0ZSA9IG5ldyBDQkNTdGF0ZSh0aGlzLm9wdGlvbnMuaXYpO1xuICB0aGlzLl9jYmNTdGF0ZSA9IHN0YXRlO1xufTtcblxucHJvdG8uX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUoaW5wLCBpbk9mZiwgb3V0LCBvdXRPZmYpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fY2JjU3RhdGU7XG4gIHZhciBzdXBlclByb3RvID0gdGhpcy5jb25zdHJ1Y3Rvci5zdXBlcl8ucHJvdG90eXBlO1xuXG4gIHZhciBpdiA9IHN0YXRlLml2O1xuICBpZiAodGhpcy50eXBlID09PSAnZW5jcnlwdCcpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspXG4gICAgICBpdltpXSBePSBpbnBbaW5PZmYgKyBpXTtcblxuICAgIHN1cGVyUHJvdG8uX3VwZGF0ZS5jYWxsKHRoaXMsIGl2LCAwLCBvdXQsIG91dE9mZik7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspXG4gICAgICBpdltpXSA9IG91dFtvdXRPZmYgKyBpXTtcbiAgfSBlbHNlIHtcbiAgICBzdXBlclByb3RvLl91cGRhdGUuY2FsbCh0aGlzLCBpbnAsIGluT2ZmLCBvdXQsIG91dE9mZik7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspXG4gICAgICBvdXRbb3V0T2ZmICsgaV0gXj0gaXZbaV07XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYmxvY2tTaXplOyBpKyspXG4gICAgICBpdltpXSA9IGlucFtpbk9mZiArIGldO1xuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG5mdW5jdGlvbiBDaXBoZXIob3B0aW9ucykge1xuICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXG4gIHRoaXMudHlwZSA9IHRoaXMub3B0aW9ucy50eXBlO1xuICB0aGlzLmJsb2NrU2l6ZSA9IDg7XG4gIHRoaXMuX2luaXQoKTtcblxuICB0aGlzLmJ1ZmZlciA9IG5ldyBBcnJheSh0aGlzLmJsb2NrU2l6ZSk7XG4gIHRoaXMuYnVmZmVyT2ZmID0gMDtcbn1cbm1vZHVsZS5leHBvcnRzID0gQ2lwaGVyO1xuXG5DaXBoZXIucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24gX2luaXQoKSB7XG4gIC8vIE1pZ2h0IGJlIG92ZXJyaWRlZFxufTtcblxuQ2lwaGVyLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUoZGF0YSkge1xuICBpZiAoZGF0YS5sZW5ndGggPT09IDApXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0aGlzLnR5cGUgPT09ICdkZWNyeXB0JylcbiAgICByZXR1cm4gdGhpcy5fdXBkYXRlRGVjcnlwdChkYXRhKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLl91cGRhdGVFbmNyeXB0KGRhdGEpO1xufTtcblxuQ2lwaGVyLnByb3RvdHlwZS5fYnVmZmVyID0gZnVuY3Rpb24gX2J1ZmZlcihkYXRhLCBvZmYpIHtcbiAgLy8gQXBwZW5kIGRhdGEgdG8gYnVmZmVyXG4gIHZhciBtaW4gPSBNYXRoLm1pbih0aGlzLmJ1ZmZlci5sZW5ndGggLSB0aGlzLmJ1ZmZlck9mZiwgZGF0YS5sZW5ndGggLSBvZmYpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG1pbjsgaSsrKVxuICAgIHRoaXMuYnVmZmVyW3RoaXMuYnVmZmVyT2ZmICsgaV0gPSBkYXRhW29mZiArIGldO1xuICB0aGlzLmJ1ZmZlck9mZiArPSBtaW47XG5cbiAgLy8gU2hpZnQgbmV4dFxuICByZXR1cm4gbWluO1xufTtcblxuQ2lwaGVyLnByb3RvdHlwZS5fZmx1c2hCdWZmZXIgPSBmdW5jdGlvbiBfZmx1c2hCdWZmZXIob3V0LCBvZmYpIHtcbiAgdGhpcy5fdXBkYXRlKHRoaXMuYnVmZmVyLCAwLCBvdXQsIG9mZik7XG4gIHRoaXMuYnVmZmVyT2ZmID0gMDtcbiAgcmV0dXJuIHRoaXMuYmxvY2tTaXplO1xufTtcblxuQ2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlRW5jcnlwdCA9IGZ1bmN0aW9uIF91cGRhdGVFbmNyeXB0KGRhdGEpIHtcbiAgdmFyIGlucHV0T2ZmID0gMDtcbiAgdmFyIG91dHB1dE9mZiA9IDA7XG5cbiAgdmFyIGNvdW50ID0gKCh0aGlzLmJ1ZmZlck9mZiArIGRhdGEubGVuZ3RoKSAvIHRoaXMuYmxvY2tTaXplKSB8IDA7XG4gIHZhciBvdXQgPSBuZXcgQXJyYXkoY291bnQgKiB0aGlzLmJsb2NrU2l6ZSk7XG5cbiAgaWYgKHRoaXMuYnVmZmVyT2ZmICE9PSAwKSB7XG4gICAgaW5wdXRPZmYgKz0gdGhpcy5fYnVmZmVyKGRhdGEsIGlucHV0T2ZmKTtcblxuICAgIGlmICh0aGlzLmJ1ZmZlck9mZiA9PT0gdGhpcy5idWZmZXIubGVuZ3RoKVxuICAgICAgb3V0cHV0T2ZmICs9IHRoaXMuX2ZsdXNoQnVmZmVyKG91dCwgb3V0cHV0T2ZmKTtcbiAgfVxuXG4gIC8vIFdyaXRlIGJsb2Nrc1xuICB2YXIgbWF4ID0gZGF0YS5sZW5ndGggLSAoKGRhdGEubGVuZ3RoIC0gaW5wdXRPZmYpICUgdGhpcy5ibG9ja1NpemUpO1xuICBmb3IgKDsgaW5wdXRPZmYgPCBtYXg7IGlucHV0T2ZmICs9IHRoaXMuYmxvY2tTaXplKSB7XG4gICAgdGhpcy5fdXBkYXRlKGRhdGEsIGlucHV0T2ZmLCBvdXQsIG91dHB1dE9mZik7XG4gICAgb3V0cHV0T2ZmICs9IHRoaXMuYmxvY2tTaXplO1xuICB9XG5cbiAgLy8gUXVldWUgcmVzdFxuICBmb3IgKDsgaW5wdXRPZmYgPCBkYXRhLmxlbmd0aDsgaW5wdXRPZmYrKywgdGhpcy5idWZmZXJPZmYrKylcbiAgICB0aGlzLmJ1ZmZlclt0aGlzLmJ1ZmZlck9mZl0gPSBkYXRhW2lucHV0T2ZmXTtcblxuICByZXR1cm4gb3V0O1xufTtcblxuQ2lwaGVyLnByb3RvdHlwZS5fdXBkYXRlRGVjcnlwdCA9IGZ1bmN0aW9uIF91cGRhdGVEZWNyeXB0KGRhdGEpIHtcbiAgdmFyIGlucHV0T2ZmID0gMDtcbiAgdmFyIG91dHB1dE9mZiA9IDA7XG5cbiAgdmFyIGNvdW50ID0gTWF0aC5jZWlsKCh0aGlzLmJ1ZmZlck9mZiArIGRhdGEubGVuZ3RoKSAvIHRoaXMuYmxvY2tTaXplKSAtIDE7XG4gIHZhciBvdXQgPSBuZXcgQXJyYXkoY291bnQgKiB0aGlzLmJsb2NrU2l6ZSk7XG5cbiAgLy8gVE9ETyhpbmR1dG55KTogb3B0aW1pemUgaXQsIHRoaXMgaXMgZmFyIGZyb20gb3B0aW1hbFxuICBmb3IgKDsgY291bnQgPiAwOyBjb3VudC0tKSB7XG4gICAgaW5wdXRPZmYgKz0gdGhpcy5fYnVmZmVyKGRhdGEsIGlucHV0T2ZmKTtcbiAgICBvdXRwdXRPZmYgKz0gdGhpcy5fZmx1c2hCdWZmZXIob3V0LCBvdXRwdXRPZmYpO1xuICB9XG5cbiAgLy8gQnVmZmVyIHJlc3Qgb2YgdGhlIGlucHV0XG4gIGlucHV0T2ZmICs9IHRoaXMuX2J1ZmZlcihkYXRhLCBpbnB1dE9mZik7XG5cbiAgcmV0dXJuIG91dDtcbn07XG5cbkNpcGhlci5wcm90b3R5cGUuZmluYWwgPSBmdW5jdGlvbiBmaW5hbChidWZmZXIpIHtcbiAgdmFyIGZpcnN0O1xuICBpZiAoYnVmZmVyKVxuICAgIGZpcnN0ID0gdGhpcy51cGRhdGUoYnVmZmVyKTtcblxuICB2YXIgbGFzdDtcbiAgaWYgKHRoaXMudHlwZSA9PT0gJ2VuY3J5cHQnKVxuICAgIGxhc3QgPSB0aGlzLl9maW5hbEVuY3J5cHQoKTtcbiAgZWxzZVxuICAgIGxhc3QgPSB0aGlzLl9maW5hbERlY3J5cHQoKTtcblxuICBpZiAoZmlyc3QpXG4gICAgcmV0dXJuIGZpcnN0LmNvbmNhdChsYXN0KTtcbiAgZWxzZVxuICAgIHJldHVybiBsYXN0O1xufTtcblxuQ2lwaGVyLnByb3RvdHlwZS5fcGFkID0gZnVuY3Rpb24gX3BhZChidWZmZXIsIG9mZikge1xuICBpZiAob2ZmID09PSAwKVxuICAgIHJldHVybiBmYWxzZTtcblxuICB3aGlsZSAob2ZmIDwgYnVmZmVyLmxlbmd0aClcbiAgICBidWZmZXJbb2ZmKytdID0gMDtcblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkNpcGhlci5wcm90b3R5cGUuX2ZpbmFsRW5jcnlwdCA9IGZ1bmN0aW9uIF9maW5hbEVuY3J5cHQoKSB7XG4gIGlmICghdGhpcy5fcGFkKHRoaXMuYnVmZmVyLCB0aGlzLmJ1ZmZlck9mZikpXG4gICAgcmV0dXJuIFtdO1xuXG4gIHZhciBvdXQgPSBuZXcgQXJyYXkodGhpcy5ibG9ja1NpemUpO1xuICB0aGlzLl91cGRhdGUodGhpcy5idWZmZXIsIDAsIG91dCwgMCk7XG4gIHJldHVybiBvdXQ7XG59O1xuXG5DaXBoZXIucHJvdG90eXBlLl91bnBhZCA9IGZ1bmN0aW9uIF91bnBhZChidWZmZXIpIHtcbiAgcmV0dXJuIGJ1ZmZlcjtcbn07XG5cbkNpcGhlci5wcm90b3R5cGUuX2ZpbmFsRGVjcnlwdCA9IGZ1bmN0aW9uIF9maW5hbERlY3J5cHQoKSB7XG4gIGFzc2VydC5lcXVhbCh0aGlzLmJ1ZmZlck9mZiwgdGhpcy5ibG9ja1NpemUsICdOb3QgZW5vdWdoIGRhdGEgdG8gZGVjcnlwdCcpO1xuICB2YXIgb3V0ID0gbmV3IEFycmF5KHRoaXMuYmxvY2tTaXplKTtcbiAgdGhpcy5fZmx1c2hCdWZmZXIob3V0LCAwKTtcblxuICByZXR1cm4gdGhpcy5fdW5wYWQob3V0KTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKCdtaW5pbWFsaXN0aWMtYXNzZXJ0Jyk7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG52YXIgZGVzID0gcmVxdWlyZSgnLi4vZGVzJyk7XG52YXIgdXRpbHMgPSBkZXMudXRpbHM7XG52YXIgQ2lwaGVyID0gZGVzLkNpcGhlcjtcblxuZnVuY3Rpb24gREVTU3RhdGUoKSB7XG4gIHRoaXMudG1wID0gbmV3IEFycmF5KDIpO1xuICB0aGlzLmtleXMgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBERVMob3B0aW9ucykge1xuICBDaXBoZXIuY2FsbCh0aGlzLCBvcHRpb25zKTtcblxuICB2YXIgc3RhdGUgPSBuZXcgREVTU3RhdGUoKTtcbiAgdGhpcy5fZGVzU3RhdGUgPSBzdGF0ZTtcblxuICB0aGlzLmRlcml2ZUtleXMoc3RhdGUsIG9wdGlvbnMua2V5KTtcbn1cbmluaGVyaXRzKERFUywgQ2lwaGVyKTtcbm1vZHVsZS5leHBvcnRzID0gREVTO1xuXG5ERVMuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKG9wdGlvbnMpIHtcbiAgcmV0dXJuIG5ldyBERVMob3B0aW9ucyk7XG59O1xuXG52YXIgc2hpZnRUYWJsZSA9IFtcbiAgMSwgMSwgMiwgMiwgMiwgMiwgMiwgMixcbiAgMSwgMiwgMiwgMiwgMiwgMiwgMiwgMVxuXTtcblxuREVTLnByb3RvdHlwZS5kZXJpdmVLZXlzID0gZnVuY3Rpb24gZGVyaXZlS2V5cyhzdGF0ZSwga2V5KSB7XG4gIHN0YXRlLmtleXMgPSBuZXcgQXJyYXkoMTYgKiAyKTtcblxuICBhc3NlcnQuZXF1YWwoa2V5Lmxlbmd0aCwgdGhpcy5ibG9ja1NpemUsICdJbnZhbGlkIGtleSBsZW5ndGgnKTtcblxuICB2YXIga0wgPSB1dGlscy5yZWFkVUludDMyQkUoa2V5LCAwKTtcbiAgdmFyIGtSID0gdXRpbHMucmVhZFVJbnQzMkJFKGtleSwgNCk7XG5cbiAgdXRpbHMucGMxKGtMLCBrUiwgc3RhdGUudG1wLCAwKTtcbiAga0wgPSBzdGF0ZS50bXBbMF07XG4gIGtSID0gc3RhdGUudG1wWzFdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0YXRlLmtleXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICB2YXIgc2hpZnQgPSBzaGlmdFRhYmxlW2kgPj4+IDFdO1xuICAgIGtMID0gdXRpbHMucjI4c2hsKGtMLCBzaGlmdCk7XG4gICAga1IgPSB1dGlscy5yMjhzaGwoa1IsIHNoaWZ0KTtcbiAgICB1dGlscy5wYzIoa0wsIGtSLCBzdGF0ZS5rZXlzLCBpKTtcbiAgfVxufTtcblxuREVTLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gX3VwZGF0ZShpbnAsIGluT2ZmLCBvdXQsIG91dE9mZikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9kZXNTdGF0ZTtcblxuICB2YXIgbCA9IHV0aWxzLnJlYWRVSW50MzJCRShpbnAsIGluT2ZmKTtcbiAgdmFyIHIgPSB1dGlscy5yZWFkVUludDMyQkUoaW5wLCBpbk9mZiArIDQpO1xuXG4gIC8vIEluaXRpYWwgUGVybXV0YXRpb25cbiAgdXRpbHMuaXAobCwgciwgc3RhdGUudG1wLCAwKTtcbiAgbCA9IHN0YXRlLnRtcFswXTtcbiAgciA9IHN0YXRlLnRtcFsxXTtcblxuICBpZiAodGhpcy50eXBlID09PSAnZW5jcnlwdCcpXG4gICAgdGhpcy5fZW5jcnlwdChzdGF0ZSwgbCwgciwgc3RhdGUudG1wLCAwKTtcbiAgZWxzZVxuICAgIHRoaXMuX2RlY3J5cHQoc3RhdGUsIGwsIHIsIHN0YXRlLnRtcCwgMCk7XG5cbiAgbCA9IHN0YXRlLnRtcFswXTtcbiAgciA9IHN0YXRlLnRtcFsxXTtcblxuICB1dGlscy53cml0ZVVJbnQzMkJFKG91dCwgbCwgb3V0T2ZmKTtcbiAgdXRpbHMud3JpdGVVSW50MzJCRShvdXQsIHIsIG91dE9mZiArIDQpO1xufTtcblxuREVTLnByb3RvdHlwZS5fcGFkID0gZnVuY3Rpb24gX3BhZChidWZmZXIsIG9mZikge1xuICB2YXIgdmFsdWUgPSBidWZmZXIubGVuZ3RoIC0gb2ZmO1xuICBmb3IgKHZhciBpID0gb2ZmOyBpIDwgYnVmZmVyLmxlbmd0aDsgaSsrKVxuICAgIGJ1ZmZlcltpXSA9IHZhbHVlO1xuXG4gIHJldHVybiB0cnVlO1xufTtcblxuREVTLnByb3RvdHlwZS5fdW5wYWQgPSBmdW5jdGlvbiBfdW5wYWQoYnVmZmVyKSB7XG4gIHZhciBwYWQgPSBidWZmZXJbYnVmZmVyLmxlbmd0aCAtIDFdO1xuICBmb3IgKHZhciBpID0gYnVmZmVyLmxlbmd0aCAtIHBhZDsgaSA8IGJ1ZmZlci5sZW5ndGg7IGkrKylcbiAgICBhc3NlcnQuZXF1YWwoYnVmZmVyW2ldLCBwYWQpO1xuXG4gIHJldHVybiBidWZmZXIuc2xpY2UoMCwgYnVmZmVyLmxlbmd0aCAtIHBhZCk7XG59O1xuXG5ERVMucHJvdG90eXBlLl9lbmNyeXB0ID0gZnVuY3Rpb24gX2VuY3J5cHQoc3RhdGUsIGxTdGFydCwgclN0YXJ0LCBvdXQsIG9mZikge1xuICB2YXIgbCA9IGxTdGFydDtcbiAgdmFyIHIgPSByU3RhcnQ7XG5cbiAgLy8gQXBwbHkgZigpIHgxNiB0aW1lc1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0YXRlLmtleXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICB2YXIga2V5TCA9IHN0YXRlLmtleXNbaV07XG4gICAgdmFyIGtleVIgPSBzdGF0ZS5rZXlzW2kgKyAxXTtcblxuICAgIC8vIGYociwgaylcbiAgICB1dGlscy5leHBhbmQociwgc3RhdGUudG1wLCAwKTtcblxuICAgIGtleUwgXj0gc3RhdGUudG1wWzBdO1xuICAgIGtleVIgXj0gc3RhdGUudG1wWzFdO1xuICAgIHZhciBzID0gdXRpbHMuc3Vic3RpdHV0ZShrZXlMLCBrZXlSKTtcbiAgICB2YXIgZiA9IHV0aWxzLnBlcm11dGUocyk7XG5cbiAgICB2YXIgdCA9IHI7XG4gICAgciA9IChsIF4gZikgPj4+IDA7XG4gICAgbCA9IHQ7XG4gIH1cblxuICAvLyBSZXZlcnNlIEluaXRpYWwgUGVybXV0YXRpb25cbiAgdXRpbHMucmlwKHIsIGwsIG91dCwgb2ZmKTtcbn07XG5cbkRFUy5wcm90b3R5cGUuX2RlY3J5cHQgPSBmdW5jdGlvbiBfZGVjcnlwdChzdGF0ZSwgbFN0YXJ0LCByU3RhcnQsIG91dCwgb2ZmKSB7XG4gIHZhciBsID0gclN0YXJ0O1xuICB2YXIgciA9IGxTdGFydDtcblxuICAvLyBBcHBseSBmKCkgeDE2IHRpbWVzXG4gIGZvciAodmFyIGkgPSBzdGF0ZS5rZXlzLmxlbmd0aCAtIDI7IGkgPj0gMDsgaSAtPSAyKSB7XG4gICAgdmFyIGtleUwgPSBzdGF0ZS5rZXlzW2ldO1xuICAgIHZhciBrZXlSID0gc3RhdGUua2V5c1tpICsgMV07XG5cbiAgICAvLyBmKHIsIGspXG4gICAgdXRpbHMuZXhwYW5kKGwsIHN0YXRlLnRtcCwgMCk7XG5cbiAgICBrZXlMIF49IHN0YXRlLnRtcFswXTtcbiAgICBrZXlSIF49IHN0YXRlLnRtcFsxXTtcbiAgICB2YXIgcyA9IHV0aWxzLnN1YnN0aXR1dGUoa2V5TCwga2V5Uik7XG4gICAgdmFyIGYgPSB1dGlscy5wZXJtdXRlKHMpO1xuXG4gICAgdmFyIHQgPSBsO1xuICAgIGwgPSAociBeIGYpID4+PiAwO1xuICAgIHIgPSB0O1xuICB9XG5cbiAgLy8gUmV2ZXJzZSBJbml0aWFsIFBlcm11dGF0aW9uXG4gIHV0aWxzLnJpcChsLCByLCBvdXQsIG9mZik7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxudmFyIGRlcyA9IHJlcXVpcmUoJy4uL2RlcycpO1xudmFyIENpcGhlciA9IGRlcy5DaXBoZXI7XG52YXIgREVTID0gZGVzLkRFUztcblxuZnVuY3Rpb24gRURFU3RhdGUodHlwZSwga2V5KSB7XG4gIGFzc2VydC5lcXVhbChrZXkubGVuZ3RoLCAyNCwgJ0ludmFsaWQga2V5IGxlbmd0aCcpO1xuXG4gIHZhciBrMSA9IGtleS5zbGljZSgwLCA4KTtcbiAgdmFyIGsyID0ga2V5LnNsaWNlKDgsIDE2KTtcbiAgdmFyIGszID0ga2V5LnNsaWNlKDE2LCAyNCk7XG5cbiAgaWYgKHR5cGUgPT09ICdlbmNyeXB0Jykge1xuICAgIHRoaXMuY2lwaGVycyA9IFtcbiAgICAgIERFUy5jcmVhdGUoeyB0eXBlOiAnZW5jcnlwdCcsIGtleTogazEgfSksXG4gICAgICBERVMuY3JlYXRlKHsgdHlwZTogJ2RlY3J5cHQnLCBrZXk6IGsyIH0pLFxuICAgICAgREVTLmNyZWF0ZSh7IHR5cGU6ICdlbmNyeXB0Jywga2V5OiBrMyB9KVxuICAgIF07XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5jaXBoZXJzID0gW1xuICAgICAgREVTLmNyZWF0ZSh7IHR5cGU6ICdkZWNyeXB0Jywga2V5OiBrMyB9KSxcbiAgICAgIERFUy5jcmVhdGUoeyB0eXBlOiAnZW5jcnlwdCcsIGtleTogazIgfSksXG4gICAgICBERVMuY3JlYXRlKHsgdHlwZTogJ2RlY3J5cHQnLCBrZXk6IGsxIH0pXG4gICAgXTtcbiAgfVxufVxuXG5mdW5jdGlvbiBFREUob3B0aW9ucykge1xuICBDaXBoZXIuY2FsbCh0aGlzLCBvcHRpb25zKTtcblxuICB2YXIgc3RhdGUgPSBuZXcgRURFU3RhdGUodGhpcy50eXBlLCB0aGlzLm9wdGlvbnMua2V5KTtcbiAgdGhpcy5fZWRlU3RhdGUgPSBzdGF0ZTtcbn1cbmluaGVyaXRzKEVERSwgQ2lwaGVyKTtcblxubW9kdWxlLmV4cG9ydHMgPSBFREU7XG5cbkVERS5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUob3B0aW9ucykge1xuICByZXR1cm4gbmV3IEVERShvcHRpb25zKTtcbn07XG5cbkVERS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUoaW5wLCBpbk9mZiwgb3V0LCBvdXRPZmYpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fZWRlU3RhdGU7XG5cbiAgc3RhdGUuY2lwaGVyc1swXS5fdXBkYXRlKGlucCwgaW5PZmYsIG91dCwgb3V0T2ZmKTtcbiAgc3RhdGUuY2lwaGVyc1sxXS5fdXBkYXRlKG91dCwgb3V0T2ZmLCBvdXQsIG91dE9mZik7XG4gIHN0YXRlLmNpcGhlcnNbMl0uX3VwZGF0ZShvdXQsIG91dE9mZiwgb3V0LCBvdXRPZmYpO1xufTtcblxuRURFLnByb3RvdHlwZS5fcGFkID0gREVTLnByb3RvdHlwZS5fcGFkO1xuRURFLnByb3RvdHlwZS5fdW5wYWQgPSBERVMucHJvdG90eXBlLl91bnBhZDtcbiIsIid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5yZWFkVUludDMyQkUgPSBmdW5jdGlvbiByZWFkVUludDMyQkUoYnl0ZXMsIG9mZikge1xuICB2YXIgcmVzID0gIChieXRlc1swICsgb2ZmXSA8PCAyNCkgfFxuICAgICAgICAgICAgIChieXRlc1sxICsgb2ZmXSA8PCAxNikgfFxuICAgICAgICAgICAgIChieXRlc1syICsgb2ZmXSA8PCA4KSB8XG4gICAgICAgICAgICAgYnl0ZXNbMyArIG9mZl07XG4gIHJldHVybiByZXMgPj4+IDA7XG59O1xuXG5leHBvcnRzLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkJFKGJ5dGVzLCB2YWx1ZSwgb2ZmKSB7XG4gIGJ5dGVzWzAgKyBvZmZdID0gdmFsdWUgPj4+IDI0O1xuICBieXRlc1sxICsgb2ZmXSA9ICh2YWx1ZSA+Pj4gMTYpICYgMHhmZjtcbiAgYnl0ZXNbMiArIG9mZl0gPSAodmFsdWUgPj4+IDgpICYgMHhmZjtcbiAgYnl0ZXNbMyArIG9mZl0gPSB2YWx1ZSAmIDB4ZmY7XG59O1xuXG5leHBvcnRzLmlwID0gZnVuY3Rpb24gaXAoaW5MLCBpblIsIG91dCwgb2ZmKSB7XG4gIHZhciBvdXRMID0gMDtcbiAgdmFyIG91dFIgPSAwO1xuXG4gIGZvciAodmFyIGkgPSA2OyBpID49IDA7IGkgLT0gMikge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDw9IDI0OyBqICs9IDgpIHtcbiAgICAgIG91dEwgPDw9IDE7XG4gICAgICBvdXRMIHw9IChpblIgPj4+IChqICsgaSkpICYgMTtcbiAgICB9XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPD0gMjQ7IGogKz0gOCkge1xuICAgICAgb3V0TCA8PD0gMTtcbiAgICAgIG91dEwgfD0gKGluTCA+Pj4gKGogKyBpKSkgJiAxO1xuICAgIH1cbiAgfVxuXG4gIGZvciAodmFyIGkgPSA2OyBpID49IDA7IGkgLT0gMikge1xuICAgIGZvciAodmFyIGogPSAxOyBqIDw9IDI1OyBqICs9IDgpIHtcbiAgICAgIG91dFIgPDw9IDE7XG4gICAgICBvdXRSIHw9IChpblIgPj4+IChqICsgaSkpICYgMTtcbiAgICB9XG4gICAgZm9yICh2YXIgaiA9IDE7IGogPD0gMjU7IGogKz0gOCkge1xuICAgICAgb3V0UiA8PD0gMTtcbiAgICAgIG91dFIgfD0gKGluTCA+Pj4gKGogKyBpKSkgJiAxO1xuICAgIH1cbiAgfVxuXG4gIG91dFtvZmYgKyAwXSA9IG91dEwgPj4+IDA7XG4gIG91dFtvZmYgKyAxXSA9IG91dFIgPj4+IDA7XG59O1xuXG5leHBvcnRzLnJpcCA9IGZ1bmN0aW9uIHJpcChpbkwsIGluUiwgb3V0LCBvZmYpIHtcbiAgdmFyIG91dEwgPSAwO1xuICB2YXIgb3V0UiA9IDA7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICBmb3IgKHZhciBqID0gMjQ7IGogPj0gMDsgaiAtPSA4KSB7XG4gICAgICBvdXRMIDw8PSAxO1xuICAgICAgb3V0TCB8PSAoaW5SID4+PiAoaiArIGkpKSAmIDE7XG4gICAgICBvdXRMIDw8PSAxO1xuICAgICAgb3V0TCB8PSAoaW5MID4+PiAoaiArIGkpKSAmIDE7XG4gICAgfVxuICB9XG4gIGZvciAodmFyIGkgPSA0OyBpIDwgODsgaSsrKSB7XG4gICAgZm9yICh2YXIgaiA9IDI0OyBqID49IDA7IGogLT0gOCkge1xuICAgICAgb3V0UiA8PD0gMTtcbiAgICAgIG91dFIgfD0gKGluUiA+Pj4gKGogKyBpKSkgJiAxO1xuICAgICAgb3V0UiA8PD0gMTtcbiAgICAgIG91dFIgfD0gKGluTCA+Pj4gKGogKyBpKSkgJiAxO1xuICAgIH1cbiAgfVxuXG4gIG91dFtvZmYgKyAwXSA9IG91dEwgPj4+IDA7XG4gIG91dFtvZmYgKyAxXSA9IG91dFIgPj4+IDA7XG59O1xuXG5leHBvcnRzLnBjMSA9IGZ1bmN0aW9uIHBjMShpbkwsIGluUiwgb3V0LCBvZmYpIHtcbiAgdmFyIG91dEwgPSAwO1xuICB2YXIgb3V0UiA9IDA7XG5cbiAgLy8gNywgMTUsIDIzLCAzMSwgMzksIDQ3LCA1NSwgNjNcbiAgLy8gNiwgMTQsIDIyLCAzMCwgMzksIDQ3LCA1NSwgNjNcbiAgLy8gNSwgMTMsIDIxLCAyOSwgMzksIDQ3LCA1NSwgNjNcbiAgLy8gNCwgMTIsIDIwLCAyOFxuICBmb3IgKHZhciBpID0gNzsgaSA+PSA1OyBpLS0pIHtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8PSAyNDsgaiArPSA4KSB7XG4gICAgICBvdXRMIDw8PSAxO1xuICAgICAgb3V0TCB8PSAoaW5SID4+IChqICsgaSkpICYgMTtcbiAgICB9XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPD0gMjQ7IGogKz0gOCkge1xuICAgICAgb3V0TCA8PD0gMTtcbiAgICAgIG91dEwgfD0gKGluTCA+PiAoaiArIGkpKSAmIDE7XG4gICAgfVxuICB9XG4gIGZvciAodmFyIGogPSAwOyBqIDw9IDI0OyBqICs9IDgpIHtcbiAgICBvdXRMIDw8PSAxO1xuICAgIG91dEwgfD0gKGluUiA+PiAoaiArIGkpKSAmIDE7XG4gIH1cblxuICAvLyAxLCA5LCAxNywgMjUsIDMzLCA0MSwgNDksIDU3XG4gIC8vIDIsIDEwLCAxOCwgMjYsIDM0LCA0MiwgNTAsIDU4XG4gIC8vIDMsIDExLCAxOSwgMjcsIDM1LCA0MywgNTEsIDU5XG4gIC8vIDM2LCA0NCwgNTIsIDYwXG4gIGZvciAodmFyIGkgPSAxOyBpIDw9IDM7IGkrKykge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDw9IDI0OyBqICs9IDgpIHtcbiAgICAgIG91dFIgPDw9IDE7XG4gICAgICBvdXRSIHw9IChpblIgPj4gKGogKyBpKSkgJiAxO1xuICAgIH1cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8PSAyNDsgaiArPSA4KSB7XG4gICAgICBvdXRSIDw8PSAxO1xuICAgICAgb3V0UiB8PSAoaW5MID4+IChqICsgaSkpICYgMTtcbiAgICB9XG4gIH1cbiAgZm9yICh2YXIgaiA9IDA7IGogPD0gMjQ7IGogKz0gOCkge1xuICAgIG91dFIgPDw9IDE7XG4gICAgb3V0UiB8PSAoaW5MID4+IChqICsgaSkpICYgMTtcbiAgfVxuXG4gIG91dFtvZmYgKyAwXSA9IG91dEwgPj4+IDA7XG4gIG91dFtvZmYgKyAxXSA9IG91dFIgPj4+IDA7XG59O1xuXG5leHBvcnRzLnIyOHNobCA9IGZ1bmN0aW9uIHIyOHNobChudW0sIHNoaWZ0KSB7XG4gIHJldHVybiAoKG51bSA8PCBzaGlmdCkgJiAweGZmZmZmZmYpIHwgKG51bSA+Pj4gKDI4IC0gc2hpZnQpKTtcbn07XG5cbnZhciBwYzJ0YWJsZSA9IFtcbiAgLy8gaW5MID0+IG91dExcbiAgMTQsIDExLCAxNywgNCwgMjcsIDIzLCAyNSwgMCxcbiAgMTMsIDIyLCA3LCAxOCwgNSwgOSwgMTYsIDI0LFxuICAyLCAyMCwgMTIsIDIxLCAxLCA4LCAxNSwgMjYsXG5cbiAgLy8gaW5SID0+IG91dFJcbiAgMTUsIDQsIDI1LCAxOSwgOSwgMSwgMjYsIDE2LFxuICA1LCAxMSwgMjMsIDgsIDEyLCA3LCAxNywgMCxcbiAgMjIsIDMsIDEwLCAxNCwgNiwgMjAsIDI3LCAyNFxuXTtcblxuZXhwb3J0cy5wYzIgPSBmdW5jdGlvbiBwYzIoaW5MLCBpblIsIG91dCwgb2ZmKSB7XG4gIHZhciBvdXRMID0gMDtcbiAgdmFyIG91dFIgPSAwO1xuXG4gIHZhciBsZW4gPSBwYzJ0YWJsZS5sZW5ndGggPj4+IDE7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICBvdXRMIDw8PSAxO1xuICAgIG91dEwgfD0gKGluTCA+Pj4gcGMydGFibGVbaV0pICYgMHgxO1xuICB9XG4gIGZvciAodmFyIGkgPSBsZW47IGkgPCBwYzJ0YWJsZS5sZW5ndGg7IGkrKykge1xuICAgIG91dFIgPDw9IDE7XG4gICAgb3V0UiB8PSAoaW5SID4+PiBwYzJ0YWJsZVtpXSkgJiAweDE7XG4gIH1cblxuICBvdXRbb2ZmICsgMF0gPSBvdXRMID4+PiAwO1xuICBvdXRbb2ZmICsgMV0gPSBvdXRSID4+PiAwO1xufTtcblxuZXhwb3J0cy5leHBhbmQgPSBmdW5jdGlvbiBleHBhbmQociwgb3V0LCBvZmYpIHtcbiAgdmFyIG91dEwgPSAwO1xuICB2YXIgb3V0UiA9IDA7XG5cbiAgb3V0TCA9ICgociAmIDEpIDw8IDUpIHwgKHIgPj4+IDI3KTtcbiAgZm9yICh2YXIgaSA9IDIzOyBpID49IDE1OyBpIC09IDQpIHtcbiAgICBvdXRMIDw8PSA2O1xuICAgIG91dEwgfD0gKHIgPj4+IGkpICYgMHgzZjtcbiAgfVxuICBmb3IgKHZhciBpID0gMTE7IGkgPj0gMzsgaSAtPSA0KSB7XG4gICAgb3V0UiB8PSAociA+Pj4gaSkgJiAweDNmO1xuICAgIG91dFIgPDw9IDY7XG4gIH1cbiAgb3V0UiB8PSAoKHIgJiAweDFmKSA8PCAxKSB8IChyID4+PiAzMSk7XG5cbiAgb3V0W29mZiArIDBdID0gb3V0TCA+Pj4gMDtcbiAgb3V0W29mZiArIDFdID0gb3V0UiA+Pj4gMDtcbn07XG5cbnZhciBzVGFibGUgPSBbXG4gIDE0LCAwLCA0LCAxNSwgMTMsIDcsIDEsIDQsIDIsIDE0LCAxNSwgMiwgMTEsIDEzLCA4LCAxLFxuICAzLCAxMCwgMTAsIDYsIDYsIDEyLCAxMiwgMTEsIDUsIDksIDksIDUsIDAsIDMsIDcsIDgsXG4gIDQsIDE1LCAxLCAxMiwgMTQsIDgsIDgsIDIsIDEzLCA0LCA2LCA5LCAyLCAxLCAxMSwgNyxcbiAgMTUsIDUsIDEyLCAxMSwgOSwgMywgNywgMTQsIDMsIDEwLCAxMCwgMCwgNSwgNiwgMCwgMTMsXG5cbiAgMTUsIDMsIDEsIDEzLCA4LCA0LCAxNCwgNywgNiwgMTUsIDExLCAyLCAzLCA4LCA0LCAxNCxcbiAgOSwgMTIsIDcsIDAsIDIsIDEsIDEzLCAxMCwgMTIsIDYsIDAsIDksIDUsIDExLCAxMCwgNSxcbiAgMCwgMTMsIDE0LCA4LCA3LCAxMCwgMTEsIDEsIDEwLCAzLCA0LCAxNSwgMTMsIDQsIDEsIDIsXG4gIDUsIDExLCA4LCA2LCAxMiwgNywgNiwgMTIsIDksIDAsIDMsIDUsIDIsIDE0LCAxNSwgOSxcblxuICAxMCwgMTMsIDAsIDcsIDksIDAsIDE0LCA5LCA2LCAzLCAzLCA0LCAxNSwgNiwgNSwgMTAsXG4gIDEsIDIsIDEzLCA4LCAxMiwgNSwgNywgMTQsIDExLCAxMiwgNCwgMTEsIDIsIDE1LCA4LCAxLFxuICAxMywgMSwgNiwgMTAsIDQsIDEzLCA5LCAwLCA4LCA2LCAxNSwgOSwgMywgOCwgMCwgNyxcbiAgMTEsIDQsIDEsIDE1LCAyLCAxNCwgMTIsIDMsIDUsIDExLCAxMCwgNSwgMTQsIDIsIDcsIDEyLFxuXG4gIDcsIDEzLCAxMywgOCwgMTQsIDExLCAzLCA1LCAwLCA2LCA2LCAxNSwgOSwgMCwgMTAsIDMsXG4gIDEsIDQsIDIsIDcsIDgsIDIsIDUsIDEyLCAxMSwgMSwgMTIsIDEwLCA0LCAxNCwgMTUsIDksXG4gIDEwLCAzLCA2LCAxNSwgOSwgMCwgMCwgNiwgMTIsIDEwLCAxMSwgMSwgNywgMTMsIDEzLCA4LFxuICAxNSwgOSwgMSwgNCwgMywgNSwgMTQsIDExLCA1LCAxMiwgMiwgNywgOCwgMiwgNCwgMTQsXG5cbiAgMiwgMTQsIDEyLCAxMSwgNCwgMiwgMSwgMTIsIDcsIDQsIDEwLCA3LCAxMSwgMTMsIDYsIDEsXG4gIDgsIDUsIDUsIDAsIDMsIDE1LCAxNSwgMTAsIDEzLCAzLCAwLCA5LCAxNCwgOCwgOSwgNixcbiAgNCwgMTEsIDIsIDgsIDEsIDEyLCAxMSwgNywgMTAsIDEsIDEzLCAxNCwgNywgMiwgOCwgMTMsXG4gIDE1LCA2LCA5LCAxNSwgMTIsIDAsIDUsIDksIDYsIDEwLCAzLCA0LCAwLCA1LCAxNCwgMyxcblxuICAxMiwgMTAsIDEsIDE1LCAxMCwgNCwgMTUsIDIsIDksIDcsIDIsIDEyLCA2LCA5LCA4LCA1LFxuICAwLCA2LCAxMywgMSwgMywgMTMsIDQsIDE0LCAxNCwgMCwgNywgMTEsIDUsIDMsIDExLCA4LFxuICA5LCA0LCAxNCwgMywgMTUsIDIsIDUsIDEyLCAyLCA5LCA4LCA1LCAxMiwgMTUsIDMsIDEwLFxuICA3LCAxMSwgMCwgMTQsIDQsIDEsIDEwLCA3LCAxLCA2LCAxMywgMCwgMTEsIDgsIDYsIDEzLFxuXG4gIDQsIDEzLCAxMSwgMCwgMiwgMTEsIDE0LCA3LCAxNSwgNCwgMCwgOSwgOCwgMSwgMTMsIDEwLFxuICAzLCAxNCwgMTIsIDMsIDksIDUsIDcsIDEyLCA1LCAyLCAxMCwgMTUsIDYsIDgsIDEsIDYsXG4gIDEsIDYsIDQsIDExLCAxMSwgMTMsIDEzLCA4LCAxMiwgMSwgMywgNCwgNywgMTAsIDE0LCA3LFxuICAxMCwgOSwgMTUsIDUsIDYsIDAsIDgsIDE1LCAwLCAxNCwgNSwgMiwgOSwgMywgMiwgMTIsXG5cbiAgMTMsIDEsIDIsIDE1LCA4LCAxMywgNCwgOCwgNiwgMTAsIDE1LCAzLCAxMSwgNywgMSwgNCxcbiAgMTAsIDEyLCA5LCA1LCAzLCA2LCAxNCwgMTEsIDUsIDAsIDAsIDE0LCAxMiwgOSwgNywgMixcbiAgNywgMiwgMTEsIDEsIDQsIDE0LCAxLCA3LCA5LCA0LCAxMiwgMTAsIDE0LCA4LCAyLCAxMyxcbiAgMCwgMTUsIDYsIDEyLCAxMCwgOSwgMTMsIDAsIDE1LCAzLCAzLCA1LCA1LCA2LCA4LCAxMVxuXTtcblxuZXhwb3J0cy5zdWJzdGl0dXRlID0gZnVuY3Rpb24gc3Vic3RpdHV0ZShpbkwsIGluUikge1xuICB2YXIgb3V0ID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICB2YXIgYiA9IChpbkwgPj4+ICgxOCAtIGkgKiA2KSkgJiAweDNmO1xuICAgIHZhciBzYiA9IHNUYWJsZVtpICogMHg0MCArIGJdO1xuXG4gICAgb3V0IDw8PSA0O1xuICAgIG91dCB8PSBzYjtcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgIHZhciBiID0gKGluUiA+Pj4gKDE4IC0gaSAqIDYpKSAmIDB4M2Y7XG4gICAgdmFyIHNiID0gc1RhYmxlWzQgKiAweDQwICsgaSAqIDB4NDAgKyBiXTtcblxuICAgIG91dCA8PD0gNDtcbiAgICBvdXQgfD0gc2I7XG4gIH1cbiAgcmV0dXJuIG91dCA+Pj4gMDtcbn07XG5cbnZhciBwZXJtdXRlVGFibGUgPSBbXG4gIDE2LCAyNSwgMTIsIDExLCAzLCAyMCwgNCwgMTUsIDMxLCAxNywgOSwgNiwgMjcsIDE0LCAxLCAyMixcbiAgMzAsIDI0LCA4LCAxOCwgMCwgNSwgMjksIDIzLCAxMywgMTksIDIsIDI2LCAxMCwgMjEsIDI4LCA3XG5dO1xuXG5leHBvcnRzLnBlcm11dGUgPSBmdW5jdGlvbiBwZXJtdXRlKG51bSkge1xuICB2YXIgb3V0ID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwZXJtdXRlVGFibGUubGVuZ3RoOyBpKyspIHtcbiAgICBvdXQgPDw9IDE7XG4gICAgb3V0IHw9IChudW0gPj4+IHBlcm11dGVUYWJsZVtpXSkgJiAweDE7XG4gIH1cbiAgcmV0dXJuIG91dCA+Pj4gMDtcbn07XG5cbmV4cG9ydHMucGFkU3BsaXQgPSBmdW5jdGlvbiBwYWRTcGxpdChudW0sIHNpemUsIGdyb3VwKSB7XG4gIHZhciBzdHIgPSBudW0udG9TdHJpbmcoMik7XG4gIHdoaWxlIChzdHIubGVuZ3RoIDwgc2l6ZSlcbiAgICBzdHIgPSAnMCcgKyBzdHI7XG5cbiAgdmFyIG91dCA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHNpemU7IGkgKz0gZ3JvdXApXG4gICAgb3V0LnB1c2goc3RyLnNsaWNlKGksIGkgKyBncm91cCkpO1xuICByZXR1cm4gb3V0LmpvaW4oJyAnKTtcbn07XG4iLCJ2YXIgZ2VuZXJhdGVQcmltZSA9IHJlcXVpcmUoJy4vbGliL2dlbmVyYXRlUHJpbWUnKVxudmFyIHByaW1lcyA9IHJlcXVpcmUoJy4vbGliL3ByaW1lcy5qc29uJylcblxudmFyIERIID0gcmVxdWlyZSgnLi9saWIvZGgnKVxuXG5mdW5jdGlvbiBnZXREaWZmaWVIZWxsbWFuIChtb2QpIHtcbiAgdmFyIHByaW1lID0gbmV3IEJ1ZmZlcihwcmltZXNbbW9kXS5wcmltZSwgJ2hleCcpXG4gIHZhciBnZW4gPSBuZXcgQnVmZmVyKHByaW1lc1ttb2RdLmdlbiwgJ2hleCcpXG5cbiAgcmV0dXJuIG5ldyBESChwcmltZSwgZ2VuKVxufVxuXG52YXIgRU5DT0RJTkdTID0ge1xuICAnYmluYXJ5JzogdHJ1ZSwgJ2hleCc6IHRydWUsICdiYXNlNjQnOiB0cnVlXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZURpZmZpZUhlbGxtYW4gKHByaW1lLCBlbmMsIGdlbmVyYXRvciwgZ2VuYykge1xuICBpZiAoQnVmZmVyLmlzQnVmZmVyKGVuYykgfHwgRU5DT0RJTkdTW2VuY10gPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBjcmVhdGVEaWZmaWVIZWxsbWFuKHByaW1lLCAnYmluYXJ5JywgZW5jLCBnZW5lcmF0b3IpXG4gIH1cblxuICBlbmMgPSBlbmMgfHwgJ2JpbmFyeSdcbiAgZ2VuYyA9IGdlbmMgfHwgJ2JpbmFyeSdcbiAgZ2VuZXJhdG9yID0gZ2VuZXJhdG9yIHx8IG5ldyBCdWZmZXIoWzJdKVxuXG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGdlbmVyYXRvcikpIHtcbiAgICBnZW5lcmF0b3IgPSBuZXcgQnVmZmVyKGdlbmVyYXRvciwgZ2VuYylcbiAgfVxuXG4gIGlmICh0eXBlb2YgcHJpbWUgPT09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIG5ldyBESChnZW5lcmF0ZVByaW1lKHByaW1lLCBnZW5lcmF0b3IpLCBnZW5lcmF0b3IsIHRydWUpXG4gIH1cblxuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihwcmltZSkpIHtcbiAgICBwcmltZSA9IG5ldyBCdWZmZXIocHJpbWUsIGVuYylcbiAgfVxuXG4gIHJldHVybiBuZXcgREgocHJpbWUsIGdlbmVyYXRvciwgdHJ1ZSlcbn1cblxuZXhwb3J0cy5EaWZmaWVIZWxsbWFuR3JvdXAgPSBleHBvcnRzLmNyZWF0ZURpZmZpZUhlbGxtYW5Hcm91cCA9IGV4cG9ydHMuZ2V0RGlmZmllSGVsbG1hbiA9IGdldERpZmZpZUhlbGxtYW5cbmV4cG9ydHMuY3JlYXRlRGlmZmllSGVsbG1hbiA9IGV4cG9ydHMuRGlmZmllSGVsbG1hbiA9IGNyZWF0ZURpZmZpZUhlbGxtYW5cbiIsInZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgTWlsbGVyUmFiaW4gPSByZXF1aXJlKCdtaWxsZXItcmFiaW4nKTtcbnZhciBtaWxsZXJSYWJpbiA9IG5ldyBNaWxsZXJSYWJpbigpO1xudmFyIFRXRU5UWUZPVVIgPSBuZXcgQk4oMjQpO1xudmFyIEVMRVZFTiA9IG5ldyBCTigxMSk7XG52YXIgVEVOID0gbmV3IEJOKDEwKTtcbnZhciBUSFJFRSA9IG5ldyBCTigzKTtcbnZhciBTRVZFTiA9IG5ldyBCTig3KTtcbnZhciBwcmltZXMgPSByZXF1aXJlKCcuL2dlbmVyYXRlUHJpbWUnKTtcbnZhciByYW5kb21CeXRlcyA9IHJlcXVpcmUoJ3JhbmRvbWJ5dGVzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IERIO1xuXG5mdW5jdGlvbiBzZXRQdWJsaWNLZXkocHViLCBlbmMpIHtcbiAgZW5jID0gZW5jIHx8ICd1dGY4JztcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIocHViKSkge1xuICAgIHB1YiA9IG5ldyBCdWZmZXIocHViLCBlbmMpO1xuICB9XG4gIHRoaXMuX3B1YiA9IG5ldyBCTihwdWIpO1xuICByZXR1cm4gdGhpcztcbn1cblxuZnVuY3Rpb24gc2V0UHJpdmF0ZUtleShwcml2LCBlbmMpIHtcbiAgZW5jID0gZW5jIHx8ICd1dGY4JztcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIocHJpdikpIHtcbiAgICBwcml2ID0gbmV3IEJ1ZmZlcihwcml2LCBlbmMpO1xuICB9XG4gIHRoaXMuX3ByaXYgPSBuZXcgQk4ocHJpdik7XG4gIHJldHVybiB0aGlzO1xufVxuXG52YXIgcHJpbWVDYWNoZSA9IHt9O1xuZnVuY3Rpb24gY2hlY2tQcmltZShwcmltZSwgZ2VuZXJhdG9yKSB7XG4gIHZhciBnZW4gPSBnZW5lcmF0b3IudG9TdHJpbmcoJ2hleCcpO1xuICB2YXIgaGV4ID0gW2dlbiwgcHJpbWUudG9TdHJpbmcoMTYpXS5qb2luKCdfJyk7XG4gIGlmIChoZXggaW4gcHJpbWVDYWNoZSkge1xuICAgIHJldHVybiBwcmltZUNhY2hlW2hleF07XG4gIH1cbiAgdmFyIGVycm9yID0gMDtcblxuICBpZiAocHJpbWUuaXNFdmVuKCkgfHxcbiAgICAhcHJpbWVzLnNpbXBsZVNpZXZlIHx8XG4gICAgIXByaW1lcy5mZXJtYXRUZXN0KHByaW1lKSB8fFxuICAgICFtaWxsZXJSYWJpbi50ZXN0KHByaW1lKSkge1xuICAgIC8vbm90IGEgcHJpbWUgc28gKzFcbiAgICBlcnJvciArPSAxO1xuXG4gICAgaWYgKGdlbiA9PT0gJzAyJyB8fCBnZW4gPT09ICcwNScpIHtcbiAgICAgIC8vIHdlJ2QgYmUgYWJsZSB0byBjaGVjayB0aGUgZ2VuZXJhdG9yXG4gICAgICAvLyBpdCB3b3VsZCBmYWlsIHNvICs4XG4gICAgICBlcnJvciArPSA4O1xuICAgIH0gZWxzZSB7XG4gICAgICAvL3dlIHdvdWxkbid0IGJlIGFibGUgdG8gdGVzdCB0aGUgZ2VuZXJhdG9yXG4gICAgICAvLyBzbyArNFxuICAgICAgZXJyb3IgKz0gNDtcbiAgICB9XG4gICAgcHJpbWVDYWNoZVtoZXhdID0gZXJyb3I7XG4gICAgcmV0dXJuIGVycm9yO1xuICB9XG4gIGlmICghbWlsbGVyUmFiaW4udGVzdChwcmltZS5zaHJuKDEpKSkge1xuICAgIC8vbm90IGEgc2FmZSBwcmltZVxuICAgIGVycm9yICs9IDI7XG4gIH1cbiAgdmFyIHJlbTtcbiAgc3dpdGNoIChnZW4pIHtcbiAgICBjYXNlICcwMic6XG4gICAgICBpZiAocHJpbWUubW9kKFRXRU5UWUZPVVIpLmNtcChFTEVWRU4pKSB7XG4gICAgICAgIC8vIHVuc3VpZGFibGUgZ2VuZXJhdG9yXG4gICAgICAgIGVycm9yICs9IDg7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICcwNSc6XG4gICAgICByZW0gPSBwcmltZS5tb2QoVEVOKTtcbiAgICAgIGlmIChyZW0uY21wKFRIUkVFKSAmJiByZW0uY21wKFNFVkVOKSkge1xuICAgICAgICAvLyBwcmltZSBtb2QgMTAgbmVlZHMgdG8gZXF1YWwgMyBvciA3XG4gICAgICAgIGVycm9yICs9IDg7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgZXJyb3IgKz0gNDtcbiAgfVxuICBwcmltZUNhY2hlW2hleF0gPSBlcnJvcjtcbiAgcmV0dXJuIGVycm9yO1xufVxuXG5mdW5jdGlvbiBESChwcmltZSwgZ2VuZXJhdG9yLCBtYWxsZWFibGUpIHtcbiAgdGhpcy5zZXRHZW5lcmF0b3IoZ2VuZXJhdG9yKTtcbiAgdGhpcy5fX3ByaW1lID0gbmV3IEJOKHByaW1lKTtcbiAgdGhpcy5fcHJpbWUgPSBCTi5tb250KHRoaXMuX19wcmltZSk7XG4gIHRoaXMuX3ByaW1lTGVuID0gcHJpbWUubGVuZ3RoO1xuICB0aGlzLl9wdWIgPSB1bmRlZmluZWQ7XG4gIHRoaXMuX3ByaXYgPSB1bmRlZmluZWQ7XG4gIHRoaXMuX3ByaW1lQ29kZSA9IHVuZGVmaW5lZDtcbiAgaWYgKG1hbGxlYWJsZSkge1xuICAgIHRoaXMuc2V0UHVibGljS2V5ID0gc2V0UHVibGljS2V5O1xuICAgIHRoaXMuc2V0UHJpdmF0ZUtleSA9IHNldFByaXZhdGVLZXk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5fcHJpbWVDb2RlID0gODtcbiAgfVxufVxuT2JqZWN0LmRlZmluZVByb3BlcnR5KERILnByb3RvdHlwZSwgJ3ZlcmlmeUVycm9yJywge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodHlwZW9mIHRoaXMuX3ByaW1lQ29kZSAhPT0gJ251bWJlcicpIHtcbiAgICAgIHRoaXMuX3ByaW1lQ29kZSA9IGNoZWNrUHJpbWUodGhpcy5fX3ByaW1lLCB0aGlzLl9fZ2VuKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3ByaW1lQ29kZTtcbiAgfVxufSk7XG5ESC5wcm90b3R5cGUuZ2VuZXJhdGVLZXlzID0gZnVuY3Rpb24gKCkge1xuICBpZiAoIXRoaXMuX3ByaXYpIHtcbiAgICB0aGlzLl9wcml2ID0gbmV3IEJOKHJhbmRvbUJ5dGVzKHRoaXMuX3ByaW1lTGVuKSk7XG4gIH1cbiAgdGhpcy5fcHViID0gdGhpcy5fZ2VuLnRvUmVkKHRoaXMuX3ByaW1lKS5yZWRQb3codGhpcy5fcHJpdikuZnJvbVJlZCgpO1xuICByZXR1cm4gdGhpcy5nZXRQdWJsaWNLZXkoKTtcbn07XG5cbkRILnByb3RvdHlwZS5jb21wdXRlU2VjcmV0ID0gZnVuY3Rpb24gKG90aGVyKSB7XG4gIG90aGVyID0gbmV3IEJOKG90aGVyKTtcbiAgb3RoZXIgPSBvdGhlci50b1JlZCh0aGlzLl9wcmltZSk7XG4gIHZhciBzZWNyZXQgPSBvdGhlci5yZWRQb3codGhpcy5fcHJpdikuZnJvbVJlZCgpO1xuICB2YXIgb3V0ID0gbmV3IEJ1ZmZlcihzZWNyZXQudG9BcnJheSgpKTtcbiAgdmFyIHByaW1lID0gdGhpcy5nZXRQcmltZSgpO1xuICBpZiAob3V0Lmxlbmd0aCA8IHByaW1lLmxlbmd0aCkge1xuICAgIHZhciBmcm9udCA9IG5ldyBCdWZmZXIocHJpbWUubGVuZ3RoIC0gb3V0Lmxlbmd0aCk7XG4gICAgZnJvbnQuZmlsbCgwKTtcbiAgICBvdXQgPSBCdWZmZXIuY29uY2F0KFtmcm9udCwgb3V0XSk7XG4gIH1cbiAgcmV0dXJuIG91dDtcbn07XG5cbkRILnByb3RvdHlwZS5nZXRQdWJsaWNLZXkgPSBmdW5jdGlvbiBnZXRQdWJsaWNLZXkoZW5jKSB7XG4gIHJldHVybiBmb3JtYXRSZXR1cm5WYWx1ZSh0aGlzLl9wdWIsIGVuYyk7XG59O1xuXG5ESC5wcm90b3R5cGUuZ2V0UHJpdmF0ZUtleSA9IGZ1bmN0aW9uIGdldFByaXZhdGVLZXkoZW5jKSB7XG4gIHJldHVybiBmb3JtYXRSZXR1cm5WYWx1ZSh0aGlzLl9wcml2LCBlbmMpO1xufTtcblxuREgucHJvdG90eXBlLmdldFByaW1lID0gZnVuY3Rpb24gKGVuYykge1xuICByZXR1cm4gZm9ybWF0UmV0dXJuVmFsdWUodGhpcy5fX3ByaW1lLCBlbmMpO1xufTtcblxuREgucHJvdG90eXBlLmdldEdlbmVyYXRvciA9IGZ1bmN0aW9uIChlbmMpIHtcbiAgcmV0dXJuIGZvcm1hdFJldHVyblZhbHVlKHRoaXMuX2dlbiwgZW5jKTtcbn07XG5cbkRILnByb3RvdHlwZS5zZXRHZW5lcmF0b3IgPSBmdW5jdGlvbiAoZ2VuLCBlbmMpIHtcbiAgZW5jID0gZW5jIHx8ICd1dGY4JztcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoZ2VuKSkge1xuICAgIGdlbiA9IG5ldyBCdWZmZXIoZ2VuLCBlbmMpO1xuICB9XG4gIHRoaXMuX19nZW4gPSBnZW47XG4gIHRoaXMuX2dlbiA9IG5ldyBCTihnZW4pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIGZvcm1hdFJldHVyblZhbHVlKGJuLCBlbmMpIHtcbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoYm4udG9BcnJheSgpKTtcbiAgaWYgKCFlbmMpIHtcbiAgICByZXR1cm4gYnVmO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBidWYudG9TdHJpbmcoZW5jKTtcbiAgfVxufVxuIiwidmFyIHJhbmRvbUJ5dGVzID0gcmVxdWlyZSgncmFuZG9tYnl0ZXMnKTtcbm1vZHVsZS5leHBvcnRzID0gZmluZFByaW1lO1xuZmluZFByaW1lLnNpbXBsZVNpZXZlID0gc2ltcGxlU2lldmU7XG5maW5kUHJpbWUuZmVybWF0VGVzdCA9IGZlcm1hdFRlc3Q7XG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIFRXRU5UWUZPVVIgPSBuZXcgQk4oMjQpO1xudmFyIE1pbGxlclJhYmluID0gcmVxdWlyZSgnbWlsbGVyLXJhYmluJyk7XG52YXIgbWlsbGVyUmFiaW4gPSBuZXcgTWlsbGVyUmFiaW4oKTtcbnZhciBPTkUgPSBuZXcgQk4oMSk7XG52YXIgVFdPID0gbmV3IEJOKDIpO1xudmFyIEZJVkUgPSBuZXcgQk4oNSk7XG52YXIgU0lYVEVFTiA9IG5ldyBCTigxNik7XG52YXIgRUlHSFQgPSBuZXcgQk4oOCk7XG52YXIgVEVOID0gbmV3IEJOKDEwKTtcbnZhciBUSFJFRSA9IG5ldyBCTigzKTtcbnZhciBTRVZFTiA9IG5ldyBCTig3KTtcbnZhciBFTEVWRU4gPSBuZXcgQk4oMTEpO1xudmFyIEZPVVIgPSBuZXcgQk4oNCk7XG52YXIgVFdFTFZFID0gbmV3IEJOKDEyKTtcbnZhciBwcmltZXMgPSBudWxsO1xuXG5mdW5jdGlvbiBfZ2V0UHJpbWVzKCkge1xuICBpZiAocHJpbWVzICE9PSBudWxsKVxuICAgIHJldHVybiBwcmltZXM7XG5cbiAgdmFyIGxpbWl0ID0gMHgxMDAwMDA7XG4gIHZhciByZXMgPSBbXTtcbiAgcmVzWzBdID0gMjtcbiAgZm9yICh2YXIgaSA9IDEsIGsgPSAzOyBrIDwgbGltaXQ7IGsgKz0gMikge1xuICAgIHZhciBzcXJ0ID0gTWF0aC5jZWlsKE1hdGguc3FydChrKSk7XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBpICYmIHJlc1tqXSA8PSBzcXJ0OyBqKyspXG4gICAgICBpZiAoayAlIHJlc1tqXSA9PT0gMClcbiAgICAgICAgYnJlYWs7XG5cbiAgICBpZiAoaSAhPT0gaiAmJiByZXNbal0gPD0gc3FydClcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgcmVzW2krK10gPSBrO1xuICB9XG4gIHByaW1lcyA9IHJlcztcbiAgcmV0dXJuIHJlcztcbn1cblxuZnVuY3Rpb24gc2ltcGxlU2lldmUocCkge1xuICB2YXIgcHJpbWVzID0gX2dldFByaW1lcygpO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcHJpbWVzLmxlbmd0aDsgaSsrKVxuICAgIGlmIChwLm1vZG4ocHJpbWVzW2ldKSA9PT0gMCkge1xuICAgICAgaWYgKHAuY21wbihwcmltZXNbaV0pID09PSAwKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gZmVybWF0VGVzdChwKSB7XG4gIHZhciByZWQgPSBCTi5tb250KHApO1xuICByZXR1cm4gVFdPLnRvUmVkKHJlZCkucmVkUG93KHAuc3VibigxKSkuZnJvbVJlZCgpLmNtcG4oMSkgPT09IDA7XG59XG5cbmZ1bmN0aW9uIGZpbmRQcmltZShiaXRzLCBnZW4pIHtcbiAgaWYgKGJpdHMgPCAxNikge1xuICAgIC8vIHRoaXMgaXMgd2hhdCBvcGVuc3NsIGRvZXNcbiAgICBpZiAoZ2VuID09PSAyIHx8IGdlbiA9PT0gNSkge1xuICAgICAgcmV0dXJuIG5ldyBCTihbMHg4YywgMHg3Yl0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbmV3IEJOKFsweDhjLCAweDI3XSk7XG4gICAgfVxuICB9XG4gIGdlbiA9IG5ldyBCTihnZW4pO1xuXG4gIHZhciBudW0sIG4yO1xuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgbnVtID0gbmV3IEJOKHJhbmRvbUJ5dGVzKE1hdGguY2VpbChiaXRzIC8gOCkpKTtcbiAgICB3aGlsZSAobnVtLmJpdExlbmd0aCgpID4gYml0cykge1xuICAgICAgbnVtLmlzaHJuKDEpO1xuICAgIH1cbiAgICBpZiAobnVtLmlzRXZlbigpKSB7XG4gICAgICBudW0uaWFkZChPTkUpO1xuICAgIH1cbiAgICBpZiAoIW51bS50ZXN0bigxKSkge1xuICAgICAgbnVtLmlhZGQoVFdPKTtcbiAgICB9XG4gICAgaWYgKCFnZW4uY21wKFRXTykpIHtcbiAgICAgIHdoaWxlIChudW0ubW9kKFRXRU5UWUZPVVIpLmNtcChFTEVWRU4pKSB7XG4gICAgICAgIG51bS5pYWRkKEZPVVIpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIWdlbi5jbXAoRklWRSkpIHtcbiAgICAgIHdoaWxlIChudW0ubW9kKFRFTikuY21wKFRIUkVFKSkge1xuICAgICAgICBudW0uaWFkZChGT1VSKTtcbiAgICAgIH1cbiAgICB9XG4gICAgbjIgPSBudW0uc2hybigxKTtcbiAgICBpZiAoc2ltcGxlU2lldmUobjIpICYmIHNpbXBsZVNpZXZlKG51bSkgJiZcbiAgICAgIGZlcm1hdFRlc3QobjIpICYmIGZlcm1hdFRlc3QobnVtKSAmJlxuICAgICAgbWlsbGVyUmFiaW4udGVzdChuMikgJiYgbWlsbGVyUmFiaW4udGVzdChudW0pKSB7XG4gICAgICByZXR1cm4gbnVtO1xuICAgIH1cbiAgfVxuXG59XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gICAgXCJtb2RwMVwiOiB7XG4gICAgICAgIFwiZ2VuXCI6IFwiMDJcIixcbiAgICAgICAgXCJwcmltZVwiOiBcImZmZmZmZmZmZmZmZmZmZmZjOTBmZGFhMjIxNjhjMjM0YzRjNjYyOGI4MGRjMWNkMTI5MDI0ZTA4OGE2N2NjNzQwMjBiYmVhNjNiMTM5YjIyNTE0YTA4Nzk4ZTM0MDRkZGVmOTUxOWIzY2QzYTQzMWIzMDJiMGE2ZGYyNWYxNDM3NGZlMTM1NmQ2ZDUxYzI0NWU0ODViNTc2NjI1ZTdlYzZmNDRjNDJlOWE2M2EzNjIwZmZmZmZmZmZmZmZmZmZmZlwiXG4gICAgfSxcbiAgICBcIm1vZHAyXCI6IHtcbiAgICAgICAgXCJnZW5cIjogXCIwMlwiLFxuICAgICAgICBcInByaW1lXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmM5MGZkYWEyMjE2OGMyMzRjNGM2NjI4YjgwZGMxY2QxMjkwMjRlMDg4YTY3Y2M3NDAyMGJiZWE2M2IxMzliMjI1MTRhMDg3OThlMzQwNGRkZWY5NTE5YjNjZDNhNDMxYjMwMmIwYTZkZjI1ZjE0Mzc0ZmUxMzU2ZDZkNTFjMjQ1ZTQ4NWI1NzY2MjVlN2VjNmY0NGM0MmU5YTYzN2VkNmIwYmZmNWNiNmY0MDZiN2VkZWUzODZiZmI1YTg5OWZhNWFlOWYyNDExN2M0YjFmZTY0OTI4NjY1MWVjZTY1MzgxZmZmZmZmZmZmZmZmZmZmZlwiXG4gICAgfSxcbiAgICBcIm1vZHA1XCI6IHtcbiAgICAgICAgXCJnZW5cIjogXCIwMlwiLFxuICAgICAgICBcInByaW1lXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmM5MGZkYWEyMjE2OGMyMzRjNGM2NjI4YjgwZGMxY2QxMjkwMjRlMDg4YTY3Y2M3NDAyMGJiZWE2M2IxMzliMjI1MTRhMDg3OThlMzQwNGRkZWY5NTE5YjNjZDNhNDMxYjMwMmIwYTZkZjI1ZjE0Mzc0ZmUxMzU2ZDZkNTFjMjQ1ZTQ4NWI1NzY2MjVlN2VjNmY0NGM0MmU5YTYzN2VkNmIwYmZmNWNiNmY0MDZiN2VkZWUzODZiZmI1YTg5OWZhNWFlOWYyNDExN2M0YjFmZTY0OTI4NjY1MWVjZTQ1YjNkYzIwMDdjYjhhMTYzYmYwNTk4ZGE0ODM2MWM1NWQzOWE2OTE2M2ZhOGZkMjRjZjVmODM2NTVkMjNkY2EzYWQ5NjFjNjJmMzU2MjA4NTUyYmI5ZWQ1MjkwNzcwOTY5NjZkNjcwYzM1NGU0YWJjOTgwNGYxNzQ2YzA4Y2EyMzczMjdmZmZmZmZmZmZmZmZmZmZmXCJcbiAgICB9LFxuICAgIFwibW9kcDE0XCI6IHtcbiAgICAgICAgXCJnZW5cIjogXCIwMlwiLFxuICAgICAgICBcInByaW1lXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmM5MGZkYWEyMjE2OGMyMzRjNGM2NjI4YjgwZGMxY2QxMjkwMjRlMDg4YTY3Y2M3NDAyMGJiZWE2M2IxMzliMjI1MTRhMDg3OThlMzQwNGRkZWY5NTE5YjNjZDNhNDMxYjMwMmIwYTZkZjI1ZjE0Mzc0ZmUxMzU2ZDZkNTFjMjQ1ZTQ4NWI1NzY2MjVlN2VjNmY0NGM0MmU5YTYzN2VkNmIwYmZmNWNiNmY0MDZiN2VkZWUzODZiZmI1YTg5OWZhNWFlOWYyNDExN2M0YjFmZTY0OTI4NjY1MWVjZTQ1YjNkYzIwMDdjYjhhMTYzYmYwNTk4ZGE0ODM2MWM1NWQzOWE2OTE2M2ZhOGZkMjRjZjVmODM2NTVkMjNkY2EzYWQ5NjFjNjJmMzU2MjA4NTUyYmI5ZWQ1MjkwNzcwOTY5NjZkNjcwYzM1NGU0YWJjOTgwNGYxNzQ2YzA4Y2ExODIxN2MzMjkwNWU0NjJlMzZjZTNiZTM5ZTc3MmMxODBlODYwMzliMjc4M2EyZWMwN2EyOGZiNWM1NWRmMDZmNGM1MmM5ZGUyYmNiZjY5NTU4MTcxODM5OTU0OTdjZWE5NTZhZTUxNWQyMjYxODk4ZmEwNTEwMTU3MjhlNWE4YWFjYWE2OGZmZmZmZmZmZmZmZmZmZmZcIlxuICAgIH0sXG4gICAgXCJtb2RwMTVcIjoge1xuICAgICAgICBcImdlblwiOiBcIjAyXCIsXG4gICAgICAgIFwicHJpbWVcIjogXCJmZmZmZmZmZmZmZmZmZmZmYzkwZmRhYTIyMTY4YzIzNGM0YzY2MjhiODBkYzFjZDEyOTAyNGUwODhhNjdjYzc0MDIwYmJlYTYzYjEzOWIyMjUxNGEwODc5OGUzNDA0ZGRlZjk1MTliM2NkM2E0MzFiMzAyYjBhNmRmMjVmMTQzNzRmZTEzNTZkNmQ1MWMyNDVlNDg1YjU3NjYyNWU3ZWM2ZjQ0YzQyZTlhNjM3ZWQ2YjBiZmY1Y2I2ZjQwNmI3ZWRlZTM4NmJmYjVhODk5ZmE1YWU5ZjI0MTE3YzRiMWZlNjQ5Mjg2NjUxZWNlNDViM2RjMjAwN2NiOGExNjNiZjA1OThkYTQ4MzYxYzU1ZDM5YTY5MTYzZmE4ZmQyNGNmNWY4MzY1NWQyM2RjYTNhZDk2MWM2MmYzNTYyMDg1NTJiYjllZDUyOTA3NzA5Njk2NmQ2NzBjMzU0ZTRhYmM5ODA0ZjE3NDZjMDhjYTE4MjE3YzMyOTA1ZTQ2MmUzNmNlM2JlMzllNzcyYzE4MGU4NjAzOWIyNzgzYTJlYzA3YTI4ZmI1YzU1ZGYwNmY0YzUyYzlkZTJiY2JmNjk1NTgxNzE4Mzk5NTQ5N2NlYTk1NmFlNTE1ZDIyNjE4OThmYTA1MTAxNTcyOGU1YThhYWFjNDJkYWQzMzE3MGQwNDUwN2EzM2E4NTUyMWFiZGYxY2JhNjRlY2ZiODUwNDU4ZGJlZjBhOGFlYTcxNTc1ZDA2MGM3ZGIzOTcwZjg1YTZlMWU0YzdhYmY1YWU4Y2RiMDkzM2Q3MWU4Yzk0ZTA0YTI1NjE5ZGNlZTNkMjI2MWFkMmVlNmJmMTJmZmEwNmQ5OGEwODY0ZDg3NjAyNzMzZWM4NmE2NDUyMWYyYjE4MTc3YjIwMGNiYmUxMTc1NzdhNjE1ZDZjNzcwOTg4YzBiYWQ5NDZlMjA4ZTI0ZmEwNzRlNWFiMzE0M2RiNWJmY2UwZmQxMDhlNGI4MmQxMjBhOTNhZDJjYWZmZmZmZmZmZmZmZmZmZmZcIlxuICAgIH0sXG4gICAgXCJtb2RwMTZcIjoge1xuICAgICAgICBcImdlblwiOiBcIjAyXCIsXG4gICAgICAgIFwicHJpbWVcIjogXCJmZmZmZmZmZmZmZmZmZmZmYzkwZmRhYTIyMTY4YzIzNGM0YzY2MjhiODBkYzFjZDEyOTAyNGUwODhhNjdjYzc0MDIwYmJlYTYzYjEzOWIyMjUxNGEwODc5OGUzNDA0ZGRlZjk1MTliM2NkM2E0MzFiMzAyYjBhNmRmMjVmMTQzNzRmZTEzNTZkNmQ1MWMyNDVlNDg1YjU3NjYyNWU3ZWM2ZjQ0YzQyZTlhNjM3ZWQ2YjBiZmY1Y2I2ZjQwNmI3ZWRlZTM4NmJmYjVhODk5ZmE1YWU5ZjI0MTE3YzRiMWZlNjQ5Mjg2NjUxZWNlNDViM2RjMjAwN2NiOGExNjNiZjA1OThkYTQ4MzYxYzU1ZDM5YTY5MTYzZmE4ZmQyNGNmNWY4MzY1NWQyM2RjYTNhZDk2MWM2MmYzNTYyMDg1NTJiYjllZDUyOTA3NzA5Njk2NmQ2NzBjMzU0ZTRhYmM5ODA0ZjE3NDZjMDhjYTE4MjE3YzMyOTA1ZTQ2MmUzNmNlM2JlMzllNzcyYzE4MGU4NjAzOWIyNzgzYTJlYzA3YTI4ZmI1YzU1ZGYwNmY0YzUyYzlkZTJiY2JmNjk1NTgxNzE4Mzk5NTQ5N2NlYTk1NmFlNTE1ZDIyNjE4OThmYTA1MTAxNTcyOGU1YThhYWFjNDJkYWQzMzE3MGQwNDUwN2EzM2E4NTUyMWFiZGYxY2JhNjRlY2ZiODUwNDU4ZGJlZjBhOGFlYTcxNTc1ZDA2MGM3ZGIzOTcwZjg1YTZlMWU0YzdhYmY1YWU4Y2RiMDkzM2Q3MWU4Yzk0ZTA0YTI1NjE5ZGNlZTNkMjI2MWFkMmVlNmJmMTJmZmEwNmQ5OGEwODY0ZDg3NjAyNzMzZWM4NmE2NDUyMWYyYjE4MTc3YjIwMGNiYmUxMTc1NzdhNjE1ZDZjNzcwOTg4YzBiYWQ5NDZlMjA4ZTI0ZmEwNzRlNWFiMzE0M2RiNWJmY2UwZmQxMDhlNGI4MmQxMjBhOTIxMDgwMTFhNzIzYzEyYTc4N2U2ZDc4ODcxOWExMGJkYmE1YjI2OTljMzI3MTg2YWY0ZTIzYzFhOTQ2ODM0YjYxNTBiZGEyNTgzZTljYTJhZDQ0Y2U4ZGJiYmMyZGIwNGRlOGVmOTJlOGVmYzE0MWZiZWNhYTYyODdjNTk0NzRlNmJjMDVkOTliMjk2NGZhMDkwYzNhMjIzM2JhMTg2NTE1YmU3ZWQxZjYxMjk3MGNlZTJkN2FmYjgxYmRkNzYyMTcwNDgxY2QwMDY5MTI3ZDViMDVhYTk5M2I0ZWE5ODhkOGZkZGMxODZmZmI3ZGM5MGE2YzA4ZjRkZjQzNWM5MzQwNjMxOTlmZmZmZmZmZmZmZmZmZmZmXCJcbiAgICB9LFxuICAgIFwibW9kcDE3XCI6IHtcbiAgICAgICAgXCJnZW5cIjogXCIwMlwiLFxuICAgICAgICBcInByaW1lXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmM5MGZkYWEyMjE2OGMyMzRjNGM2NjI4YjgwZGMxY2QxMjkwMjRlMDg4YTY3Y2M3NDAyMGJiZWE2M2IxMzliMjI1MTRhMDg3OThlMzQwNGRkZWY5NTE5YjNjZDNhNDMxYjMwMmIwYTZkZjI1ZjE0Mzc0ZmUxMzU2ZDZkNTFjMjQ1ZTQ4NWI1NzY2MjVlN2VjNmY0NGM0MmU5YTYzN2VkNmIwYmZmNWNiNmY0MDZiN2VkZWUzODZiZmI1YTg5OWZhNWFlOWYyNDExN2M0YjFmZTY0OTI4NjY1MWVjZTQ1YjNkYzIwMDdjYjhhMTYzYmYwNTk4ZGE0ODM2MWM1NWQzOWE2OTE2M2ZhOGZkMjRjZjVmODM2NTVkMjNkY2EzYWQ5NjFjNjJmMzU2MjA4NTUyYmI5ZWQ1MjkwNzcwOTY5NjZkNjcwYzM1NGU0YWJjOTgwNGYxNzQ2YzA4Y2ExODIxN2MzMjkwNWU0NjJlMzZjZTNiZTM5ZTc3MmMxODBlODYwMzliMjc4M2EyZWMwN2EyOGZiNWM1NWRmMDZmNGM1MmM5ZGUyYmNiZjY5NTU4MTcxODM5OTU0OTdjZWE5NTZhZTUxNWQyMjYxODk4ZmEwNTEwMTU3MjhlNWE4YWFhYzQyZGFkMzMxNzBkMDQ1MDdhMzNhODU1MjFhYmRmMWNiYTY0ZWNmYjg1MDQ1OGRiZWYwYThhZWE3MTU3NWQwNjBjN2RiMzk3MGY4NWE2ZTFlNGM3YWJmNWFlOGNkYjA5MzNkNzFlOGM5NGUwNGEyNTYxOWRjZWUzZDIyNjFhZDJlZTZiZjEyZmZhMDZkOThhMDg2NGQ4NzYwMjczM2VjODZhNjQ1MjFmMmIxODE3N2IyMDBjYmJlMTE3NTc3YTYxNWQ2Yzc3MDk4OGMwYmFkOTQ2ZTIwOGUyNGZhMDc0ZTVhYjMxNDNkYjViZmNlMGZkMTA4ZTRiODJkMTIwYTkyMTA4MDExYTcyM2MxMmE3ODdlNmQ3ODg3MTlhMTBiZGJhNWIyNjk5YzMyNzE4NmFmNGUyM2MxYTk0NjgzNGI2MTUwYmRhMjU4M2U5Y2EyYWQ0NGNlOGRiYmJjMmRiMDRkZThlZjkyZThlZmMxNDFmYmVjYWE2Mjg3YzU5NDc0ZTZiYzA1ZDk5YjI5NjRmYTA5MGMzYTIyMzNiYTE4NjUxNWJlN2VkMWY2MTI5NzBjZWUyZDdhZmI4MWJkZDc2MjE3MDQ4MWNkMDA2OTEyN2Q1YjA1YWE5OTNiNGVhOTg4ZDhmZGRjMTg2ZmZiN2RjOTBhNmMwOGY0ZGY0MzVjOTM0MDI4NDkyMzZjM2ZhYjRkMjdjNzAyNmMxZDRkY2IyNjAyNjQ2ZGVjOTc1MWU3NjNkYmEzN2JkZjhmZjk0MDZhZDllNTMwZWU1ZGIzODJmNDEzMDAxYWViMDZhNTNlZDkwMjdkODMxMTc5NzI3YjA4NjVhODkxOGRhM2VkYmViY2Y5YjE0ZWQ0NGNlNmNiYWNlZDRiYjFiZGI3ZjE0NDdlNmNjMjU0YjMzMjA1MTUxMmJkN2FmNDI2ZmI4ZjQwMTM3OGNkMmJmNTk4M2NhMDFjNjRiOTJlY2YwMzJlYTE1ZDE3MjFkMDNmNDgyZDdjZTZlNzRmZWY2ZDU1ZTcwMmY0Njk4MGM4MmI1YTg0MDMxOTAwYjFjOWU1OWU3Yzk3ZmJlYzdlOGYzMjNhOTdhN2UzNmNjODhiZTBmMWQ0NWI3ZmY1ODVhYzU0YmQ0MDdiMjJiNDE1NGFhY2M4ZjZkN2ViZjQ4ZTFkODE0Y2M1ZWQyMGY4MDM3ZTBhNzk3MTVlZWYyOWJlMzI4MDZhMWQ1OGJiN2M1ZGE3NmY1NTBhYTNkOGExZmJmZjBlYjE5Y2NiMWEzMTNkNTVjZGE1NmM5ZWMyZWYyOTYzMjM4N2ZlOGQ3NmUzYzA0NjgwNDNlOGY2NjNmNDg2MGVlMTJiZjJkNWIwYjc0NzRkNmU2OTRmOTFlNmRjYzQwMjRmZmZmZmZmZmZmZmZmZmZmXCJcbiAgICB9LFxuICAgIFwibW9kcDE4XCI6IHtcbiAgICAgICAgXCJnZW5cIjogXCIwMlwiLFxuICAgICAgICBcInByaW1lXCI6IFwiZmZmZmZmZmZmZmZmZmZmZmM5MGZkYWEyMjE2OGMyMzRjNGM2NjI4YjgwZGMxY2QxMjkwMjRlMDg4YTY3Y2M3NDAyMGJiZWE2M2IxMzliMjI1MTRhMDg3OThlMzQwNGRkZWY5NTE5YjNjZDNhNDMxYjMwMmIwYTZkZjI1ZjE0Mzc0ZmUxMzU2ZDZkNTFjMjQ1ZTQ4NWI1NzY2MjVlN2VjNmY0NGM0MmU5YTYzN2VkNmIwYmZmNWNiNmY0MDZiN2VkZWUzODZiZmI1YTg5OWZhNWFlOWYyNDExN2M0YjFmZTY0OTI4NjY1MWVjZTQ1YjNkYzIwMDdjYjhhMTYzYmYwNTk4ZGE0ODM2MWM1NWQzOWE2OTE2M2ZhOGZkMjRjZjVmODM2NTVkMjNkY2EzYWQ5NjFjNjJmMzU2MjA4NTUyYmI5ZWQ1MjkwNzcwOTY5NjZkNjcwYzM1NGU0YWJjOTgwNGYxNzQ2YzA4Y2ExODIxN2MzMjkwNWU0NjJlMzZjZTNiZTM5ZTc3MmMxODBlODYwMzliMjc4M2EyZWMwN2EyOGZiNWM1NWRmMDZmNGM1MmM5ZGUyYmNiZjY5NTU4MTcxODM5OTU0OTdjZWE5NTZhZTUxNWQyMjYxODk4ZmEwNTEwMTU3MjhlNWE4YWFhYzQyZGFkMzMxNzBkMDQ1MDdhMzNhODU1MjFhYmRmMWNiYTY0ZWNmYjg1MDQ1OGRiZWYwYThhZWE3MTU3NWQwNjBjN2RiMzk3MGY4NWE2ZTFlNGM3YWJmNWFlOGNkYjA5MzNkNzFlOGM5NGUwNGEyNTYxOWRjZWUzZDIyNjFhZDJlZTZiZjEyZmZhMDZkOThhMDg2NGQ4NzYwMjczM2VjODZhNjQ1MjFmMmIxODE3N2IyMDBjYmJlMTE3NTc3YTYxNWQ2Yzc3MDk4OGMwYmFkOTQ2ZTIwOGUyNGZhMDc0ZTVhYjMxNDNkYjViZmNlMGZkMTA4ZTRiODJkMTIwYTkyMTA4MDExYTcyM2MxMmE3ODdlNmQ3ODg3MTlhMTBiZGJhNWIyNjk5YzMyNzE4NmFmNGUyM2MxYTk0NjgzNGI2MTUwYmRhMjU4M2U5Y2EyYWQ0NGNlOGRiYmJjMmRiMDRkZThlZjkyZThlZmMxNDFmYmVjYWE2Mjg3YzU5NDc0ZTZiYzA1ZDk5YjI5NjRmYTA5MGMzYTIyMzNiYTE4NjUxNWJlN2VkMWY2MTI5NzBjZWUyZDdhZmI4MWJkZDc2MjE3MDQ4MWNkMDA2OTEyN2Q1YjA1YWE5OTNiNGVhOTg4ZDhmZGRjMTg2ZmZiN2RjOTBhNmMwOGY0ZGY0MzVjOTM0MDI4NDkyMzZjM2ZhYjRkMjdjNzAyNmMxZDRkY2IyNjAyNjQ2ZGVjOTc1MWU3NjNkYmEzN2JkZjhmZjk0MDZhZDllNTMwZWU1ZGIzODJmNDEzMDAxYWViMDZhNTNlZDkwMjdkODMxMTc5NzI3YjA4NjVhODkxOGRhM2VkYmViY2Y5YjE0ZWQ0NGNlNmNiYWNlZDRiYjFiZGI3ZjE0NDdlNmNjMjU0YjMzMjA1MTUxMmJkN2FmNDI2ZmI4ZjQwMTM3OGNkMmJmNTk4M2NhMDFjNjRiOTJlY2YwMzJlYTE1ZDE3MjFkMDNmNDgyZDdjZTZlNzRmZWY2ZDU1ZTcwMmY0Njk4MGM4MmI1YTg0MDMxOTAwYjFjOWU1OWU3Yzk3ZmJlYzdlOGYzMjNhOTdhN2UzNmNjODhiZTBmMWQ0NWI3ZmY1ODVhYzU0YmQ0MDdiMjJiNDE1NGFhY2M4ZjZkN2ViZjQ4ZTFkODE0Y2M1ZWQyMGY4MDM3ZTBhNzk3MTVlZWYyOWJlMzI4MDZhMWQ1OGJiN2M1ZGE3NmY1NTBhYTNkOGExZmJmZjBlYjE5Y2NiMWEzMTNkNTVjZGE1NmM5ZWMyZWYyOTYzMjM4N2ZlOGQ3NmUzYzA0NjgwNDNlOGY2NjNmNDg2MGVlMTJiZjJkNWIwYjc0NzRkNmU2OTRmOTFlNmRiZTExNTk3NGEzOTI2ZjEyZmVlNWU0Mzg3NzdjYjZhOTMyZGY4Y2Q4YmVjNGQwNzNiOTMxYmEzYmM4MzJiNjhkOWRkMzAwNzQxZmE3YmY4YWZjNDdlZDI1NzZmNjkzNmJhNDI0NjYzYWFiNjM5YzVhZTRmNTY4MzQyM2I0NzQyYmYxYzk3ODIzOGYxNmNiZTM5ZDY1MmRlM2ZkYjhiZWZjODQ4YWQ5MjIyMjJlMDRhNDAzN2MwNzEzZWI1N2E4MWEyM2YwYzczNDczZmM2NDZjZWEzMDZiNGJjYmM4ODYyZjgzODVkZGZhOWQ0YjdmYTJjMDg3ZTg3OTY4MzMwM2VkNWJkZDNhMDYyYjNjZjViM2EyNzhhNjZkMmExM2Y4M2Y0NGY4MmRkZjMxMGVlMDc0YWI2YTM2NDU5N2U4OTlhMDI1NWRjMTY0ZjMxY2M1MDg0Njg1MWRmOWFiNDgxOTVkZWQ3ZWExYjFkNTEwYmQ3ZWU3NGQ3M2ZhZjM2YmMzMWVjZmEyNjgzNTkwNDZmNGViODc5ZjkyNDAwOTQzOGI0ODFjNmNkNzg4OWEwMDJlZDVlZTM4MmJjOTE5MGRhNmZjMDI2ZTQ3OTU1OGU0NDc1Njc3ZTlhYTllMzA1MGUyNzY1Njk0ZGZjODFmNTZlODgwYjk2ZTcxNjBjOTgwZGQ5OGVkZDNkZmZmZmZmZmZmZmZmZmZmZmZcIlxuICAgIH1cbn0iLCIndXNlIHN0cmljdCc7XG5cbnZhciBlbGxpcHRpYyA9IGV4cG9ydHM7XG5cbmVsbGlwdGljLnZlcnNpb24gPSByZXF1aXJlKCcuLi9wYWNrYWdlLmpzb24nKS52ZXJzaW9uO1xuZWxsaXB0aWMudXRpbHMgPSByZXF1aXJlKCcuL2VsbGlwdGljL3V0aWxzJyk7XG5lbGxpcHRpYy5yYW5kID0gcmVxdWlyZSgnYnJvcmFuZCcpO1xuZWxsaXB0aWMuY3VydmUgPSByZXF1aXJlKCcuL2VsbGlwdGljL2N1cnZlJyk7XG5lbGxpcHRpYy5jdXJ2ZXMgPSByZXF1aXJlKCcuL2VsbGlwdGljL2N1cnZlcycpO1xuXG4vLyBQcm90b2NvbHNcbmVsbGlwdGljLmVjID0gcmVxdWlyZSgnLi9lbGxpcHRpYy9lYycpO1xuZWxsaXB0aWMuZWRkc2EgPSByZXF1aXJlKCcuL2VsbGlwdGljL2VkZHNhJyk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCcuLi8uLi9lbGxpcHRpYycpO1xudmFyIHV0aWxzID0gZWxsaXB0aWMudXRpbHM7XG52YXIgZ2V0TkFGID0gdXRpbHMuZ2V0TkFGO1xudmFyIGdldEpTRiA9IHV0aWxzLmdldEpTRjtcbnZhciBhc3NlcnQgPSB1dGlscy5hc3NlcnQ7XG5cbmZ1bmN0aW9uIEJhc2VDdXJ2ZSh0eXBlLCBjb25mKSB7XG4gIHRoaXMudHlwZSA9IHR5cGU7XG4gIHRoaXMucCA9IG5ldyBCTihjb25mLnAsIDE2KTtcblxuICAvLyBVc2UgTW9udGdvbWVyeSwgd2hlbiB0aGVyZSBpcyBubyBmYXN0IHJlZHVjdGlvbiBmb3IgdGhlIHByaW1lXG4gIHRoaXMucmVkID0gY29uZi5wcmltZSA/IEJOLnJlZChjb25mLnByaW1lKSA6IEJOLm1vbnQodGhpcy5wKTtcblxuICAvLyBVc2VmdWwgZm9yIG1hbnkgY3VydmVzXG4gIHRoaXMuemVybyA9IG5ldyBCTigwKS50b1JlZCh0aGlzLnJlZCk7XG4gIHRoaXMub25lID0gbmV3IEJOKDEpLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy50d28gPSBuZXcgQk4oMikudG9SZWQodGhpcy5yZWQpO1xuXG4gIC8vIEN1cnZlIGNvbmZpZ3VyYXRpb24sIG9wdGlvbmFsXG4gIHRoaXMubiA9IGNvbmYubiAmJiBuZXcgQk4oY29uZi5uLCAxNik7XG4gIHRoaXMuZyA9IGNvbmYuZyAmJiB0aGlzLnBvaW50RnJvbUpTT04oY29uZi5nLCBjb25mLmdSZWQpO1xuXG4gIC8vIFRlbXBvcmFyeSBhcnJheXNcbiAgdGhpcy5fd25hZlQxID0gbmV3IEFycmF5KDQpO1xuICB0aGlzLl93bmFmVDIgPSBuZXcgQXJyYXkoNCk7XG4gIHRoaXMuX3duYWZUMyA9IG5ldyBBcnJheSg0KTtcbiAgdGhpcy5fd25hZlQ0ID0gbmV3IEFycmF5KDQpO1xuXG4gIC8vIEdlbmVyYWxpemVkIEdyZWcgTWF4d2VsbCdzIHRyaWNrXG4gIHZhciBhZGp1c3RDb3VudCA9IHRoaXMubiAmJiB0aGlzLnAuZGl2KHRoaXMubik7XG4gIGlmICghYWRqdXN0Q291bnQgfHwgYWRqdXN0Q291bnQuY21wbigxMDApID4gMCkge1xuICAgIHRoaXMucmVkTiA9IG51bGw7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5fbWF4d2VsbFRyaWNrID0gdHJ1ZTtcbiAgICB0aGlzLnJlZE4gPSB0aGlzLm4udG9SZWQodGhpcy5yZWQpO1xuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IEJhc2VDdXJ2ZTtcblxuQmFzZUN1cnZlLnByb3RvdHlwZS5wb2ludCA9IGZ1bmN0aW9uIHBvaW50KCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xufTtcblxuQmFzZUN1cnZlLnByb3RvdHlwZS52YWxpZGF0ZSA9IGZ1bmN0aW9uIHZhbGlkYXRlKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xufTtcblxuQmFzZUN1cnZlLnByb3RvdHlwZS5fZml4ZWROYWZNdWwgPSBmdW5jdGlvbiBfZml4ZWROYWZNdWwocCwgaykge1xuICBhc3NlcnQocC5wcmVjb21wdXRlZCk7XG4gIHZhciBkb3VibGVzID0gcC5fZ2V0RG91YmxlcygpO1xuXG4gIHZhciBuYWYgPSBnZXROQUYoaywgMSk7XG4gIHZhciBJID0gKDEgPDwgKGRvdWJsZXMuc3RlcCArIDEpKSAtIChkb3VibGVzLnN0ZXAgJSAyID09PSAwID8gMiA6IDEpO1xuICBJIC89IDM7XG5cbiAgLy8gVHJhbnNsYXRlIGludG8gbW9yZSB3aW5kb3dlZCBmb3JtXG4gIHZhciByZXByID0gW107XG4gIGZvciAodmFyIGogPSAwOyBqIDwgbmFmLmxlbmd0aDsgaiArPSBkb3VibGVzLnN0ZXApIHtcbiAgICB2YXIgbmFmVyA9IDA7XG4gICAgZm9yICh2YXIgayA9IGogKyBkb3VibGVzLnN0ZXAgLSAxOyBrID49IGo7IGstLSlcbiAgICAgIG5hZlcgPSAobmFmVyA8PCAxKSArIG5hZltrXTtcbiAgICByZXByLnB1c2gobmFmVyk7XG4gIH1cblxuICB2YXIgYSA9IHRoaXMuanBvaW50KG51bGwsIG51bGwsIG51bGwpO1xuICB2YXIgYiA9IHRoaXMuanBvaW50KG51bGwsIG51bGwsIG51bGwpO1xuICBmb3IgKHZhciBpID0gSTsgaSA+IDA7IGktLSkge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgcmVwci5sZW5ndGg7IGorKykge1xuICAgICAgdmFyIG5hZlcgPSByZXByW2pdO1xuICAgICAgaWYgKG5hZlcgPT09IGkpXG4gICAgICAgIGIgPSBiLm1peGVkQWRkKGRvdWJsZXMucG9pbnRzW2pdKTtcbiAgICAgIGVsc2UgaWYgKG5hZlcgPT09IC1pKVxuICAgICAgICBiID0gYi5taXhlZEFkZChkb3VibGVzLnBvaW50c1tqXS5uZWcoKSk7XG4gICAgfVxuICAgIGEgPSBhLmFkZChiKTtcbiAgfVxuICByZXR1cm4gYS50b1AoKTtcbn07XG5cbkJhc2VDdXJ2ZS5wcm90b3R5cGUuX3duYWZNdWwgPSBmdW5jdGlvbiBfd25hZk11bChwLCBrKSB7XG4gIHZhciB3ID0gNDtcblxuICAvLyBQcmVjb21wdXRlIHdpbmRvd1xuICB2YXIgbmFmUG9pbnRzID0gcC5fZ2V0TkFGUG9pbnRzKHcpO1xuICB3ID0gbmFmUG9pbnRzLnduZDtcbiAgdmFyIHduZCA9IG5hZlBvaW50cy5wb2ludHM7XG5cbiAgLy8gR2V0IE5BRiBmb3JtXG4gIHZhciBuYWYgPSBnZXROQUYoaywgdyk7XG5cbiAgLy8gQWRkIGB0aGlzYCooTisxKSBmb3IgZXZlcnkgdy1OQUYgaW5kZXhcbiAgdmFyIGFjYyA9IHRoaXMuanBvaW50KG51bGwsIG51bGwsIG51bGwpO1xuICBmb3IgKHZhciBpID0gbmFmLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgLy8gQ291bnQgemVyb2VzXG4gICAgZm9yICh2YXIgayA9IDA7IGkgPj0gMCAmJiBuYWZbaV0gPT09IDA7IGktLSlcbiAgICAgIGsrKztcbiAgICBpZiAoaSA+PSAwKVxuICAgICAgaysrO1xuICAgIGFjYyA9IGFjYy5kYmxwKGspO1xuXG4gICAgaWYgKGkgPCAwKVxuICAgICAgYnJlYWs7XG4gICAgdmFyIHogPSBuYWZbaV07XG4gICAgYXNzZXJ0KHogIT09IDApO1xuICAgIGlmIChwLnR5cGUgPT09ICdhZmZpbmUnKSB7XG4gICAgICAvLyBKICstIFBcbiAgICAgIGlmICh6ID4gMClcbiAgICAgICAgYWNjID0gYWNjLm1peGVkQWRkKHduZFsoeiAtIDEpID4+IDFdKTtcbiAgICAgIGVsc2VcbiAgICAgICAgYWNjID0gYWNjLm1peGVkQWRkKHduZFsoLXogLSAxKSA+PiAxXS5uZWcoKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEogKy0gSlxuICAgICAgaWYgKHogPiAwKVxuICAgICAgICBhY2MgPSBhY2MuYWRkKHduZFsoeiAtIDEpID4+IDFdKTtcbiAgICAgIGVsc2VcbiAgICAgICAgYWNjID0gYWNjLmFkZCh3bmRbKC16IC0gMSkgPj4gMV0ubmVnKCkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcC50eXBlID09PSAnYWZmaW5lJyA/IGFjYy50b1AoKSA6IGFjYztcbn07XG5cbkJhc2VDdXJ2ZS5wcm90b3R5cGUuX3duYWZNdWxBZGQgPSBmdW5jdGlvbiBfd25hZk11bEFkZChkZWZXLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50cyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2VmZnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGphY29iaWFuUmVzdWx0KSB7XG4gIHZhciB3bmRXaWR0aCA9IHRoaXMuX3duYWZUMTtcbiAgdmFyIHduZCA9IHRoaXMuX3duYWZUMjtcbiAgdmFyIG5hZiA9IHRoaXMuX3duYWZUMztcblxuICAvLyBGaWxsIGFsbCBhcnJheXNcbiAgdmFyIG1heCA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICB2YXIgcCA9IHBvaW50c1tpXTtcbiAgICB2YXIgbmFmUG9pbnRzID0gcC5fZ2V0TkFGUG9pbnRzKGRlZlcpO1xuICAgIHduZFdpZHRoW2ldID0gbmFmUG9pbnRzLnduZDtcbiAgICB3bmRbaV0gPSBuYWZQb2ludHMucG9pbnRzO1xuICB9XG5cbiAgLy8gQ29tYiBzbWFsbCB3aW5kb3cgTkFGc1xuICBmb3IgKHZhciBpID0gbGVuIC0gMTsgaSA+PSAxOyBpIC09IDIpIHtcbiAgICB2YXIgYSA9IGkgLSAxO1xuICAgIHZhciBiID0gaTtcbiAgICBpZiAod25kV2lkdGhbYV0gIT09IDEgfHwgd25kV2lkdGhbYl0gIT09IDEpIHtcbiAgICAgIG5hZlthXSA9IGdldE5BRihjb2VmZnNbYV0sIHduZFdpZHRoW2FdKTtcbiAgICAgIG5hZltiXSA9IGdldE5BRihjb2VmZnNbYl0sIHduZFdpZHRoW2JdKTtcbiAgICAgIG1heCA9IE1hdGgubWF4KG5hZlthXS5sZW5ndGgsIG1heCk7XG4gICAgICBtYXggPSBNYXRoLm1heChuYWZbYl0ubGVuZ3RoLCBtYXgpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdmFyIGNvbWIgPSBbXG4gICAgICBwb2ludHNbYV0sIC8qIDEgKi9cbiAgICAgIG51bGwsIC8qIDMgKi9cbiAgICAgIG51bGwsIC8qIDUgKi9cbiAgICAgIHBvaW50c1tiXSAvKiA3ICovXG4gICAgXTtcblxuICAgIC8vIFRyeSB0byBhdm9pZCBQcm9qZWN0aXZlIHBvaW50cywgaWYgcG9zc2libGVcbiAgICBpZiAocG9pbnRzW2FdLnkuY21wKHBvaW50c1tiXS55KSA9PT0gMCkge1xuICAgICAgY29tYlsxXSA9IHBvaW50c1thXS5hZGQocG9pbnRzW2JdKTtcbiAgICAgIGNvbWJbMl0gPSBwb2ludHNbYV0udG9KKCkubWl4ZWRBZGQocG9pbnRzW2JdLm5lZygpKTtcbiAgICB9IGVsc2UgaWYgKHBvaW50c1thXS55LmNtcChwb2ludHNbYl0ueS5yZWROZWcoKSkgPT09IDApIHtcbiAgICAgIGNvbWJbMV0gPSBwb2ludHNbYV0udG9KKCkubWl4ZWRBZGQocG9pbnRzW2JdKTtcbiAgICAgIGNvbWJbMl0gPSBwb2ludHNbYV0uYWRkKHBvaW50c1tiXS5uZWcoKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbWJbMV0gPSBwb2ludHNbYV0udG9KKCkubWl4ZWRBZGQocG9pbnRzW2JdKTtcbiAgICAgIGNvbWJbMl0gPSBwb2ludHNbYV0udG9KKCkubWl4ZWRBZGQocG9pbnRzW2JdLm5lZygpKTtcbiAgICB9XG5cbiAgICB2YXIgaW5kZXggPSBbXG4gICAgICAtMywgLyogLTEgLTEgKi9cbiAgICAgIC0xLCAvKiAtMSAwICovXG4gICAgICAtNSwgLyogLTEgMSAqL1xuICAgICAgLTcsIC8qIDAgLTEgKi9cbiAgICAgIDAsIC8qIDAgMCAqL1xuICAgICAgNywgLyogMCAxICovXG4gICAgICA1LCAvKiAxIC0xICovXG4gICAgICAxLCAvKiAxIDAgKi9cbiAgICAgIDMgIC8qIDEgMSAqL1xuICAgIF07XG5cbiAgICB2YXIganNmID0gZ2V0SlNGKGNvZWZmc1thXSwgY29lZmZzW2JdKTtcbiAgICBtYXggPSBNYXRoLm1heChqc2ZbMF0ubGVuZ3RoLCBtYXgpO1xuICAgIG5hZlthXSA9IG5ldyBBcnJheShtYXgpO1xuICAgIG5hZltiXSA9IG5ldyBBcnJheShtYXgpO1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWF4OyBqKyspIHtcbiAgICAgIHZhciBqYSA9IGpzZlswXVtqXSB8IDA7XG4gICAgICB2YXIgamIgPSBqc2ZbMV1bal0gfCAwO1xuXG4gICAgICBuYWZbYV1bal0gPSBpbmRleFsoamEgKyAxKSAqIDMgKyAoamIgKyAxKV07XG4gICAgICBuYWZbYl1bal0gPSAwO1xuICAgICAgd25kW2FdID0gY29tYjtcbiAgICB9XG4gIH1cblxuICB2YXIgYWNjID0gdGhpcy5qcG9pbnQobnVsbCwgbnVsbCwgbnVsbCk7XG4gIHZhciB0bXAgPSB0aGlzLl93bmFmVDQ7XG4gIGZvciAodmFyIGkgPSBtYXg7IGkgPj0gMDsgaS0tKSB7XG4gICAgdmFyIGsgPSAwO1xuXG4gICAgd2hpbGUgKGkgPj0gMCkge1xuICAgICAgdmFyIHplcm8gPSB0cnVlO1xuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBsZW47IGorKykge1xuICAgICAgICB0bXBbal0gPSBuYWZbal1baV0gfCAwO1xuICAgICAgICBpZiAodG1wW2pdICE9PSAwKVxuICAgICAgICAgIHplcm8gPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmICghemVybylcbiAgICAgICAgYnJlYWs7XG4gICAgICBrKys7XG4gICAgICBpLS07XG4gICAgfVxuICAgIGlmIChpID49IDApXG4gICAgICBrKys7XG4gICAgYWNjID0gYWNjLmRibHAoayk7XG4gICAgaWYgKGkgPCAwKVxuICAgICAgYnJlYWs7XG5cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IGxlbjsgaisrKSB7XG4gICAgICB2YXIgeiA9IHRtcFtqXTtcbiAgICAgIHZhciBwO1xuICAgICAgaWYgKHogPT09IDApXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgZWxzZSBpZiAoeiA+IDApXG4gICAgICAgIHAgPSB3bmRbal1bKHogLSAxKSA+PiAxXTtcbiAgICAgIGVsc2UgaWYgKHogPCAwKVxuICAgICAgICBwID0gd25kW2pdWygteiAtIDEpID4+IDFdLm5lZygpO1xuXG4gICAgICBpZiAocC50eXBlID09PSAnYWZmaW5lJylcbiAgICAgICAgYWNjID0gYWNjLm1peGVkQWRkKHApO1xuICAgICAgZWxzZVxuICAgICAgICBhY2MgPSBhY2MuYWRkKHApO1xuICAgIH1cbiAgfVxuICAvLyBaZXJvaWZ5IHJlZmVyZW5jZXNcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICB3bmRbaV0gPSBudWxsO1xuXG4gIGlmIChqYWNvYmlhblJlc3VsdClcbiAgICByZXR1cm4gYWNjO1xuICBlbHNlXG4gICAgcmV0dXJuIGFjYy50b1AoKTtcbn07XG5cbmZ1bmN0aW9uIEJhc2VQb2ludChjdXJ2ZSwgdHlwZSkge1xuICB0aGlzLmN1cnZlID0gY3VydmU7XG4gIHRoaXMudHlwZSA9IHR5cGU7XG4gIHRoaXMucHJlY29tcHV0ZWQgPSBudWxsO1xufVxuQmFzZUN1cnZlLkJhc2VQb2ludCA9IEJhc2VQb2ludDtcblxuQmFzZVBvaW50LnByb3RvdHlwZS5lcSA9IGZ1bmN0aW9uIGVxKC8qb3RoZXIqLykge1xuICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xufTtcblxuQmFzZVBvaW50LnByb3RvdHlwZS52YWxpZGF0ZSA9IGZ1bmN0aW9uIHZhbGlkYXRlKCkge1xuICByZXR1cm4gdGhpcy5jdXJ2ZS52YWxpZGF0ZSh0aGlzKTtcbn07XG5cbkJhc2VDdXJ2ZS5wcm90b3R5cGUuZGVjb2RlUG9pbnQgPSBmdW5jdGlvbiBkZWNvZGVQb2ludChieXRlcywgZW5jKSB7XG4gIGJ5dGVzID0gdXRpbHMudG9BcnJheShieXRlcywgZW5jKTtcblxuICB2YXIgbGVuID0gdGhpcy5wLmJ5dGVMZW5ndGgoKTtcblxuICAvLyB1bmNvbXByZXNzZWQsIGh5YnJpZC1vZGQsIGh5YnJpZC1ldmVuXG4gIGlmICgoYnl0ZXNbMF0gPT09IDB4MDQgfHwgYnl0ZXNbMF0gPT09IDB4MDYgfHwgYnl0ZXNbMF0gPT09IDB4MDcpICYmXG4gICAgICBieXRlcy5sZW5ndGggLSAxID09PSAyICogbGVuKSB7XG4gICAgaWYgKGJ5dGVzWzBdID09PSAweDA2KVxuICAgICAgYXNzZXJ0KGJ5dGVzW2J5dGVzLmxlbmd0aCAtIDFdICUgMiA9PT0gMCk7XG4gICAgZWxzZSBpZiAoYnl0ZXNbMF0gPT09IDB4MDcpXG4gICAgICBhc3NlcnQoYnl0ZXNbYnl0ZXMubGVuZ3RoIC0gMV0gJSAyID09PSAxKTtcblxuICAgIHZhciByZXMgPSAgdGhpcy5wb2ludChieXRlcy5zbGljZSgxLCAxICsgbGVuKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZXMuc2xpY2UoMSArIGxlbiwgMSArIDIgKiBsZW4pKTtcblxuICAgIHJldHVybiByZXM7XG4gIH0gZWxzZSBpZiAoKGJ5dGVzWzBdID09PSAweDAyIHx8IGJ5dGVzWzBdID09PSAweDAzKSAmJlxuICAgICAgICAgICAgICBieXRlcy5sZW5ndGggLSAxID09PSBsZW4pIHtcbiAgICByZXR1cm4gdGhpcy5wb2ludEZyb21YKGJ5dGVzLnNsaWNlKDEsIDEgKyBsZW4pLCBieXRlc1swXSA9PT0gMHgwMyk7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIHBvaW50IGZvcm1hdCcpO1xufTtcblxuQmFzZVBvaW50LnByb3RvdHlwZS5lbmNvZGVDb21wcmVzc2VkID0gZnVuY3Rpb24gZW5jb2RlQ29tcHJlc3NlZChlbmMpIHtcbiAgcmV0dXJuIHRoaXMuZW5jb2RlKGVuYywgdHJ1ZSk7XG59O1xuXG5CYXNlUG9pbnQucHJvdG90eXBlLl9lbmNvZGUgPSBmdW5jdGlvbiBfZW5jb2RlKGNvbXBhY3QpIHtcbiAgdmFyIGxlbiA9IHRoaXMuY3VydmUucC5ieXRlTGVuZ3RoKCk7XG4gIHZhciB4ID0gdGhpcy5nZXRYKCkudG9BcnJheSgnYmUnLCBsZW4pO1xuXG4gIGlmIChjb21wYWN0KVxuICAgIHJldHVybiBbIHRoaXMuZ2V0WSgpLmlzRXZlbigpID8gMHgwMiA6IDB4MDMgXS5jb25jYXQoeCk7XG5cbiAgcmV0dXJuIFsgMHgwNCBdLmNvbmNhdCh4LCB0aGlzLmdldFkoKS50b0FycmF5KCdiZScsIGxlbikpIDtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKGVuYywgY29tcGFjdCkge1xuICByZXR1cm4gdXRpbHMuZW5jb2RlKHRoaXMuX2VuY29kZShjb21wYWN0KSwgZW5jKTtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUucHJlY29tcHV0ZSA9IGZ1bmN0aW9uIHByZWNvbXB1dGUocG93ZXIpIHtcbiAgaWYgKHRoaXMucHJlY29tcHV0ZWQpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgdmFyIHByZWNvbXB1dGVkID0ge1xuICAgIGRvdWJsZXM6IG51bGwsXG4gICAgbmFmOiBudWxsLFxuICAgIGJldGE6IG51bGxcbiAgfTtcbiAgcHJlY29tcHV0ZWQubmFmID0gdGhpcy5fZ2V0TkFGUG9pbnRzKDgpO1xuICBwcmVjb21wdXRlZC5kb3VibGVzID0gdGhpcy5fZ2V0RG91Ymxlcyg0LCBwb3dlcik7XG4gIHByZWNvbXB1dGVkLmJldGEgPSB0aGlzLl9nZXRCZXRhKCk7XG4gIHRoaXMucHJlY29tcHV0ZWQgPSBwcmVjb21wdXRlZDtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuX2hhc0RvdWJsZXMgPSBmdW5jdGlvbiBfaGFzRG91YmxlcyhrKSB7XG4gIGlmICghdGhpcy5wcmVjb21wdXRlZClcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIGRvdWJsZXMgPSB0aGlzLnByZWNvbXB1dGVkLmRvdWJsZXM7XG4gIGlmICghZG91YmxlcylcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgcmV0dXJuIGRvdWJsZXMucG9pbnRzLmxlbmd0aCA+PSBNYXRoLmNlaWwoKGsuYml0TGVuZ3RoKCkgKyAxKSAvIGRvdWJsZXMuc3RlcCk7XG59O1xuXG5CYXNlUG9pbnQucHJvdG90eXBlLl9nZXREb3VibGVzID0gZnVuY3Rpb24gX2dldERvdWJsZXMoc3RlcCwgcG93ZXIpIHtcbiAgaWYgKHRoaXMucHJlY29tcHV0ZWQgJiYgdGhpcy5wcmVjb21wdXRlZC5kb3VibGVzKVxuICAgIHJldHVybiB0aGlzLnByZWNvbXB1dGVkLmRvdWJsZXM7XG5cbiAgdmFyIGRvdWJsZXMgPSBbIHRoaXMgXTtcbiAgdmFyIGFjYyA9IHRoaXM7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcG93ZXI7IGkgKz0gc3RlcCkge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgc3RlcDsgaisrKVxuICAgICAgYWNjID0gYWNjLmRibCgpO1xuICAgIGRvdWJsZXMucHVzaChhY2MpO1xuICB9XG4gIHJldHVybiB7XG4gICAgc3RlcDogc3RlcCxcbiAgICBwb2ludHM6IGRvdWJsZXNcbiAgfTtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuX2dldE5BRlBvaW50cyA9IGZ1bmN0aW9uIF9nZXROQUZQb2ludHMod25kKSB7XG4gIGlmICh0aGlzLnByZWNvbXB1dGVkICYmIHRoaXMucHJlY29tcHV0ZWQubmFmKVxuICAgIHJldHVybiB0aGlzLnByZWNvbXB1dGVkLm5hZjtcblxuICB2YXIgcmVzID0gWyB0aGlzIF07XG4gIHZhciBtYXggPSAoMSA8PCB3bmQpIC0gMTtcbiAgdmFyIGRibCA9IG1heCA9PT0gMSA/IG51bGwgOiB0aGlzLmRibCgpO1xuICBmb3IgKHZhciBpID0gMTsgaSA8IG1heDsgaSsrKVxuICAgIHJlc1tpXSA9IHJlc1tpIC0gMV0uYWRkKGRibCk7XG4gIHJldHVybiB7XG4gICAgd25kOiB3bmQsXG4gICAgcG9pbnRzOiByZXNcbiAgfTtcbn07XG5cbkJhc2VQb2ludC5wcm90b3R5cGUuX2dldEJldGEgPSBmdW5jdGlvbiBfZ2V0QmV0YSgpIHtcbiAgcmV0dXJuIG51bGw7XG59O1xuXG5CYXNlUG9pbnQucHJvdG90eXBlLmRibHAgPSBmdW5jdGlvbiBkYmxwKGspIHtcbiAgdmFyIHIgPSB0aGlzO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGs7IGkrKylcbiAgICByID0gci5kYmwoKTtcbiAgcmV0dXJuIHI7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3VydmUgPSByZXF1aXJlKCcuLi9jdXJ2ZScpO1xudmFyIGVsbGlwdGljID0gcmVxdWlyZSgnLi4vLi4vZWxsaXB0aWMnKTtcbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xudmFyIEJhc2UgPSBjdXJ2ZS5iYXNlO1xuXG52YXIgYXNzZXJ0ID0gZWxsaXB0aWMudXRpbHMuYXNzZXJ0O1xuXG5mdW5jdGlvbiBFZHdhcmRzQ3VydmUoY29uZikge1xuICAvLyBOT1RFOiBJbXBvcnRhbnQgYXMgd2UgYXJlIGNyZWF0aW5nIHBvaW50IGluIEJhc2UuY2FsbCgpXG4gIHRoaXMudHdpc3RlZCA9IChjb25mLmEgfCAwKSAhPT0gMTtcbiAgdGhpcy5tT25lQSA9IHRoaXMudHdpc3RlZCAmJiAoY29uZi5hIHwgMCkgPT09IC0xO1xuICB0aGlzLmV4dGVuZGVkID0gdGhpcy5tT25lQTtcblxuICBCYXNlLmNhbGwodGhpcywgJ2Vkd2FyZHMnLCBjb25mKTtcblxuICB0aGlzLmEgPSBuZXcgQk4oY29uZi5hLCAxNikudW1vZCh0aGlzLnJlZC5tKTtcbiAgdGhpcy5hID0gdGhpcy5hLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy5jID0gbmV3IEJOKGNvbmYuYywgMTYpLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy5jMiA9IHRoaXMuYy5yZWRTcXIoKTtcbiAgdGhpcy5kID0gbmV3IEJOKGNvbmYuZCwgMTYpLnRvUmVkKHRoaXMucmVkKTtcbiAgdGhpcy5kZCA9IHRoaXMuZC5yZWRBZGQodGhpcy5kKTtcblxuICBhc3NlcnQoIXRoaXMudHdpc3RlZCB8fCB0aGlzLmMuZnJvbVJlZCgpLmNtcG4oMSkgPT09IDApO1xuICB0aGlzLm9uZUMgPSAoY29uZi5jIHwgMCkgPT09IDE7XG59XG5pbmhlcml0cyhFZHdhcmRzQ3VydmUsIEJhc2UpO1xubW9kdWxlLmV4cG9ydHMgPSBFZHdhcmRzQ3VydmU7XG5cbkVkd2FyZHNDdXJ2ZS5wcm90b3R5cGUuX211bEEgPSBmdW5jdGlvbiBfbXVsQShudW0pIHtcbiAgaWYgKHRoaXMubU9uZUEpXG4gICAgcmV0dXJuIG51bS5yZWROZWcoKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLmEucmVkTXVsKG51bSk7XG59O1xuXG5FZHdhcmRzQ3VydmUucHJvdG90eXBlLl9tdWxDID0gZnVuY3Rpb24gX211bEMobnVtKSB7XG4gIGlmICh0aGlzLm9uZUMpXG4gICAgcmV0dXJuIG51bTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLmMucmVkTXVsKG51bSk7XG59O1xuXG4vLyBKdXN0IGZvciBjb21wYXRpYmlsaXR5IHdpdGggU2hvcnQgY3VydmVcbkVkd2FyZHNDdXJ2ZS5wcm90b3R5cGUuanBvaW50ID0gZnVuY3Rpb24ganBvaW50KHgsIHksIHosIHQpIHtcbiAgcmV0dXJuIHRoaXMucG9pbnQoeCwgeSwgeiwgdCk7XG59O1xuXG5FZHdhcmRzQ3VydmUucHJvdG90eXBlLnBvaW50RnJvbVggPSBmdW5jdGlvbiBwb2ludEZyb21YKHgsIG9kZCkge1xuICB4ID0gbmV3IEJOKHgsIDE2KTtcbiAgaWYgKCF4LnJlZClcbiAgICB4ID0geC50b1JlZCh0aGlzLnJlZCk7XG5cbiAgdmFyIHgyID0geC5yZWRTcXIoKTtcbiAgdmFyIHJocyA9IHRoaXMuYzIucmVkU3ViKHRoaXMuYS5yZWRNdWwoeDIpKTtcbiAgdmFyIGxocyA9IHRoaXMub25lLnJlZFN1Yih0aGlzLmMyLnJlZE11bCh0aGlzLmQpLnJlZE11bCh4MikpO1xuXG4gIHZhciB5MiA9IHJocy5yZWRNdWwobGhzLnJlZEludm0oKSk7XG4gIHZhciB5ID0geTIucmVkU3FydCgpO1xuICBpZiAoeS5yZWRTcXIoKS5yZWRTdWIoeTIpLmNtcCh0aGlzLnplcm8pICE9PSAwKVxuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBwb2ludCcpO1xuXG4gIHZhciBpc09kZCA9IHkuZnJvbVJlZCgpLmlzT2RkKCk7XG4gIGlmIChvZGQgJiYgIWlzT2RkIHx8ICFvZGQgJiYgaXNPZGQpXG4gICAgeSA9IHkucmVkTmVnKCk7XG5cbiAgcmV0dXJuIHRoaXMucG9pbnQoeCwgeSk7XG59O1xuXG5FZHdhcmRzQ3VydmUucHJvdG90eXBlLnBvaW50RnJvbVkgPSBmdW5jdGlvbiBwb2ludEZyb21ZKHksIG9kZCkge1xuICB5ID0gbmV3IEJOKHksIDE2KTtcbiAgaWYgKCF5LnJlZClcbiAgICB5ID0geS50b1JlZCh0aGlzLnJlZCk7XG5cbiAgLy8geF4yID0gKHleMiAtIGNeMikgLyAoY14yIGQgeV4yIC0gYSlcbiAgdmFyIHkyID0geS5yZWRTcXIoKTtcbiAgdmFyIGxocyA9IHkyLnJlZFN1Yih0aGlzLmMyKTtcbiAgdmFyIHJocyA9IHkyLnJlZE11bCh0aGlzLmQpLnJlZE11bCh0aGlzLmMyKS5yZWRTdWIodGhpcy5hKTtcbiAgdmFyIHgyID0gbGhzLnJlZE11bChyaHMucmVkSW52bSgpKTtcblxuICBpZiAoeDIuY21wKHRoaXMuemVybykgPT09IDApIHtcbiAgICBpZiAob2RkKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHBvaW50Jyk7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIHRoaXMucG9pbnQodGhpcy56ZXJvLCB5KTtcbiAgfVxuXG4gIHZhciB4ID0geDIucmVkU3FydCgpO1xuICBpZiAoeC5yZWRTcXIoKS5yZWRTdWIoeDIpLmNtcCh0aGlzLnplcm8pICE9PSAwKVxuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBwb2ludCcpO1xuXG4gIGlmICh4LmZyb21SZWQoKS5pc09kZCgpICE9PSBvZGQpXG4gICAgeCA9IHgucmVkTmVnKCk7XG5cbiAgcmV0dXJuIHRoaXMucG9pbnQoeCwgeSk7XG59O1xuXG5FZHdhcmRzQ3VydmUucHJvdG90eXBlLnZhbGlkYXRlID0gZnVuY3Rpb24gdmFsaWRhdGUocG9pbnQpIHtcbiAgaWYgKHBvaW50LmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gdHJ1ZTtcblxuICAvLyBDdXJ2ZTogQSAqIFheMiArIFleMiA9IENeMiAqICgxICsgRCAqIFheMiAqIFleMilcbiAgcG9pbnQubm9ybWFsaXplKCk7XG5cbiAgdmFyIHgyID0gcG9pbnQueC5yZWRTcXIoKTtcbiAgdmFyIHkyID0gcG9pbnQueS5yZWRTcXIoKTtcbiAgdmFyIGxocyA9IHgyLnJlZE11bCh0aGlzLmEpLnJlZEFkZCh5Mik7XG4gIHZhciByaHMgPSB0aGlzLmMyLnJlZE11bCh0aGlzLm9uZS5yZWRBZGQodGhpcy5kLnJlZE11bCh4MikucmVkTXVsKHkyKSkpO1xuXG4gIHJldHVybiBsaHMuY21wKHJocykgPT09IDA7XG59O1xuXG5mdW5jdGlvbiBQb2ludChjdXJ2ZSwgeCwgeSwgeiwgdCkge1xuICBCYXNlLkJhc2VQb2ludC5jYWxsKHRoaXMsIGN1cnZlLCAncHJvamVjdGl2ZScpO1xuICBpZiAoeCA9PT0gbnVsbCAmJiB5ID09PSBudWxsICYmIHogPT09IG51bGwpIHtcbiAgICB0aGlzLnggPSB0aGlzLmN1cnZlLnplcm87XG4gICAgdGhpcy55ID0gdGhpcy5jdXJ2ZS5vbmU7XG4gICAgdGhpcy56ID0gdGhpcy5jdXJ2ZS5vbmU7XG4gICAgdGhpcy50ID0gdGhpcy5jdXJ2ZS56ZXJvO1xuICAgIHRoaXMuek9uZSA9IHRydWU7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy54ID0gbmV3IEJOKHgsIDE2KTtcbiAgICB0aGlzLnkgPSBuZXcgQk4oeSwgMTYpO1xuICAgIHRoaXMueiA9IHogPyBuZXcgQk4oeiwgMTYpIDogdGhpcy5jdXJ2ZS5vbmU7XG4gICAgdGhpcy50ID0gdCAmJiBuZXcgQk4odCwgMTYpO1xuICAgIGlmICghdGhpcy54LnJlZClcbiAgICAgIHRoaXMueCA9IHRoaXMueC50b1JlZCh0aGlzLmN1cnZlLnJlZCk7XG4gICAgaWYgKCF0aGlzLnkucmVkKVxuICAgICAgdGhpcy55ID0gdGhpcy55LnRvUmVkKHRoaXMuY3VydmUucmVkKTtcbiAgICBpZiAoIXRoaXMuei5yZWQpXG4gICAgICB0aGlzLnogPSB0aGlzLnoudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICAgIGlmICh0aGlzLnQgJiYgIXRoaXMudC5yZWQpXG4gICAgICB0aGlzLnQgPSB0aGlzLnQudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICAgIHRoaXMuek9uZSA9IHRoaXMueiA9PT0gdGhpcy5jdXJ2ZS5vbmU7XG5cbiAgICAvLyBVc2UgZXh0ZW5kZWQgY29vcmRpbmF0ZXNcbiAgICBpZiAodGhpcy5jdXJ2ZS5leHRlbmRlZCAmJiAhdGhpcy50KSB7XG4gICAgICB0aGlzLnQgPSB0aGlzLngucmVkTXVsKHRoaXMueSk7XG4gICAgICBpZiAoIXRoaXMuek9uZSlcbiAgICAgICAgdGhpcy50ID0gdGhpcy50LnJlZE11bCh0aGlzLnoucmVkSW52bSgpKTtcbiAgICB9XG4gIH1cbn1cbmluaGVyaXRzKFBvaW50LCBCYXNlLkJhc2VQb2ludCk7XG5cbkVkd2FyZHNDdXJ2ZS5wcm90b3R5cGUucG9pbnRGcm9tSlNPTiA9IGZ1bmN0aW9uIHBvaW50RnJvbUpTT04ob2JqKSB7XG4gIHJldHVybiBQb2ludC5mcm9tSlNPTih0aGlzLCBvYmopO1xufTtcblxuRWR3YXJkc0N1cnZlLnByb3RvdHlwZS5wb2ludCA9IGZ1bmN0aW9uIHBvaW50KHgsIHksIHosIHQpIHtcbiAgcmV0dXJuIG5ldyBQb2ludCh0aGlzLCB4LCB5LCB6LCB0KTtcbn07XG5cblBvaW50LmZyb21KU09OID0gZnVuY3Rpb24gZnJvbUpTT04oY3VydmUsIG9iaikge1xuICByZXR1cm4gbmV3IFBvaW50KGN1cnZlLCBvYmpbMF0sIG9ialsxXSwgb2JqWzJdKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgaWYgKHRoaXMuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiAnPEVDIFBvaW50IEluZmluaXR5Pic7XG4gIHJldHVybiAnPEVDIFBvaW50IHg6ICcgKyB0aGlzLnguZnJvbVJlZCgpLnRvU3RyaW5nKDE2LCAyKSArXG4gICAgICAnIHk6ICcgKyB0aGlzLnkuZnJvbVJlZCgpLnRvU3RyaW5nKDE2LCAyKSArXG4gICAgICAnIHo6ICcgKyB0aGlzLnouZnJvbVJlZCgpLnRvU3RyaW5nKDE2LCAyKSArICc+Jztcbn07XG5cblBvaW50LnByb3RvdHlwZS5pc0luZmluaXR5ID0gZnVuY3Rpb24gaXNJbmZpbml0eSgpIHtcbiAgLy8gWFhYIFRoaXMgY29kZSBhc3N1bWVzIHRoYXQgemVybyBpcyBhbHdheXMgemVybyBpbiByZWRcbiAgcmV0dXJuIHRoaXMueC5jbXBuKDApID09PSAwICYmXG4gICAgKHRoaXMueS5jbXAodGhpcy56KSA9PT0gMCB8fFxuICAgICh0aGlzLnpPbmUgJiYgdGhpcy55LmNtcCh0aGlzLmN1cnZlLmMpID09PSAwKSk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuX2V4dERibCA9IGZ1bmN0aW9uIF9leHREYmwoKSB7XG4gIC8vIGh5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by10d2lzdGVkLWV4dGVuZGVkLTEuaHRtbFxuICAvLyAgICAgI2RvdWJsaW5nLWRibC0yMDA4LWh3Y2RcbiAgLy8gNE0gKyA0U1xuXG4gIC8vIEEgPSBYMV4yXG4gIHZhciBhID0gdGhpcy54LnJlZFNxcigpO1xuICAvLyBCID0gWTFeMlxuICB2YXIgYiA9IHRoaXMueS5yZWRTcXIoKTtcbiAgLy8gQyA9IDIgKiBaMV4yXG4gIHZhciBjID0gdGhpcy56LnJlZFNxcigpO1xuICBjID0gYy5yZWRJQWRkKGMpO1xuICAvLyBEID0gYSAqIEFcbiAgdmFyIGQgPSB0aGlzLmN1cnZlLl9tdWxBKGEpO1xuICAvLyBFID0gKFgxICsgWTEpXjIgLSBBIC0gQlxuICB2YXIgZSA9IHRoaXMueC5yZWRBZGQodGhpcy55KS5yZWRTcXIoKS5yZWRJU3ViKGEpLnJlZElTdWIoYik7XG4gIC8vIEcgPSBEICsgQlxuICB2YXIgZyA9IGQucmVkQWRkKGIpO1xuICAvLyBGID0gRyAtIENcbiAgdmFyIGYgPSBnLnJlZFN1YihjKTtcbiAgLy8gSCA9IEQgLSBCXG4gIHZhciBoID0gZC5yZWRTdWIoYik7XG4gIC8vIFgzID0gRSAqIEZcbiAgdmFyIG54ID0gZS5yZWRNdWwoZik7XG4gIC8vIFkzID0gRyAqIEhcbiAgdmFyIG55ID0gZy5yZWRNdWwoaCk7XG4gIC8vIFQzID0gRSAqIEhcbiAgdmFyIG50ID0gZS5yZWRNdWwoaCk7XG4gIC8vIFozID0gRiAqIEdcbiAgdmFyIG56ID0gZi5yZWRNdWwoZyk7XG4gIHJldHVybiB0aGlzLmN1cnZlLnBvaW50KG54LCBueSwgbnosIG50KTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5fcHJvakRibCA9IGZ1bmN0aW9uIF9wcm9qRGJsKCkge1xuICAvLyBoeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tdHdpc3RlZC1wcm9qZWN0aXZlLmh0bWxcbiAgLy8gICAgICNkb3VibGluZy1kYmwtMjAwOC1iYmpscFxuICAvLyAgICAgI2RvdWJsaW5nLWRibC0yMDA3LWJsXG4gIC8vIGFuZCBvdGhlcnNcbiAgLy8gR2VuZXJhbGx5IDNNICsgNFMgb3IgMk0gKyA0U1xuXG4gIC8vIEIgPSAoWDEgKyBZMSleMlxuICB2YXIgYiA9IHRoaXMueC5yZWRBZGQodGhpcy55KS5yZWRTcXIoKTtcbiAgLy8gQyA9IFgxXjJcbiAgdmFyIGMgPSB0aGlzLngucmVkU3FyKCk7XG4gIC8vIEQgPSBZMV4yXG4gIHZhciBkID0gdGhpcy55LnJlZFNxcigpO1xuXG4gIHZhciBueDtcbiAgdmFyIG55O1xuICB2YXIgbno7XG4gIGlmICh0aGlzLmN1cnZlLnR3aXN0ZWQpIHtcbiAgICAvLyBFID0gYSAqIENcbiAgICB2YXIgZSA9IHRoaXMuY3VydmUuX211bEEoYyk7XG4gICAgLy8gRiA9IEUgKyBEXG4gICAgdmFyIGYgPSBlLnJlZEFkZChkKTtcbiAgICBpZiAodGhpcy56T25lKSB7XG4gICAgICAvLyBYMyA9IChCIC0gQyAtIEQpICogKEYgLSAyKVxuICAgICAgbnggPSBiLnJlZFN1YihjKS5yZWRTdWIoZCkucmVkTXVsKGYucmVkU3ViKHRoaXMuY3VydmUudHdvKSk7XG4gICAgICAvLyBZMyA9IEYgKiAoRSAtIEQpXG4gICAgICBueSA9IGYucmVkTXVsKGUucmVkU3ViKGQpKTtcbiAgICAgIC8vIFozID0gRl4yIC0gMiAqIEZcbiAgICAgIG56ID0gZi5yZWRTcXIoKS5yZWRTdWIoZikucmVkU3ViKGYpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBIID0gWjFeMlxuICAgICAgdmFyIGggPSB0aGlzLnoucmVkU3FyKCk7XG4gICAgICAvLyBKID0gRiAtIDIgKiBIXG4gICAgICB2YXIgaiA9IGYucmVkU3ViKGgpLnJlZElTdWIoaCk7XG4gICAgICAvLyBYMyA9IChCLUMtRCkqSlxuICAgICAgbnggPSBiLnJlZFN1YihjKS5yZWRJU3ViKGQpLnJlZE11bChqKTtcbiAgICAgIC8vIFkzID0gRiAqIChFIC0gRClcbiAgICAgIG55ID0gZi5yZWRNdWwoZS5yZWRTdWIoZCkpO1xuICAgICAgLy8gWjMgPSBGICogSlxuICAgICAgbnogPSBmLnJlZE11bChqKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gRSA9IEMgKyBEXG4gICAgdmFyIGUgPSBjLnJlZEFkZChkKTtcbiAgICAvLyBIID0gKGMgKiBaMSleMlxuICAgIHZhciBoID0gdGhpcy5jdXJ2ZS5fbXVsQyh0aGlzLnopLnJlZFNxcigpO1xuICAgIC8vIEogPSBFIC0gMiAqIEhcbiAgICB2YXIgaiA9IGUucmVkU3ViKGgpLnJlZFN1YihoKTtcbiAgICAvLyBYMyA9IGMgKiAoQiAtIEUpICogSlxuICAgIG54ID0gdGhpcy5jdXJ2ZS5fbXVsQyhiLnJlZElTdWIoZSkpLnJlZE11bChqKTtcbiAgICAvLyBZMyA9IGMgKiBFICogKEMgLSBEKVxuICAgIG55ID0gdGhpcy5jdXJ2ZS5fbXVsQyhlKS5yZWRNdWwoYy5yZWRJU3ViKGQpKTtcbiAgICAvLyBaMyA9IEUgKiBKXG4gICAgbnogPSBlLnJlZE11bChqKTtcbiAgfVxuICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChueCwgbnksIG56KTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5kYmwgPSBmdW5jdGlvbiBkYmwoKSB7XG4gIGlmICh0aGlzLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyBEb3VibGUgaW4gZXh0ZW5kZWQgY29vcmRpbmF0ZXNcbiAgaWYgKHRoaXMuY3VydmUuZXh0ZW5kZWQpXG4gICAgcmV0dXJuIHRoaXMuX2V4dERibCgpO1xuICBlbHNlXG4gICAgcmV0dXJuIHRoaXMuX3Byb2pEYmwoKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5fZXh0QWRkID0gZnVuY3Rpb24gX2V4dEFkZChwKSB7XG4gIC8vIGh5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by10d2lzdGVkLWV4dGVuZGVkLTEuaHRtbFxuICAvLyAgICAgI2FkZGl0aW9uLWFkZC0yMDA4LWh3Y2QtM1xuICAvLyA4TVxuXG4gIC8vIEEgPSAoWTEgLSBYMSkgKiAoWTIgLSBYMilcbiAgdmFyIGEgPSB0aGlzLnkucmVkU3ViKHRoaXMueCkucmVkTXVsKHAueS5yZWRTdWIocC54KSk7XG4gIC8vIEIgPSAoWTEgKyBYMSkgKiAoWTIgKyBYMilcbiAgdmFyIGIgPSB0aGlzLnkucmVkQWRkKHRoaXMueCkucmVkTXVsKHAueS5yZWRBZGQocC54KSk7XG4gIC8vIEMgPSBUMSAqIGsgKiBUMlxuICB2YXIgYyA9IHRoaXMudC5yZWRNdWwodGhpcy5jdXJ2ZS5kZCkucmVkTXVsKHAudCk7XG4gIC8vIEQgPSBaMSAqIDIgKiBaMlxuICB2YXIgZCA9IHRoaXMuei5yZWRNdWwocC56LnJlZEFkZChwLnopKTtcbiAgLy8gRSA9IEIgLSBBXG4gIHZhciBlID0gYi5yZWRTdWIoYSk7XG4gIC8vIEYgPSBEIC0gQ1xuICB2YXIgZiA9IGQucmVkU3ViKGMpO1xuICAvLyBHID0gRCArIENcbiAgdmFyIGcgPSBkLnJlZEFkZChjKTtcbiAgLy8gSCA9IEIgKyBBXG4gIHZhciBoID0gYi5yZWRBZGQoYSk7XG4gIC8vIFgzID0gRSAqIEZcbiAgdmFyIG54ID0gZS5yZWRNdWwoZik7XG4gIC8vIFkzID0gRyAqIEhcbiAgdmFyIG55ID0gZy5yZWRNdWwoaCk7XG4gIC8vIFQzID0gRSAqIEhcbiAgdmFyIG50ID0gZS5yZWRNdWwoaCk7XG4gIC8vIFozID0gRiAqIEdcbiAgdmFyIG56ID0gZi5yZWRNdWwoZyk7XG4gIHJldHVybiB0aGlzLmN1cnZlLnBvaW50KG54LCBueSwgbnosIG50KTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5fcHJvakFkZCA9IGZ1bmN0aW9uIF9wcm9qQWRkKHApIHtcbiAgLy8gaHlwZXJlbGxpcHRpYy5vcmcvRUZEL2cxcC9hdXRvLXR3aXN0ZWQtcHJvamVjdGl2ZS5odG1sXG4gIC8vICAgICAjYWRkaXRpb24tYWRkLTIwMDgtYmJqbHBcbiAgLy8gICAgICNhZGRpdGlvbi1hZGQtMjAwNy1ibFxuICAvLyAxME0gKyAxU1xuXG4gIC8vIEEgPSBaMSAqIFoyXG4gIHZhciBhID0gdGhpcy56LnJlZE11bChwLnopO1xuICAvLyBCID0gQV4yXG4gIHZhciBiID0gYS5yZWRTcXIoKTtcbiAgLy8gQyA9IFgxICogWDJcbiAgdmFyIGMgPSB0aGlzLngucmVkTXVsKHAueCk7XG4gIC8vIEQgPSBZMSAqIFkyXG4gIHZhciBkID0gdGhpcy55LnJlZE11bChwLnkpO1xuICAvLyBFID0gZCAqIEMgKiBEXG4gIHZhciBlID0gdGhpcy5jdXJ2ZS5kLnJlZE11bChjKS5yZWRNdWwoZCk7XG4gIC8vIEYgPSBCIC0gRVxuICB2YXIgZiA9IGIucmVkU3ViKGUpO1xuICAvLyBHID0gQiArIEVcbiAgdmFyIGcgPSBiLnJlZEFkZChlKTtcbiAgLy8gWDMgPSBBICogRiAqICgoWDEgKyBZMSkgKiAoWDIgKyBZMikgLSBDIC0gRClcbiAgdmFyIHRtcCA9IHRoaXMueC5yZWRBZGQodGhpcy55KS5yZWRNdWwocC54LnJlZEFkZChwLnkpKS5yZWRJU3ViKGMpLnJlZElTdWIoZCk7XG4gIHZhciBueCA9IGEucmVkTXVsKGYpLnJlZE11bCh0bXApO1xuICB2YXIgbnk7XG4gIHZhciBuejtcbiAgaWYgKHRoaXMuY3VydmUudHdpc3RlZCkge1xuICAgIC8vIFkzID0gQSAqIEcgKiAoRCAtIGEgKiBDKVxuICAgIG55ID0gYS5yZWRNdWwoZykucmVkTXVsKGQucmVkU3ViKHRoaXMuY3VydmUuX211bEEoYykpKTtcbiAgICAvLyBaMyA9IEYgKiBHXG4gICAgbnogPSBmLnJlZE11bChnKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBZMyA9IEEgKiBHICogKEQgLSBDKVxuICAgIG55ID0gYS5yZWRNdWwoZykucmVkTXVsKGQucmVkU3ViKGMpKTtcbiAgICAvLyBaMyA9IGMgKiBGICogR1xuICAgIG56ID0gdGhpcy5jdXJ2ZS5fbXVsQyhmKS5yZWRNdWwoZyk7XG4gIH1cbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQobngsIG55LCBueik7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gYWRkKHApIHtcbiAgaWYgKHRoaXMuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiBwO1xuICBpZiAocC5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgaWYgKHRoaXMuY3VydmUuZXh0ZW5kZWQpXG4gICAgcmV0dXJuIHRoaXMuX2V4dEFkZChwKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLl9wcm9qQWRkKHApO1xufTtcblxuUG9pbnQucHJvdG90eXBlLm11bCA9IGZ1bmN0aW9uIG11bChrKSB7XG4gIGlmICh0aGlzLl9oYXNEb3VibGVzKGspKVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl9maXhlZE5hZk11bCh0aGlzLCBrKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl93bmFmTXVsKHRoaXMsIGspO1xufTtcblxuUG9pbnQucHJvdG90eXBlLm11bEFkZCA9IGZ1bmN0aW9uIG11bEFkZChrMSwgcCwgazIpIHtcbiAgcmV0dXJuIHRoaXMuY3VydmUuX3duYWZNdWxBZGQoMSwgWyB0aGlzLCBwIF0sIFsgazEsIGsyIF0sIDIsIGZhbHNlKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5qbXVsQWRkID0gZnVuY3Rpb24gam11bEFkZChrMSwgcCwgazIpIHtcbiAgcmV0dXJuIHRoaXMuY3VydmUuX3duYWZNdWxBZGQoMSwgWyB0aGlzLCBwIF0sIFsgazEsIGsyIF0sIDIsIHRydWUpO1xufTtcblxuUG9pbnQucHJvdG90eXBlLm5vcm1hbGl6ZSA9IGZ1bmN0aW9uIG5vcm1hbGl6ZSgpIHtcbiAgaWYgKHRoaXMuek9uZSlcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyBOb3JtYWxpemUgY29vcmRpbmF0ZXNcbiAgdmFyIHppID0gdGhpcy56LnJlZEludm0oKTtcbiAgdGhpcy54ID0gdGhpcy54LnJlZE11bCh6aSk7XG4gIHRoaXMueSA9IHRoaXMueS5yZWRNdWwoemkpO1xuICBpZiAodGhpcy50KVxuICAgIHRoaXMudCA9IHRoaXMudC5yZWRNdWwoemkpO1xuICB0aGlzLnogPSB0aGlzLmN1cnZlLm9uZTtcbiAgdGhpcy56T25lID0gdHJ1ZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUubmVnID0gZnVuY3Rpb24gbmVnKCkge1xuICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludCh0aGlzLngucmVkTmVnKCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMueSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy56LFxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnQgJiYgdGhpcy50LnJlZE5lZygpKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5nZXRYID0gZnVuY3Rpb24gZ2V0WCgpIHtcbiAgdGhpcy5ub3JtYWxpemUoKTtcbiAgcmV0dXJuIHRoaXMueC5mcm9tUmVkKCk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZ2V0WSA9IGZ1bmN0aW9uIGdldFkoKSB7XG4gIHRoaXMubm9ybWFsaXplKCk7XG4gIHJldHVybiB0aGlzLnkuZnJvbVJlZCgpO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmVxID0gZnVuY3Rpb24gZXEob3RoZXIpIHtcbiAgcmV0dXJuIHRoaXMgPT09IG90aGVyIHx8XG4gICAgICAgICB0aGlzLmdldFgoKS5jbXAob3RoZXIuZ2V0WCgpKSA9PT0gMCAmJlxuICAgICAgICAgdGhpcy5nZXRZKCkuY21wKG90aGVyLmdldFkoKSkgPT09IDA7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZXFYVG9QID0gZnVuY3Rpb24gZXFYVG9QKHgpIHtcbiAgdmFyIHJ4ID0geC50b1JlZCh0aGlzLmN1cnZlLnJlZCkucmVkTXVsKHRoaXMueik7XG4gIGlmICh0aGlzLnguY21wKHJ4KSA9PT0gMClcbiAgICByZXR1cm4gdHJ1ZTtcblxuICB2YXIgeGMgPSB4LmNsb25lKCk7XG4gIHZhciB0ID0gdGhpcy5jdXJ2ZS5yZWROLnJlZE11bCh0aGlzLnopO1xuICBmb3IgKDs7KSB7XG4gICAgeGMuaWFkZCh0aGlzLmN1cnZlLm4pO1xuICAgIGlmICh4Yy5jbXAodGhpcy5jdXJ2ZS5wKSA+PSAwKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgcngucmVkSUFkZCh0KTtcbiAgICBpZiAodGhpcy54LmNtcChyeCkgPT09IDApXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufTtcblxuLy8gQ29tcGF0aWJpbGl0eSB3aXRoIEJhc2VDdXJ2ZVxuUG9pbnQucHJvdG90eXBlLnRvUCA9IFBvaW50LnByb3RvdHlwZS5ub3JtYWxpemU7XG5Qb2ludC5wcm90b3R5cGUubWl4ZWRBZGQgPSBQb2ludC5wcm90b3R5cGUuYWRkO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3VydmUgPSBleHBvcnRzO1xuXG5jdXJ2ZS5iYXNlID0gcmVxdWlyZSgnLi9iYXNlJyk7XG5jdXJ2ZS5zaG9ydCA9IHJlcXVpcmUoJy4vc2hvcnQnKTtcbmN1cnZlLm1vbnQgPSByZXF1aXJlKCcuL21vbnQnKTtcbmN1cnZlLmVkd2FyZHMgPSByZXF1aXJlKCcuL2Vkd2FyZHMnKTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGN1cnZlID0gcmVxdWlyZSgnLi4vY3VydmUnKTtcbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xudmFyIEJhc2UgPSBjdXJ2ZS5iYXNlO1xuXG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCcuLi8uLi9lbGxpcHRpYycpO1xudmFyIHV0aWxzID0gZWxsaXB0aWMudXRpbHM7XG5cbmZ1bmN0aW9uIE1vbnRDdXJ2ZShjb25mKSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnbW9udCcsIGNvbmYpO1xuXG4gIHRoaXMuYSA9IG5ldyBCTihjb25mLmEsIDE2KS50b1JlZCh0aGlzLnJlZCk7XG4gIHRoaXMuYiA9IG5ldyBCTihjb25mLmIsIDE2KS50b1JlZCh0aGlzLnJlZCk7XG4gIHRoaXMuaTQgPSBuZXcgQk4oNCkudG9SZWQodGhpcy5yZWQpLnJlZEludm0oKTtcbiAgdGhpcy50d28gPSBuZXcgQk4oMikudG9SZWQodGhpcy5yZWQpO1xuICB0aGlzLmEyNCA9IHRoaXMuaTQucmVkTXVsKHRoaXMuYS5yZWRBZGQodGhpcy50d28pKTtcbn1cbmluaGVyaXRzKE1vbnRDdXJ2ZSwgQmFzZSk7XG5tb2R1bGUuZXhwb3J0cyA9IE1vbnRDdXJ2ZTtcblxuTW9udEN1cnZlLnByb3RvdHlwZS52YWxpZGF0ZSA9IGZ1bmN0aW9uIHZhbGlkYXRlKHBvaW50KSB7XG4gIHZhciB4ID0gcG9pbnQubm9ybWFsaXplKCkueDtcbiAgdmFyIHgyID0geC5yZWRTcXIoKTtcbiAgdmFyIHJocyA9IHgyLnJlZE11bCh4KS5yZWRBZGQoeDIucmVkTXVsKHRoaXMuYSkpLnJlZEFkZCh4KTtcbiAgdmFyIHkgPSByaHMucmVkU3FydCgpO1xuXG4gIHJldHVybiB5LnJlZFNxcigpLmNtcChyaHMpID09PSAwO1xufTtcblxuZnVuY3Rpb24gUG9pbnQoY3VydmUsIHgsIHopIHtcbiAgQmFzZS5CYXNlUG9pbnQuY2FsbCh0aGlzLCBjdXJ2ZSwgJ3Byb2plY3RpdmUnKTtcbiAgaWYgKHggPT09IG51bGwgJiYgeiA9PT0gbnVsbCkge1xuICAgIHRoaXMueCA9IHRoaXMuY3VydmUub25lO1xuICAgIHRoaXMueiA9IHRoaXMuY3VydmUuemVybztcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnggPSBuZXcgQk4oeCwgMTYpO1xuICAgIHRoaXMueiA9IG5ldyBCTih6LCAxNik7XG4gICAgaWYgKCF0aGlzLngucmVkKVxuICAgICAgdGhpcy54ID0gdGhpcy54LnRvUmVkKHRoaXMuY3VydmUucmVkKTtcbiAgICBpZiAoIXRoaXMuei5yZWQpXG4gICAgICB0aGlzLnogPSB0aGlzLnoudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICB9XG59XG5pbmhlcml0cyhQb2ludCwgQmFzZS5CYXNlUG9pbnQpO1xuXG5Nb250Q3VydmUucHJvdG90eXBlLmRlY29kZVBvaW50ID0gZnVuY3Rpb24gZGVjb2RlUG9pbnQoYnl0ZXMsIGVuYykge1xuICByZXR1cm4gdGhpcy5wb2ludCh1dGlscy50b0FycmF5KGJ5dGVzLCBlbmMpLCAxKTtcbn07XG5cbk1vbnRDdXJ2ZS5wcm90b3R5cGUucG9pbnQgPSBmdW5jdGlvbiBwb2ludCh4LCB6KSB7XG4gIHJldHVybiBuZXcgUG9pbnQodGhpcywgeCwgeik7XG59O1xuXG5Nb250Q3VydmUucHJvdG90eXBlLnBvaW50RnJvbUpTT04gPSBmdW5jdGlvbiBwb2ludEZyb21KU09OKG9iaikge1xuICByZXR1cm4gUG9pbnQuZnJvbUpTT04odGhpcywgb2JqKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5wcmVjb21wdXRlID0gZnVuY3Rpb24gcHJlY29tcHV0ZSgpIHtcbiAgLy8gTm8tb3Bcbn07XG5cblBvaW50LnByb3RvdHlwZS5fZW5jb2RlID0gZnVuY3Rpb24gX2VuY29kZSgpIHtcbiAgcmV0dXJuIHRoaXMuZ2V0WCgpLnRvQXJyYXkoJ2JlJywgdGhpcy5jdXJ2ZS5wLmJ5dGVMZW5ndGgoKSk7XG59O1xuXG5Qb2ludC5mcm9tSlNPTiA9IGZ1bmN0aW9uIGZyb21KU09OKGN1cnZlLCBvYmopIHtcbiAgcmV0dXJuIG5ldyBQb2ludChjdXJ2ZSwgb2JqWzBdLCBvYmpbMV0gfHwgY3VydmUub25lKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgaWYgKHRoaXMuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiAnPEVDIFBvaW50IEluZmluaXR5Pic7XG4gIHJldHVybiAnPEVDIFBvaW50IHg6ICcgKyB0aGlzLnguZnJvbVJlZCgpLnRvU3RyaW5nKDE2LCAyKSArXG4gICAgICAnIHo6ICcgKyB0aGlzLnouZnJvbVJlZCgpLnRvU3RyaW5nKDE2LCAyKSArICc+Jztcbn07XG5cblBvaW50LnByb3RvdHlwZS5pc0luZmluaXR5ID0gZnVuY3Rpb24gaXNJbmZpbml0eSgpIHtcbiAgLy8gWFhYIFRoaXMgY29kZSBhc3N1bWVzIHRoYXQgemVybyBpcyBhbHdheXMgemVybyBpbiByZWRcbiAgcmV0dXJuIHRoaXMuei5jbXBuKDApID09PSAwO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmRibCA9IGZ1bmN0aW9uIGRibCgpIHtcbiAgLy8gaHR0cDovL2h5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by1tb250Z29tLXh6Lmh0bWwjZG91YmxpbmctZGJsLTE5ODctbS0zXG4gIC8vIDJNICsgMlMgKyA0QVxuXG4gIC8vIEEgPSBYMSArIFoxXG4gIHZhciBhID0gdGhpcy54LnJlZEFkZCh0aGlzLnopO1xuICAvLyBBQSA9IEFeMlxuICB2YXIgYWEgPSBhLnJlZFNxcigpO1xuICAvLyBCID0gWDEgLSBaMVxuICB2YXIgYiA9IHRoaXMueC5yZWRTdWIodGhpcy56KTtcbiAgLy8gQkIgPSBCXjJcbiAgdmFyIGJiID0gYi5yZWRTcXIoKTtcbiAgLy8gQyA9IEFBIC0gQkJcbiAgdmFyIGMgPSBhYS5yZWRTdWIoYmIpO1xuICAvLyBYMyA9IEFBICogQkJcbiAgdmFyIG54ID0gYWEucmVkTXVsKGJiKTtcbiAgLy8gWjMgPSBDICogKEJCICsgQTI0ICogQylcbiAgdmFyIG56ID0gYy5yZWRNdWwoYmIucmVkQWRkKHRoaXMuY3VydmUuYTI0LnJlZE11bChjKSkpO1xuICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChueCwgbnopO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIGFkZCgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdOb3Qgc3VwcG9ydGVkIG9uIE1vbnRnb21lcnkgY3VydmUnKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5kaWZmQWRkID0gZnVuY3Rpb24gZGlmZkFkZChwLCBkaWZmKSB7XG4gIC8vIGh0dHA6Ly9oeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tbW9udGdvbS14ei5odG1sI2RpZmZhZGQtZGFkZC0xOTg3LW0tM1xuICAvLyA0TSArIDJTICsgNkFcblxuICAvLyBBID0gWDIgKyBaMlxuICB2YXIgYSA9IHRoaXMueC5yZWRBZGQodGhpcy56KTtcbiAgLy8gQiA9IFgyIC0gWjJcbiAgdmFyIGIgPSB0aGlzLngucmVkU3ViKHRoaXMueik7XG4gIC8vIEMgPSBYMyArIFozXG4gIHZhciBjID0gcC54LnJlZEFkZChwLnopO1xuICAvLyBEID0gWDMgLSBaM1xuICB2YXIgZCA9IHAueC5yZWRTdWIocC56KTtcbiAgLy8gREEgPSBEICogQVxuICB2YXIgZGEgPSBkLnJlZE11bChhKTtcbiAgLy8gQ0IgPSBDICogQlxuICB2YXIgY2IgPSBjLnJlZE11bChiKTtcbiAgLy8gWDUgPSBaMSAqIChEQSArIENCKV4yXG4gIHZhciBueCA9IGRpZmYuei5yZWRNdWwoZGEucmVkQWRkKGNiKS5yZWRTcXIoKSk7XG4gIC8vIFo1ID0gWDEgKiAoREEgLSBDQileMlxuICB2YXIgbnogPSBkaWZmLngucmVkTXVsKGRhLnJlZElTdWIoY2IpLnJlZFNxcigpKTtcbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQobngsIG56KTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5tdWwgPSBmdW5jdGlvbiBtdWwoaykge1xuICB2YXIgdCA9IGsuY2xvbmUoKTtcbiAgdmFyIGEgPSB0aGlzOyAvLyAoTiAvIDIpICogUSArIFFcbiAgdmFyIGIgPSB0aGlzLmN1cnZlLnBvaW50KG51bGwsIG51bGwpOyAvLyAoTiAvIDIpICogUVxuICB2YXIgYyA9IHRoaXM7IC8vIFFcblxuICBmb3IgKHZhciBiaXRzID0gW107IHQuY21wbigwKSAhPT0gMDsgdC5pdXNocm4oMSkpXG4gICAgYml0cy5wdXNoKHQuYW5kbG4oMSkpO1xuXG4gIGZvciAodmFyIGkgPSBiaXRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgaWYgKGJpdHNbaV0gPT09IDApIHtcbiAgICAgIC8vIE4gKiBRICsgUSA9ICgoTiAvIDIpICogUSArIFEpKSArIChOIC8gMikgKiBRXG4gICAgICBhID0gYS5kaWZmQWRkKGIsIGMpO1xuICAgICAgLy8gTiAqIFEgPSAyICogKChOIC8gMikgKiBRICsgUSkpXG4gICAgICBiID0gYi5kYmwoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTiAqIFEgPSAoKE4gLyAyKSAqIFEgKyBRKSArICgoTiAvIDIpICogUSlcbiAgICAgIGIgPSBhLmRpZmZBZGQoYiwgYyk7XG4gICAgICAvLyBOICogUSArIFEgPSAyICogKChOIC8gMikgKiBRICsgUSlcbiAgICAgIGEgPSBhLmRibCgpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYjtcbn07XG5cblBvaW50LnByb3RvdHlwZS5tdWxBZGQgPSBmdW5jdGlvbiBtdWxBZGQoKSB7XG4gIHRocm93IG5ldyBFcnJvcignTm90IHN1cHBvcnRlZCBvbiBNb250Z29tZXJ5IGN1cnZlJyk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuanVtbEFkZCA9IGZ1bmN0aW9uIGp1bWxBZGQoKSB7XG4gIHRocm93IG5ldyBFcnJvcignTm90IHN1cHBvcnRlZCBvbiBNb250Z29tZXJ5IGN1cnZlJyk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZXEgPSBmdW5jdGlvbiBlcShvdGhlcikge1xuICByZXR1cm4gdGhpcy5nZXRYKCkuY21wKG90aGVyLmdldFgoKSkgPT09IDA7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUubm9ybWFsaXplID0gZnVuY3Rpb24gbm9ybWFsaXplKCkge1xuICB0aGlzLnggPSB0aGlzLngucmVkTXVsKHRoaXMuei5yZWRJbnZtKCkpO1xuICB0aGlzLnogPSB0aGlzLmN1cnZlLm9uZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZ2V0WCA9IGZ1bmN0aW9uIGdldFgoKSB7XG4gIC8vIE5vcm1hbGl6ZSBjb29yZGluYXRlc1xuICB0aGlzLm5vcm1hbGl6ZSgpO1xuXG4gIHJldHVybiB0aGlzLnguZnJvbVJlZCgpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGN1cnZlID0gcmVxdWlyZSgnLi4vY3VydmUnKTtcbnZhciBlbGxpcHRpYyA9IHJlcXVpcmUoJy4uLy4uL2VsbGlwdGljJyk7XG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbnZhciBCYXNlID0gY3VydmUuYmFzZTtcblxudmFyIGFzc2VydCA9IGVsbGlwdGljLnV0aWxzLmFzc2VydDtcblxuZnVuY3Rpb24gU2hvcnRDdXJ2ZShjb25mKSB7XG4gIEJhc2UuY2FsbCh0aGlzLCAnc2hvcnQnLCBjb25mKTtcblxuICB0aGlzLmEgPSBuZXcgQk4oY29uZi5hLCAxNikudG9SZWQodGhpcy5yZWQpO1xuICB0aGlzLmIgPSBuZXcgQk4oY29uZi5iLCAxNikudG9SZWQodGhpcy5yZWQpO1xuICB0aGlzLnRpbnYgPSB0aGlzLnR3by5yZWRJbnZtKCk7XG5cbiAgdGhpcy56ZXJvQSA9IHRoaXMuYS5mcm9tUmVkKCkuY21wbigwKSA9PT0gMDtcbiAgdGhpcy50aHJlZUEgPSB0aGlzLmEuZnJvbVJlZCgpLnN1Yih0aGlzLnApLmNtcG4oLTMpID09PSAwO1xuXG4gIC8vIElmIHRoZSBjdXJ2ZSBpcyBlbmRvbW9ycGhpYywgcHJlY2FsY3VsYXRlIGJldGEgYW5kIGxhbWJkYVxuICB0aGlzLmVuZG8gPSB0aGlzLl9nZXRFbmRvbW9ycGhpc20oY29uZik7XG4gIHRoaXMuX2VuZG9XbmFmVDEgPSBuZXcgQXJyYXkoNCk7XG4gIHRoaXMuX2VuZG9XbmFmVDIgPSBuZXcgQXJyYXkoNCk7XG59XG5pbmhlcml0cyhTaG9ydEN1cnZlLCBCYXNlKTtcbm1vZHVsZS5leHBvcnRzID0gU2hvcnRDdXJ2ZTtcblxuU2hvcnRDdXJ2ZS5wcm90b3R5cGUuX2dldEVuZG9tb3JwaGlzbSA9IGZ1bmN0aW9uIF9nZXRFbmRvbW9ycGhpc20oY29uZikge1xuICAvLyBObyBlZmZpY2llbnQgZW5kb21vcnBoaXNtXG4gIGlmICghdGhpcy56ZXJvQSB8fCAhdGhpcy5nIHx8ICF0aGlzLm4gfHwgdGhpcy5wLm1vZG4oMykgIT09IDEpXG4gICAgcmV0dXJuO1xuXG4gIC8vIENvbXB1dGUgYmV0YSBhbmQgbGFtYmRhLCB0aGF0IGxhbWJkYSAqIFAgPSAoYmV0YSAqIFB4OyBQeSlcbiAgdmFyIGJldGE7XG4gIHZhciBsYW1iZGE7XG4gIGlmIChjb25mLmJldGEpIHtcbiAgICBiZXRhID0gbmV3IEJOKGNvbmYuYmV0YSwgMTYpLnRvUmVkKHRoaXMucmVkKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgYmV0YXMgPSB0aGlzLl9nZXRFbmRvUm9vdHModGhpcy5wKTtcbiAgICAvLyBDaG9vc2UgdGhlIHNtYWxsZXN0IGJldGFcbiAgICBiZXRhID0gYmV0YXNbMF0uY21wKGJldGFzWzFdKSA8IDAgPyBiZXRhc1swXSA6IGJldGFzWzFdO1xuICAgIGJldGEgPSBiZXRhLnRvUmVkKHRoaXMucmVkKTtcbiAgfVxuICBpZiAoY29uZi5sYW1iZGEpIHtcbiAgICBsYW1iZGEgPSBuZXcgQk4oY29uZi5sYW1iZGEsIDE2KTtcbiAgfSBlbHNlIHtcbiAgICAvLyBDaG9vc2UgdGhlIGxhbWJkYSB0aGF0IGlzIG1hdGNoaW5nIHNlbGVjdGVkIGJldGFcbiAgICB2YXIgbGFtYmRhcyA9IHRoaXMuX2dldEVuZG9Sb290cyh0aGlzLm4pO1xuICAgIGlmICh0aGlzLmcubXVsKGxhbWJkYXNbMF0pLnguY21wKHRoaXMuZy54LnJlZE11bChiZXRhKSkgPT09IDApIHtcbiAgICAgIGxhbWJkYSA9IGxhbWJkYXNbMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIGxhbWJkYSA9IGxhbWJkYXNbMV07XG4gICAgICBhc3NlcnQodGhpcy5nLm11bChsYW1iZGEpLnguY21wKHRoaXMuZy54LnJlZE11bChiZXRhKSkgPT09IDApO1xuICAgIH1cbiAgfVxuXG4gIC8vIEdldCBiYXNpcyB2ZWN0b3JzLCB1c2VkIGZvciBiYWxhbmNlZCBsZW5ndGgtdHdvIHJlcHJlc2VudGF0aW9uXG4gIHZhciBiYXNpcztcbiAgaWYgKGNvbmYuYmFzaXMpIHtcbiAgICBiYXNpcyA9IGNvbmYuYmFzaXMubWFwKGZ1bmN0aW9uKHZlYykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYTogbmV3IEJOKHZlYy5hLCAxNiksXG4gICAgICAgIGI6IG5ldyBCTih2ZWMuYiwgMTYpXG4gICAgICB9O1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGJhc2lzID0gdGhpcy5fZ2V0RW5kb0Jhc2lzKGxhbWJkYSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGJldGE6IGJldGEsXG4gICAgbGFtYmRhOiBsYW1iZGEsXG4gICAgYmFzaXM6IGJhc2lzXG4gIH07XG59O1xuXG5TaG9ydEN1cnZlLnByb3RvdHlwZS5fZ2V0RW5kb1Jvb3RzID0gZnVuY3Rpb24gX2dldEVuZG9Sb290cyhudW0pIHtcbiAgLy8gRmluZCByb290cyBvZiBmb3IgeF4yICsgeCArIDEgaW4gRlxuICAvLyBSb290ID0gKC0xICstIFNxcnQoLTMpKSAvIDJcbiAgLy9cbiAgdmFyIHJlZCA9IG51bSA9PT0gdGhpcy5wID8gdGhpcy5yZWQgOiBCTi5tb250KG51bSk7XG4gIHZhciB0aW52ID0gbmV3IEJOKDIpLnRvUmVkKHJlZCkucmVkSW52bSgpO1xuICB2YXIgbnRpbnYgPSB0aW52LnJlZE5lZygpO1xuXG4gIHZhciBzID0gbmV3IEJOKDMpLnRvUmVkKHJlZCkucmVkTmVnKCkucmVkU3FydCgpLnJlZE11bCh0aW52KTtcblxuICB2YXIgbDEgPSBudGludi5yZWRBZGQocykuZnJvbVJlZCgpO1xuICB2YXIgbDIgPSBudGludi5yZWRTdWIocykuZnJvbVJlZCgpO1xuICByZXR1cm4gWyBsMSwgbDIgXTtcbn07XG5cblNob3J0Q3VydmUucHJvdG90eXBlLl9nZXRFbmRvQmFzaXMgPSBmdW5jdGlvbiBfZ2V0RW5kb0Jhc2lzKGxhbWJkYSkge1xuICAvLyBhcHJ4U3FydCA+PSBzcXJ0KHRoaXMubilcbiAgdmFyIGFwcnhTcXJ0ID0gdGhpcy5uLnVzaHJuKE1hdGguZmxvb3IodGhpcy5uLmJpdExlbmd0aCgpIC8gMikpO1xuXG4gIC8vIDMuNzRcbiAgLy8gUnVuIEVHQ0QsIHVudGlsIHIoTCArIDEpIDwgYXByeFNxcnRcbiAgdmFyIHUgPSBsYW1iZGE7XG4gIHZhciB2ID0gdGhpcy5uLmNsb25lKCk7XG4gIHZhciB4MSA9IG5ldyBCTigxKTtcbiAgdmFyIHkxID0gbmV3IEJOKDApO1xuICB2YXIgeDIgPSBuZXcgQk4oMCk7XG4gIHZhciB5MiA9IG5ldyBCTigxKTtcblxuICAvLyBOT1RFOiBhbGwgdmVjdG9ycyBhcmUgcm9vdHMgb2Y6IGEgKyBiICogbGFtYmRhID0gMCAobW9kIG4pXG4gIHZhciBhMDtcbiAgdmFyIGIwO1xuICAvLyBGaXJzdCB2ZWN0b3JcbiAgdmFyIGExO1xuICB2YXIgYjE7XG4gIC8vIFNlY29uZCB2ZWN0b3JcbiAgdmFyIGEyO1xuICB2YXIgYjI7XG5cbiAgdmFyIHByZXZSO1xuICB2YXIgaSA9IDA7XG4gIHZhciByO1xuICB2YXIgeDtcbiAgd2hpbGUgKHUuY21wbigwKSAhPT0gMCkge1xuICAgIHZhciBxID0gdi5kaXYodSk7XG4gICAgciA9IHYuc3ViKHEubXVsKHUpKTtcbiAgICB4ID0geDIuc3ViKHEubXVsKHgxKSk7XG4gICAgdmFyIHkgPSB5Mi5zdWIocS5tdWwoeTEpKTtcblxuICAgIGlmICghYTEgJiYgci5jbXAoYXByeFNxcnQpIDwgMCkge1xuICAgICAgYTAgPSBwcmV2Ui5uZWcoKTtcbiAgICAgIGIwID0geDE7XG4gICAgICBhMSA9IHIubmVnKCk7XG4gICAgICBiMSA9IHg7XG4gICAgfSBlbHNlIGlmIChhMSAmJiArK2kgPT09IDIpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBwcmV2UiA9IHI7XG5cbiAgICB2ID0gdTtcbiAgICB1ID0gcjtcbiAgICB4MiA9IHgxO1xuICAgIHgxID0geDtcbiAgICB5MiA9IHkxO1xuICAgIHkxID0geTtcbiAgfVxuICBhMiA9IHIubmVnKCk7XG4gIGIyID0geDtcblxuICB2YXIgbGVuMSA9IGExLnNxcigpLmFkZChiMS5zcXIoKSk7XG4gIHZhciBsZW4yID0gYTIuc3FyKCkuYWRkKGIyLnNxcigpKTtcbiAgaWYgKGxlbjIuY21wKGxlbjEpID49IDApIHtcbiAgICBhMiA9IGEwO1xuICAgIGIyID0gYjA7XG4gIH1cblxuICAvLyBOb3JtYWxpemUgc2lnbnNcbiAgaWYgKGExLm5lZ2F0aXZlKSB7XG4gICAgYTEgPSBhMS5uZWcoKTtcbiAgICBiMSA9IGIxLm5lZygpO1xuICB9XG4gIGlmIChhMi5uZWdhdGl2ZSkge1xuICAgIGEyID0gYTIubmVnKCk7XG4gICAgYjIgPSBiMi5uZWcoKTtcbiAgfVxuXG4gIHJldHVybiBbXG4gICAgeyBhOiBhMSwgYjogYjEgfSxcbiAgICB7IGE6IGEyLCBiOiBiMiB9XG4gIF07XG59O1xuXG5TaG9ydEN1cnZlLnByb3RvdHlwZS5fZW5kb1NwbGl0ID0gZnVuY3Rpb24gX2VuZG9TcGxpdChrKSB7XG4gIHZhciBiYXNpcyA9IHRoaXMuZW5kby5iYXNpcztcbiAgdmFyIHYxID0gYmFzaXNbMF07XG4gIHZhciB2MiA9IGJhc2lzWzFdO1xuXG4gIHZhciBjMSA9IHYyLmIubXVsKGspLmRpdlJvdW5kKHRoaXMubik7XG4gIHZhciBjMiA9IHYxLmIubmVnKCkubXVsKGspLmRpdlJvdW5kKHRoaXMubik7XG5cbiAgdmFyIHAxID0gYzEubXVsKHYxLmEpO1xuICB2YXIgcDIgPSBjMi5tdWwodjIuYSk7XG4gIHZhciBxMSA9IGMxLm11bCh2MS5iKTtcbiAgdmFyIHEyID0gYzIubXVsKHYyLmIpO1xuXG4gIC8vIENhbGN1bGF0ZSBhbnN3ZXJcbiAgdmFyIGsxID0gay5zdWIocDEpLnN1YihwMik7XG4gIHZhciBrMiA9IHExLmFkZChxMikubmVnKCk7XG4gIHJldHVybiB7IGsxOiBrMSwgazI6IGsyIH07XG59O1xuXG5TaG9ydEN1cnZlLnByb3RvdHlwZS5wb2ludEZyb21YID0gZnVuY3Rpb24gcG9pbnRGcm9tWCh4LCBvZGQpIHtcbiAgeCA9IG5ldyBCTih4LCAxNik7XG4gIGlmICgheC5yZWQpXG4gICAgeCA9IHgudG9SZWQodGhpcy5yZWQpO1xuXG4gIHZhciB5MiA9IHgucmVkU3FyKCkucmVkTXVsKHgpLnJlZElBZGQoeC5yZWRNdWwodGhpcy5hKSkucmVkSUFkZCh0aGlzLmIpO1xuICB2YXIgeSA9IHkyLnJlZFNxcnQoKTtcbiAgaWYgKHkucmVkU3FyKCkucmVkU3ViKHkyKS5jbXAodGhpcy56ZXJvKSAhPT0gMClcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgcG9pbnQnKTtcblxuICAvLyBYWFggSXMgdGhlcmUgYW55IHdheSB0byB0ZWxsIGlmIHRoZSBudW1iZXIgaXMgb2RkIHdpdGhvdXQgY29udmVydGluZyBpdFxuICAvLyB0byBub24tcmVkIGZvcm0/XG4gIHZhciBpc09kZCA9IHkuZnJvbVJlZCgpLmlzT2RkKCk7XG4gIGlmIChvZGQgJiYgIWlzT2RkIHx8ICFvZGQgJiYgaXNPZGQpXG4gICAgeSA9IHkucmVkTmVnKCk7XG5cbiAgcmV0dXJuIHRoaXMucG9pbnQoeCwgeSk7XG59O1xuXG5TaG9ydEN1cnZlLnByb3RvdHlwZS52YWxpZGF0ZSA9IGZ1bmN0aW9uIHZhbGlkYXRlKHBvaW50KSB7XG4gIGlmIChwb2ludC5pbmYpXG4gICAgcmV0dXJuIHRydWU7XG5cbiAgdmFyIHggPSBwb2ludC54O1xuICB2YXIgeSA9IHBvaW50Lnk7XG5cbiAgdmFyIGF4ID0gdGhpcy5hLnJlZE11bCh4KTtcbiAgdmFyIHJocyA9IHgucmVkU3FyKCkucmVkTXVsKHgpLnJlZElBZGQoYXgpLnJlZElBZGQodGhpcy5iKTtcbiAgcmV0dXJuIHkucmVkU3FyKCkucmVkSVN1YihyaHMpLmNtcG4oMCkgPT09IDA7XG59O1xuXG5TaG9ydEN1cnZlLnByb3RvdHlwZS5fZW5kb1duYWZNdWxBZGQgPVxuICAgIGZ1bmN0aW9uIF9lbmRvV25hZk11bEFkZChwb2ludHMsIGNvZWZmcywgamFjb2JpYW5SZXN1bHQpIHtcbiAgdmFyIG5wb2ludHMgPSB0aGlzLl9lbmRvV25hZlQxO1xuICB2YXIgbmNvZWZmcyA9IHRoaXMuX2VuZG9XbmFmVDI7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHNwbGl0ID0gdGhpcy5fZW5kb1NwbGl0KGNvZWZmc1tpXSk7XG4gICAgdmFyIHAgPSBwb2ludHNbaV07XG4gICAgdmFyIGJldGEgPSBwLl9nZXRCZXRhKCk7XG5cbiAgICBpZiAoc3BsaXQuazEubmVnYXRpdmUpIHtcbiAgICAgIHNwbGl0LmsxLmluZWcoKTtcbiAgICAgIHAgPSBwLm5lZyh0cnVlKTtcbiAgICB9XG4gICAgaWYgKHNwbGl0LmsyLm5lZ2F0aXZlKSB7XG4gICAgICBzcGxpdC5rMi5pbmVnKCk7XG4gICAgICBiZXRhID0gYmV0YS5uZWcodHJ1ZSk7XG4gICAgfVxuXG4gICAgbnBvaW50c1tpICogMl0gPSBwO1xuICAgIG5wb2ludHNbaSAqIDIgKyAxXSA9IGJldGE7XG4gICAgbmNvZWZmc1tpICogMl0gPSBzcGxpdC5rMTtcbiAgICBuY29lZmZzW2kgKiAyICsgMV0gPSBzcGxpdC5rMjtcbiAgfVxuICB2YXIgcmVzID0gdGhpcy5fd25hZk11bEFkZCgxLCBucG9pbnRzLCBuY29lZmZzLCBpICogMiwgamFjb2JpYW5SZXN1bHQpO1xuXG4gIC8vIENsZWFuLXVwIHJlZmVyZW5jZXMgdG8gcG9pbnRzIGFuZCBjb2VmZmljaWVudHNcbiAgZm9yICh2YXIgaiA9IDA7IGogPCBpICogMjsgaisrKSB7XG4gICAgbnBvaW50c1tqXSA9IG51bGw7XG4gICAgbmNvZWZmc1tqXSA9IG51bGw7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn07XG5cbmZ1bmN0aW9uIFBvaW50KGN1cnZlLCB4LCB5LCBpc1JlZCkge1xuICBCYXNlLkJhc2VQb2ludC5jYWxsKHRoaXMsIGN1cnZlLCAnYWZmaW5lJyk7XG4gIGlmICh4ID09PSBudWxsICYmIHkgPT09IG51bGwpIHtcbiAgICB0aGlzLnggPSBudWxsO1xuICAgIHRoaXMueSA9IG51bGw7XG4gICAgdGhpcy5pbmYgPSB0cnVlO1xuICB9IGVsc2Uge1xuICAgIHRoaXMueCA9IG5ldyBCTih4LCAxNik7XG4gICAgdGhpcy55ID0gbmV3IEJOKHksIDE2KTtcbiAgICAvLyBGb3JjZSByZWRnb21lcnkgcmVwcmVzZW50YXRpb24gd2hlbiBsb2FkaW5nIGZyb20gSlNPTlxuICAgIGlmIChpc1JlZCkge1xuICAgICAgdGhpcy54LmZvcmNlUmVkKHRoaXMuY3VydmUucmVkKTtcbiAgICAgIHRoaXMueS5mb3JjZVJlZCh0aGlzLmN1cnZlLnJlZCk7XG4gICAgfVxuICAgIGlmICghdGhpcy54LnJlZClcbiAgICAgIHRoaXMueCA9IHRoaXMueC50b1JlZCh0aGlzLmN1cnZlLnJlZCk7XG4gICAgaWYgKCF0aGlzLnkucmVkKVxuICAgICAgdGhpcy55ID0gdGhpcy55LnRvUmVkKHRoaXMuY3VydmUucmVkKTtcbiAgICB0aGlzLmluZiA9IGZhbHNlO1xuICB9XG59XG5pbmhlcml0cyhQb2ludCwgQmFzZS5CYXNlUG9pbnQpO1xuXG5TaG9ydEN1cnZlLnByb3RvdHlwZS5wb2ludCA9IGZ1bmN0aW9uIHBvaW50KHgsIHksIGlzUmVkKSB7XG4gIHJldHVybiBuZXcgUG9pbnQodGhpcywgeCwgeSwgaXNSZWQpO1xufTtcblxuU2hvcnRDdXJ2ZS5wcm90b3R5cGUucG9pbnRGcm9tSlNPTiA9IGZ1bmN0aW9uIHBvaW50RnJvbUpTT04ob2JqLCByZWQpIHtcbiAgcmV0dXJuIFBvaW50LmZyb21KU09OKHRoaXMsIG9iaiwgcmVkKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5fZ2V0QmV0YSA9IGZ1bmN0aW9uIF9nZXRCZXRhKCkge1xuICBpZiAoIXRoaXMuY3VydmUuZW5kbylcbiAgICByZXR1cm47XG5cbiAgdmFyIHByZSA9IHRoaXMucHJlY29tcHV0ZWQ7XG4gIGlmIChwcmUgJiYgcHJlLmJldGEpXG4gICAgcmV0dXJuIHByZS5iZXRhO1xuXG4gIHZhciBiZXRhID0gdGhpcy5jdXJ2ZS5wb2ludCh0aGlzLngucmVkTXVsKHRoaXMuY3VydmUuZW5kby5iZXRhKSwgdGhpcy55KTtcbiAgaWYgKHByZSkge1xuICAgIHZhciBjdXJ2ZSA9IHRoaXMuY3VydmU7XG4gICAgdmFyIGVuZG9NdWwgPSBmdW5jdGlvbihwKSB7XG4gICAgICByZXR1cm4gY3VydmUucG9pbnQocC54LnJlZE11bChjdXJ2ZS5lbmRvLmJldGEpLCBwLnkpO1xuICAgIH07XG4gICAgcHJlLmJldGEgPSBiZXRhO1xuICAgIGJldGEucHJlY29tcHV0ZWQgPSB7XG4gICAgICBiZXRhOiBudWxsLFxuICAgICAgbmFmOiBwcmUubmFmICYmIHtcbiAgICAgICAgd25kOiBwcmUubmFmLnduZCxcbiAgICAgICAgcG9pbnRzOiBwcmUubmFmLnBvaW50cy5tYXAoZW5kb011bClcbiAgICAgIH0sXG4gICAgICBkb3VibGVzOiBwcmUuZG91YmxlcyAmJiB7XG4gICAgICAgIHN0ZXA6IHByZS5kb3VibGVzLnN0ZXAsXG4gICAgICAgIHBvaW50czogcHJlLmRvdWJsZXMucG9pbnRzLm1hcChlbmRvTXVsKVxuICAgICAgfVxuICAgIH07XG4gIH1cbiAgcmV0dXJuIGJldGE7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICBpZiAoIXRoaXMucHJlY29tcHV0ZWQpXG4gICAgcmV0dXJuIFsgdGhpcy54LCB0aGlzLnkgXTtcblxuICByZXR1cm4gWyB0aGlzLngsIHRoaXMueSwgdGhpcy5wcmVjb21wdXRlZCAmJiB7XG4gICAgZG91YmxlczogdGhpcy5wcmVjb21wdXRlZC5kb3VibGVzICYmIHtcbiAgICAgIHN0ZXA6IHRoaXMucHJlY29tcHV0ZWQuZG91Ymxlcy5zdGVwLFxuICAgICAgcG9pbnRzOiB0aGlzLnByZWNvbXB1dGVkLmRvdWJsZXMucG9pbnRzLnNsaWNlKDEpXG4gICAgfSxcbiAgICBuYWY6IHRoaXMucHJlY29tcHV0ZWQubmFmICYmIHtcbiAgICAgIHduZDogdGhpcy5wcmVjb21wdXRlZC5uYWYud25kLFxuICAgICAgcG9pbnRzOiB0aGlzLnByZWNvbXB1dGVkLm5hZi5wb2ludHMuc2xpY2UoMSlcbiAgICB9XG4gIH0gXTtcbn07XG5cblBvaW50LmZyb21KU09OID0gZnVuY3Rpb24gZnJvbUpTT04oY3VydmUsIG9iaiwgcmVkKSB7XG4gIGlmICh0eXBlb2Ygb2JqID09PSAnc3RyaW5nJylcbiAgICBvYmogPSBKU09OLnBhcnNlKG9iaik7XG4gIHZhciByZXMgPSBjdXJ2ZS5wb2ludChvYmpbMF0sIG9ialsxXSwgcmVkKTtcbiAgaWYgKCFvYmpbMl0pXG4gICAgcmV0dXJuIHJlcztcblxuICBmdW5jdGlvbiBvYmoycG9pbnQob2JqKSB7XG4gICAgcmV0dXJuIGN1cnZlLnBvaW50KG9ialswXSwgb2JqWzFdLCByZWQpO1xuICB9XG5cbiAgdmFyIHByZSA9IG9ialsyXTtcbiAgcmVzLnByZWNvbXB1dGVkID0ge1xuICAgIGJldGE6IG51bGwsXG4gICAgZG91YmxlczogcHJlLmRvdWJsZXMgJiYge1xuICAgICAgc3RlcDogcHJlLmRvdWJsZXMuc3RlcCxcbiAgICAgIHBvaW50czogWyByZXMgXS5jb25jYXQocHJlLmRvdWJsZXMucG9pbnRzLm1hcChvYmoycG9pbnQpKVxuICAgIH0sXG4gICAgbmFmOiBwcmUubmFmICYmIHtcbiAgICAgIHduZDogcHJlLm5hZi53bmQsXG4gICAgICBwb2ludHM6IFsgcmVzIF0uY29uY2F0KHByZS5uYWYucG9pbnRzLm1hcChvYmoycG9pbnQpKVxuICAgIH1cbiAgfTtcbiAgcmV0dXJuIHJlcztcbn07XG5cblBvaW50LnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgaWYgKHRoaXMuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiAnPEVDIFBvaW50IEluZmluaXR5Pic7XG4gIHJldHVybiAnPEVDIFBvaW50IHg6ICcgKyB0aGlzLnguZnJvbVJlZCgpLnRvU3RyaW5nKDE2LCAyKSArXG4gICAgICAnIHk6ICcgKyB0aGlzLnkuZnJvbVJlZCgpLnRvU3RyaW5nKDE2LCAyKSArICc+Jztcbn07XG5cblBvaW50LnByb3RvdHlwZS5pc0luZmluaXR5ID0gZnVuY3Rpb24gaXNJbmZpbml0eSgpIHtcbiAgcmV0dXJuIHRoaXMuaW5mO1xufTtcblxuUG9pbnQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIGFkZChwKSB7XG4gIC8vIE8gKyBQID0gUFxuICBpZiAodGhpcy5pbmYpXG4gICAgcmV0dXJuIHA7XG5cbiAgLy8gUCArIE8gPSBQXG4gIGlmIChwLmluZilcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyBQICsgUCA9IDJQXG4gIGlmICh0aGlzLmVxKHApKVxuICAgIHJldHVybiB0aGlzLmRibCgpO1xuXG4gIC8vIFAgKyAoLVApID0gT1xuICBpZiAodGhpcy5uZWcoKS5lcShwKSlcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChudWxsLCBudWxsKTtcblxuICAvLyBQICsgUSA9IE9cbiAgaWYgKHRoaXMueC5jbXAocC54KSA9PT0gMClcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChudWxsLCBudWxsKTtcblxuICB2YXIgYyA9IHRoaXMueS5yZWRTdWIocC55KTtcbiAgaWYgKGMuY21wbigwKSAhPT0gMClcbiAgICBjID0gYy5yZWRNdWwodGhpcy54LnJlZFN1YihwLngpLnJlZEludm0oKSk7XG4gIHZhciBueCA9IGMucmVkU3FyKCkucmVkSVN1Yih0aGlzLngpLnJlZElTdWIocC54KTtcbiAgdmFyIG55ID0gYy5yZWRNdWwodGhpcy54LnJlZFN1YihueCkpLnJlZElTdWIodGhpcy55KTtcbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQobngsIG55KTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5kYmwgPSBmdW5jdGlvbiBkYmwoKSB7XG4gIGlmICh0aGlzLmluZilcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyAyUCA9IE9cbiAgdmFyIHlzMSA9IHRoaXMueS5yZWRBZGQodGhpcy55KTtcbiAgaWYgKHlzMS5jbXBuKDApID09PSAwKVxuICAgIHJldHVybiB0aGlzLmN1cnZlLnBvaW50KG51bGwsIG51bGwpO1xuXG4gIHZhciBhID0gdGhpcy5jdXJ2ZS5hO1xuXG4gIHZhciB4MiA9IHRoaXMueC5yZWRTcXIoKTtcbiAgdmFyIGR5aW52ID0geXMxLnJlZEludm0oKTtcbiAgdmFyIGMgPSB4Mi5yZWRBZGQoeDIpLnJlZElBZGQoeDIpLnJlZElBZGQoYSkucmVkTXVsKGR5aW52KTtcblxuICB2YXIgbnggPSBjLnJlZFNxcigpLnJlZElTdWIodGhpcy54LnJlZEFkZCh0aGlzLngpKTtcbiAgdmFyIG55ID0gYy5yZWRNdWwodGhpcy54LnJlZFN1YihueCkpLnJlZElTdWIodGhpcy55KTtcbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQobngsIG55KTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5nZXRYID0gZnVuY3Rpb24gZ2V0WCgpIHtcbiAgcmV0dXJuIHRoaXMueC5mcm9tUmVkKCk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZ2V0WSA9IGZ1bmN0aW9uIGdldFkoKSB7XG4gIHJldHVybiB0aGlzLnkuZnJvbVJlZCgpO1xufTtcblxuUG9pbnQucHJvdG90eXBlLm11bCA9IGZ1bmN0aW9uIG11bChrKSB7XG4gIGsgPSBuZXcgQk4oaywgMTYpO1xuXG4gIGlmICh0aGlzLl9oYXNEb3VibGVzKGspKVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl9maXhlZE5hZk11bCh0aGlzLCBrKTtcbiAgZWxzZSBpZiAodGhpcy5jdXJ2ZS5lbmRvKVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl9lbmRvV25hZk11bEFkZChbIHRoaXMgXSwgWyBrIF0pO1xuICBlbHNlXG4gICAgcmV0dXJuIHRoaXMuY3VydmUuX3duYWZNdWwodGhpcywgayk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUubXVsQWRkID0gZnVuY3Rpb24gbXVsQWRkKGsxLCBwMiwgazIpIHtcbiAgdmFyIHBvaW50cyA9IFsgdGhpcywgcDIgXTtcbiAgdmFyIGNvZWZmcyA9IFsgazEsIGsyIF07XG4gIGlmICh0aGlzLmN1cnZlLmVuZG8pXG4gICAgcmV0dXJuIHRoaXMuY3VydmUuX2VuZG9XbmFmTXVsQWRkKHBvaW50cywgY29lZmZzKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl93bmFmTXVsQWRkKDEsIHBvaW50cywgY29lZmZzLCAyKTtcbn07XG5cblBvaW50LnByb3RvdHlwZS5qbXVsQWRkID0gZnVuY3Rpb24gam11bEFkZChrMSwgcDIsIGsyKSB7XG4gIHZhciBwb2ludHMgPSBbIHRoaXMsIHAyIF07XG4gIHZhciBjb2VmZnMgPSBbIGsxLCBrMiBdO1xuICBpZiAodGhpcy5jdXJ2ZS5lbmRvKVxuICAgIHJldHVybiB0aGlzLmN1cnZlLl9lbmRvV25hZk11bEFkZChwb2ludHMsIGNvZWZmcywgdHJ1ZSk7XG4gIGVsc2VcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5fd25hZk11bEFkZCgxLCBwb2ludHMsIGNvZWZmcywgMiwgdHJ1ZSk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUuZXEgPSBmdW5jdGlvbiBlcShwKSB7XG4gIHJldHVybiB0aGlzID09PSBwIHx8XG4gICAgICAgICB0aGlzLmluZiA9PT0gcC5pbmYgJiZcbiAgICAgICAgICAgICAodGhpcy5pbmYgfHwgdGhpcy54LmNtcChwLngpID09PSAwICYmIHRoaXMueS5jbXAocC55KSA9PT0gMCk7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUubmVnID0gZnVuY3Rpb24gbmVnKF9wcmVjb21wdXRlKSB7XG4gIGlmICh0aGlzLmluZilcbiAgICByZXR1cm4gdGhpcztcblxuICB2YXIgcmVzID0gdGhpcy5jdXJ2ZS5wb2ludCh0aGlzLngsIHRoaXMueS5yZWROZWcoKSk7XG4gIGlmIChfcHJlY29tcHV0ZSAmJiB0aGlzLnByZWNvbXB1dGVkKSB7XG4gICAgdmFyIHByZSA9IHRoaXMucHJlY29tcHV0ZWQ7XG4gICAgdmFyIG5lZ2F0ZSA9IGZ1bmN0aW9uKHApIHtcbiAgICAgIHJldHVybiBwLm5lZygpO1xuICAgIH07XG4gICAgcmVzLnByZWNvbXB1dGVkID0ge1xuICAgICAgbmFmOiBwcmUubmFmICYmIHtcbiAgICAgICAgd25kOiBwcmUubmFmLnduZCxcbiAgICAgICAgcG9pbnRzOiBwcmUubmFmLnBvaW50cy5tYXAobmVnYXRlKVxuICAgICAgfSxcbiAgICAgIGRvdWJsZXM6IHByZS5kb3VibGVzICYmIHtcbiAgICAgICAgc3RlcDogcHJlLmRvdWJsZXMuc3RlcCxcbiAgICAgICAgcG9pbnRzOiBwcmUuZG91Ymxlcy5wb2ludHMubWFwKG5lZ2F0ZSlcbiAgICAgIH1cbiAgICB9O1xuICB9XG4gIHJldHVybiByZXM7XG59O1xuXG5Qb2ludC5wcm90b3R5cGUudG9KID0gZnVuY3Rpb24gdG9KKCkge1xuICBpZiAodGhpcy5pbmYpXG4gICAgcmV0dXJuIHRoaXMuY3VydmUuanBvaW50KG51bGwsIG51bGwsIG51bGwpO1xuXG4gIHZhciByZXMgPSB0aGlzLmN1cnZlLmpwb2ludCh0aGlzLngsIHRoaXMueSwgdGhpcy5jdXJ2ZS5vbmUpO1xuICByZXR1cm4gcmVzO1xufTtcblxuZnVuY3Rpb24gSlBvaW50KGN1cnZlLCB4LCB5LCB6KSB7XG4gIEJhc2UuQmFzZVBvaW50LmNhbGwodGhpcywgY3VydmUsICdqYWNvYmlhbicpO1xuICBpZiAoeCA9PT0gbnVsbCAmJiB5ID09PSBudWxsICYmIHogPT09IG51bGwpIHtcbiAgICB0aGlzLnggPSB0aGlzLmN1cnZlLm9uZTtcbiAgICB0aGlzLnkgPSB0aGlzLmN1cnZlLm9uZTtcbiAgICB0aGlzLnogPSBuZXcgQk4oMCk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy54ID0gbmV3IEJOKHgsIDE2KTtcbiAgICB0aGlzLnkgPSBuZXcgQk4oeSwgMTYpO1xuICAgIHRoaXMueiA9IG5ldyBCTih6LCAxNik7XG4gIH1cbiAgaWYgKCF0aGlzLngucmVkKVxuICAgIHRoaXMueCA9IHRoaXMueC50b1JlZCh0aGlzLmN1cnZlLnJlZCk7XG4gIGlmICghdGhpcy55LnJlZClcbiAgICB0aGlzLnkgPSB0aGlzLnkudG9SZWQodGhpcy5jdXJ2ZS5yZWQpO1xuICBpZiAoIXRoaXMuei5yZWQpXG4gICAgdGhpcy56ID0gdGhpcy56LnRvUmVkKHRoaXMuY3VydmUucmVkKTtcblxuICB0aGlzLnpPbmUgPSB0aGlzLnogPT09IHRoaXMuY3VydmUub25lO1xufVxuaW5oZXJpdHMoSlBvaW50LCBCYXNlLkJhc2VQb2ludCk7XG5cblNob3J0Q3VydmUucHJvdG90eXBlLmpwb2ludCA9IGZ1bmN0aW9uIGpwb2ludCh4LCB5LCB6KSB7XG4gIHJldHVybiBuZXcgSlBvaW50KHRoaXMsIHgsIHksIHopO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS50b1AgPSBmdW5jdGlvbiB0b1AoKSB7XG4gIGlmICh0aGlzLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludChudWxsLCBudWxsKTtcblxuICB2YXIgemludiA9IHRoaXMuei5yZWRJbnZtKCk7XG4gIHZhciB6aW52MiA9IHppbnYucmVkU3FyKCk7XG4gIHZhciBheCA9IHRoaXMueC5yZWRNdWwoemludjIpO1xuICB2YXIgYXkgPSB0aGlzLnkucmVkTXVsKHppbnYyKS5yZWRNdWwoemludik7XG5cbiAgcmV0dXJuIHRoaXMuY3VydmUucG9pbnQoYXgsIGF5KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUubmVnID0gZnVuY3Rpb24gbmVnKCkge1xuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQodGhpcy54LCB0aGlzLnkucmVkTmVnKCksIHRoaXMueik7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIGFkZChwKSB7XG4gIC8vIE8gKyBQID0gUFxuICBpZiAodGhpcy5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHA7XG5cbiAgLy8gUCArIE8gPSBQXG4gIGlmIChwLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyAxMk0gKyA0UyArIDdBXG4gIHZhciBwejIgPSBwLnoucmVkU3FyKCk7XG4gIHZhciB6MiA9IHRoaXMuei5yZWRTcXIoKTtcbiAgdmFyIHUxID0gdGhpcy54LnJlZE11bChwejIpO1xuICB2YXIgdTIgPSBwLngucmVkTXVsKHoyKTtcbiAgdmFyIHMxID0gdGhpcy55LnJlZE11bChwejIucmVkTXVsKHAueikpO1xuICB2YXIgczIgPSBwLnkucmVkTXVsKHoyLnJlZE11bCh0aGlzLnopKTtcblxuICB2YXIgaCA9IHUxLnJlZFN1Yih1Mik7XG4gIHZhciByID0gczEucmVkU3ViKHMyKTtcbiAgaWYgKGguY21wbigwKSA9PT0gMCkge1xuICAgIGlmIChyLmNtcG4oMCkgIT09IDApXG4gICAgICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobnVsbCwgbnVsbCwgbnVsbCk7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIHRoaXMuZGJsKCk7XG4gIH1cblxuICB2YXIgaDIgPSBoLnJlZFNxcigpO1xuICB2YXIgaDMgPSBoMi5yZWRNdWwoaCk7XG4gIHZhciB2ID0gdTEucmVkTXVsKGgyKTtcblxuICB2YXIgbnggPSByLnJlZFNxcigpLnJlZElBZGQoaDMpLnJlZElTdWIodikucmVkSVN1Yih2KTtcbiAgdmFyIG55ID0gci5yZWRNdWwodi5yZWRJU3ViKG54KSkucmVkSVN1YihzMS5yZWRNdWwoaDMpKTtcbiAgdmFyIG56ID0gdGhpcy56LnJlZE11bChwLnopLnJlZE11bChoKTtcblxuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobngsIG55LCBueik7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLm1peGVkQWRkID0gZnVuY3Rpb24gbWl4ZWRBZGQocCkge1xuICAvLyBPICsgUCA9IFBcbiAgaWYgKHRoaXMuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiBwLnRvSigpO1xuXG4gIC8vIFAgKyBPID0gUFxuICBpZiAocC5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8gOE0gKyAzUyArIDdBXG4gIHZhciB6MiA9IHRoaXMuei5yZWRTcXIoKTtcbiAgdmFyIHUxID0gdGhpcy54O1xuICB2YXIgdTIgPSBwLngucmVkTXVsKHoyKTtcbiAgdmFyIHMxID0gdGhpcy55O1xuICB2YXIgczIgPSBwLnkucmVkTXVsKHoyKS5yZWRNdWwodGhpcy56KTtcblxuICB2YXIgaCA9IHUxLnJlZFN1Yih1Mik7XG4gIHZhciByID0gczEucmVkU3ViKHMyKTtcbiAgaWYgKGguY21wbigwKSA9PT0gMCkge1xuICAgIGlmIChyLmNtcG4oMCkgIT09IDApXG4gICAgICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobnVsbCwgbnVsbCwgbnVsbCk7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIHRoaXMuZGJsKCk7XG4gIH1cblxuICB2YXIgaDIgPSBoLnJlZFNxcigpO1xuICB2YXIgaDMgPSBoMi5yZWRNdWwoaCk7XG4gIHZhciB2ID0gdTEucmVkTXVsKGgyKTtcblxuICB2YXIgbnggPSByLnJlZFNxcigpLnJlZElBZGQoaDMpLnJlZElTdWIodikucmVkSVN1Yih2KTtcbiAgdmFyIG55ID0gci5yZWRNdWwodi5yZWRJU3ViKG54KSkucmVkSVN1YihzMS5yZWRNdWwoaDMpKTtcbiAgdmFyIG56ID0gdGhpcy56LnJlZE11bChoKTtcblxuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobngsIG55LCBueik7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLmRibHAgPSBmdW5jdGlvbiBkYmxwKHBvdykge1xuICBpZiAocG93ID09PSAwKVxuICAgIHJldHVybiB0aGlzO1xuICBpZiAodGhpcy5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHRoaXM7XG4gIGlmICghcG93KVxuICAgIHJldHVybiB0aGlzLmRibCgpO1xuXG4gIGlmICh0aGlzLmN1cnZlLnplcm9BIHx8IHRoaXMuY3VydmUudGhyZWVBKSB7XG4gICAgdmFyIHIgPSB0aGlzO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcG93OyBpKyspXG4gICAgICByID0gci5kYmwoKTtcbiAgICByZXR1cm4gcjtcbiAgfVxuXG4gIC8vIDFNICsgMlMgKyAxQSArIE4gKiAoNFMgKyA1TSArIDhBKVxuICAvLyBOID0gMSA9PiA2TSArIDZTICsgOUFcbiAgdmFyIGEgPSB0aGlzLmN1cnZlLmE7XG4gIHZhciB0aW52ID0gdGhpcy5jdXJ2ZS50aW52O1xuXG4gIHZhciBqeCA9IHRoaXMueDtcbiAgdmFyIGp5ID0gdGhpcy55O1xuICB2YXIganogPSB0aGlzLno7XG4gIHZhciBqejQgPSBqei5yZWRTcXIoKS5yZWRTcXIoKTtcblxuICAvLyBSZXVzZSByZXN1bHRzXG4gIHZhciBqeWQgPSBqeS5yZWRBZGQoankpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHBvdzsgaSsrKSB7XG4gICAgdmFyIGp4MiA9IGp4LnJlZFNxcigpO1xuICAgIHZhciBqeWQyID0ganlkLnJlZFNxcigpO1xuICAgIHZhciBqeWQ0ID0ganlkMi5yZWRTcXIoKTtcbiAgICB2YXIgYyA9IGp4Mi5yZWRBZGQoangyKS5yZWRJQWRkKGp4MikucmVkSUFkZChhLnJlZE11bChqejQpKTtcblxuICAgIHZhciB0MSA9IGp4LnJlZE11bChqeWQyKTtcbiAgICB2YXIgbnggPSBjLnJlZFNxcigpLnJlZElTdWIodDEucmVkQWRkKHQxKSk7XG4gICAgdmFyIHQyID0gdDEucmVkSVN1YihueCk7XG4gICAgdmFyIGRueSA9IGMucmVkTXVsKHQyKTtcbiAgICBkbnkgPSBkbnkucmVkSUFkZChkbnkpLnJlZElTdWIoanlkNCk7XG4gICAgdmFyIG56ID0ganlkLnJlZE11bChqeik7XG4gICAgaWYgKGkgKyAxIDwgcG93KVxuICAgICAgano0ID0gano0LnJlZE11bChqeWQ0KTtcblxuICAgIGp4ID0gbng7XG4gICAganogPSBuejtcbiAgICBqeWQgPSBkbnk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQoangsIGp5ZC5yZWRNdWwodGludiksIGp6KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUuZGJsID0gZnVuY3Rpb24gZGJsKCkge1xuICBpZiAodGhpcy5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgaWYgKHRoaXMuY3VydmUuemVyb0EpXG4gICAgcmV0dXJuIHRoaXMuX3plcm9EYmwoKTtcbiAgZWxzZSBpZiAodGhpcy5jdXJ2ZS50aHJlZUEpXG4gICAgcmV0dXJuIHRoaXMuX3RocmVlRGJsKCk7XG4gIGVsc2VcbiAgICByZXR1cm4gdGhpcy5fZGJsKCk7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLl96ZXJvRGJsID0gZnVuY3Rpb24gX3plcm9EYmwoKSB7XG4gIHZhciBueDtcbiAgdmFyIG55O1xuICB2YXIgbno7XG4gIC8vIFogPSAxXG4gIGlmICh0aGlzLnpPbmUpIHtcbiAgICAvLyBoeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tc2hvcnR3LWphY29iaWFuLTAuaHRtbFxuICAgIC8vICAgICAjZG91YmxpbmctbWRibC0yMDA3LWJsXG4gICAgLy8gMU0gKyA1UyArIDE0QVxuXG4gICAgLy8gWFggPSBYMV4yXG4gICAgdmFyIHh4ID0gdGhpcy54LnJlZFNxcigpO1xuICAgIC8vIFlZID0gWTFeMlxuICAgIHZhciB5eSA9IHRoaXMueS5yZWRTcXIoKTtcbiAgICAvLyBZWVlZID0gWVleMlxuICAgIHZhciB5eXl5ID0geXkucmVkU3FyKCk7XG4gICAgLy8gUyA9IDIgKiAoKFgxICsgWVkpXjIgLSBYWCAtIFlZWVkpXG4gICAgdmFyIHMgPSB0aGlzLngucmVkQWRkKHl5KS5yZWRTcXIoKS5yZWRJU3ViKHh4KS5yZWRJU3ViKHl5eXkpO1xuICAgIHMgPSBzLnJlZElBZGQocyk7XG4gICAgLy8gTSA9IDMgKiBYWCArIGE7IGEgPSAwXG4gICAgdmFyIG0gPSB4eC5yZWRBZGQoeHgpLnJlZElBZGQoeHgpO1xuICAgIC8vIFQgPSBNIF4gMiAtIDIqU1xuICAgIHZhciB0ID0gbS5yZWRTcXIoKS5yZWRJU3ViKHMpLnJlZElTdWIocyk7XG5cbiAgICAvLyA4ICogWVlZWVxuICAgIHZhciB5eXl5OCA9IHl5eXkucmVkSUFkZCh5eXl5KTtcbiAgICB5eXl5OCA9IHl5eXk4LnJlZElBZGQoeXl5eTgpO1xuICAgIHl5eXk4ID0geXl5eTgucmVkSUFkZCh5eXl5OCk7XG5cbiAgICAvLyBYMyA9IFRcbiAgICBueCA9IHQ7XG4gICAgLy8gWTMgPSBNICogKFMgLSBUKSAtIDggKiBZWVlZXG4gICAgbnkgPSBtLnJlZE11bChzLnJlZElTdWIodCkpLnJlZElTdWIoeXl5eTgpO1xuICAgIC8vIFozID0gMipZMVxuICAgIG56ID0gdGhpcy55LnJlZEFkZCh0aGlzLnkpO1xuICB9IGVsc2Uge1xuICAgIC8vIGh5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by1zaG9ydHctamFjb2JpYW4tMC5odG1sXG4gICAgLy8gICAgICNkb3VibGluZy1kYmwtMjAwOS1sXG4gICAgLy8gMk0gKyA1UyArIDEzQVxuXG4gICAgLy8gQSA9IFgxXjJcbiAgICB2YXIgYSA9IHRoaXMueC5yZWRTcXIoKTtcbiAgICAvLyBCID0gWTFeMlxuICAgIHZhciBiID0gdGhpcy55LnJlZFNxcigpO1xuICAgIC8vIEMgPSBCXjJcbiAgICB2YXIgYyA9IGIucmVkU3FyKCk7XG4gICAgLy8gRCA9IDIgKiAoKFgxICsgQileMiAtIEEgLSBDKVxuICAgIHZhciBkID0gdGhpcy54LnJlZEFkZChiKS5yZWRTcXIoKS5yZWRJU3ViKGEpLnJlZElTdWIoYyk7XG4gICAgZCA9IGQucmVkSUFkZChkKTtcbiAgICAvLyBFID0gMyAqIEFcbiAgICB2YXIgZSA9IGEucmVkQWRkKGEpLnJlZElBZGQoYSk7XG4gICAgLy8gRiA9IEVeMlxuICAgIHZhciBmID0gZS5yZWRTcXIoKTtcblxuICAgIC8vIDggKiBDXG4gICAgdmFyIGM4ID0gYy5yZWRJQWRkKGMpO1xuICAgIGM4ID0gYzgucmVkSUFkZChjOCk7XG4gICAgYzggPSBjOC5yZWRJQWRkKGM4KTtcblxuICAgIC8vIFgzID0gRiAtIDIgKiBEXG4gICAgbnggPSBmLnJlZElTdWIoZCkucmVkSVN1YihkKTtcbiAgICAvLyBZMyA9IEUgKiAoRCAtIFgzKSAtIDggKiBDXG4gICAgbnkgPSBlLnJlZE11bChkLnJlZElTdWIobngpKS5yZWRJU3ViKGM4KTtcbiAgICAvLyBaMyA9IDIgKiBZMSAqIFoxXG4gICAgbnogPSB0aGlzLnkucmVkTXVsKHRoaXMueik7XG4gICAgbnogPSBuei5yZWRJQWRkKG56KTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLmN1cnZlLmpwb2ludChueCwgbnksIG56KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUuX3RocmVlRGJsID0gZnVuY3Rpb24gX3RocmVlRGJsKCkge1xuICB2YXIgbng7XG4gIHZhciBueTtcbiAgdmFyIG56O1xuICAvLyBaID0gMVxuICBpZiAodGhpcy56T25lKSB7XG4gICAgLy8gaHlwZXJlbGxpcHRpYy5vcmcvRUZEL2cxcC9hdXRvLXNob3J0dy1qYWNvYmlhbi0zLmh0bWxcbiAgICAvLyAgICAgI2RvdWJsaW5nLW1kYmwtMjAwNy1ibFxuICAgIC8vIDFNICsgNVMgKyAxNUFcblxuICAgIC8vIFhYID0gWDFeMlxuICAgIHZhciB4eCA9IHRoaXMueC5yZWRTcXIoKTtcbiAgICAvLyBZWSA9IFkxXjJcbiAgICB2YXIgeXkgPSB0aGlzLnkucmVkU3FyKCk7XG4gICAgLy8gWVlZWSA9IFlZXjJcbiAgICB2YXIgeXl5eSA9IHl5LnJlZFNxcigpO1xuICAgIC8vIFMgPSAyICogKChYMSArIFlZKV4yIC0gWFggLSBZWVlZKVxuICAgIHZhciBzID0gdGhpcy54LnJlZEFkZCh5eSkucmVkU3FyKCkucmVkSVN1Yih4eCkucmVkSVN1Yih5eXl5KTtcbiAgICBzID0gcy5yZWRJQWRkKHMpO1xuICAgIC8vIE0gPSAzICogWFggKyBhXG4gICAgdmFyIG0gPSB4eC5yZWRBZGQoeHgpLnJlZElBZGQoeHgpLnJlZElBZGQodGhpcy5jdXJ2ZS5hKTtcbiAgICAvLyBUID0gTV4yIC0gMiAqIFNcbiAgICB2YXIgdCA9IG0ucmVkU3FyKCkucmVkSVN1YihzKS5yZWRJU3ViKHMpO1xuICAgIC8vIFgzID0gVFxuICAgIG54ID0gdDtcbiAgICAvLyBZMyA9IE0gKiAoUyAtIFQpIC0gOCAqIFlZWVlcbiAgICB2YXIgeXl5eTggPSB5eXl5LnJlZElBZGQoeXl5eSk7XG4gICAgeXl5eTggPSB5eXl5OC5yZWRJQWRkKHl5eXk4KTtcbiAgICB5eXl5OCA9IHl5eXk4LnJlZElBZGQoeXl5eTgpO1xuICAgIG55ID0gbS5yZWRNdWwocy5yZWRJU3ViKHQpKS5yZWRJU3ViKHl5eXk4KTtcbiAgICAvLyBaMyA9IDIgKiBZMVxuICAgIG56ID0gdGhpcy55LnJlZEFkZCh0aGlzLnkpO1xuICB9IGVsc2Uge1xuICAgIC8vIGh5cGVyZWxsaXB0aWMub3JnL0VGRC9nMXAvYXV0by1zaG9ydHctamFjb2JpYW4tMy5odG1sI2RvdWJsaW5nLWRibC0yMDAxLWJcbiAgICAvLyAzTSArIDVTXG5cbiAgICAvLyBkZWx0YSA9IFoxXjJcbiAgICB2YXIgZGVsdGEgPSB0aGlzLnoucmVkU3FyKCk7XG4gICAgLy8gZ2FtbWEgPSBZMV4yXG4gICAgdmFyIGdhbW1hID0gdGhpcy55LnJlZFNxcigpO1xuICAgIC8vIGJldGEgPSBYMSAqIGdhbW1hXG4gICAgdmFyIGJldGEgPSB0aGlzLngucmVkTXVsKGdhbW1hKTtcbiAgICAvLyBhbHBoYSA9IDMgKiAoWDEgLSBkZWx0YSkgKiAoWDEgKyBkZWx0YSlcbiAgICB2YXIgYWxwaGEgPSB0aGlzLngucmVkU3ViKGRlbHRhKS5yZWRNdWwodGhpcy54LnJlZEFkZChkZWx0YSkpO1xuICAgIGFscGhhID0gYWxwaGEucmVkQWRkKGFscGhhKS5yZWRJQWRkKGFscGhhKTtcbiAgICAvLyBYMyA9IGFscGhhXjIgLSA4ICogYmV0YVxuICAgIHZhciBiZXRhNCA9IGJldGEucmVkSUFkZChiZXRhKTtcbiAgICBiZXRhNCA9IGJldGE0LnJlZElBZGQoYmV0YTQpO1xuICAgIHZhciBiZXRhOCA9IGJldGE0LnJlZEFkZChiZXRhNCk7XG4gICAgbnggPSBhbHBoYS5yZWRTcXIoKS5yZWRJU3ViKGJldGE4KTtcbiAgICAvLyBaMyA9IChZMSArIFoxKV4yIC0gZ2FtbWEgLSBkZWx0YVxuICAgIG56ID0gdGhpcy55LnJlZEFkZCh0aGlzLnopLnJlZFNxcigpLnJlZElTdWIoZ2FtbWEpLnJlZElTdWIoZGVsdGEpO1xuICAgIC8vIFkzID0gYWxwaGEgKiAoNCAqIGJldGEgLSBYMykgLSA4ICogZ2FtbWFeMlxuICAgIHZhciBnZ2FtbWE4ID0gZ2FtbWEucmVkU3FyKCk7XG4gICAgZ2dhbW1hOCA9IGdnYW1tYTgucmVkSUFkZChnZ2FtbWE4KTtcbiAgICBnZ2FtbWE4ID0gZ2dhbW1hOC5yZWRJQWRkKGdnYW1tYTgpO1xuICAgIGdnYW1tYTggPSBnZ2FtbWE4LnJlZElBZGQoZ2dhbW1hOCk7XG4gICAgbnkgPSBhbHBoYS5yZWRNdWwoYmV0YTQucmVkSVN1YihueCkpLnJlZElTdWIoZ2dhbW1hOCk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5jdXJ2ZS5qcG9pbnQobngsIG55LCBueik7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLl9kYmwgPSBmdW5jdGlvbiBfZGJsKCkge1xuICB2YXIgYSA9IHRoaXMuY3VydmUuYTtcblxuICAvLyA0TSArIDZTICsgMTBBXG4gIHZhciBqeCA9IHRoaXMueDtcbiAgdmFyIGp5ID0gdGhpcy55O1xuICB2YXIganogPSB0aGlzLno7XG4gIHZhciBqejQgPSBqei5yZWRTcXIoKS5yZWRTcXIoKTtcblxuICB2YXIgangyID0gangucmVkU3FyKCk7XG4gIHZhciBqeTIgPSBqeS5yZWRTcXIoKTtcblxuICB2YXIgYyA9IGp4Mi5yZWRBZGQoangyKS5yZWRJQWRkKGp4MikucmVkSUFkZChhLnJlZE11bChqejQpKTtcblxuICB2YXIganhkNCA9IGp4LnJlZEFkZChqeCk7XG4gIGp4ZDQgPSBqeGQ0LnJlZElBZGQoanhkNCk7XG4gIHZhciB0MSA9IGp4ZDQucmVkTXVsKGp5Mik7XG4gIHZhciBueCA9IGMucmVkU3FyKCkucmVkSVN1Yih0MS5yZWRBZGQodDEpKTtcbiAgdmFyIHQyID0gdDEucmVkSVN1YihueCk7XG5cbiAgdmFyIGp5ZDggPSBqeTIucmVkU3FyKCk7XG4gIGp5ZDggPSBqeWQ4LnJlZElBZGQoanlkOCk7XG4gIGp5ZDggPSBqeWQ4LnJlZElBZGQoanlkOCk7XG4gIGp5ZDggPSBqeWQ4LnJlZElBZGQoanlkOCk7XG4gIHZhciBueSA9IGMucmVkTXVsKHQyKS5yZWRJU3ViKGp5ZDgpO1xuICB2YXIgbnogPSBqeS5yZWRBZGQoankpLnJlZE11bChqeik7XG5cbiAgcmV0dXJuIHRoaXMuY3VydmUuanBvaW50KG54LCBueSwgbnopO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS50cnBsID0gZnVuY3Rpb24gdHJwbCgpIHtcbiAgaWYgKCF0aGlzLmN1cnZlLnplcm9BKVxuICAgIHJldHVybiB0aGlzLmRibCgpLmFkZCh0aGlzKTtcblxuICAvLyBoeXBlcmVsbGlwdGljLm9yZy9FRkQvZzFwL2F1dG8tc2hvcnR3LWphY29iaWFuLTAuaHRtbCN0cmlwbGluZy10cGwtMjAwNy1ibFxuICAvLyA1TSArIDEwUyArIC4uLlxuXG4gIC8vIFhYID0gWDFeMlxuICB2YXIgeHggPSB0aGlzLngucmVkU3FyKCk7XG4gIC8vIFlZID0gWTFeMlxuICB2YXIgeXkgPSB0aGlzLnkucmVkU3FyKCk7XG4gIC8vIFpaID0gWjFeMlxuICB2YXIgenogPSB0aGlzLnoucmVkU3FyKCk7XG4gIC8vIFlZWVkgPSBZWV4yXG4gIHZhciB5eXl5ID0geXkucmVkU3FyKCk7XG4gIC8vIE0gPSAzICogWFggKyBhICogWloyOyBhID0gMFxuICB2YXIgbSA9IHh4LnJlZEFkZCh4eCkucmVkSUFkZCh4eCk7XG4gIC8vIE1NID0gTV4yXG4gIHZhciBtbSA9IG0ucmVkU3FyKCk7XG4gIC8vIEUgPSA2ICogKChYMSArIFlZKV4yIC0gWFggLSBZWVlZKSAtIE1NXG4gIHZhciBlID0gdGhpcy54LnJlZEFkZCh5eSkucmVkU3FyKCkucmVkSVN1Yih4eCkucmVkSVN1Yih5eXl5KTtcbiAgZSA9IGUucmVkSUFkZChlKTtcbiAgZSA9IGUucmVkQWRkKGUpLnJlZElBZGQoZSk7XG4gIGUgPSBlLnJlZElTdWIobW0pO1xuICAvLyBFRSA9IEVeMlxuICB2YXIgZWUgPSBlLnJlZFNxcigpO1xuICAvLyBUID0gMTYqWVlZWVxuICB2YXIgdCA9IHl5eXkucmVkSUFkZCh5eXl5KTtcbiAgdCA9IHQucmVkSUFkZCh0KTtcbiAgdCA9IHQucmVkSUFkZCh0KTtcbiAgdCA9IHQucmVkSUFkZCh0KTtcbiAgLy8gVSA9IChNICsgRSleMiAtIE1NIC0gRUUgLSBUXG4gIHZhciB1ID0gbS5yZWRJQWRkKGUpLnJlZFNxcigpLnJlZElTdWIobW0pLnJlZElTdWIoZWUpLnJlZElTdWIodCk7XG4gIC8vIFgzID0gNCAqIChYMSAqIEVFIC0gNCAqIFlZICogVSlcbiAgdmFyIHl5dTQgPSB5eS5yZWRNdWwodSk7XG4gIHl5dTQgPSB5eXU0LnJlZElBZGQoeXl1NCk7XG4gIHl5dTQgPSB5eXU0LnJlZElBZGQoeXl1NCk7XG4gIHZhciBueCA9IHRoaXMueC5yZWRNdWwoZWUpLnJlZElTdWIoeXl1NCk7XG4gIG54ID0gbngucmVkSUFkZChueCk7XG4gIG54ID0gbngucmVkSUFkZChueCk7XG4gIC8vIFkzID0gOCAqIFkxICogKFUgKiAoVCAtIFUpIC0gRSAqIEVFKVxuICB2YXIgbnkgPSB0aGlzLnkucmVkTXVsKHUucmVkTXVsKHQucmVkSVN1Yih1KSkucmVkSVN1YihlLnJlZE11bChlZSkpKTtcbiAgbnkgPSBueS5yZWRJQWRkKG55KTtcbiAgbnkgPSBueS5yZWRJQWRkKG55KTtcbiAgbnkgPSBueS5yZWRJQWRkKG55KTtcbiAgLy8gWjMgPSAoWjEgKyBFKV4yIC0gWlogLSBFRVxuICB2YXIgbnogPSB0aGlzLnoucmVkQWRkKGUpLnJlZFNxcigpLnJlZElTdWIoenopLnJlZElTdWIoZWUpO1xuXG4gIHJldHVybiB0aGlzLmN1cnZlLmpwb2ludChueCwgbnksIG56KTtcbn07XG5cbkpQb2ludC5wcm90b3R5cGUubXVsID0gZnVuY3Rpb24gbXVsKGssIGtiYXNlKSB7XG4gIGsgPSBuZXcgQk4oaywga2Jhc2UpO1xuXG4gIHJldHVybiB0aGlzLmN1cnZlLl93bmFmTXVsKHRoaXMsIGspO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS5lcSA9IGZ1bmN0aW9uIGVxKHApIHtcbiAgaWYgKHAudHlwZSA9PT0gJ2FmZmluZScpXG4gICAgcmV0dXJuIHRoaXMuZXEocC50b0ooKSk7XG5cbiAgaWYgKHRoaXMgPT09IHApXG4gICAgcmV0dXJuIHRydWU7XG5cbiAgLy8geDEgKiB6Ml4yID09IHgyICogejFeMlxuICB2YXIgejIgPSB0aGlzLnoucmVkU3FyKCk7XG4gIHZhciBwejIgPSBwLnoucmVkU3FyKCk7XG4gIGlmICh0aGlzLngucmVkTXVsKHB6MikucmVkSVN1YihwLngucmVkTXVsKHoyKSkuY21wbigwKSAhPT0gMClcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgLy8geTEgKiB6Ml4zID09IHkyICogejFeM1xuICB2YXIgejMgPSB6Mi5yZWRNdWwodGhpcy56KTtcbiAgdmFyIHB6MyA9IHB6Mi5yZWRNdWwocC56KTtcbiAgcmV0dXJuIHRoaXMueS5yZWRNdWwocHozKS5yZWRJU3ViKHAueS5yZWRNdWwoejMpKS5jbXBuKDApID09PSAwO1xufTtcblxuSlBvaW50LnByb3RvdHlwZS5lcVhUb1AgPSBmdW5jdGlvbiBlcVhUb1AoeCkge1xuICB2YXIgenMgPSB0aGlzLnoucmVkU3FyKCk7XG4gIHZhciByeCA9IHgudG9SZWQodGhpcy5jdXJ2ZS5yZWQpLnJlZE11bCh6cyk7XG4gIGlmICh0aGlzLnguY21wKHJ4KSA9PT0gMClcbiAgICByZXR1cm4gdHJ1ZTtcblxuICB2YXIgeGMgPSB4LmNsb25lKCk7XG4gIHZhciB0ID0gdGhpcy5jdXJ2ZS5yZWROLnJlZE11bCh6cyk7XG4gIGZvciAoOzspIHtcbiAgICB4Yy5pYWRkKHRoaXMuY3VydmUubik7XG4gICAgaWYgKHhjLmNtcCh0aGlzLmN1cnZlLnApID49IDApXG4gICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICByeC5yZWRJQWRkKHQpO1xuICAgIGlmICh0aGlzLnguY21wKHJ4KSA9PT0gMClcbiAgICAgIHJldHVybiB0cnVlO1xuICB9XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0KCkge1xuICBpZiAodGhpcy5pc0luZmluaXR5KCkpXG4gICAgcmV0dXJuICc8RUMgSlBvaW50IEluZmluaXR5Pic7XG4gIHJldHVybiAnPEVDIEpQb2ludCB4OiAnICsgdGhpcy54LnRvU3RyaW5nKDE2LCAyKSArXG4gICAgICAnIHk6ICcgKyB0aGlzLnkudG9TdHJpbmcoMTYsIDIpICtcbiAgICAgICcgejogJyArIHRoaXMuei50b1N0cmluZygxNiwgMikgKyAnPic7XG59O1xuXG5KUG9pbnQucHJvdG90eXBlLmlzSW5maW5pdHkgPSBmdW5jdGlvbiBpc0luZmluaXR5KCkge1xuICAvLyBYWFggVGhpcyBjb2RlIGFzc3VtZXMgdGhhdCB6ZXJvIGlzIGFsd2F5cyB6ZXJvIGluIHJlZFxuICByZXR1cm4gdGhpcy56LmNtcG4oMCkgPT09IDA7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgY3VydmVzID0gZXhwb3J0cztcblxudmFyIGhhc2ggPSByZXF1aXJlKCdoYXNoLmpzJyk7XG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCcuLi9lbGxpcHRpYycpO1xuXG52YXIgYXNzZXJ0ID0gZWxsaXB0aWMudXRpbHMuYXNzZXJ0O1xuXG5mdW5jdGlvbiBQcmVzZXRDdXJ2ZShvcHRpb25zKSB7XG4gIGlmIChvcHRpb25zLnR5cGUgPT09ICdzaG9ydCcpXG4gICAgdGhpcy5jdXJ2ZSA9IG5ldyBlbGxpcHRpYy5jdXJ2ZS5zaG9ydChvcHRpb25zKTtcbiAgZWxzZSBpZiAob3B0aW9ucy50eXBlID09PSAnZWR3YXJkcycpXG4gICAgdGhpcy5jdXJ2ZSA9IG5ldyBlbGxpcHRpYy5jdXJ2ZS5lZHdhcmRzKG9wdGlvbnMpO1xuICBlbHNlXG4gICAgdGhpcy5jdXJ2ZSA9IG5ldyBlbGxpcHRpYy5jdXJ2ZS5tb250KG9wdGlvbnMpO1xuICB0aGlzLmcgPSB0aGlzLmN1cnZlLmc7XG4gIHRoaXMubiA9IHRoaXMuY3VydmUubjtcbiAgdGhpcy5oYXNoID0gb3B0aW9ucy5oYXNoO1xuXG4gIGFzc2VydCh0aGlzLmcudmFsaWRhdGUoKSwgJ0ludmFsaWQgY3VydmUnKTtcbiAgYXNzZXJ0KHRoaXMuZy5tdWwodGhpcy5uKS5pc0luZmluaXR5KCksICdJbnZhbGlkIGN1cnZlLCBHKk4gIT0gTycpO1xufVxuY3VydmVzLlByZXNldEN1cnZlID0gUHJlc2V0Q3VydmU7XG5cbmZ1bmN0aW9uIGRlZmluZUN1cnZlKG5hbWUsIG9wdGlvbnMpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGN1cnZlcywgbmFtZSwge1xuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgY3VydmUgPSBuZXcgUHJlc2V0Q3VydmUob3B0aW9ucyk7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3VydmVzLCBuYW1lLCB7XG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgdmFsdWU6IGN1cnZlXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBjdXJ2ZTtcbiAgICB9XG4gIH0pO1xufVxuXG5kZWZpbmVDdXJ2ZSgncDE5MicsIHtcbiAgdHlwZTogJ3Nob3J0JyxcbiAgcHJpbWU6ICdwMTkyJyxcbiAgcDogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZlIGZmZmZmZmZmIGZmZmZmZmZmJyxcbiAgYTogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZlIGZmZmZmZmZmIGZmZmZmZmZjJyxcbiAgYjogJzY0MjEwNTE5IGU1OWM4MGU3IDBmYTdlOWFiIDcyMjQzMDQ5IGZlYjhkZWVjIGMxNDZiOWIxJyxcbiAgbjogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIDk5ZGVmODM2IDE0NmJjOWIxIGI0ZDIyODMxJyxcbiAgaGFzaDogaGFzaC5zaGEyNTYsXG4gIGdSZWQ6IGZhbHNlLFxuICBnOiBbXG4gICAgJzE4OGRhODBlIGIwMzA5MGY2IDdjYmYyMGViIDQzYTE4ODAwIGY0ZmYwYWZkIDgyZmYxMDEyJyxcbiAgICAnMDcxOTJiOTUgZmZjOGRhNzggNjMxMDExZWQgNmIyNGNkZDUgNzNmOTc3YTEgMWU3OTQ4MTEnXG4gIF1cbn0pO1xuXG5kZWZpbmVDdXJ2ZSgncDIyNCcsIHtcbiAgdHlwZTogJ3Nob3J0JyxcbiAgcHJpbWU6ICdwMjI0JyxcbiAgcDogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIDAwMDAwMDAwIDAwMDAwMDAwIDAwMDAwMDAxJyxcbiAgYTogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZlIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZlJyxcbiAgYjogJ2I0MDUwYTg1IDBjMDRiM2FiIGY1NDEzMjU2IDUwNDRiMGI3IGQ3YmZkOGJhIDI3MGIzOTQzIDIzNTVmZmI0JyxcbiAgbjogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmYxNmEyIGUwYjhmMDNlIDEzZGQyOTQ1IDVjNWMyYTNkJyxcbiAgaGFzaDogaGFzaC5zaGEyNTYsXG4gIGdSZWQ6IGZhbHNlLFxuICBnOiBbXG4gICAgJ2I3MGUwY2JkIDZiYjRiZjdmIDMyMTM5MGI5IDRhMDNjMWQzIDU2YzIxMTIyIDM0MzI4MGQ2IDExNWMxZDIxJyxcbiAgICAnYmQzNzYzODggYjVmNzIzZmIgNGMyMmRmZTYgY2Q0Mzc1YTAgNWEwNzQ3NjQgNDRkNTgxOTkgODUwMDdlMzQnXG4gIF1cbn0pO1xuXG5kZWZpbmVDdXJ2ZSgncDI1NicsIHtcbiAgdHlwZTogJ3Nob3J0JyxcbiAgcHJpbWU6IG51bGwsXG4gIHA6ICdmZmZmZmZmZiAwMDAwMDAwMSAwMDAwMDAwMCAwMDAwMDAwMCAwMDAwMDAwMCBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZicsXG4gIGE6ICdmZmZmZmZmZiAwMDAwMDAwMSAwMDAwMDAwMCAwMDAwMDAwMCAwMDAwMDAwMCBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmYycsXG4gIGI6ICc1YWM2MzVkOCBhYTNhOTNlNyBiM2ViYmQ1NSA3Njk4ODZiYyA2NTFkMDZiMCBjYzUzYjBmNiAzYmNlM2MzZSAyN2QyNjA0YicsXG4gIG46ICdmZmZmZmZmZiAwMDAwMDAwMCBmZmZmZmZmZiBmZmZmZmZmZiBiY2U2ZmFhZCBhNzE3OWU4NCBmM2I5Y2FjMiBmYzYzMjU1MScsXG4gIGhhc2g6IGhhc2guc2hhMjU2LFxuICBnUmVkOiBmYWxzZSxcbiAgZzogW1xuICAgICc2YjE3ZDFmMiBlMTJjNDI0NyBmOGJjZTZlNSA2M2E0NDBmMiA3NzAzN2Q4MSAyZGViMzNhMCBmNGExMzk0NSBkODk4YzI5NicsXG4gICAgJzRmZTM0MmUyIGZlMWE3ZjliIDhlZTdlYjRhIDdjMGY5ZTE2IDJiY2UzMzU3IDZiMzE1ZWNlIGNiYjY0MDY4IDM3YmY1MWY1J1xuICBdXG59KTtcblxuZGVmaW5lQ3VydmUoJ3AzODQnLCB7XG4gIHR5cGU6ICdzaG9ydCcsXG4gIHByaW1lOiBudWxsLFxuICBwOiAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgJyArXG4gICAgICdmZmZmZmZmZSBmZmZmZmZmZiAwMDAwMDAwMCAwMDAwMDAwMCBmZmZmZmZmZicsXG4gIGE6ICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiAnICtcbiAgICAgJ2ZmZmZmZmZlIGZmZmZmZmZmIDAwMDAwMDAwIDAwMDAwMDAwIGZmZmZmZmZjJyxcbiAgYjogJ2IzMzEyZmE3IGUyM2VlN2U0IDk4OGUwNTZiIGUzZjgyZDE5IDE4MWQ5YzZlIGZlODE0MTEyIDAzMTQwODhmICcgK1xuICAgICAnNTAxMzg3NWEgYzY1NjM5OGQgOGEyZWQxOWQgMmE4NWM4ZWQgZDNlYzJhZWYnLFxuICBuOiAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgYzc2MzRkODEgJyArXG4gICAgICdmNDM3MmRkZiA1ODFhMGRiMiA0OGIwYTc3YSBlY2VjMTk2YSBjY2M1Mjk3MycsXG4gIGhhc2g6IGhhc2guc2hhMzg0LFxuICBnUmVkOiBmYWxzZSxcbiAgZzogW1xuICAgICdhYTg3Y2EyMiBiZThiMDUzNyA4ZWIxYzcxZSBmMzIwYWQ3NCA2ZTFkM2I2MiA4YmE3OWI5OCA1OWY3NDFlMCA4MjU0MmEzOCAnICtcbiAgICAnNTUwMmYyNWQgYmY1NTI5NmMgM2E1NDVlMzggNzI3NjBhYjcnLFxuICAgICczNjE3ZGU0YSA5NjI2MmM2ZiA1ZDllOThiZiA5MjkyZGMyOSBmOGY0MWRiZCAyODlhMTQ3YyBlOWRhMzExMyBiNWYwYjhjMCAnICtcbiAgICAnMGE2MGIxY2UgMWQ3ZTgxOWQgN2E0MzFkN2MgOTBlYTBlNWYnXG4gIF1cbn0pO1xuXG5kZWZpbmVDdXJ2ZSgncDUyMScsIHtcbiAgdHlwZTogJ3Nob3J0JyxcbiAgcHJpbWU6IG51bGwsXG4gIHA6ICcwMDAwMDFmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiAnICtcbiAgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmICcgK1xuICAgICAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYnLFxuICBhOiAnMDAwMDAxZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgJyArXG4gICAgICdmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiAnICtcbiAgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZjJyxcbiAgYjogJzAwMDAwMDUxIDk1M2ViOTYxIDhlMWM5YTFmIDkyOWEyMWEwIGI2ODU0MGVlIGEyZGE3MjViICcgK1xuICAgICAnOTliMzE1ZjMgYjhiNDg5OTEgOGVmMTA5ZTEgNTYxOTM5NTEgZWM3ZTkzN2IgMTY1MmMwYmQgJyArXG4gICAgICczYmIxYmYwNyAzNTczZGY4OCAzZDJjMzRmMSBlZjQ1MWZkNCA2YjUwM2YwMCcsXG4gIG46ICcwMDAwMDFmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiBmZmZmZmZmZiAnICtcbiAgICAgJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZhIDUxODY4NzgzIGJmMmY5NjZiIDdmY2MwMTQ4ICcgK1xuICAgICAnZjcwOWE1ZDAgM2JiNWM5YjggODk5YzQ3YWUgYmI2ZmI3MWUgOTEzODY0MDknLFxuICBoYXNoOiBoYXNoLnNoYTUxMixcbiAgZ1JlZDogZmFsc2UsXG4gIGc6IFtcbiAgICAnMDAwMDAwYzYgODU4ZTA2YjcgMDQwNGU5Y2QgOWUzZWNiNjYgMjM5NWI0NDIgOWM2NDgxMzkgJyArXG4gICAgJzA1M2ZiNTIxIGY4MjhhZjYwIDZiNGQzZGJhIGExNGI1ZTc3IGVmZTc1OTI4IGZlMWRjMTI3ICcgK1xuICAgICdhMmZmYThkZSAzMzQ4YjNjMSA4NTZhNDI5YiBmOTdlN2UzMSBjMmU1YmQ2NicsXG4gICAgJzAwMDAwMTE4IDM5Mjk2YTc4IDlhM2JjMDA0IDVjOGE1ZmI0IDJjN2QxYmQ5IDk4ZjU0NDQ5ICcgK1xuICAgICc1NzliNDQ2OCAxN2FmYmQxNyAyNzNlNjYyYyA5N2VlNzI5OSA1ZWY0MjY0MCBjNTUwYjkwMSAnICtcbiAgICAnM2ZhZDA3NjEgMzUzYzcwODYgYTI3MmMyNDAgODhiZTk0NzYgOWZkMTY2NTAnXG4gIF1cbn0pO1xuXG5kZWZpbmVDdXJ2ZSgnY3VydmUyNTUxOScsIHtcbiAgdHlwZTogJ21vbnQnLFxuICBwcmltZTogJ3AyNTUxOScsXG4gIHA6ICc3ZmZmZmZmZmZmZmZmZmZmIGZmZmZmZmZmZmZmZmZmZmYgZmZmZmZmZmZmZmZmZmZmZiBmZmZmZmZmZmZmZmZmZmVkJyxcbiAgYTogJzc2ZDA2JyxcbiAgYjogJzEnLFxuICBuOiAnMTAwMDAwMDAwMDAwMDAwMCAwMDAwMDAwMDAwMDAwMDAwIDE0ZGVmOWRlYTJmNzljZDYgNTgxMjYzMWE1Y2Y1ZDNlZCcsXG4gIGhhc2g6IGhhc2guc2hhMjU2LFxuICBnUmVkOiBmYWxzZSxcbiAgZzogW1xuICAgICc5J1xuICBdXG59KTtcblxuZGVmaW5lQ3VydmUoJ2VkMjU1MTknLCB7XG4gIHR5cGU6ICdlZHdhcmRzJyxcbiAgcHJpbWU6ICdwMjU1MTknLFxuICBwOiAnN2ZmZmZmZmZmZmZmZmZmZiBmZmZmZmZmZmZmZmZmZmZmIGZmZmZmZmZmZmZmZmZmZmYgZmZmZmZmZmZmZmZmZmZlZCcsXG4gIGE6ICctMScsXG4gIGM6ICcxJyxcbiAgLy8gLTEyMTY2NSAqICgxMjE2NjZeKC0xKSkgKG1vZCBQKVxuICBkOiAnNTIwMzZjZWUyYjZmZmU3MyA4Y2M3NDA3OTc3NzllODk4IDAwNzAwYTRkNDE0MWQ4YWIgNzVlYjRkY2ExMzU5NzhhMycsXG4gIG46ICcxMDAwMDAwMDAwMDAwMDAwIDAwMDAwMDAwMDAwMDAwMDAgMTRkZWY5ZGVhMmY3OWNkNiA1ODEyNjMxYTVjZjVkM2VkJyxcbiAgaGFzaDogaGFzaC5zaGEyNTYsXG4gIGdSZWQ6IGZhbHNlLFxuICBnOiBbXG4gICAgJzIxNjkzNmQzY2Q2ZTUzZmVjMGE0ZTIzMWZkZDZkYzVjNjkyY2M3NjA5NTI1YTdiMmM5NTYyZDYwOGYyNWQ1MWEnLFxuXG4gICAgLy8gNC81XG4gICAgJzY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NTgnXG4gIF1cbn0pO1xuXG52YXIgcHJlO1xudHJ5IHtcbiAgcHJlID0gcmVxdWlyZSgnLi9wcmVjb21wdXRlZC9zZWNwMjU2azEnKTtcbn0gY2F0Y2ggKGUpIHtcbiAgcHJlID0gdW5kZWZpbmVkO1xufVxuXG5kZWZpbmVDdXJ2ZSgnc2VjcDI1NmsxJywge1xuICB0eXBlOiAnc2hvcnQnLFxuICBwcmltZTogJ2syNTYnLFxuICBwOiAnZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmYgZmZmZmZmZmUgZmZmZmZjMmYnLFxuICBhOiAnMCcsXG4gIGI6ICc3JyxcbiAgbjogJ2ZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZmIGZmZmZmZmZlIGJhYWVkY2U2IGFmNDhhMDNiIGJmZDI1ZThjIGQwMzY0MTQxJyxcbiAgaDogJzEnLFxuICBoYXNoOiBoYXNoLnNoYTI1NixcblxuICAvLyBQcmVjb21wdXRlZCBlbmRvbW9ycGhpc21cbiAgYmV0YTogJzdhZTk2YTJiNjU3YzA3MTA2ZTY0NDc5ZWFjMzQzNGU5OWNmMDQ5NzUxMmY1ODk5NWMxMzk2YzI4NzE5NTAxZWUnLFxuICBsYW1iZGE6ICc1MzYzYWQ0Y2MwNWMzMGUwYTUyNjFjMDI4ODEyNjQ1YTEyMmUyMmVhMjA4MTY2NzhkZjAyOTY3YzFiMjNiZDcyJyxcbiAgYmFzaXM6IFtcbiAgICB7XG4gICAgICBhOiAnMzA4NmQyMjFhN2Q0NmJjZGU4NmM5MGU0OTI4NGViMTUnLFxuICAgICAgYjogJy1lNDQzN2VkNjAxMGU4ODI4NmY1NDdmYTkwYWJmZTRjMydcbiAgICB9LFxuICAgIHtcbiAgICAgIGE6ICcxMTRjYTUwZjdhOGUyZjNmNjU3YzExMDhkOWQ0NGNmZDgnLFxuICAgICAgYjogJzMwODZkMjIxYTdkNDZiY2RlODZjOTBlNDkyODRlYjE1J1xuICAgIH1cbiAgXSxcblxuICBnUmVkOiBmYWxzZSxcbiAgZzogW1xuICAgICc3OWJlNjY3ZWY5ZGNiYmFjNTVhMDYyOTVjZTg3MGIwNzAyOWJmY2RiMmRjZTI4ZDk1OWYyODE1YjE2ZjgxNzk4JyxcbiAgICAnNDgzYWRhNzcyNmEzYzQ2NTVkYTRmYmZjMGUxMTA4YThmZDE3YjQ0OGE2ODU1NDE5OWM0N2QwOGZmYjEwZDRiOCcsXG4gICAgcHJlXG4gIF1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIEhtYWNEUkJHID0gcmVxdWlyZSgnaG1hYy1kcmJnJyk7XG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCcuLi8uLi9lbGxpcHRpYycpO1xudmFyIHV0aWxzID0gZWxsaXB0aWMudXRpbHM7XG52YXIgYXNzZXJ0ID0gdXRpbHMuYXNzZXJ0O1xuXG52YXIgS2V5UGFpciA9IHJlcXVpcmUoJy4va2V5Jyk7XG52YXIgU2lnbmF0dXJlID0gcmVxdWlyZSgnLi9zaWduYXR1cmUnKTtcblxuZnVuY3Rpb24gRUMob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgRUMpKVxuICAgIHJldHVybiBuZXcgRUMob3B0aW9ucyk7XG5cbiAgLy8gU2hvcnRjdXQgYGVsbGlwdGljLmVjKGN1cnZlLW5hbWUpYFxuICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdzdHJpbmcnKSB7XG4gICAgYXNzZXJ0KGVsbGlwdGljLmN1cnZlcy5oYXNPd25Qcm9wZXJ0eShvcHRpb25zKSwgJ1Vua25vd24gY3VydmUgJyArIG9wdGlvbnMpO1xuXG4gICAgb3B0aW9ucyA9IGVsbGlwdGljLmN1cnZlc1tvcHRpb25zXTtcbiAgfVxuXG4gIC8vIFNob3J0Y3V0IGZvciBgZWxsaXB0aWMuZWMoZWxsaXB0aWMuY3VydmVzLmN1cnZlTmFtZSlgXG4gIGlmIChvcHRpb25zIGluc3RhbmNlb2YgZWxsaXB0aWMuY3VydmVzLlByZXNldEN1cnZlKVxuICAgIG9wdGlvbnMgPSB7IGN1cnZlOiBvcHRpb25zIH07XG5cbiAgdGhpcy5jdXJ2ZSA9IG9wdGlvbnMuY3VydmUuY3VydmU7XG4gIHRoaXMubiA9IHRoaXMuY3VydmUubjtcbiAgdGhpcy5uaCA9IHRoaXMubi51c2hybigxKTtcbiAgdGhpcy5nID0gdGhpcy5jdXJ2ZS5nO1xuXG4gIC8vIFBvaW50IG9uIGN1cnZlXG4gIHRoaXMuZyA9IG9wdGlvbnMuY3VydmUuZztcbiAgdGhpcy5nLnByZWNvbXB1dGUob3B0aW9ucy5jdXJ2ZS5uLmJpdExlbmd0aCgpICsgMSk7XG5cbiAgLy8gSGFzaCBmb3IgZnVuY3Rpb24gZm9yIERSQkdcbiAgdGhpcy5oYXNoID0gb3B0aW9ucy5oYXNoIHx8IG9wdGlvbnMuY3VydmUuaGFzaDtcbn1cbm1vZHVsZS5leHBvcnRzID0gRUM7XG5cbkVDLnByb3RvdHlwZS5rZXlQYWlyID0gZnVuY3Rpb24ga2V5UGFpcihvcHRpb25zKSB7XG4gIHJldHVybiBuZXcgS2V5UGFpcih0aGlzLCBvcHRpb25zKTtcbn07XG5cbkVDLnByb3RvdHlwZS5rZXlGcm9tUHJpdmF0ZSA9IGZ1bmN0aW9uIGtleUZyb21Qcml2YXRlKHByaXYsIGVuYykge1xuICByZXR1cm4gS2V5UGFpci5mcm9tUHJpdmF0ZSh0aGlzLCBwcml2LCBlbmMpO1xufTtcblxuRUMucHJvdG90eXBlLmtleUZyb21QdWJsaWMgPSBmdW5jdGlvbiBrZXlGcm9tUHVibGljKHB1YiwgZW5jKSB7XG4gIHJldHVybiBLZXlQYWlyLmZyb21QdWJsaWModGhpcywgcHViLCBlbmMpO1xufTtcblxuRUMucHJvdG90eXBlLmdlbktleVBhaXIgPSBmdW5jdGlvbiBnZW5LZXlQYWlyKG9wdGlvbnMpIHtcbiAgaWYgKCFvcHRpb25zKVxuICAgIG9wdGlvbnMgPSB7fTtcblxuICAvLyBJbnN0YW50aWF0ZSBIbWFjX0RSQkdcbiAgdmFyIGRyYmcgPSBuZXcgSG1hY0RSQkcoe1xuICAgIGhhc2g6IHRoaXMuaGFzaCxcbiAgICBwZXJzOiBvcHRpb25zLnBlcnMsXG4gICAgcGVyc0VuYzogb3B0aW9ucy5wZXJzRW5jIHx8ICd1dGY4JyxcbiAgICBlbnRyb3B5OiBvcHRpb25zLmVudHJvcHkgfHwgZWxsaXB0aWMucmFuZCh0aGlzLmhhc2guaG1hY1N0cmVuZ3RoKSxcbiAgICBlbnRyb3B5RW5jOiBvcHRpb25zLmVudHJvcHkgJiYgb3B0aW9ucy5lbnRyb3B5RW5jIHx8ICd1dGY4JyxcbiAgICBub25jZTogdGhpcy5uLnRvQXJyYXkoKVxuICB9KTtcblxuICB2YXIgYnl0ZXMgPSB0aGlzLm4uYnl0ZUxlbmd0aCgpO1xuICB2YXIgbnMyID0gdGhpcy5uLnN1YihuZXcgQk4oMikpO1xuICBkbyB7XG4gICAgdmFyIHByaXYgPSBuZXcgQk4oZHJiZy5nZW5lcmF0ZShieXRlcykpO1xuICAgIGlmIChwcml2LmNtcChuczIpID4gMClcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgcHJpdi5pYWRkbigxKTtcbiAgICByZXR1cm4gdGhpcy5rZXlGcm9tUHJpdmF0ZShwcml2KTtcbiAgfSB3aGlsZSAodHJ1ZSk7XG59O1xuXG5FQy5wcm90b3R5cGUuX3RydW5jYXRlVG9OID0gZnVuY3Rpb24gdHJ1bmNhdGVUb04obXNnLCB0cnVuY09ubHkpIHtcbiAgdmFyIGRlbHRhID0gbXNnLmJ5dGVMZW5ndGgoKSAqIDggLSB0aGlzLm4uYml0TGVuZ3RoKCk7XG4gIGlmIChkZWx0YSA+IDApXG4gICAgbXNnID0gbXNnLnVzaHJuKGRlbHRhKTtcbiAgaWYgKCF0cnVuY09ubHkgJiYgbXNnLmNtcCh0aGlzLm4pID49IDApXG4gICAgcmV0dXJuIG1zZy5zdWIodGhpcy5uKTtcbiAgZWxzZVxuICAgIHJldHVybiBtc2c7XG59O1xuXG5FQy5wcm90b3R5cGUuc2lnbiA9IGZ1bmN0aW9uIHNpZ24obXNnLCBrZXksIGVuYywgb3B0aW9ucykge1xuICBpZiAodHlwZW9mIGVuYyA9PT0gJ29iamVjdCcpIHtcbiAgICBvcHRpb25zID0gZW5jO1xuICAgIGVuYyA9IG51bGw7XG4gIH1cbiAgaWYgKCFvcHRpb25zKVxuICAgIG9wdGlvbnMgPSB7fTtcblxuICBrZXkgPSB0aGlzLmtleUZyb21Qcml2YXRlKGtleSwgZW5jKTtcbiAgbXNnID0gdGhpcy5fdHJ1bmNhdGVUb04obmV3IEJOKG1zZywgMTYpKTtcblxuICAvLyBaZXJvLWV4dGVuZCBrZXkgdG8gcHJvdmlkZSBlbm91Z2ggZW50cm9weVxuICB2YXIgYnl0ZXMgPSB0aGlzLm4uYnl0ZUxlbmd0aCgpO1xuICB2YXIgYmtleSA9IGtleS5nZXRQcml2YXRlKCkudG9BcnJheSgnYmUnLCBieXRlcyk7XG5cbiAgLy8gWmVyby1leHRlbmQgbm9uY2UgdG8gaGF2ZSB0aGUgc2FtZSBieXRlIHNpemUgYXMgTlxuICB2YXIgbm9uY2UgPSBtc2cudG9BcnJheSgnYmUnLCBieXRlcyk7XG5cbiAgLy8gSW5zdGFudGlhdGUgSG1hY19EUkJHXG4gIHZhciBkcmJnID0gbmV3IEhtYWNEUkJHKHtcbiAgICBoYXNoOiB0aGlzLmhhc2gsXG4gICAgZW50cm9weTogYmtleSxcbiAgICBub25jZTogbm9uY2UsXG4gICAgcGVyczogb3B0aW9ucy5wZXJzLFxuICAgIHBlcnNFbmM6IG9wdGlvbnMucGVyc0VuYyB8fCAndXRmOCdcbiAgfSk7XG5cbiAgLy8gTnVtYmVyIG9mIGJ5dGVzIHRvIGdlbmVyYXRlXG4gIHZhciBuczEgPSB0aGlzLm4uc3ViKG5ldyBCTigxKSk7XG5cbiAgZm9yICh2YXIgaXRlciA9IDA7IHRydWU7IGl0ZXIrKykge1xuICAgIHZhciBrID0gb3B0aW9ucy5rID9cbiAgICAgICAgb3B0aW9ucy5rKGl0ZXIpIDpcbiAgICAgICAgbmV3IEJOKGRyYmcuZ2VuZXJhdGUodGhpcy5uLmJ5dGVMZW5ndGgoKSkpO1xuICAgIGsgPSB0aGlzLl90cnVuY2F0ZVRvTihrLCB0cnVlKTtcbiAgICBpZiAoay5jbXBuKDEpIDw9IDAgfHwgay5jbXAobnMxKSA+PSAwKVxuICAgICAgY29udGludWU7XG5cbiAgICB2YXIga3AgPSB0aGlzLmcubXVsKGspO1xuICAgIGlmIChrcC5pc0luZmluaXR5KCkpXG4gICAgICBjb250aW51ZTtcblxuICAgIHZhciBrcFggPSBrcC5nZXRYKCk7XG4gICAgdmFyIHIgPSBrcFgudW1vZCh0aGlzLm4pO1xuICAgIGlmIChyLmNtcG4oMCkgPT09IDApXG4gICAgICBjb250aW51ZTtcblxuICAgIHZhciBzID0gay5pbnZtKHRoaXMubikubXVsKHIubXVsKGtleS5nZXRQcml2YXRlKCkpLmlhZGQobXNnKSk7XG4gICAgcyA9IHMudW1vZCh0aGlzLm4pO1xuICAgIGlmIChzLmNtcG4oMCkgPT09IDApXG4gICAgICBjb250aW51ZTtcblxuICAgIHZhciByZWNvdmVyeVBhcmFtID0gKGtwLmdldFkoKS5pc09kZCgpID8gMSA6IDApIHxcbiAgICAgICAgICAgICAgICAgICAgICAgIChrcFguY21wKHIpICE9PSAwID8gMiA6IDApO1xuXG4gICAgLy8gVXNlIGNvbXBsZW1lbnQgb2YgYHNgLCBpZiBpdCBpcyA+IGBuIC8gMmBcbiAgICBpZiAob3B0aW9ucy5jYW5vbmljYWwgJiYgcy5jbXAodGhpcy5uaCkgPiAwKSB7XG4gICAgICBzID0gdGhpcy5uLnN1YihzKTtcbiAgICAgIHJlY292ZXJ5UGFyYW0gXj0gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFNpZ25hdHVyZSh7IHI6IHIsIHM6IHMsIHJlY292ZXJ5UGFyYW06IHJlY292ZXJ5UGFyYW0gfSk7XG4gIH1cbn07XG5cbkVDLnByb3RvdHlwZS52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobXNnLCBzaWduYXR1cmUsIGtleSwgZW5jKSB7XG4gIG1zZyA9IHRoaXMuX3RydW5jYXRlVG9OKG5ldyBCTihtc2csIDE2KSk7XG4gIGtleSA9IHRoaXMua2V5RnJvbVB1YmxpYyhrZXksIGVuYyk7XG4gIHNpZ25hdHVyZSA9IG5ldyBTaWduYXR1cmUoc2lnbmF0dXJlLCAnaGV4Jyk7XG5cbiAgLy8gUGVyZm9ybSBwcmltaXRpdmUgdmFsdWVzIHZhbGlkYXRpb25cbiAgdmFyIHIgPSBzaWduYXR1cmUucjtcbiAgdmFyIHMgPSBzaWduYXR1cmUucztcbiAgaWYgKHIuY21wbigxKSA8IDAgfHwgci5jbXAodGhpcy5uKSA+PSAwKVxuICAgIHJldHVybiBmYWxzZTtcbiAgaWYgKHMuY21wbigxKSA8IDAgfHwgcy5jbXAodGhpcy5uKSA+PSAwKVxuICAgIHJldHVybiBmYWxzZTtcblxuICAvLyBWYWxpZGF0ZSBzaWduYXR1cmVcbiAgdmFyIHNpbnYgPSBzLmludm0odGhpcy5uKTtcbiAgdmFyIHUxID0gc2ludi5tdWwobXNnKS51bW9kKHRoaXMubik7XG4gIHZhciB1MiA9IHNpbnYubXVsKHIpLnVtb2QodGhpcy5uKTtcblxuICBpZiAoIXRoaXMuY3VydmUuX21heHdlbGxUcmljaykge1xuICAgIHZhciBwID0gdGhpcy5nLm11bEFkZCh1MSwga2V5LmdldFB1YmxpYygpLCB1Mik7XG4gICAgaWYgKHAuaXNJbmZpbml0eSgpKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgcmV0dXJuIHAuZ2V0WCgpLnVtb2QodGhpcy5uKS5jbXAocikgPT09IDA7XG4gIH1cblxuICAvLyBOT1RFOiBHcmVnIE1heHdlbGwncyB0cmljaywgaW5zcGlyZWQgYnk6XG4gIC8vIGh0dHBzOi8vZ2l0LmlvL3ZhZDNLXG5cbiAgdmFyIHAgPSB0aGlzLmcuam11bEFkZCh1MSwga2V5LmdldFB1YmxpYygpLCB1Mik7XG4gIGlmIChwLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgLy8gQ29tcGFyZSBgcC54YCBvZiBKYWNvYmlhbiBwb2ludCB3aXRoIGByYCxcbiAgLy8gdGhpcyB3aWxsIGRvIGBwLnggPT0gciAqIHAuel4yYCBpbnN0ZWFkIG9mIG11bHRpcGx5aW5nIGBwLnhgIGJ5IHRoZVxuICAvLyBpbnZlcnNlIG9mIGBwLnpeMmBcbiAgcmV0dXJuIHAuZXFYVG9QKHIpO1xufTtcblxuRUMucHJvdG90eXBlLnJlY292ZXJQdWJLZXkgPSBmdW5jdGlvbihtc2csIHNpZ25hdHVyZSwgaiwgZW5jKSB7XG4gIGFzc2VydCgoMyAmIGopID09PSBqLCAnVGhlIHJlY292ZXJ5IHBhcmFtIGlzIG1vcmUgdGhhbiB0d28gYml0cycpO1xuICBzaWduYXR1cmUgPSBuZXcgU2lnbmF0dXJlKHNpZ25hdHVyZSwgZW5jKTtcblxuICB2YXIgbiA9IHRoaXMubjtcbiAgdmFyIGUgPSBuZXcgQk4obXNnKTtcbiAgdmFyIHIgPSBzaWduYXR1cmUucjtcbiAgdmFyIHMgPSBzaWduYXR1cmUucztcblxuICAvLyBBIHNldCBMU0Igc2lnbmlmaWVzIHRoYXQgdGhlIHktY29vcmRpbmF0ZSBpcyBvZGRcbiAgdmFyIGlzWU9kZCA9IGogJiAxO1xuICB2YXIgaXNTZWNvbmRLZXkgPSBqID4+IDE7XG4gIGlmIChyLmNtcCh0aGlzLmN1cnZlLnAudW1vZCh0aGlzLmN1cnZlLm4pKSA+PSAwICYmIGlzU2Vjb25kS2V5KVxuICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGZpbmQgc2VuY29uZCBrZXkgY2FuZGluYXRlJyk7XG5cbiAgLy8gMS4xLiBMZXQgeCA9IHIgKyBqbi5cbiAgaWYgKGlzU2Vjb25kS2V5KVxuICAgIHIgPSB0aGlzLmN1cnZlLnBvaW50RnJvbVgoci5hZGQodGhpcy5jdXJ2ZS5uKSwgaXNZT2RkKTtcbiAgZWxzZVxuICAgIHIgPSB0aGlzLmN1cnZlLnBvaW50RnJvbVgociwgaXNZT2RkKTtcblxuICB2YXIgckludiA9IHNpZ25hdHVyZS5yLmludm0obik7XG4gIHZhciBzMSA9IG4uc3ViKGUpLm11bChySW52KS51bW9kKG4pO1xuICB2YXIgczIgPSBzLm11bChySW52KS51bW9kKG4pO1xuXG4gIC8vIDEuNi4xIENvbXB1dGUgUSA9IHJeLTEgKHNSIC0gIGVHKVxuICAvLyAgICAgICAgICAgICAgIFEgPSByXi0xIChzUiArIC1lRylcbiAgcmV0dXJuIHRoaXMuZy5tdWxBZGQoczEsIHIsIHMyKTtcbn07XG5cbkVDLnByb3RvdHlwZS5nZXRLZXlSZWNvdmVyeVBhcmFtID0gZnVuY3Rpb24oZSwgc2lnbmF0dXJlLCBRLCBlbmMpIHtcbiAgc2lnbmF0dXJlID0gbmV3IFNpZ25hdHVyZShzaWduYXR1cmUsIGVuYyk7XG4gIGlmIChzaWduYXR1cmUucmVjb3ZlcnlQYXJhbSAhPT0gbnVsbClcbiAgICByZXR1cm4gc2lnbmF0dXJlLnJlY292ZXJ5UGFyYW07XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICB2YXIgUXByaW1lO1xuICAgIHRyeSB7XG4gICAgICBRcHJpbWUgPSB0aGlzLnJlY292ZXJQdWJLZXkoZSwgc2lnbmF0dXJlLCBpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoUXByaW1lLmVxKFEpKVxuICAgICAgcmV0dXJuIGk7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZmluZCB2YWxpZCByZWNvdmVyeSBmYWN0b3InKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCcuLi8uLi9lbGxpcHRpYycpO1xudmFyIHV0aWxzID0gZWxsaXB0aWMudXRpbHM7XG52YXIgYXNzZXJ0ID0gdXRpbHMuYXNzZXJ0O1xuXG5mdW5jdGlvbiBLZXlQYWlyKGVjLCBvcHRpb25zKSB7XG4gIHRoaXMuZWMgPSBlYztcbiAgdGhpcy5wcml2ID0gbnVsbDtcbiAgdGhpcy5wdWIgPSBudWxsO1xuXG4gIC8vIEtleVBhaXIoZWMsIHsgcHJpdjogLi4uLCBwdWI6IC4uLiB9KVxuICBpZiAob3B0aW9ucy5wcml2KVxuICAgIHRoaXMuX2ltcG9ydFByaXZhdGUob3B0aW9ucy5wcml2LCBvcHRpb25zLnByaXZFbmMpO1xuICBpZiAob3B0aW9ucy5wdWIpXG4gICAgdGhpcy5faW1wb3J0UHVibGljKG9wdGlvbnMucHViLCBvcHRpb25zLnB1YkVuYyk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEtleVBhaXI7XG5cbktleVBhaXIuZnJvbVB1YmxpYyA9IGZ1bmN0aW9uIGZyb21QdWJsaWMoZWMsIHB1YiwgZW5jKSB7XG4gIGlmIChwdWIgaW5zdGFuY2VvZiBLZXlQYWlyKVxuICAgIHJldHVybiBwdWI7XG5cbiAgcmV0dXJuIG5ldyBLZXlQYWlyKGVjLCB7XG4gICAgcHViOiBwdWIsXG4gICAgcHViRW5jOiBlbmNcbiAgfSk7XG59O1xuXG5LZXlQYWlyLmZyb21Qcml2YXRlID0gZnVuY3Rpb24gZnJvbVByaXZhdGUoZWMsIHByaXYsIGVuYykge1xuICBpZiAocHJpdiBpbnN0YW5jZW9mIEtleVBhaXIpXG4gICAgcmV0dXJuIHByaXY7XG5cbiAgcmV0dXJuIG5ldyBLZXlQYWlyKGVjLCB7XG4gICAgcHJpdjogcHJpdixcbiAgICBwcml2RW5jOiBlbmNcbiAgfSk7XG59O1xuXG5LZXlQYWlyLnByb3RvdHlwZS52YWxpZGF0ZSA9IGZ1bmN0aW9uIHZhbGlkYXRlKCkge1xuICB2YXIgcHViID0gdGhpcy5nZXRQdWJsaWMoKTtcblxuICBpZiAocHViLmlzSW5maW5pdHkoKSlcbiAgICByZXR1cm4geyByZXN1bHQ6IGZhbHNlLCByZWFzb246ICdJbnZhbGlkIHB1YmxpYyBrZXknIH07XG4gIGlmICghcHViLnZhbGlkYXRlKCkpXG4gICAgcmV0dXJuIHsgcmVzdWx0OiBmYWxzZSwgcmVhc29uOiAnUHVibGljIGtleSBpcyBub3QgYSBwb2ludCcgfTtcbiAgaWYgKCFwdWIubXVsKHRoaXMuZWMuY3VydmUubikuaXNJbmZpbml0eSgpKVxuICAgIHJldHVybiB7IHJlc3VsdDogZmFsc2UsIHJlYXNvbjogJ1B1YmxpYyBrZXkgKiBOICE9IE8nIH07XG5cbiAgcmV0dXJuIHsgcmVzdWx0OiB0cnVlLCByZWFzb246IG51bGwgfTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLmdldFB1YmxpYyA9IGZ1bmN0aW9uIGdldFB1YmxpYyhjb21wYWN0LCBlbmMpIHtcbiAgLy8gY29tcGFjdCBpcyBvcHRpb25hbCBhcmd1bWVudFxuICBpZiAodHlwZW9mIGNvbXBhY3QgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jID0gY29tcGFjdDtcbiAgICBjb21wYWN0ID0gbnVsbDtcbiAgfVxuXG4gIGlmICghdGhpcy5wdWIpXG4gICAgdGhpcy5wdWIgPSB0aGlzLmVjLmcubXVsKHRoaXMucHJpdik7XG5cbiAgaWYgKCFlbmMpXG4gICAgcmV0dXJuIHRoaXMucHViO1xuXG4gIHJldHVybiB0aGlzLnB1Yi5lbmNvZGUoZW5jLCBjb21wYWN0KTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLmdldFByaXZhdGUgPSBmdW5jdGlvbiBnZXRQcml2YXRlKGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdGhpcy5wcml2LnRvU3RyaW5nKDE2LCAyKTtcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzLnByaXY7XG59O1xuXG5LZXlQYWlyLnByb3RvdHlwZS5faW1wb3J0UHJpdmF0ZSA9IGZ1bmN0aW9uIF9pbXBvcnRQcml2YXRlKGtleSwgZW5jKSB7XG4gIHRoaXMucHJpdiA9IG5ldyBCTihrZXksIGVuYyB8fCAxNik7XG5cbiAgLy8gRW5zdXJlIHRoYXQgdGhlIHByaXYgd29uJ3QgYmUgYmlnZ2VyIHRoYW4gbiwgb3RoZXJ3aXNlIHdlIG1heSBmYWlsXG4gIC8vIGluIGZpeGVkIG11bHRpcGxpY2F0aW9uIG1ldGhvZFxuICB0aGlzLnByaXYgPSB0aGlzLnByaXYudW1vZCh0aGlzLmVjLmN1cnZlLm4pO1xufTtcblxuS2V5UGFpci5wcm90b3R5cGUuX2ltcG9ydFB1YmxpYyA9IGZ1bmN0aW9uIF9pbXBvcnRQdWJsaWMoa2V5LCBlbmMpIHtcbiAgaWYgKGtleS54IHx8IGtleS55KSB7XG4gICAgLy8gTW9udGdvbWVyeSBwb2ludHMgb25seSBoYXZlIGFuIGB4YCBjb29yZGluYXRlLlxuICAgIC8vIFdlaWVyc3RyYXNzL0Vkd2FyZHMgcG9pbnRzIG9uIHRoZSBvdGhlciBoYW5kIGhhdmUgYm90aCBgeGAgYW5kXG4gICAgLy8gYHlgIGNvb3JkaW5hdGVzLlxuICAgIGlmICh0aGlzLmVjLmN1cnZlLnR5cGUgPT09ICdtb250Jykge1xuICAgICAgYXNzZXJ0KGtleS54LCAnTmVlZCB4IGNvb3JkaW5hdGUnKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZWMuY3VydmUudHlwZSA9PT0gJ3Nob3J0JyB8fFxuICAgICAgICAgICAgICAgdGhpcy5lYy5jdXJ2ZS50eXBlID09PSAnZWR3YXJkcycpIHtcbiAgICAgIGFzc2VydChrZXkueCAmJiBrZXkueSwgJ05lZWQgYm90aCB4IGFuZCB5IGNvb3JkaW5hdGUnKTtcbiAgICB9XG4gICAgdGhpcy5wdWIgPSB0aGlzLmVjLmN1cnZlLnBvaW50KGtleS54LCBrZXkueSk7XG4gICAgcmV0dXJuO1xuICB9XG4gIHRoaXMucHViID0gdGhpcy5lYy5jdXJ2ZS5kZWNvZGVQb2ludChrZXksIGVuYyk7XG59O1xuXG4vLyBFQ0RIXG5LZXlQYWlyLnByb3RvdHlwZS5kZXJpdmUgPSBmdW5jdGlvbiBkZXJpdmUocHViKSB7XG4gIHJldHVybiBwdWIubXVsKHRoaXMucHJpdikuZ2V0WCgpO1xufTtcblxuLy8gRUNEU0FcbktleVBhaXIucHJvdG90eXBlLnNpZ24gPSBmdW5jdGlvbiBzaWduKG1zZywgZW5jLCBvcHRpb25zKSB7XG4gIHJldHVybiB0aGlzLmVjLnNpZ24obXNnLCB0aGlzLCBlbmMsIG9wdGlvbnMpO1xufTtcblxuS2V5UGFpci5wcm90b3R5cGUudmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1zZywgc2lnbmF0dXJlKSB7XG4gIHJldHVybiB0aGlzLmVjLnZlcmlmeShtc2csIHNpZ25hdHVyZSwgdGhpcyk7XG59O1xuXG5LZXlQYWlyLnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgcmV0dXJuICc8S2V5IHByaXY6ICcgKyAodGhpcy5wcml2ICYmIHRoaXMucHJpdi50b1N0cmluZygxNiwgMikpICtcbiAgICAgICAgICcgcHViOiAnICsgKHRoaXMucHViICYmIHRoaXMucHViLmluc3BlY3QoKSkgKyAnID4nO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEJOID0gcmVxdWlyZSgnYm4uanMnKTtcblxudmFyIGVsbGlwdGljID0gcmVxdWlyZSgnLi4vLi4vZWxsaXB0aWMnKTtcbnZhciB1dGlscyA9IGVsbGlwdGljLnV0aWxzO1xudmFyIGFzc2VydCA9IHV0aWxzLmFzc2VydDtcblxuZnVuY3Rpb24gU2lnbmF0dXJlKG9wdGlvbnMsIGVuYykge1xuICBpZiAob3B0aW9ucyBpbnN0YW5jZW9mIFNpZ25hdHVyZSlcbiAgICByZXR1cm4gb3B0aW9ucztcblxuICBpZiAodGhpcy5faW1wb3J0REVSKG9wdGlvbnMsIGVuYykpXG4gICAgcmV0dXJuO1xuXG4gIGFzc2VydChvcHRpb25zLnIgJiYgb3B0aW9ucy5zLCAnU2lnbmF0dXJlIHdpdGhvdXQgciBvciBzJyk7XG4gIHRoaXMuciA9IG5ldyBCTihvcHRpb25zLnIsIDE2KTtcbiAgdGhpcy5zID0gbmV3IEJOKG9wdGlvbnMucywgMTYpO1xuICBpZiAob3B0aW9ucy5yZWNvdmVyeVBhcmFtID09PSB1bmRlZmluZWQpXG4gICAgdGhpcy5yZWNvdmVyeVBhcmFtID0gbnVsbDtcbiAgZWxzZVxuICAgIHRoaXMucmVjb3ZlcnlQYXJhbSA9IG9wdGlvbnMucmVjb3ZlcnlQYXJhbTtcbn1cbm1vZHVsZS5leHBvcnRzID0gU2lnbmF0dXJlO1xuXG5mdW5jdGlvbiBQb3NpdGlvbigpIHtcbiAgdGhpcy5wbGFjZSA9IDA7XG59XG5cbmZ1bmN0aW9uIGdldExlbmd0aChidWYsIHApIHtcbiAgdmFyIGluaXRpYWwgPSBidWZbcC5wbGFjZSsrXTtcbiAgaWYgKCEoaW5pdGlhbCAmIDB4ODApKSB7XG4gICAgcmV0dXJuIGluaXRpYWw7XG4gIH1cbiAgdmFyIG9jdGV0TGVuID0gaW5pdGlhbCAmIDB4ZjtcbiAgdmFyIHZhbCA9IDA7XG4gIGZvciAodmFyIGkgPSAwLCBvZmYgPSBwLnBsYWNlOyBpIDwgb2N0ZXRMZW47IGkrKywgb2ZmKyspIHtcbiAgICB2YWwgPDw9IDg7XG4gICAgdmFsIHw9IGJ1ZltvZmZdO1xuICB9XG4gIHAucGxhY2UgPSBvZmY7XG4gIHJldHVybiB2YWw7XG59XG5cbmZ1bmN0aW9uIHJtUGFkZGluZyhidWYpIHtcbiAgdmFyIGkgPSAwO1xuICB2YXIgbGVuID0gYnVmLmxlbmd0aCAtIDE7XG4gIHdoaWxlICghYnVmW2ldICYmICEoYnVmW2kgKyAxXSAmIDB4ODApICYmIGkgPCBsZW4pIHtcbiAgICBpKys7XG4gIH1cbiAgaWYgKGkgPT09IDApIHtcbiAgICByZXR1cm4gYnVmO1xuICB9XG4gIHJldHVybiBidWYuc2xpY2UoaSk7XG59XG5cblNpZ25hdHVyZS5wcm90b3R5cGUuX2ltcG9ydERFUiA9IGZ1bmN0aW9uIF9pbXBvcnRERVIoZGF0YSwgZW5jKSB7XG4gIGRhdGEgPSB1dGlscy50b0FycmF5KGRhdGEsIGVuYyk7XG4gIHZhciBwID0gbmV3IFBvc2l0aW9uKCk7XG4gIGlmIChkYXRhW3AucGxhY2UrK10gIT09IDB4MzApIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIGxlbiA9IGdldExlbmd0aChkYXRhLCBwKTtcbiAgaWYgKChsZW4gKyBwLnBsYWNlKSAhPT0gZGF0YS5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGRhdGFbcC5wbGFjZSsrXSAhPT0gMHgwMikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgcmxlbiA9IGdldExlbmd0aChkYXRhLCBwKTtcbiAgdmFyIHIgPSBkYXRhLnNsaWNlKHAucGxhY2UsIHJsZW4gKyBwLnBsYWNlKTtcbiAgcC5wbGFjZSArPSBybGVuO1xuICBpZiAoZGF0YVtwLnBsYWNlKytdICE9PSAweDAyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBzbGVuID0gZ2V0TGVuZ3RoKGRhdGEsIHApO1xuICBpZiAoZGF0YS5sZW5ndGggIT09IHNsZW4gKyBwLnBsYWNlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBzID0gZGF0YS5zbGljZShwLnBsYWNlLCBzbGVuICsgcC5wbGFjZSk7XG4gIGlmIChyWzBdID09PSAwICYmIChyWzFdICYgMHg4MCkpIHtcbiAgICByID0gci5zbGljZSgxKTtcbiAgfVxuICBpZiAoc1swXSA9PT0gMCAmJiAoc1sxXSAmIDB4ODApKSB7XG4gICAgcyA9IHMuc2xpY2UoMSk7XG4gIH1cblxuICB0aGlzLnIgPSBuZXcgQk4ocik7XG4gIHRoaXMucyA9IG5ldyBCTihzKTtcbiAgdGhpcy5yZWNvdmVyeVBhcmFtID0gbnVsbDtcblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdExlbmd0aChhcnIsIGxlbikge1xuICBpZiAobGVuIDwgMHg4MCkge1xuICAgIGFyci5wdXNoKGxlbik7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBvY3RldHMgPSAxICsgKE1hdGgubG9nKGxlbikgLyBNYXRoLkxOMiA+Pj4gMyk7XG4gIGFyci5wdXNoKG9jdGV0cyB8IDB4ODApO1xuICB3aGlsZSAoLS1vY3RldHMpIHtcbiAgICBhcnIucHVzaCgobGVuID4+PiAob2N0ZXRzIDw8IDMpKSAmIDB4ZmYpO1xuICB9XG4gIGFyci5wdXNoKGxlbik7XG59XG5cblNpZ25hdHVyZS5wcm90b3R5cGUudG9ERVIgPSBmdW5jdGlvbiB0b0RFUihlbmMpIHtcbiAgdmFyIHIgPSB0aGlzLnIudG9BcnJheSgpO1xuICB2YXIgcyA9IHRoaXMucy50b0FycmF5KCk7XG5cbiAgLy8gUGFkIHZhbHVlc1xuICBpZiAoclswXSAmIDB4ODApXG4gICAgciA9IFsgMCBdLmNvbmNhdChyKTtcbiAgLy8gUGFkIHZhbHVlc1xuICBpZiAoc1swXSAmIDB4ODApXG4gICAgcyA9IFsgMCBdLmNvbmNhdChzKTtcblxuICByID0gcm1QYWRkaW5nKHIpO1xuICBzID0gcm1QYWRkaW5nKHMpO1xuXG4gIHdoaWxlICghc1swXSAmJiAhKHNbMV0gJiAweDgwKSkge1xuICAgIHMgPSBzLnNsaWNlKDEpO1xuICB9XG4gIHZhciBhcnIgPSBbIDB4MDIgXTtcbiAgY29uc3RydWN0TGVuZ3RoKGFyciwgci5sZW5ndGgpO1xuICBhcnIgPSBhcnIuY29uY2F0KHIpO1xuICBhcnIucHVzaCgweDAyKTtcbiAgY29uc3RydWN0TGVuZ3RoKGFyciwgcy5sZW5ndGgpO1xuICB2YXIgYmFja0hhbGYgPSBhcnIuY29uY2F0KHMpO1xuICB2YXIgcmVzID0gWyAweDMwIF07XG4gIGNvbnN0cnVjdExlbmd0aChyZXMsIGJhY2tIYWxmLmxlbmd0aCk7XG4gIHJlcyA9IHJlcy5jb25jYXQoYmFja0hhbGYpO1xuICByZXR1cm4gdXRpbHMuZW5jb2RlKHJlcywgZW5jKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNoID0gcmVxdWlyZSgnaGFzaC5qcycpO1xudmFyIGVsbGlwdGljID0gcmVxdWlyZSgnLi4vLi4vZWxsaXB0aWMnKTtcbnZhciB1dGlscyA9IGVsbGlwdGljLnV0aWxzO1xudmFyIGFzc2VydCA9IHV0aWxzLmFzc2VydDtcbnZhciBwYXJzZUJ5dGVzID0gdXRpbHMucGFyc2VCeXRlcztcbnZhciBLZXlQYWlyID0gcmVxdWlyZSgnLi9rZXknKTtcbnZhciBTaWduYXR1cmUgPSByZXF1aXJlKCcuL3NpZ25hdHVyZScpO1xuXG5mdW5jdGlvbiBFRERTQShjdXJ2ZSkge1xuICBhc3NlcnQoY3VydmUgPT09ICdlZDI1NTE5JywgJ29ubHkgdGVzdGVkIHdpdGggZWQyNTUxOSBzbyBmYXInKTtcblxuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgRUREU0EpKVxuICAgIHJldHVybiBuZXcgRUREU0EoY3VydmUpO1xuXG4gIHZhciBjdXJ2ZSA9IGVsbGlwdGljLmN1cnZlc1tjdXJ2ZV0uY3VydmU7XG4gIHRoaXMuY3VydmUgPSBjdXJ2ZTtcbiAgdGhpcy5nID0gY3VydmUuZztcbiAgdGhpcy5nLnByZWNvbXB1dGUoY3VydmUubi5iaXRMZW5ndGgoKSArIDEpO1xuXG4gIHRoaXMucG9pbnRDbGFzcyA9IGN1cnZlLnBvaW50KCkuY29uc3RydWN0b3I7XG4gIHRoaXMuZW5jb2RpbmdMZW5ndGggPSBNYXRoLmNlaWwoY3VydmUubi5iaXRMZW5ndGgoKSAvIDgpO1xuICB0aGlzLmhhc2ggPSBoYXNoLnNoYTUxMjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBFRERTQTtcblxuLyoqXG4qIEBwYXJhbSB7QXJyYXl8U3RyaW5nfSBtZXNzYWdlIC0gbWVzc2FnZSBieXRlc1xuKiBAcGFyYW0ge0FycmF5fFN0cmluZ3xLZXlQYWlyfSBzZWNyZXQgLSBzZWNyZXQgYnl0ZXMgb3IgYSBrZXlwYWlyXG4qIEByZXR1cm5zIHtTaWduYXR1cmV9IC0gc2lnbmF0dXJlXG4qL1xuRUREU0EucHJvdG90eXBlLnNpZ24gPSBmdW5jdGlvbiBzaWduKG1lc3NhZ2UsIHNlY3JldCkge1xuICBtZXNzYWdlID0gcGFyc2VCeXRlcyhtZXNzYWdlKTtcbiAgdmFyIGtleSA9IHRoaXMua2V5RnJvbVNlY3JldChzZWNyZXQpO1xuICB2YXIgciA9IHRoaXMuaGFzaEludChrZXkubWVzc2FnZVByZWZpeCgpLCBtZXNzYWdlKTtcbiAgdmFyIFIgPSB0aGlzLmcubXVsKHIpO1xuICB2YXIgUmVuY29kZWQgPSB0aGlzLmVuY29kZVBvaW50KFIpO1xuICB2YXIgc18gPSB0aGlzLmhhc2hJbnQoUmVuY29kZWQsIGtleS5wdWJCeXRlcygpLCBtZXNzYWdlKVxuICAgICAgICAgICAgICAgLm11bChrZXkucHJpdigpKTtcbiAgdmFyIFMgPSByLmFkZChzXykudW1vZCh0aGlzLmN1cnZlLm4pO1xuICByZXR1cm4gdGhpcy5tYWtlU2lnbmF0dXJlKHsgUjogUiwgUzogUywgUmVuY29kZWQ6IFJlbmNvZGVkIH0pO1xufTtcblxuLyoqXG4qIEBwYXJhbSB7QXJyYXl9IG1lc3NhZ2UgLSBtZXNzYWdlIGJ5dGVzXG4qIEBwYXJhbSB7QXJyYXl8U3RyaW5nfFNpZ25hdHVyZX0gc2lnIC0gc2lnIGJ5dGVzXG4qIEBwYXJhbSB7QXJyYXl8U3RyaW5nfFBvaW50fEtleVBhaXJ9IHB1YiAtIHB1YmxpYyBrZXlcbiogQHJldHVybnMge0Jvb2xlYW59IC0gdHJ1ZSBpZiBwdWJsaWMga2V5IG1hdGNoZXMgc2lnIG9mIG1lc3NhZ2VcbiovXG5FRERTQS5wcm90b3R5cGUudmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UsIHNpZywgcHViKSB7XG4gIG1lc3NhZ2UgPSBwYXJzZUJ5dGVzKG1lc3NhZ2UpO1xuICBzaWcgPSB0aGlzLm1ha2VTaWduYXR1cmUoc2lnKTtcbiAgdmFyIGtleSA9IHRoaXMua2V5RnJvbVB1YmxpYyhwdWIpO1xuICB2YXIgaCA9IHRoaXMuaGFzaEludChzaWcuUmVuY29kZWQoKSwga2V5LnB1YkJ5dGVzKCksIG1lc3NhZ2UpO1xuICB2YXIgU0cgPSB0aGlzLmcubXVsKHNpZy5TKCkpO1xuICB2YXIgUnBsdXNBaCA9IHNpZy5SKCkuYWRkKGtleS5wdWIoKS5tdWwoaCkpO1xuICByZXR1cm4gUnBsdXNBaC5lcShTRyk7XG59O1xuXG5FRERTQS5wcm90b3R5cGUuaGFzaEludCA9IGZ1bmN0aW9uIGhhc2hJbnQoKSB7XG4gIHZhciBoYXNoID0gdGhpcy5oYXNoKCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKVxuICAgIGhhc2gudXBkYXRlKGFyZ3VtZW50c1tpXSk7XG4gIHJldHVybiB1dGlscy5pbnRGcm9tTEUoaGFzaC5kaWdlc3QoKSkudW1vZCh0aGlzLmN1cnZlLm4pO1xufTtcblxuRUREU0EucHJvdG90eXBlLmtleUZyb21QdWJsaWMgPSBmdW5jdGlvbiBrZXlGcm9tUHVibGljKHB1Yikge1xuICByZXR1cm4gS2V5UGFpci5mcm9tUHVibGljKHRoaXMsIHB1Yik7XG59O1xuXG5FRERTQS5wcm90b3R5cGUua2V5RnJvbVNlY3JldCA9IGZ1bmN0aW9uIGtleUZyb21TZWNyZXQoc2VjcmV0KSB7XG4gIHJldHVybiBLZXlQYWlyLmZyb21TZWNyZXQodGhpcywgc2VjcmV0KTtcbn07XG5cbkVERFNBLnByb3RvdHlwZS5tYWtlU2lnbmF0dXJlID0gZnVuY3Rpb24gbWFrZVNpZ25hdHVyZShzaWcpIHtcbiAgaWYgKHNpZyBpbnN0YW5jZW9mIFNpZ25hdHVyZSlcbiAgICByZXR1cm4gc2lnO1xuICByZXR1cm4gbmV3IFNpZ25hdHVyZSh0aGlzLCBzaWcpO1xufTtcblxuLyoqXG4qICogaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL2RyYWZ0LWpvc2Vmc3Nvbi1lZGRzYS1lZDI1NTE5LTAzI3NlY3Rpb24tNS4yXG4qXG4qIEVERFNBIGRlZmluZXMgbWV0aG9kcyBmb3IgZW5jb2RpbmcgYW5kIGRlY29kaW5nIHBvaW50cyBhbmQgaW50ZWdlcnMuIFRoZXNlIGFyZVxuKiBoZWxwZXIgY29udmVuaWVuY2UgbWV0aG9kcywgdGhhdCBwYXNzIGFsb25nIHRvIHV0aWxpdHkgZnVuY3Rpb25zIGltcGxpZWRcbiogcGFyYW1ldGVycy5cbipcbiovXG5FRERTQS5wcm90b3R5cGUuZW5jb2RlUG9pbnQgPSBmdW5jdGlvbiBlbmNvZGVQb2ludChwb2ludCkge1xuICB2YXIgZW5jID0gcG9pbnQuZ2V0WSgpLnRvQXJyYXkoJ2xlJywgdGhpcy5lbmNvZGluZ0xlbmd0aCk7XG4gIGVuY1t0aGlzLmVuY29kaW5nTGVuZ3RoIC0gMV0gfD0gcG9pbnQuZ2V0WCgpLmlzT2RkKCkgPyAweDgwIDogMDtcbiAgcmV0dXJuIGVuYztcbn07XG5cbkVERFNBLnByb3RvdHlwZS5kZWNvZGVQb2ludCA9IGZ1bmN0aW9uIGRlY29kZVBvaW50KGJ5dGVzKSB7XG4gIGJ5dGVzID0gdXRpbHMucGFyc2VCeXRlcyhieXRlcyk7XG5cbiAgdmFyIGxhc3RJeCA9IGJ5dGVzLmxlbmd0aCAtIDE7XG4gIHZhciBub3JtZWQgPSBieXRlcy5zbGljZSgwLCBsYXN0SXgpLmNvbmNhdChieXRlc1tsYXN0SXhdICYgfjB4ODApO1xuICB2YXIgeElzT2RkID0gKGJ5dGVzW2xhc3RJeF0gJiAweDgwKSAhPT0gMDtcblxuICB2YXIgeSA9IHV0aWxzLmludEZyb21MRShub3JtZWQpO1xuICByZXR1cm4gdGhpcy5jdXJ2ZS5wb2ludEZyb21ZKHksIHhJc09kZCk7XG59O1xuXG5FRERTQS5wcm90b3R5cGUuZW5jb2RlSW50ID0gZnVuY3Rpb24gZW5jb2RlSW50KG51bSkge1xuICByZXR1cm4gbnVtLnRvQXJyYXkoJ2xlJywgdGhpcy5lbmNvZGluZ0xlbmd0aCk7XG59O1xuXG5FRERTQS5wcm90b3R5cGUuZGVjb2RlSW50ID0gZnVuY3Rpb24gZGVjb2RlSW50KGJ5dGVzKSB7XG4gIHJldHVybiB1dGlscy5pbnRGcm9tTEUoYnl0ZXMpO1xufTtcblxuRUREU0EucHJvdG90eXBlLmlzUG9pbnQgPSBmdW5jdGlvbiBpc1BvaW50KHZhbCkge1xuICByZXR1cm4gdmFsIGluc3RhbmNlb2YgdGhpcy5wb2ludENsYXNzO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGVsbGlwdGljID0gcmVxdWlyZSgnLi4vLi4vZWxsaXB0aWMnKTtcbnZhciB1dGlscyA9IGVsbGlwdGljLnV0aWxzO1xudmFyIGFzc2VydCA9IHV0aWxzLmFzc2VydDtcbnZhciBwYXJzZUJ5dGVzID0gdXRpbHMucGFyc2VCeXRlcztcbnZhciBjYWNoZWRQcm9wZXJ0eSA9IHV0aWxzLmNhY2hlZFByb3BlcnR5O1xuXG4vKipcbiogQHBhcmFtIHtFRERTQX0gZWRkc2EgLSBpbnN0YW5jZVxuKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zIC0gcHVibGljL3ByaXZhdGUga2V5IHBhcmFtZXRlcnNcbipcbiogQHBhcmFtIHtBcnJheTxCeXRlPn0gW3BhcmFtcy5zZWNyZXRdIC0gc2VjcmV0IHNlZWQgYnl0ZXNcbiogQHBhcmFtIHtQb2ludH0gW3BhcmFtcy5wdWJdIC0gcHVibGljIGtleSBwb2ludCAoYWthIGBBYCBpbiBlZGRzYSB0ZXJtcylcbiogQHBhcmFtIHtBcnJheTxCeXRlPn0gW3BhcmFtcy5wdWJdIC0gcHVibGljIGtleSBwb2ludCBlbmNvZGVkIGFzIGJ5dGVzXG4qXG4qL1xuZnVuY3Rpb24gS2V5UGFpcihlZGRzYSwgcGFyYW1zKSB7XG4gIHRoaXMuZWRkc2EgPSBlZGRzYTtcbiAgdGhpcy5fc2VjcmV0ID0gcGFyc2VCeXRlcyhwYXJhbXMuc2VjcmV0KTtcbiAgaWYgKGVkZHNhLmlzUG9pbnQocGFyYW1zLnB1YikpXG4gICAgdGhpcy5fcHViID0gcGFyYW1zLnB1YjtcbiAgZWxzZVxuICAgIHRoaXMuX3B1YkJ5dGVzID0gcGFyc2VCeXRlcyhwYXJhbXMucHViKTtcbn1cblxuS2V5UGFpci5mcm9tUHVibGljID0gZnVuY3Rpb24gZnJvbVB1YmxpYyhlZGRzYSwgcHViKSB7XG4gIGlmIChwdWIgaW5zdGFuY2VvZiBLZXlQYWlyKVxuICAgIHJldHVybiBwdWI7XG4gIHJldHVybiBuZXcgS2V5UGFpcihlZGRzYSwgeyBwdWI6IHB1YiB9KTtcbn07XG5cbktleVBhaXIuZnJvbVNlY3JldCA9IGZ1bmN0aW9uIGZyb21TZWNyZXQoZWRkc2EsIHNlY3JldCkge1xuICBpZiAoc2VjcmV0IGluc3RhbmNlb2YgS2V5UGFpcilcbiAgICByZXR1cm4gc2VjcmV0O1xuICByZXR1cm4gbmV3IEtleVBhaXIoZWRkc2EsIHsgc2VjcmV0OiBzZWNyZXQgfSk7XG59O1xuXG5LZXlQYWlyLnByb3RvdHlwZS5zZWNyZXQgPSBmdW5jdGlvbiBzZWNyZXQoKSB7XG4gIHJldHVybiB0aGlzLl9zZWNyZXQ7XG59O1xuXG5jYWNoZWRQcm9wZXJ0eShLZXlQYWlyLCAncHViQnl0ZXMnLCBmdW5jdGlvbiBwdWJCeXRlcygpIHtcbiAgcmV0dXJuIHRoaXMuZWRkc2EuZW5jb2RlUG9pbnQodGhpcy5wdWIoKSk7XG59KTtcblxuY2FjaGVkUHJvcGVydHkoS2V5UGFpciwgJ3B1YicsIGZ1bmN0aW9uIHB1YigpIHtcbiAgaWYgKHRoaXMuX3B1YkJ5dGVzKVxuICAgIHJldHVybiB0aGlzLmVkZHNhLmRlY29kZVBvaW50KHRoaXMuX3B1YkJ5dGVzKTtcbiAgcmV0dXJuIHRoaXMuZWRkc2EuZy5tdWwodGhpcy5wcml2KCkpO1xufSk7XG5cbmNhY2hlZFByb3BlcnR5KEtleVBhaXIsICdwcml2Qnl0ZXMnLCBmdW5jdGlvbiBwcml2Qnl0ZXMoKSB7XG4gIHZhciBlZGRzYSA9IHRoaXMuZWRkc2E7XG4gIHZhciBoYXNoID0gdGhpcy5oYXNoKCk7XG4gIHZhciBsYXN0SXggPSBlZGRzYS5lbmNvZGluZ0xlbmd0aCAtIDE7XG5cbiAgdmFyIGEgPSBoYXNoLnNsaWNlKDAsIGVkZHNhLmVuY29kaW5nTGVuZ3RoKTtcbiAgYVswXSAmPSAyNDg7XG4gIGFbbGFzdEl4XSAmPSAxMjc7XG4gIGFbbGFzdEl4XSB8PSA2NDtcblxuICByZXR1cm4gYTtcbn0pO1xuXG5jYWNoZWRQcm9wZXJ0eShLZXlQYWlyLCAncHJpdicsIGZ1bmN0aW9uIHByaXYoKSB7XG4gIHJldHVybiB0aGlzLmVkZHNhLmRlY29kZUludCh0aGlzLnByaXZCeXRlcygpKTtcbn0pO1xuXG5jYWNoZWRQcm9wZXJ0eShLZXlQYWlyLCAnaGFzaCcsIGZ1bmN0aW9uIGhhc2goKSB7XG4gIHJldHVybiB0aGlzLmVkZHNhLmhhc2goKS51cGRhdGUodGhpcy5zZWNyZXQoKSkuZGlnZXN0KCk7XG59KTtcblxuY2FjaGVkUHJvcGVydHkoS2V5UGFpciwgJ21lc3NhZ2VQcmVmaXgnLCBmdW5jdGlvbiBtZXNzYWdlUHJlZml4KCkge1xuICByZXR1cm4gdGhpcy5oYXNoKCkuc2xpY2UodGhpcy5lZGRzYS5lbmNvZGluZ0xlbmd0aCk7XG59KTtcblxuS2V5UGFpci5wcm90b3R5cGUuc2lnbiA9IGZ1bmN0aW9uIHNpZ24obWVzc2FnZSkge1xuICBhc3NlcnQodGhpcy5fc2VjcmV0LCAnS2V5UGFpciBjYW4gb25seSB2ZXJpZnknKTtcbiAgcmV0dXJuIHRoaXMuZWRkc2Euc2lnbihtZXNzYWdlLCB0aGlzKTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlLCBzaWcpIHtcbiAgcmV0dXJuIHRoaXMuZWRkc2EudmVyaWZ5KG1lc3NhZ2UsIHNpZywgdGhpcyk7XG59O1xuXG5LZXlQYWlyLnByb3RvdHlwZS5nZXRTZWNyZXQgPSBmdW5jdGlvbiBnZXRTZWNyZXQoZW5jKSB7XG4gIGFzc2VydCh0aGlzLl9zZWNyZXQsICdLZXlQYWlyIGlzIHB1YmxpYyBvbmx5Jyk7XG4gIHJldHVybiB1dGlscy5lbmNvZGUodGhpcy5zZWNyZXQoKSwgZW5jKTtcbn07XG5cbktleVBhaXIucHJvdG90eXBlLmdldFB1YmxpYyA9IGZ1bmN0aW9uIGdldFB1YmxpYyhlbmMpIHtcbiAgcmV0dXJuIHV0aWxzLmVuY29kZSh0aGlzLnB1YkJ5dGVzKCksIGVuYyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEtleVBhaXI7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgZWxsaXB0aWMgPSByZXF1aXJlKCcuLi8uLi9lbGxpcHRpYycpO1xudmFyIHV0aWxzID0gZWxsaXB0aWMudXRpbHM7XG52YXIgYXNzZXJ0ID0gdXRpbHMuYXNzZXJ0O1xudmFyIGNhY2hlZFByb3BlcnR5ID0gdXRpbHMuY2FjaGVkUHJvcGVydHk7XG52YXIgcGFyc2VCeXRlcyA9IHV0aWxzLnBhcnNlQnl0ZXM7XG5cbi8qKlxuKiBAcGFyYW0ge0VERFNBfSBlZGRzYSAtIGVkZHNhIGluc3RhbmNlXG4qIEBwYXJhbSB7QXJyYXk8Qnl0ZXM+fE9iamVjdH0gc2lnIC1cbiogQHBhcmFtIHtBcnJheTxCeXRlcz58UG9pbnR9IFtzaWcuUl0gLSBSIHBvaW50IGFzIFBvaW50IG9yIGJ5dGVzXG4qIEBwYXJhbSB7QXJyYXk8Qnl0ZXM+fGJufSBbc2lnLlNdIC0gUyBzY2FsYXIgYXMgYm4gb3IgYnl0ZXNcbiogQHBhcmFtIHtBcnJheTxCeXRlcz59IFtzaWcuUmVuY29kZWRdIC0gUiBwb2ludCBlbmNvZGVkXG4qIEBwYXJhbSB7QXJyYXk8Qnl0ZXM+fSBbc2lnLlNlbmNvZGVkXSAtIFMgc2NhbGFyIGVuY29kZWRcbiovXG5mdW5jdGlvbiBTaWduYXR1cmUoZWRkc2EsIHNpZykge1xuICB0aGlzLmVkZHNhID0gZWRkc2E7XG5cbiAgaWYgKHR5cGVvZiBzaWcgIT09ICdvYmplY3QnKVxuICAgIHNpZyA9IHBhcnNlQnl0ZXMoc2lnKTtcblxuICBpZiAoQXJyYXkuaXNBcnJheShzaWcpKSB7XG4gICAgc2lnID0ge1xuICAgICAgUjogc2lnLnNsaWNlKDAsIGVkZHNhLmVuY29kaW5nTGVuZ3RoKSxcbiAgICAgIFM6IHNpZy5zbGljZShlZGRzYS5lbmNvZGluZ0xlbmd0aClcbiAgICB9O1xuICB9XG5cbiAgYXNzZXJ0KHNpZy5SICYmIHNpZy5TLCAnU2lnbmF0dXJlIHdpdGhvdXQgUiBvciBTJyk7XG5cbiAgaWYgKGVkZHNhLmlzUG9pbnQoc2lnLlIpKVxuICAgIHRoaXMuX1IgPSBzaWcuUjtcbiAgaWYgKHNpZy5TIGluc3RhbmNlb2YgQk4pXG4gICAgdGhpcy5fUyA9IHNpZy5TO1xuXG4gIHRoaXMuX1JlbmNvZGVkID0gQXJyYXkuaXNBcnJheShzaWcuUikgPyBzaWcuUiA6IHNpZy5SZW5jb2RlZDtcbiAgdGhpcy5fU2VuY29kZWQgPSBBcnJheS5pc0FycmF5KHNpZy5TKSA/IHNpZy5TIDogc2lnLlNlbmNvZGVkO1xufVxuXG5jYWNoZWRQcm9wZXJ0eShTaWduYXR1cmUsICdTJywgZnVuY3Rpb24gUygpIHtcbiAgcmV0dXJuIHRoaXMuZWRkc2EuZGVjb2RlSW50KHRoaXMuU2VuY29kZWQoKSk7XG59KTtcblxuY2FjaGVkUHJvcGVydHkoU2lnbmF0dXJlLCAnUicsIGZ1bmN0aW9uIFIoKSB7XG4gIHJldHVybiB0aGlzLmVkZHNhLmRlY29kZVBvaW50KHRoaXMuUmVuY29kZWQoKSk7XG59KTtcblxuY2FjaGVkUHJvcGVydHkoU2lnbmF0dXJlLCAnUmVuY29kZWQnLCBmdW5jdGlvbiBSZW5jb2RlZCgpIHtcbiAgcmV0dXJuIHRoaXMuZWRkc2EuZW5jb2RlUG9pbnQodGhpcy5SKCkpO1xufSk7XG5cbmNhY2hlZFByb3BlcnR5KFNpZ25hdHVyZSwgJ1NlbmNvZGVkJywgZnVuY3Rpb24gU2VuY29kZWQoKSB7XG4gIHJldHVybiB0aGlzLmVkZHNhLmVuY29kZUludCh0aGlzLlMoKSk7XG59KTtcblxuU2lnbmF0dXJlLnByb3RvdHlwZS50b0J5dGVzID0gZnVuY3Rpb24gdG9CeXRlcygpIHtcbiAgcmV0dXJuIHRoaXMuUmVuY29kZWQoKS5jb25jYXQodGhpcy5TZW5jb2RlZCgpKTtcbn07XG5cblNpZ25hdHVyZS5wcm90b3R5cGUudG9IZXggPSBmdW5jdGlvbiB0b0hleCgpIHtcbiAgcmV0dXJuIHV0aWxzLmVuY29kZSh0aGlzLnRvQnl0ZXMoKSwgJ2hleCcpLnRvVXBwZXJDYXNlKCk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFNpZ25hdHVyZTtcbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuICBkb3VibGVzOiB7XG4gICAgc3RlcDogNCxcbiAgICBwb2ludHM6IFtcbiAgICAgIFtcbiAgICAgICAgJ2U2MGZjZTkzYjU5ZTllYzUzMDExYWFiYzIxYzIzZTk3YjJhMzEzNjliODdhNWFlOWM0NGVlODllMmE2ZGVjMGEnLFxuICAgICAgICAnZjdlMzUwNzM5OWU1OTU5MjlkYjk5ZjM0ZjU3OTM3MTAxMjk2ODkxZTQ0ZDIzZjBiZTFmMzJjY2U2OTYxNjgyMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4MjgyMjYzMjEyYzYwOWQ5ZWEyYTZlM2UxNzJkZTIzOGQ4YzM5Y2FiZDVhYzFjYTEwNjQ2ZTIzZmQ1ZjUxNTA4JyxcbiAgICAgICAgJzExZjhhODA5ODU1N2RmZTQ1ZTgyNTZlODMwYjYwYWNlNjJkNjEzYWMyZjdiMTdiZWQzMWI2ZWFmZjZlMjZjYWYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMTc1ZTE1OWY3MjhiODY1YTcyZjk5Y2M2YzZmYzg0NmRlMGI5MzgzM2ZkMjIyMmVkNzNmY2U1YjU1MWU1YjczOScsXG4gICAgICAgICdkMzUwNmUwZDllM2M3OWViYTRlZjk3YTUxZmY3MWY1ZWFjYjU5NTVhZGQyNDM0NWM2ZWZhNmZmZWU5ZmVkNjk1J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzM2M2Q5MGQ0NDdiMDBjOWM5OWNlYWMwNWI2MjYyZWUwNTM0NDFjN2U1NTU1MmZmZTUyNmJhZDhmODNmZjQ2NDAnLFxuICAgICAgICAnNGUyNzNhZGZjNzMyMjIxOTUzYjQ0NTM5N2YzMzYzMTQ1YjlhODkwMDgxOTllY2I2MjAwM2M3ZjNiZWU5ZGU5J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzhiNGI1ZjE2NWRmM2MyYmU4YzYyNDRiNWI3NDU2Mzg4NDNlNGE3ODFhMTViY2QxYjY5Zjc5YTU1ZGZmZGY4MGMnLFxuICAgICAgICAnNGFhZDBhNmY2OGQzMDhiNGIzZmJkNzgxM2FiMGRhMDRmOWUzMzY1NDYxNjJlZTU2YjNlZmYwYzY1ZmQ0ZmQzNidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3MjNjYmFhNmU1ZGI5OTZkNmJmNzcxYzAwYmQ1NDhjN2I3MDBkYmZmYTZjMGU3N2JjYjYxMTU5MjUyMzJmY2RhJyxcbiAgICAgICAgJzk2ZTg2N2I1NTk1Y2M0OThhOTIxMTM3NDg4ODI0ZDZlMjY2MGEwNjUzNzc5NDk0ODAxZGMwNjlkOWViMzlmNWYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZWViZmE0ZDQ5M2JlYmY5OGJhNWZlZWM4MTJjMmQzYjUwOTQ3OTYxMjM3YTkxOTgzOWE1MzNlY2EwZTdkZDdmYScsXG4gICAgICAgICc1ZDlhOGNhMzk3MGVmMGYyNjllZTdlZGFmMTc4MDg5ZDlhZTRjZGMzYTcxMWY3MTJkZGZkNGZkYWUxZGU4OTk5J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzEwMGY0NGRhNjk2ZTcxNjcyNzkxZDBhMDliN2JkZTQ1OWYxMjE1YTI5YjNjMDNiZmVmZDc4MzViMzlhNDhkYjAnLFxuICAgICAgICAnY2RkOWUxMzE5MmEwMGI3NzJlYzhmMzMwMGMwOTA2NjZiN2ZmNGExOGZmNTE5NWFjMGZiZDVjZDYyYmM2NWEwOSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlMTAzMWJlMjYyYzdlZDFiMWRjOTIyN2E0YTA0YzAxN2E3N2Y4ZDQ0NjRmM2IzODUyYzhhY2RlNmU1MzRmZDJkJyxcbiAgICAgICAgJzlkNzA2MTkyODk0MDQwNWU2YmI2YTQxNzY1OTc1MzVhZjI5MmRkNDE5ZTFjZWQ3OWE0NGYxOGYyOTQ1NmEwMGQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZmVlYTZjYWU0NmQ1NWI1MzBhYzI4MzlmMTQzYmQ3ZWM1Y2Y4YjI2NmE0MWQ2YWY1MmQ1ZTY4OGQ5MDk0Njk2ZCcsXG4gICAgICAgICdlNTdjNmI2Yzk3ZGNlMWJhYjA2ZTRlMTJiZjNlY2Q1Yzk4MWM4OTU3Y2M0MTQ0MmQzMTU1ZGViZjE4MDkwMDg4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2RhNjdhOTFkOTEwNDljZGNiMzY3YmU0YmU2ZmZjYTNjZmVlZDY1N2Q4MDg1ODNkZTMzZmE5NzhiYzFlYzZjYjEnLFxuICAgICAgICAnOWJhY2FhMzU0ODE2NDJiYzQxZjQ2M2Y3ZWM5NzgwZTVkZWM3YWRjNTA4Zjc0MGExN2U5ZWE4ZTI3YTY4YmUxZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc1MzkwNGZhYTBiMzM0Y2RkYTZlMDAwOTM1ZWYyMjE1MWVjMDhkMGY3YmIxMTA2OWY1NzU0NWNjYzFhMzdiN2MwJyxcbiAgICAgICAgJzViYzA4N2QwYmM4MDEwNmQ4OGM5ZWNjYWMyMGQzYzFjMTM5OTk5ODFlMTQ0MzQ2OTlkY2IwOTZiMDIyNzcxYzgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOGU3YmNkMGJkMzU5ODNhNzcxOWNjYTc3NjRjYTkwNjc3OWI1M2EwNDNhOWI4YmNhZWZmOTU5ZjQzYWQ4NjA0NycsXG4gICAgICAgICcxMGI3NzcwYjJhM2RhNGIzOTQwMzEwNDIwY2E5NTE0NTc5ZTg4ZTJlNDdmZDY4YjNlYTEwMDQ3ZTg0NjAzNzJhJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzM4NWVlZDM0YzFjZGZmMjFlNmQwODE4Njg5YjgxYmRlNzFhN2Y0ZjE4Mzk3ZTY2OTBhODQxZTE1OTljNDM4NjInLFxuICAgICAgICAnMjgzYmViYzNlOGVhMjNmNTY3MDFkZTE5ZTllYmY0NTc2YjMwNGVlYzIwODZkYzhjYzA0NThmZTU1NDJlNTQ1MydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc2ZjlkOWI4MDNlY2YxOTE2MzdjNzNhNDQxM2RmYTE4MGZkZGY4NGE1OTQ3ZmJjOWM2MDZlZDg2YzNmYWMzYTcnLFxuICAgICAgICAnN2M4MGM2OGU2MDMwNTliYTY5YjhlMmEzMGU0NWM0ZDQ3ZWE0ZGQyZjVjMjgxMDAyZDg2ODkwNjAzYTg0MjE2MCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczMzIyZDQwMTI0M2M0ZTI1ODJhMjE0N2MxMDRkNmVjYmY3NzRkMTYzZGIwZjVlNTMxM2I3ZTBlNzQyZDBlNmJkJyxcbiAgICAgICAgJzU2ZTcwNzk3ZTk2NjRlZjViZmIwMTliYzRkZGFmOWI3MjgwNWY2M2VhMjg3M2FmNjI0ZjNhMmU5NmMyOGIyYTAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnODU2NzJjN2QyZGUwYjdkYTJiZDE3NzBkODk2NjU4Njg3NDFiM2Y5YWY3NjQzMzk3NzIxZDc0ZDI4MTM0YWI4MycsXG4gICAgICAgICc3YzQ4MWI5YjViNDNiMmViNjM3NDA0OWJmYTYyYzJlNWU3N2YxN2ZjYzUyOThmNDRjOGUzMDk0Zjc5MDMxM2E2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzk0OGJmODA5YjE5ODhhNDZiMDZjOWYxOTE5NDEzYjEwZjkyMjZjNjBmNjY4ODMyZmZkOTU5YWY2MGM4MmEwYScsXG4gICAgICAgICc1M2E1NjI4NTZkY2I2NjQ2ZGM2Yjc0YzVkMWMzNDE4YzZkNGRmZjA4Yzk3Y2QyYmVkNGNiN2Y4OGQ4YzhlNTg5J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzYyNjBjZTdmNDYxODAxYzM0ZjA2N2NlMGYwMjg3M2E4ZjFiMGU0NGRmYzY5NzUyYWNjZWNkODE5ZjM4ZmQ4ZTgnLFxuICAgICAgICAnYmMyZGE4MmI2ZmE1YjU3MWE3ZjA5MDQ5Nzc2YTFlZjdlY2QyOTIyMzgwNTFjMTk4YzFhODRlOTViMmI0YWUxNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlNTAzN2RlMGFmYzFkOGQ0M2Q4MzQ4NDE0YmJmNDEwMzA0M2VjOGY1NzViZmRjNDMyOTUzY2M4ZDIwMzdmYTJkJyxcbiAgICAgICAgJzQ1NzE1MzRiYWE5NGQzYjVmOWY5OGQwOWZiOTkwYmRkYmQ1ZjViMDNlYzQ4MWYxMGUwZTVkYzg0MWQ3NTViZGEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTA2MzcyYjBmNGEyMDdhZGY1ZWE5MDVlOGYxNzcxYjRlN2U4ZGJkMWM2YTZjNWI3MjU4NjZhMGFlNGZjZTcyNScsXG4gICAgICAgICc3YTkwODk3NGJjZTE4Y2ZlMTJhMjdiYjJhZDVhNDg4Y2Q3NDg0YTc3ODcxMDQ4NzBiMjcwMzRmOTRlZWUzMWRkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzIxM2M3YTcxNWNkNWQ0NTM1OGQwYmJmOWRjMGNlMDIyMDRiMTBiZGRlMmEzZjU4NTQwYWQ2OTA4ZDA1NTk3NTQnLFxuICAgICAgICAnNGI2ZGFkMGI1YWU0NjI1MDcwMTNhZDA2MjQ1YmExOTBiYjQ4NTBmNWYzNmE3ZWVkZGZmMmMyNzUzNGI0NThmMidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc0ZTdjMjcyYTdhZjRiMzRlOGRiYjkzNTJhNTQxOWE4N2UyODM4YzcwYWRjNjJjZGRmMGNjM2EzYjA4ZmJkNTNjJyxcbiAgICAgICAgJzE3NzQ5Yzc2NmM5ZDBiMThlMTZmZDA5ZjZkZWY2ODFiNTMwYjk2MTRiZmY3ZGQzM2UwYjM5NDE4MTdkY2FhZTYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZmVhNzRlM2RiZTc3OGIxYjEwZjIzOGFkNjE2ODZhYTVjNzZlM2RiMmJlNDMwNTc2MzI0MjdlMjg0MGZiMjdiNicsXG4gICAgICAgICc2ZTA1NjhkYjliMGIxMzI5N2NmNjc0ZGVjY2I2YWY5MzEyNmI1OTZiOTczZjdiNzc3MDFkM2RiN2YyM2NiOTZmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc2ZTY0MTEzZjY3N2NmMGUxMGEyNTcwZDU5OTk2OGQzMTU0NGUxNzliNzYwNDMyOTUyYzAyYTQ0MTdiZGRlMzknLFxuICAgICAgICAnYzkwZGRmOGRlZTRlOTVjZjU3NzA2NmQ3MDY4MWYwZDM1ZTJhMzNkMmI1NmQyMDMyYjRiMTc1MmQxOTAxYWMwMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdjNzM4YzU2YjAzYjJhYmUxZTgyODFiYWE3NDNmOGY5YThmN2NjNjQzZGYyNmNiZWUzYWIxNTAyNDJiY2JiODkxJyxcbiAgICAgICAgJzg5M2ZiNTc4OTUxYWQyNTM3ZjcxOGYyZWFjYmZiYmJiODIzMTRlZWY3ODgwY2ZlOTE3ZTczNWQ5Njk5YTg0YzMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDg5NTYyNjU0OGI2NWI4MWUyNjRjNzYzN2M5NzI4NzdkMWQ3MmU1ZjNhOTI1MDE0MzcyZTlmNjU4OGY2YzE0YicsXG4gICAgICAgICdmZWJmYWEzOGYyYmM3ZWFlNzI4ZWM2MDgxOGMzNDBlYjAzNDI4ZDYzMmJiMDY3ZTE3OTM2M2VkNzVkN2Q5OTFmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2I4ZGE5NDAzMmE5NTc1MThlYjBmNjQzMzU3MWU4NzYxY2VmZmM3MzY5M2U4NGVkZDQ5MTUwYTU2NGY2NzZlMDMnLFxuICAgICAgICAnMjgwNGRmYTQ0ODA1YTFlNGQ3Yzk5Y2M5NzYyODA4YjA5MmNjNTg0ZDk1ZmYzYjUxMTQ4OGU0ZTc0ZWZkZjZlNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlODBmZWExNDQ0MWZiMzNhN2Q4YWRhYjk0NzVkN2ZhYjIwMTllZmZiNTE1NmE3OTJmMWExMTc3OGUzYzBkZjVkJyxcbiAgICAgICAgJ2VlZDFkZTdmNjM4ZTAwNzcxZTg5NzY4Y2EzY2E5NDQ3MmQxNTVlODBhZjMyMmVhOWZjYjQyOTFiNmFjOWVjNzgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYTMwMTY5N2JkZmNkNzA0MzEzYmE0OGU1MWQ1Njc1NDNmMmExODIwMzFlZmQ2OTE1ZGRjMDdiYmNjNGUxNjA3MCcsXG4gICAgICAgICc3MzcwZjkxY2ZiNjdlNGY1MDgxODA5ZmEyNWQ0MGY5YjE3MzVkYmY3YzBhMTFhMTMwYzBkMWEwNDFlMTc3ZWExJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzkwYWQ4NWIzODlkNmI5MzY0NjNmOWQwNTEyNjc4ZGUyMDhjYzMzMGIxMTMwN2ZmZmFiN2FjNjNlM2ZiMDRlZDQnLFxuICAgICAgICAnZTUwN2EzNjIwYTM4MjYxYWZmZGNiZDk0MjcyMjJiODM5YWVmYWJlMTU4Mjg5NGQ5OTFkNGQ0OGNiNmVmMTUwJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzhmNjhiOWQyZjYzYjVmMzM5MjM5YzFhZDk4MWYxNjJlZTg4YzU2Nzg3MjNlYTMzNTFiN2I0NDRjOWVjNGMwZGEnLFxuICAgICAgICAnNjYyYTlmMmRiYTA2Mzk4NmRlMWQ5MGMyYjZiZTIxNWRiYmVhMmNmZTk1NTEwYmZkZjIzY2JmNzk1MDFmZmY4MidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlNGYzZmIwMTc2YWY4NWQ2NWZmOTlmZjkxOThjMzYwOTFmNDhlODY1MDM2ODFlM2U2Njg2ZmQ1MDUzMjMxZTExJyxcbiAgICAgICAgJzFlNjM2MzNhZDBlZjRmMWMxNjYxYTZkMGVhMDJiNzI4NmNjN2U3NGVjOTUxZDFjOTgyMmMzODU3NmZlYjczYmMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOGMwMGZhOWIxOGViZjMzMWViOTYxNTM3YTQ1YTQyNjZjNzAzNGYyZjBkNGUxZDA3MTZmYjZlYWUyMGVhZTI5ZScsXG4gICAgICAgICdlZmE0NzI2N2ZlYTUyMWExYTlkYzM0M2EzNzM2Yzk3NGMyZmFkYWZhODFlMzZjNTRlN2QyYTRjNjY3MDI0MTRiJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2U3YTI2Y2U2OWRkNDgyOWYzZTEwY2VjMGE5ZTk4ZWQzMTQzZDA4NGYzMDhiOTJjMDk5N2ZkZGZjNjBjYjNlNDEnLFxuICAgICAgICAnMmE3NThlMzAwZmE3OTg0YjQ3MWIwMDZhMWFhZmJiMThkMGE2YjJjMDQyMGU4M2UyMGU4YTk0MjFjZjJjZmQ1MSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdiNjQ1OWUwZWUzNjYyZWM4ZDIzNTQwYzIyM2JjYmRjNTcxY2JjYjk2N2Q3OTQyNGYzY2YyOWViM2RlNmI4MGVmJyxcbiAgICAgICAgJzY3Yzg3NmQwNmYzZTA2ZGUxZGFkZjE2ZTU2NjFkYjNjNGIzYWU2ZDQ4ZTM1YjJmZjMwYmYwYjYxYTcxYmE0NSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkNjhhODBjODI4MGJiODQwNzkzMjM0YWExMThmMDYyMzFkNmYxZmM2N2U3M2M1YTVkZWRhMGY1YjQ5Njk0M2U4JyxcbiAgICAgICAgJ2RiOGJhOWZmZjRiNTg2ZDAwYzRiMWY5MTc3YjBlMjhiNWIwZTdiOGY3ODQ1Mjk1YTI5NGM4NDI2NmIxMzMxMjAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzI0YWVkN2RmNjVjODA0MjUyZGMwMjcwOTA3YTMwYjA5NjEyYWViOTczNDQ5Y2VhNDA5NTk4MGZjMjhkM2Q1ZCcsXG4gICAgICAgICc2NDhhMzY1Nzc0YjYxZjJmZjEzMGMwYzM1YWVjMWY0ZjE5MjEzYjBjN2UzMzI4NDM5NjcyMjRhZjk2YWI3Yzg0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzRkZjljMTQ5MTljZGU2MWY2ZDUxZGZkYmU1ZmVlNWRjZWVjNDE0M2JhOGQxY2E4ODhlOGJkMzczZmQwNTRjOTYnLFxuICAgICAgICAnMzVlYzUxMDkyZDg3MjgwNTA5NzRjMjNhMWQ4NWQ0YjVkNTA2Y2RjMjg4NDkwMTkyZWJhYzA2Y2FkMTBkNWQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOWMzOTE5YTg0YTQ3NDg3MGZhZWQ4YTljMWNjNjYwMjE1MjM0ODkwNTRkN2YwMzA4Y2JmYzk5YzhhYzFmOThjZCcsXG4gICAgICAgICdkZGI4NGYwZjRhNGRkZDU3NTg0ZjA0NGJmMjYwZTY0MTkwNTMyNmY3NmM2NGM4ZTZiZTdlNWUwM2Q0ZmM1OTlkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzYwNTcxNzBiMWRkMTJmZGY4ZGUwNWYyODFkOGUwNmJiOTFlMTQ5M2E4YjkxZDRjYzVhMjEzODIxMjBhOTU5ZTUnLFxuICAgICAgICAnOWExYWYwYjI2YTZhNDgwN2FkZDlhMmRhZjcxZGYyNjI0NjUxNTJiYzNlZTI0YzY1ZTg5OWJlOTMyMzg1YTJhOCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhNTc2ZGY4ZTIzYTA4NDExNDIxNDM5YTQ1MThkYTMxODgwY2VmMGZiYTdkNGRmMTJiMWE2OTczZWVjYjk0MjY2JyxcbiAgICAgICAgJzQwYTZiZjIwZTc2NjQwYjJjOTJiOTdhZmU1OGNkODJjNDMyZTEwYTdmNTE0ZDlmM2VlOGJlMTFhZTFiMjhlYzgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzc3OGE3OGMyOGRlYzNlMzBhMDVmZTk2MjlkZThjMzhiYjMwZDFmNWNmOWEzYTIwOGY3NjM4ODliZTU4YWQ3MScsXG4gICAgICAgICczNDYyNmQ5YWI1YTViMjJmZjcwOThlMTJmMmZmNTgwMDg3YjM4NDExZmYyNGFjNTYzYjUxM2ZjMWZkOWY0M2FjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzkyODk1NWVlNjM3YTg0NDYzNzI5ZmQzMGU3YWZkMmVkNWY5NjI3NGU1YWQ3ZTVjYjA5ZWRhOWMwNmQ5MDNhYycsXG4gICAgICAgICdjMjU2MjEwMDNkM2Y0MmE4MjdiNzhhMTMwOTNhOTVlZWFjM2QyNmVmYThhOGQ4M2ZjNTE4MGU5MzViY2QwOTFmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzg1ZDBmZWYzZWM2ZGIxMDkzOTkwNjRmM2EwZTNiMjg1NTY0NWI0YTkwN2FkMzU0NTI3YWFlNzUxNjNkODI3NTEnLFxuICAgICAgICAnMWYwMzY0ODQxM2EzOGMwYmUyOWQ0OTZlNTgyY2Y1NjYzZTg3NTFlOTY4NzczMzE1ODJjMjM3YTI0ZWIxZjk2MidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdmZjJiMGRjZTk3ZWVjZTk3YzFjOWI2MDQxNzk4Yjg1ZGZkZmI2ZDg4ODJkYTIwMzA4ZjU0MDQ4MjQ1MjYwODdlJyxcbiAgICAgICAgJzQ5M2QxM2ZlZjUyNGJhMTg4YWY0YzRkYzU0ZDA3OTM2YzdiN2VkNmZiOTBlMmNlYjJjOTUxZTAxZjBjMjk5MDcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnODI3ZmJiZTRiMWU4ODBlYTllZDJiMmU2MzAxYjIxMmI1N2YxZWUxNDhjZDZkZDI4NzgwZTVlMmNmODU2ZTI0MScsXG4gICAgICAgICdjNjBmOWM5MjNjNzI3YjBiNzFiZWYyYzY3ZDFkMTI2ODdmZjdhNjMxODY5MDMxNjZkNjA1YjY4YmFlYzI5M2VjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2VhYTY0OWYyMWY1MWJkYmFlN2JlNGFlMzRjZTZlNTIxN2E1OGZkY2U3ZjQ3ZjlhYTdmM2I1OGZhMjEyMGUyYjMnLFxuICAgICAgICAnYmUzMjc5ZWQ1YmJiYjAzYWM2OWE4MGY4OTg3OWFhNWEwMWE2Yjk2NWYxM2Y3ZTU5ZDQ3YTUzMDViYTVhZDkzZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlNGE0MmQ0M2M1Y2YxNjlkOTM5MWRmNmRlY2Y0MmVlNTQxYjZkOGYwYzlhMTM3NDAxZTIzNjMyZGRhMzRkMjRmJyxcbiAgICAgICAgJzRkOWY5MmU3MTZkMWM3MzUyNmZjOTljY2ZiOGFkMzRjZTg4NmVlZGZhOGQ4ZTRmMTNhN2Y3MTMxZGViYTk0MTQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMWVjODBmZWYzNjBjYmRkOTU0MTYwZmFkYWIzNTJiNmI5MmI1MzU3NmE4OGZlYTQ5NDcxNzNiOWQ0MzAwYmYxOScsXG4gICAgICAgICdhZWVmZTkzNzU2YjUzNDBkMmYzYTQ5NThhN2FiYmY1ZTAxNDZlNzdmNjI5NWEwN2I2NzFjZGMxY2MxMDdjZWZkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzE0NmE3NzhjMDQ2NzBjMmY5MWIwMGFmNDY4MGRmYThiY2UzNDkwNzE3ZDU4YmE4ODlkZGI1OTI4MzY2NjQyYmUnLFxuICAgICAgICAnYjMxOGUwZWMzMzU0MDI4YWRkNjY5ODI3ZjlkNGIyODcwYWFhOTcxZDJmN2U1ZWQxZDBiMjk3NDgzZDgzZWZkMCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdmYTUwYzBmNjFkMjJlNWYwN2UzYWNlYmIxYWEwN2IxMjhkMDAxMjIwOWEyOGI5Nzc2ZDc2YTg3OTMxODBlZWY5JyxcbiAgICAgICAgJzZiODRjNjkyMjM5N2ViYTliNzJjZDI4NzIyODFhNjhhNWU2ODMyOTNhNTdhMjEzYjM4Y2Q4ZDdkM2Y0ZjI4MTEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZGExZDYxZDBjYTcyMWExMWIxYTViZjZiN2Q4OGU4NDIxYTI4OGFiNWQ1YmJhNTIyMGU1M2QzMmI1ZjA2N2VjMicsXG4gICAgICAgICc4MTU3ZjU1YTdjOTkzMDZjNzljMDc2NjE2MWM5MWUyOTY2YTczODk5ZDI3OWI0OGE2NTVmYmEwZjFhZDgzNmYxJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2E4ZTI4MmZmMGM5NzA2OTA3MjE1ZmY5OGU4ZmQ0MTY2MTUzMTFkZTA0NDZmMWUwNjJhNzNiMDYxMGQwNjRlMTMnLFxuICAgICAgICAnN2Y5NzM1NWI4ZGI4MWMwOWFiZmI3ZjNjNWIyNTE1ODg4YjY3OWEzZTUwZGQ2YmQ2Y2VmN2M3MzExMWY0Y2MwYydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxNzRhNTNiOWM5YTI4NTg3MmQzOWU1NmU2OTEzY2FiMTVkNTliMWZhNTEyNTA4YzAyMmYzODJkZTgzMTk0OTdjJyxcbiAgICAgICAgJ2NjYzlkYzM3YWJmYzljMTY1N2I0MTU1ZjJjNDdmOWU2NjQ2YjNhMWQ4Y2I5ODU0MzgzZGExM2FjMDc5YWZhNzMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOTU5Mzk2OTgxOTQzNzg1YzNkM2U1N2VkZjUwMThjZGJlMDM5ZTczMGU0OTE4YjNkODg0ZmRmZjA5NDc1YjdiYScsXG4gICAgICAgICcyZTdlNTUyODg4YzMzMWRkOGJhMDM4NmE0YjljZDY4NDljNjUzZjY0Yzg3MDkzODVlOWI4YWJmODc1MjRmMmZkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2QyYTYzYTUwYWU0MDFlNTZkNjQ1YTExNTNiMTA5YThmY2NhMGE0M2Q1NjFmYmEyZGJiNTEzNDBjOWQ4MmIxNTEnLFxuICAgICAgICAnZTgyZDg2ZmI2NDQzZmNiNzU2NWFlZTU4YjI5NDgyMjBhNzBmNzUwYWY0ODRjYTUyZDQxNDIxNzRkY2Y4OTQwNSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc2NDU4N2UyMzM1NDcxZWI4OTBlZTc4OTZkN2NmZGM4NjZiYWNiZGJkMzgzOTMxN2IzNDM2ZjliNDU2MTdlMDczJyxcbiAgICAgICAgJ2Q5OWZjZGQ1YmY2OTAyZTJhZTk2ZGQ2NDQ3YzI5OWExODViOTBhMzkxMzNhZWFiMzU4Mjk5ZTVlOWZhZjY1ODknXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnODQ4MWJkZTBlNGU0ZDg4NWIzYTU0NmQzZTU0OWRlMDQyZjBhYTZjZWEyNTBlN2ZkMzU4ZDZjODZkZDQ1ZTQ1OCcsXG4gICAgICAgICczOGVlN2I4Y2JhNTQwNGRkODRhMjViZjM5Y2VjYjJjYTkwMGE3OWM0MmIyNjJlNTU2ZDY0YjFiNTk3NzkwNTdlJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzEzNDY0YTU3YTc4MTAyYWE2MmI2OTc5YWU4MTdmNDYzN2ZmY2ZlZDNjNGIxY2UzMGJjZDYzMDNmNmNhZjY2NmInLFxuICAgICAgICAnNjliZTE1OTAwNDYxNDU4MGVmN2U0MzM0NTNjY2IwY2E0OGYzMDBhODFkMDk0MmUxM2Y0OTVhOTA3ZjZlY2MyNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdiYzRhOWRmNWI3MTNmZTJlOWFlZjQzMGJjYzFkYzk3YTBjZDljY2VkZTJmMjg1ODhjYWRhM2EwZDJkODNmMzY2JyxcbiAgICAgICAgJ2QzYTgxY2E2ZTc4NWMwNjM4MzkzN2FkZjRiNzk4Y2FhNmU4YTlmYmZhNTQ3YjE2ZDc1OGQ2NjY1ODFmMzNjMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4YzI4YTk3YmY4Mjk4YmMwZDIzZDhjNzQ5NDUyYTMyZTY5NGI2NWUzMGE5NDcyYTM5NTRhYjMwZmU1MzI0Y2FhJyxcbiAgICAgICAgJzQwYTMwNDYzYTMzMDUxOTMzNzhmZWRmMzFmN2NjMGViN2FlNzg0ZjA0NTFjYjk0NTllNzFkYzczY2JlZjk0ODInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOGVhOTY2NjEzOTUyN2E4YzFkZDk0Y2U0ZjA3MWZkMjNjOGIzNTBjNWE0YmIzMzc0OGM0YmExMTFmYWNjYWUwJyxcbiAgICAgICAgJzYyMGVmYWJiYzhlZTI3ODJlMjRlN2MwY2ZiOTVjNWQ3MzViNzgzYmU5Y2YwZjhlOTU1YWYzNGEzMGU2MmI5NDUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZGQzNjI1ZmFlZjViYTA2MDc0NjY5NzE2YmJkMzc4OGQ4OWJkZGU4MTU5NTk5NjgwOTJmNzZjYzRlYjlhOTc4NycsXG4gICAgICAgICc3YTE4OGZhMzUyMGUzMGQ0NjFkYTI1MDEwNDU3MzFjYTk0MTQ2MTk4Mjg4MzM5NTkzN2Y2OGQwMGM2NDRhNTczJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2Y3MTBkNzlkOWViOTYyMjk3ZTRmNjIzMmI0MGU4ZjdmZWIyYmM2MzgxNDYxNGQ2OTJjMTJkZTc1MjQwODIyMWUnLFxuICAgICAgICAnZWE5OGU2NzIzMmQzYjMyOTVkM2I1MzU1MzIxMTVjY2FjODYxMmM3MjE4NTE2MTc1MjZhZTQ3YTljNzdiZmM4MidcbiAgICAgIF1cbiAgICBdXG4gIH0sXG4gIG5hZjoge1xuICAgIHduZDogNyxcbiAgICBwb2ludHM6IFtcbiAgICAgIFtcbiAgICAgICAgJ2Y5MzA4YTAxOTI1OGMzMTA0OTM0NGY4NWY4OWQ1MjI5YjUzMWM4NDU4MzZmOTliMDg2MDFmMTEzYmNlMDM2ZjknLFxuICAgICAgICAnMzg4ZjdiMGY2MzJkZTgxNDBmZTMzN2U2MmEzN2YzNTY2NTAwYTk5OTM0YzIyMzFiNmNiOWZkNzU4NGI4ZTY3MidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcyZjhiZGU0ZDFhMDcyMDkzNTViNGE3MjUwYTVjNTEyOGU4OGI4NGJkZGM2MTlhYjdjYmE4ZDU2OWIyNDBlZmU0JyxcbiAgICAgICAgJ2Q4YWMyMjI2MzZlNWUzZDZkNGRiYTlkZGE2YzljNDI2Zjc4ODI3MWJhYjBkNjg0MGRjYTg3ZDNhYTZhYzYyZDYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNWNiZGYwNjQ2ZTVkYjRlYWEzOThmMzY1ZjJlYTdhMGUzZDQxOWI3ZTAzMzBlMzljZTkyYmRkZWRjYWM0ZjliYycsXG4gICAgICAgICc2YWViY2E0MGJhMjU1OTYwYTMxNzhkNmQ4NjFhNTRkYmE4MTNkMGI4MTNmZGU3YjVhNTA4MjYyODA4NzI2NGRhJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2FjZDQ4NGUyZjBjN2Y2NTMwOWFkMTc4YTlmNTU5YWJkZTA5Nzk2OTc0YzU3ZTcxNGMzNWYxMTBkZmMyN2NjYmUnLFxuICAgICAgICAnY2MzMzg5MjFiMGE3ZDlmZDY0MzgwOTcxNzYzYjYxZTlhZGQ4ODhhNDM3NWY4ZTBmMDVjYzI2MmFjNjRmOWMzNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3NzRhZTdmODU4YTk0MTFlNWVmNDI0NmI3MGM2NWFhYzU2NDk5ODBiZTVjMTc4OTFiYmVjMTc4OTVkYTAwOGNiJyxcbiAgICAgICAgJ2Q5ODRhMDMyZWI2YjVlMTkwMjQzZGQ1NmQ3YjdiMzY1MzcyZGIxZTJkZmY5ZDZhODMwMWQ3NGM5Yzk1M2M2MWInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZjI4NzczYzJkOTc1Mjg4YmM3ZDFkMjA1YzM3NDg2NTFiMDc1ZmJjNjYxMGU1OGNkZGVlZGRmOGYxOTQwNWFhOCcsXG4gICAgICAgICdhYjA5MDJlOGQ4ODBhODk3NTgyMTJlYjY1Y2RhZjQ3M2ExYTA2ZGE1MjFmYTkxZjI5YjVjYjUyZGIwM2VkODEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDc5MjRkNGY3ZDQzZWE5NjVhNDY1YWUzMDk1ZmY0MTEzMWU1OTQ2ZjNjODVmNzllNDRhZGJjZjhlMjdlMDgwZScsXG4gICAgICAgICc1ODFlMjg3MmE4NmM3MmE2ODM4NDJlYzIyOGNjNmRlZmVhNDBhZjJiZDg5NmQzYTVjNTA0ZGM5ZmY2YTI2YjU4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2RlZmRlYTRjZGI2Nzc3NTBhNDIwZmVlODA3ZWFjZjIxZWI5ODk4YWU3OWI5NzY4NzY2ZTRmYWEwNGEyZDRhMzQnLFxuICAgICAgICAnNDIxMWFiMDY5NDYzNTE2OGU5OTdiMGVhZDJhOTNkYWVjZWQxZjRhMDRhOTVjMGY2Y2ZiMTk5ZjY5ZTU2ZWI3NydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcyYjRlYTBhNzk3YTQ0M2QyOTNlZjVjZmY0NDRmNDk3OWYwNmFjZmViZDdlODZkMjc3NDc1NjU2MTM4Mzg1YjZjJyxcbiAgICAgICAgJzg1ZTg5YmMwMzc5NDVkOTNiMzQzMDgzYjVhMWM4NjEzMWEwMWY2MGM1MDI2OTc2M2I1NzBjODU0ZTVjMDliN2EnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzUyYmJmNGE0Y2RkMTI1NjRmOTNmYTMzMmNlMzMzMzAxZDlhZDQwMjcxZjgxMDcxODEzNDBhZWYyNWJlNTlkNScsXG4gICAgICAgICczMjFlYjQwNzUzNDhmNTM0ZDU5YzE4MjU5ZGRhM2UxZjRhMWIzYjJlNzFiMTAzOWM2N2JkM2Q4YmNmODE5OThjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzJmYTIxMDRkNmIzOGQxMWIwMjMwMDEwNTU5ODc5MTI0ZTQyYWI4ZGZlZmY1ZmYyOWRjOWNkYWRkNGVjYWNjM2YnLFxuICAgICAgICAnMmRlMTA2ODI5NWRkODY1YjY0NTY5MzM1YmQ1ZGQ4MDE4MWQ3MGVjZmM4ODI2NDg0MjNiYTc2YjUzMmI3ZDY3J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzkyNDgyNzliMDliNGQ2OGRhYjIxYTliMDY2ZWRkYTgzMjYzYzNkODRlMDk1NzJlMjY5Y2EwY2Q3ZjU0NTM3MTQnLFxuICAgICAgICAnNzMwMTZmN2JmMjM0YWFkZTVkMWFhNzFiZGVhMmIxZmYzZmMwZGUyYTg4NzkxMmZmZTU0YTMyY2U5N2NiMzQwMidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkYWVkNGYyYmUzYThiZjI3OGU3MDEzMmZiMGJlYjc1MjJmNTcwZTE0NGJmNjE1YzA3ZTk5NmQ0NDNkZWU4NzI5JyxcbiAgICAgICAgJ2E2OWRjZTRhN2Q2Yzk4ZThkNGExYWNhODdlZjhkNzAwM2Y4M2MyMzBmM2FmYTcyNmFiNDBlNTIyOTBiZTFjNTUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYzQ0ZDEyYzcwNjVkODEyZThhY2YyOGQ3Y2JiMTlmOTAxMWVjZDllOWZkZjI4MWIwZTZhM2I1ZTg3ZDIyZTdkYicsXG4gICAgICAgICcyMTE5YTQ2MGNlMzI2Y2RjNzZjNDU5MjZjOTgyZmRhYzBlMTA2ZTg2MWVkZjYxYzVhMDM5MDYzZjBlMGU2NDgyJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzZhMjQ1YmY2ZGM2OTg1MDRjODlhMjBjZmRlZDYwODUzMTUyYjY5NTMzNmMyODA2M2I2MWM2NWNiZDI2OWU2YjQnLFxuICAgICAgICAnZTAyMmNmNDJjMmJkNGE3MDhiM2Y1MTI2ZjE2YTI0YWQ4YjMzYmE0OGQwNDIzYjZlZmQ1ZTYzNDgxMDBkOGE4MidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxNjk3ZmZhNmZkOWRlNjI3YzA3N2UzZDJmZTU0MTA4NGNlMTMzMDBiMGJlYzExNDZmOTVhZTU3ZjBkMGJkNmE1JyxcbiAgICAgICAgJ2I5YzM5OGYxODY4MDZmNWQyNzU2MTUwNmU0NTU3NDMzYTJjZjE1MDA5ZTQ5OGFlN2FkZWU5ZDYzZDAxYjIzOTYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNjA1YmRiMDE5OTgxNzE4Yjk4NmQwZjA3ZTgzNGNiMGQ5ZGViODM2MGZmYjdmNjFkZjk4MjM0NWVmMjdhNzQ3OScsXG4gICAgICAgICcyOTcyZDJkZTRmOGQyMDY4MWE3OGQ5M2VjOTZmZTIzYzI2YmZhZTg0ZmIxNGRiNDNiMDFlMWU5MDU2YjhjNDknXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNjJkMTRkYWI0MTUwYmY0OTc0MDJmZGM0NWEyMTVlMTBkY2IwMWMzNTQ5NTliMTBjZmUzMWM3ZTlkODdmZjMzZCcsXG4gICAgICAgICc4MGZjMDZiZDhjYzViMDEwOTgwODhhMTk1MGVlZDBkYjAxYWExMzI5NjdhYjQ3MjIzNWY1NjQyNDgzYjI1ZWFmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzgwYzYwYWQwMDQwZjI3ZGFkZTViNGIwNmM0MDhlNTZiMmM1MGU5ZjU2YjliOGI0MjVlNTU1YzJmODYzMDhiNmYnLFxuICAgICAgICAnMWMzODMwM2YxY2M1YzMwZjI2ZTY2YmFkN2ZlNzJmNzBhNjVlZWQ0Y2JlNzAyNGViMWFhMDFmNTY0MzBiZDU3YSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3YTkzNzVhZDYxNjdhZDU0YWE3NGM2MzQ4Y2M1NGQzNDRjYzVkYzk0ODdkODQ3MDQ5ZDVlYWJiMGZhMDNjOGZiJyxcbiAgICAgICAgJ2QwZTNmYTllY2E4NzI2OTA5NTU5ZTBkNzkyNjkwNDZiZGM1OWVhMTBjNzBjZTJiMDJkNDk5ZWMyMjRkYzdmNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkNTI4ZWNkOWI2OTZiNTRjOTA3YTllZDA0NTQ0N2E3OWJiNDA4ZWMzOWI2OGRmNTA0YmI1MWY0NTliYzNmZmM5JyxcbiAgICAgICAgJ2VlY2Y0MTI1MzEzNmU1Zjk5OTY2ZjIxODgxZmQ2NTZlYmM0MzQ1NDA1YzUyMGRiYzA2MzQ2NWI1MjE0MDk5MzMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNDkzNzBhNGI1ZjQzNDEyZWEyNWY1MTRlOGVjZGFkMDUyNjYxMTVlNGE3ZWNiMTM4NzIzMTgwOGY4YjQ1OTYzJyxcbiAgICAgICAgJzc1OGYzZjQxYWZkNmVkNDI4YjMwODFiMDUxMmZkNjJhNTRjM2YzYWZiYjViNjc2NGI2NTMwNTJhMTI5NDljOWEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzdmMjMwOTM2ZWU4OGNiYmQ3M2RmOTMwZDY0NzAyZWY4ODFkODExZTBlMTQ5OGUyZjFjMTNlYjFmYzM0NWQ3NCcsXG4gICAgICAgICc5NThlZjQyYTc4ODZiNjQwMGEwODI2NmU5YmExYjM3ODk2Yzk1MzMwZDk3MDc3Y2JiZThlYjNjNzY3MWM2MGQ2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2YyZGFjOTkxY2M0Y2U0YjllYTQ0ODg3ZTVjN2MwYmNlNThjODAwNzRhYjlkNGRiYWViMjg1MzFiNzczOWY1MzAnLFxuICAgICAgICAnZTBkZWRjOWIzYjJmOGRhZDRkYTFmMzJkZWMyNTMxZGY5ZWI1ZmJlYjA1OThlNGZkMWExMTdkYmE3MDNhM2MzNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc0NjNiM2Q5ZjY2MjYyMWZiMWI0YmU4ZmJiZTI1MjAxMjVhMjE2Y2RmYzlkYWUzZGViY2JhNDg1MGM2OTBkNDViJyxcbiAgICAgICAgJzVlZDQzMGQ3OGMyOTZjMzU0MzExNDMwNmRkODYyMmQ3YzYyMmUyN2M5NzBhMWRlMzFjYjM3N2IwMWFmNzMwN2UnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZjE2ZjgwNDI0NGU0NmUyYTA5MjMyZDRhZmYzYjU5OTc2Yjk4ZmFjMTQzMjhhMmQxYTMyNDk2YjQ5OTk4ZjI0NycsXG4gICAgICAgICdjZWRhYmQ5YjgyMjAzZjdlMTNkMjA2ZmNkZjRlMzNkOTJhNmM1M2MyNmU1Y2NlMjZkNjU3OTk2MmM0ZTMxZGY2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2NhZjc1NDI3MmRjODQ1NjNiMDM1MmI3YTE0MzExYWY1NWQyNDUzMTVhY2UyN2M2NTM2OWUxNWY3MTUxZDQxZDEnLFxuICAgICAgICAnY2I0NzQ2NjBlZjM1ZjVmMmE0MWI2NDNmYTVlNDYwNTc1ZjRmYTliNzk2MjIzMmE1YzMyZjkwODMxOGEwNDQ3NidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcyNjAwY2E0YjI4MmNiOTg2Zjg1ZDBmMTcwOTk3OWQ4YjQ0YTA5YzA3Y2I4NmQ3YzEyNDQ5N2JjODZmMDgyMTIwJyxcbiAgICAgICAgJzQxMTliODg3NTNjMTViZDZhNjkzYjAzZmNkZGJiNDVkNWFjNmJlNzRhYjVmMGVmNDRiMGJlOTQ3NWE3ZTRiNDAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzYzNWNhNzJkN2U4NDMyYzMzOGVjNTNjZDEyMjIwYmMwMWM0ODY4NWUyNGY3ZGM4YzYwMmE3NzQ2OTk4ZTQzNScsXG4gICAgICAgICc5MWI2NDk2MDk0ODlkNjEzZDFkNWU1OTBmNzhlNmQ3NGVjZmMwNjFkNTcwNDhiYWQ5ZTc2ZjMwMmM1YjljNjEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzU0ZTMyMzlmMzI1NTcwY2RiYmY0YTg3ZGVlZThhNjZiN2YyYjMzNDc5ZDQ2OGZiYzFhNTA3NDNiZjU2Y2MxOCcsXG4gICAgICAgICc2NzNmYjg2ZTViZGEzMGZiM2NkMGVkMzA0ZWE0OWEwMjNlZTMzZDAxOTdhNjk1ZDBjNWQ5ODA5M2M1MzY2ODMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTNlNmJkMTA3MWExZTk2YWZmNTc4NTljODJkNTcwZjAzMzA4MDA2NjFkMWM5NTJmOWZlMjY5NDY5MWQ5YjllOCcsXG4gICAgICAgICc1OWM5ZTBiYmEzOTRlNzZmNDBjMGFhNTgzNzlhM2NiNmE1YTIyODM5OTNlOTBjNDE2NzAwMmFmNDkyMGUzN2Y1J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzE4NmI0ODNkMDU2YTAzMzgyNmFlNzNkODhmNzMyOTg1YzRjY2IxZjMyYmEzNWY0YjRjYzQ3ZmRjZjA0YWE2ZWInLFxuICAgICAgICAnM2I5NTJkMzJjNjdjZjc3ZTJlMTc0NDZlMjA0MTgwYWIyMWZiODA5MDg5NTEzOGI0YTRhNzk3Zjg2ZTgwODg4YidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkZjlkNzBhNmI5ODc2Y2U1NDRjOTg1NjFmNGJlNGY3MjU0NDJlNmQyYjczN2Q5YzkxYTgzMjE3MjRjZTA5NjNmJyxcbiAgICAgICAgJzU1ZWIyZGFmZDg0ZDZjY2Q1Zjg2MmI3ODVkYzM5ZDRhYjE1NzIyMjcyMGVmOWRhMjE3YjhjNDVjZjJiYTI0MTcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNWVkZDVjYzIzYzUxZTg3YTQ5N2NhODE1ZDVkY2UwZjhhYjUyNTU0Zjg0OWVkODk5NWRlNjRjNWYzNGNlNzE0MycsXG4gICAgICAgICdlZmFlOWM4ZGJjMTQxMzA2NjFlOGNlYzAzMGM4OWFkMGMxM2M2NmMwZDE3YTI5MDVjZGM3MDZhYjczOTlhODY4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzI5MDc5OGMyYjY0NzY4MzBkYTEyZmUwMjI4N2U5ZTc3N2FhM2ZiYTFjMzU1YjE3YTcyMmQzNjJmODQ2MTRmYmEnLFxuICAgICAgICAnZTM4ZGE3NmRjZDQ0MDYyMTk4OGQwMGJjZjc5YWYyNWQ1YjI5YzA5NGRiMmEyMzE0NmQwMDNhZmQ0MTk0M2U3YSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhZjNjNDIzYTk1ZDlmNWIzMDU0NzU0ZWZhMTUwYWMzOWNkMjk1NTJmZTM2MDI1NzM2MmRmZGVjZWY0MDUzYjQ1JyxcbiAgICAgICAgJ2Y5OGEzZmQ4MzFlYjJiNzQ5YTkzYjBlNmYzNWNmYjQwYzhjZDVhYTY2N2ExNTU4MWJjMmZlZGVkNDk4ZmQ5YzYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzY2ZGJiMjRkMTM0ZTc0NWNjY2FhMjhjOTliZjI3NDkwNmJiNjZiMjZkY2Y5OGRmOGQyZmVkNTBkODg0MjQ5YScsXG4gICAgICAgICc3NDRiMTE1MmVhY2JlNWUzOGRjYzg4Nzk4MGRhMzhiODk3NTg0YTY1ZmEwNmNlZGQyYzkyNGY5N2NiYWM1OTk2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzU5ZGJmNDZmOGM5NDc1OWJhMjEyNzdjMzM3ODRmNDE2NDVmN2I0NGY2YzU5NmE1OGNlOTJlNjY2MTkxYWJlM2UnLFxuICAgICAgICAnYzUzNGFkNDQxNzVmYmMzMDBmNGVhNmNlNjQ4MzA5YTA0MmNlNzM5YTc5MTk3OThjZDg1ZTIxNmM0YTMwN2Y2ZSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdmMTNhZGE5NTEwM2M0NTM3MzA1ZTY5MWU3NGU5YTRhOGRkNjQ3ZTcxMWE5NWU3M2NiNjJkYzYwMThjZmQ4N2I4JyxcbiAgICAgICAgJ2UxMzgxN2I0NGVlMTRkZTY2M2JmNGJjODA4MzQxZjMyNjk0OWUyMWE2YTc1YzI1NzA3Nzg0MTliZGFmNTczM2QnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzc1NGI0ZmEwZThhY2VkMDZkNDE2N2EyYzU5Y2NhNGNkYTE4NjljMDZlYmFkZmI2NDg4NTUwMDE1YTg4NTIyYycsXG4gICAgICAgICczMGU5M2U4NjRlNjY5ZDgyMjI0Yjk2N2MzMDIwYjhmYThkMWU0ZTM1MGI2Y2JjYzUzN2E0OGI1Nzg0MTE2M2EyJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzk0OGRjYWRmNTk5MGUwNDhhYTM4NzRkNDZhYmVmOWQ3MDE4NThmOTVkZTgwNDFkMmE2ODI4Yzk5ZTIyNjI1MTknLFxuICAgICAgICAnZTQ5MWE0MjUzN2Y2ZTU5N2Q1ZDI4YTMyMjRiMWJjMjVkZjkxNTRlZmJkMmVmMWQyY2JiYTJjYWU1MzQ3ZDU3ZSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3OTYyNDE0NDUwYzc2YzE2ODljN2I0OGY4MjAyZWMzN2ZiMjI0Y2Y1YWMwYmZhMTU3MDMyOGE4YTNkN2M3N2FiJyxcbiAgICAgICAgJzEwMGI2MTBlYzRmZmI0NzYwZDVjMWZjMTMzZWY2ZjZiMTI1MDdhMDUxZjA0YWM1NzYwYWZhNWIyOWRiODM0MzcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzUxNDA4NzgzNDk2NGI1NGIxNWIxNjA2NDRkOTE1NDg1YTE2OTc3MjI1Yjg4NDdiYjBkZDA4NTEzN2VjNDdjYScsXG4gICAgICAgICdlZjBhZmJiMjA1NjIwNTQ0OGUxNjUyYzQ4ZTgxMjdmYzYwMzllNzdjMTVjMjM3OGI3ZTdkMTVhMGRlMjkzMzExJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2QzY2MzMGFkNmI0ODNlNGJjNzljZTJjOWRkOGJjNTQ5OTNlOTQ3ZWI4ZGY3ODdiNDQyOTQzZDNmN2I1MjdlYWYnLFxuICAgICAgICAnOGIzNzhhMjJkODI3Mjc4ZDg5YzVlOWJlOGY5NTA4YWUzYzJhZDQ2MjkwMzU4NjMwYWZiMzRkYjA0ZWVkZTBhNCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxNjI0ZDg0NzgwNzMyODYwY2UxYzc4ZmNiZmVmZTA4YjJiMjk4MjNkYjkxM2Y2NDkzOTc1YmEwZmY0ODQ3NjEwJyxcbiAgICAgICAgJzY4NjUxY2Y5YjZkYTkwM2UwOTE0NDQ4YzZjZDlkNGNhODk2ODc4ZjUyODJiZTRjOGNjMDZlMmE0MDQwNzg1NzUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNzMzY2U4MGRhOTU1YThhMjY5MDJjOTU2MzNlNjJhOTg1MTkyNDc0YjVhZjIwN2RhNmRmN2I0ZmQ1ZmM2MWNkNCcsXG4gICAgICAgICdmNTQzNWEyYmQyYmFkZjdkNDg1YTRkOGI4ZGI5ZmNjZTNlMWVmOGUwMjAxZTQ1NzhjNTQ2NzNiYzFkYzVlYTFkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzE1ZDk0NDEyNTQ5NDUwNjRjZjFhMWMzM2JiZDNiNDlmODk2NmM1MDkyMTcxZTY5OWVmMjU4ZGZhYjgxYzA0NWMnLFxuICAgICAgICAnZDU2ZWIzMGI2OTQ2M2U3MjM0ZjUxMzdiNzNiODQxNzc0MzQ4MDBiYWNlYmZjNjg1ZmMzN2JiZTllZmU0MDcwZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhMWQwZmNmMmVjOWRlNjc1YjYxMjEzNmU1Y2U3MGQyNzFjMjE0MTdjOWQyYjhhYWFhYzEzODU5OWQwNzE3OTQwJyxcbiAgICAgICAgJ2VkZDc3ZjUwYmNiNWEzY2FiMmU5MDczNzMwOTY2N2YyNjQxNDYyYTU0MDcwZjNkNTE5MjEyZDM5YzE5N2E2MjknXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTIyZmJlMTVjMGFmOGNjYzU3ODBjMDczNWY4NGRiZTlhNzkwYmFkZWU4MjQ1YzA2YzdjYTM3MzMxY2IzNjk4MCcsXG4gICAgICAgICdhODU1YmFiYWQ1Y2Q2MGM4OGI0MzBhNjlmNTNhMWE3YTM4Mjg5MTU0OTY0Nzk5YmU0M2QwNmQ3N2QzMWRhMDYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzExMDkxZGQ5ODYwZThlMjBlZTEzNDczYzExNTVmNWY2OTYzNWUzOTQ3MDRlYWE3NDAwOTQ1MjI0NmNmYTliMycsXG4gICAgICAgICc2NmRiNjU2Zjg3ZDFmMDRmZmZkMWYwNDc4OGMwNjgzMDg3MWVjNWE2NGZlZWU2ODViZDgwZjBiMTI4NmQ4Mzc0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzM0YzFmZDA0ZDMwMWJlODliMzFjMDQ0MmQzZTZhYzI0ODgzOTI4YjQ1YTkzNDA3ODE4NjdkNDIzMmVjMmRiZGYnLFxuICAgICAgICAnOTQxNDY4NWU5N2IxYjU5NTRiZDQ2ZjczMDE3NDEzNmQ1N2YxY2VlYjQ4NzQ0M2RjNTMyMTg1N2JhNzNhYmVlJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2YyMTllYTVkNmI1NDcwMWMxYzE0ZGU1YjU1N2ViNDJhOGQxM2YzYWJiY2QwOGFmZmNjMmE1ZTZiMDQ5YjhkNjMnLFxuICAgICAgICAnNGNiOTU5NTdlODNkNDBiMGY3M2FmNDU0NGNjY2Y2YjFmNGIwOGQzYzA3YjI3ZmI4ZDhjMjk2MmE0MDA3NjZkMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkN2I4NzQwZjc0YThmYmFhYjFmNjgzZGI4ZjQ1ZGUyNjU0M2E1NDkwYmNhNjI3MDg3MjM2OTEyNDY5YTBiNDQ4JyxcbiAgICAgICAgJ2ZhNzc5NjgxMjhkOWM5MmVlMTAxMGYzMzdhZDQ3MTdlZmYxNWRiNWVkM2MwNDliMzQxMWUwMzE1ZWFhNDU5M2InXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzJkMzFjMjIyZjhmNmYwZWY4NmY3Yzk4ZDNhMzMzNWVhZDViY2QzMmFiZGQ5NDI4OWZlNGQzMDkxYWE4MjRiZicsXG4gICAgICAgICc1ZjMwMzJmNTg5MjE1NmUzOWNjZDNkNzkxNWI5ZTFkYTJlNmRhYzllNmYyNmU5NjExMThkMTRiODQ2MmUxNjYxJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc0NjFmMzcxOTE0YWIzMjY3MTA0NWExNTVkOTgzMWVhODc5M2Q3N2NkNTk1OTJjNDM0MGY4NmNiYzE4MzQ3YjUnLFxuICAgICAgICAnOGVjMGJhMjM4Yjk2YmVjMGNiZGRkY2FlMGFhNDQyNTQyZWVlMWZmNTBjOTg2ZWE2YjM5ODQ3YjNjYzA5MmZmNidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdlZTA3OWFkYjFkZjE4NjAwNzQzNTZhMjVhYTM4MjA2YTZkNzE2YjJjM2U2NzQ1M2QyODc2OThiYWQ3YjJiMmQ2JyxcbiAgICAgICAgJzhkYzI0MTJhYWZlM2JlNWM0YzVmMzdlMGVjYzVmOWY2YTQ0Njk4OWFmMDRjNGUyNWViYWFjNDc5ZWMxYzhjMWUnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMTZlYzkzZTQ0N2VjODNmMDQ2N2IxODMwMmVlNjIwZjdlNjVkZTMzMTg3NGM5ZGM3MmJmZDg2MTZiYTlkYTZiNScsXG4gICAgICAgICc1ZTQ2MzExNTBlNjJmYjQwZDBlOGMyYTdjYTU4MDRhMzlkNTgxODZhNTBlNDk3MTM5NjI2Nzc4ZTI1YjA2NzRkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2VhYTVmOTgwYzI0NWY2ZjAzODk3ODI5MGFmYTcwYjZiZDg4NTU4OTdmOThiNmFhNDg1Yjk2MDY1ZDUzN2JkOTknLFxuICAgICAgICAnZjY1ZjVkM2UyOTJjMmUwODE5YTUyODM5MWM5OTQ2MjRkNzg0ODY5ZDdlNmVhNjdmYjE4MDQxMDI0ZWRjMDdkYydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3OGM5NDA3NTQ0YWMxMzI2OTJlZTE5MTBhMDI0Mzk5NThhZTA0ODc3MTUxMzQyZWE5NmM0YjZiMzVhNDlmNTEnLFxuICAgICAgICAnZjNlMDMxOTE2OWViOWI4NWQ1NDA0Nzk1NTM5YTVlNjhmYTFmYmQ1ODNjMDY0ZDI0NjJiNjc1ZjE5NGEzZGRiNCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc0OTRmNGJlMjE5YTFhNzcwMTZkY2Q4Mzg0MzFhZWEwMDAxY2RjOGFlN2E2ZmM2ODg3MjY1NzhkOTcwMjg1N2E1JyxcbiAgICAgICAgJzQyMjQyYTk2OTI4M2E1ZjMzOWJhN2YwNzVlMzZiYTJhZjkyNWNlMzBkNzY3ZWQ2ZTU1ZjRiMDMxODgwZDU2MmMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYTU5OGE4MDMwZGE2ZDg2YzZiYzdmMmY1MTQ0ZWE1NDlkMjgyMTFlYTU4ZmFhNzBlYmY0YzFlNjY1YzFmZTliNScsXG4gICAgICAgICcyMDRiNWQ2Zjg0ODIyYzMwN2U0YjRhNzE0MDczN2FlYzIzZmM2M2I2NWIzNWY4NmExMDAyNmRiZDJkODY0ZTZiJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2M0MTkxNjM2NWFiYjJiNWQwOTE5MmY1ZjJkYmVhZmVjMjA4ZjAyMGYxMjU3MGExODRkYmFkYzNlNTg1OTU5OTcnLFxuICAgICAgICAnNGYxNDM1MWQwMDg3ZWZhNDlkMjQ1YjMyODk4NDk4OWQ1Y2FmOTQ1MGYzNGJmYzBlZDE2ZTk2YjU4ZmE5OTEzJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzg0MWQ2MDYzYTU4NmZhNDc1YTcyNDYwNGRhMDNiYzViOTJhMmUwZDJlMGEzNmFjZmU0YzczYTU1MTQ3NDI4ODEnLFxuICAgICAgICAnNzM4NjdmNTljMDY1OWU4MTkwNGY5YTFjNzU0MzY5OGU2MjU2MmQ2NzQ0YzE2OWNlN2EzNmRlMDFhOGQ2MTU0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzVlOTViYjM5OWE2OTcxZDM3NjAyNjk0N2Y4OWJkZTJmMjgyYjMzODEwOTI4YmU0ZGVkMTEyYWM0ZDcwZTIwZDUnLFxuICAgICAgICAnMzlmMjNmMzY2ODA5MDg1YmVlYmZjNzExODEzMTM3NzVhOTljOWFlZDdkOGJhMzhiMTYxMzg0Yzc0NjAxMjg2NSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczNmU0NjQxYTUzOTQ4ZmQ0NzZjMzlmOGE5OWZkOTc0ZTVlYzA3NTY0YjUzMTVkOGJmOTk0NzFiY2EwZWYyZjY2JyxcbiAgICAgICAgJ2QyNDI0YjFiMWFiZTRlYjgxNjQyMjdiMDg1YzlhYTk0NTZlYTEzNDkzZmQ1NjNlMDZmZDUxY2Y1Njk0Yzc4ZmMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzM2NTgxZWE3YmZiYmIyOTBjMTkxYTJmNTA3YTQxY2Y1NjQzODQyMTcwZTkxNGZhZWFiMjdjMmM1NzlmNzI2JyxcbiAgICAgICAgJ2VhZDEyMTY4NTk1ZmUxYmU5OTI1MjEyOWI2ZTU2YjMzOTFmN2FiMTQxMGNkMWUwZWYzZGNkY2FiZDJmZGEyMjQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOGFiODk4MTZkYWRmZDZiNmExZjI2MzRmY2YwMGVjODQwMzc4MTAyNWVkNjg5MGM0ODQ5NzQyNzA2YmQ0M2VkZScsXG4gICAgICAgICc2ZmRjZWYwOWYyZjZkMGEwNDRlNjU0YWVmNjI0MTM2ZjUwM2Q0NTljM2U4OTg0NTg1OGE0N2E5MTI5Y2RkMjRlJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzFlMzNmMWE3NDZjOWM1Nzc4MTMzMzQ0ZDkyOTlmY2FhMjBiMDkzOGU4YWNmZjI1NDRiYjQwMjg0YjhjNWZiOTQnLFxuICAgICAgICAnNjA2NjAyNTdkZDExYjNhYTljOGVkNjE4ZDI0ZWRmZjIzMDZkMzIwZjFkMDMwMTBlMzNhN2QyMDU3ZjNiM2I2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzg1YjdjMWRjYjNjZWMxYjdlZTdmMzBkZWQ3OWRkMjBhMGVkMWY0Y2MxOGNiY2ZjZmE0MTAzNjFmZDhmMDhmMzEnLFxuICAgICAgICAnM2Q5OGE5Y2RkMDI2ZGQ0M2YzOTA0OGYyNWE4ODQ3ZjRmY2FmYWQxODk1ZDdhNjMzYzZmZWQzYzM1ZTk5OTUxMSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcyOWRmOWZiZDhkOWU0NjUwOTI3NWY0YjEyNWQ2ZDQ1ZDdmYmU5YTNiODc4YTdhZjg3MmEyODAwNjYxYWM1ZjUxJyxcbiAgICAgICAgJ2I0YzRmZTk5Yzc3NWE2MDZlMmQ4ODYyMTc5MTM5ZmZkYTYxZGM4NjFjMDE5ZTU1Y2QyODc2ZWIyYTI3ZDg0YidcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhMGIxY2FlMDZiMGE4NDdhM2ZlYTZlNjcxYWFmOGFkZmRmZTU4Y2EyZjc2ODEwNWM4MDgyYjJlNDQ5ZmNlMjUyJyxcbiAgICAgICAgJ2FlNDM0MTAyZWRkZTA5NThlYzRiMTlkOTE3YTZhMjhlNmI3MmRhMTgzNGFmZjBlNjUwZjA0OTUwM2EyOTZjZjInXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNGU4Y2VhZmI5YjNlOWExMzZkYzdmZjY3ZTg0MDI5NWI0OTlkZmIzYjIxMzNlNGJhMTEzZjJlNGMwZTEyMWU1JyxcbiAgICAgICAgJ2NmMjE3NDExOGM4YjZkN2E0YjQ4ZjZkNTM0Y2U1Yzc5NDIyYzA4NmE2MzQ2MDUwMmI4MjdjZTYyYTMyNjY4M2MnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZDI0YTQ0ZTA0N2UxOWI2ZjVhZmI4MWM3Y2EyZjY5MDgwYTUwNzY2ODlhMDEwOTE5ZjQyNzI1YzJiNzg5YTMzYicsXG4gICAgICAgICc2ZmI4ZDU1OTFiNDY2ZjhmYzYzZGI1MGYxYzBmMWM2OTAxM2Y5OTY4ODdiODI0NGQyY2RlYzQxN2FmZWE4ZmEzJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2VhMDE2MDZhN2E2YzljZGQyNDlmZGZjZmFjYjk5NTg0MDAxZWRkMjhhYmJhYjc3YjUxMDRlOThlOGUzYjM1ZDQnLFxuICAgICAgICAnMzIyYWY0OTA4YzczMTJiMGNmYmZlMzY5ZjdhN2IzY2RiN2Q0NDk0YmMyODIzNzAwY2ZkNjUyMTg4YTNlYTk4ZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdhZjhhZGRiZjJiNjYxYzhhNmM2MzI4NjU1ZWI5NjY1MTI1MjAwN2Q4YzVlYTMxYmU0YWQxOTZkZThjZTIxMzFmJyxcbiAgICAgICAgJzY3NDllNjdjMDI5Yjg1ZjUyYTAzNGVhZmQwOTY4MzZiMjUyMDgxODY4MGUyNmFjOGYzZGZiY2RiNzE3NDk3MDAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTNhZTE5NzQ1NjZjYTA2Y2M1MTZkNDdlMGZiMTY1YTY3NGEzZGFiY2ZjYTE1ZTcyMmYwZTM0NTBmNDU4ODknLFxuICAgICAgICAnMmFlYWJlN2U0NTMxNTEwMTE2MjE3ZjA3YmY0ZDA3MzAwZGU5N2U0ODc0ZjgxZjUzMzQyMGE3MmVlYjBiZDZhNCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc1OTFlZTM1NTMxM2Q5OTcyMWNmNjk5M2ZmZWQxZTNlMzAxOTkzZmYzZWQyNTg4MDIwNzVlYThjZWQzOTdlMjQ2JyxcbiAgICAgICAgJ2IwZWE1NThhMTEzYzMwYmVhNjBmYzQ3NzU0NjBjNzkwMWZmMGIwNTNkMjVjYTJiZGVlZTk4ZjFhNGJlNWQxOTYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMTEzOTZkNTVmZGE1NGM0OWYxOWFhOTczMThkOGRhNjFmYTg1ODRlNDdiMDg0OTQ1MDc3Y2YwMzI1NWI1Mjk4NCcsXG4gICAgICAgICc5OThjNzRhOGNkNDVhYzAxMjg5ZDU4MzNhN2JlYjQ3NDRmZjUzNmIwMWIyNTdiZTRjNTc2N2JlYTkzZWE1N2E0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzNjNWQyYTFiYTM5YzVhMTc5MDAwMDczOGM5ZTBjNDBiOGRjZGZkNTQ2ODc1NGI2NDA1NTQwMTU3ZTAxN2FhN2EnLFxuICAgICAgICAnYjIyODQyNzk5OTVhMzRlMmY5ZDRkZTczOTZmYzE4YjgwZjliOGI5ZmRkMjcwZjY2NjFmNzljYTRjODFiZDI1NydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdjYzg3MDRiOGE2MGEwZGVmYTNhOTlhNzI5OWYyZTljM2ZiYzM5NWFmYjA0YWMwNzg0MjVlZjhhMTc5M2NjMDMwJyxcbiAgICAgICAgJ2JkZDQ2MDM5ZmVlZDE3ODgxZDFlMDg2MmRiMzQ3ZjhjZjM5NWI3NGZjNGJjZGM0ZTk0MGI3NGUzYWMxZjFiMTMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYzUzM2U0ZjdlYTg1NTVhYWNkOTc3N2FjNWNhZDI5Yjk3ZGQ0ZGVmY2NjNTNlZTdlYTIwNDExOWIyODg5YjE5NycsXG4gICAgICAgICc2ZjBhMjU2YmM1ZWZkZjQyOWEyZmI2MjQyZjFhNDNhMmQ5YjkyNWJiNGE0YjNhMjZiYjhlMGY0NWViNTk2MDk2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2MxNGY4ZjJjY2IyN2Q2ZjEwOWY2ZDA4ZDAzY2M5NmE2OWJhOGMzNGVlYzA3YmJjZjU2NmQ0OGUzM2RhNjU5MycsXG4gICAgICAgICdjMzU5ZDY5MjNiYjM5OGY3ZmQ0NDczZTE2ZmUxYzI4NDc1Yjc0MGRkMDk4MDc1ZTZjMGU4NjQ5MTEzZGMzYTM4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2E2Y2JjMzA0NmJjNmE0NTBiYWMyNDc4OWZhMTcxMTVhNGM5NzM5ZWQ3NWY4ZjIxY2U0NDFmNzJlMGI5MGU2ZWYnLFxuICAgICAgICAnMjFhZTdmNDY4MGU4ODliYjEzMDYxOWUyYzBmOTVhMzYwY2ViNTczYzcwNjAzMTM5ODYyYWZkNjE3ZmE5YjlmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzM0N2Q2ZDlhMDJjNDg5MjdlYmZiODZjMTM1OWIxY2FmMTMwYTNjMDI2N2QxMWNlNjM0NGIzOWY5OWQ0M2NjMzgnLFxuICAgICAgICAnNjBlYTdmNjFhMzUzNTI0ZDFjOTg3ZjZlY2VjOTJmMDg2ZDU2NWFiNjg3ODcwY2IxMjY4OWZmMWUzMWM3NDQ0OCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkYTY1NDVkMjE4MWRiOGQ5ODNmN2RjYjM3NWVmNTg2NmQ0N2M2N2IxYmYzMWM4Y2Y4NTVlZjc0MzdiNzI2NTZhJyxcbiAgICAgICAgJzQ5Yjk2NzE1YWI2ODc4YTc5ZTc4ZjA3Y2U1NjgwYzVkNjY3MzA1MWI0OTM1YmQ4OTdmZWE4MjRiNzdkYzIwOGEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYzQwNzQ3Y2M5ZDAxMmNiMWExM2I4MTQ4MzA5YzZkZTdlYzI1ZDY5NDVkNjU3MTQ2YjlkNTk5NGI4ZmViMTExMScsXG4gICAgICAgICc1Y2E1NjA3NTNiZTJhMTJmYzZkZTZjYWYyY2I0ODk1NjVkYjkzNjE1NmI5NTE0ZTFiYjVlODMwMzdlMGZhMmQ0J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzRlNDJjOGVjODJjOTk3OThjY2YzYTYxMGJlODcwZTc4MzM4YzdmNzEzMzQ4YmQzNGM4MjAzZWY0MDM3ZjM1MDInLFxuICAgICAgICAnNzU3MWQ3NGVlNWUwZmI5MmE3YThiMzNhMDc3ODMzNDFhNTQ5MjE0NGNjNTRiY2M0MGE5NDQ3MzY5MzYwNjQzNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICczNzc1YWI3MDg5YmM2YWY4MjNhYmEyZTFhZjcwYjIzNmQyNTFjYWRiMGM4Njc0MzI4NzUyMmExYjNiMGRlZGVhJyxcbiAgICAgICAgJ2JlNTJkMTA3YmNmYTA5ZDhiY2I5NzM2YTgyOGNmYTdmYWM4ZGIxN2JmN2E3NmEyYzQyYWQ5NjE0MDkwMThjZjcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnY2VlMzFjYmY3ZTM0ZWMzNzlkOTRmYjgxNGQzZDc3NWFkOTU0NTk1ZDEzMTRiYTg4NDY5NTllM2U4MmY3NGUyNicsXG4gICAgICAgICc4ZmQ2NGExNGMwNmI1ODljMjZiOTQ3YWUyYmNmNmJmYTAxNDllZjBiZTE0ZWQ0ZDgwZjQ0OGEwMWM0M2IxYzZkJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2I0ZjllYWVhMDliNjkxNzYxOWY2ZWE2YTRlYjU0NjRlZmRkYjU4ZmQ0NWIxZWJlZmNkYzFhMDFkMDhiNDc5ODYnLFxuICAgICAgICAnMzllNWM5OTI1YjVhNTRiMDc0MzNhNGYxOGM2MTcyNmY4YmIxMzFjMDEyY2E1NDJlYjI0YThhYzA3MjAwNjgyYSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkNDI2M2RmYzNkMmRmOTIzYTAxNzlhNDg5NjZkMzBjZTg0ZTI1MTVhZmMzZGNjYzFiNzc5MDc3OTJlYmNjNjBlJyxcbiAgICAgICAgJzYyZGZhZjA3YTBmNzhmZWIzMGUzMGQ2Mjk1ODUzY2UxODllMTI3NzYwYWQ2Y2Y3ZmFlMTY0ZTEyMmEyMDhkNTQnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNDg0NTc1MjQ4MjBmYTY1YTRmOGQzNWViNjkzMDg1N2MwMDMyYWNjMGE0YTJkZTQyMjIzM2VlZGE4OTc2MTJjNCcsXG4gICAgICAgICcyNWE3NDhhYjM2Nzk3OWQ5ODczM2MzOGExZmExYzJlN2RjNmNjMDdkYjJkNjBhOWFlN2E3NmFhYTQ5YmQwZjc3J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2RmZWVlZjE4ODExMDFmMmNiMTE2NDRmM2EyYWZkZmMyMDQ1ZTE5OTE5MTUyOTIzZjM2N2ExNzY3YzExY2NlZGEnLFxuICAgICAgICAnZWNmYjcwNTZjZjFkZTA0MmY5NDIwYmFiMzk2NzkzYzBjMzkwYmRlNzRiNGJiZGZmMTZhODNhZTA5YTlhNzUxNydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc2ZDdlZjZiMTc1NDNmODM3M2M1NzNmNDRlMWYzODk4MzVkODliY2JjNjA2MmNlZDM2YzgyZGY4M2I4ZmFlODU5JyxcbiAgICAgICAgJ2NkNDUwZWMzMzU0Mzg5ODZkZmVmYTEwYzU3ZmVhOWJjYzUyMWEwOTU5YjJkODBiYmY3NGIxOTBkY2E3MTJkMTAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZTc1NjA1ZDU5MTAyYTVhMjY4NDUwMGQzYjk5MWYyZTNmM2M4OGI5MzIyNTU0NzAzNWFmMjVhZjY2ZTA0NTQxZicsXG4gICAgICAgICdmNWM1NDc1NGE4ZjcxZWU1NDBiOWI0ODcyODQ3M2UzMTRmNzI5YWM1MzA4YjA2OTM4MzYwOTkwZTJiZmFkMTI1J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2ViOTg2NjBmNGM0ZGZhYTA2YTJiZTQ1M2Q1MDIwYmM5OWEwYzJlNjBhYmUzODg0NTdkZDQzZmVmYjFlZDYyMGMnLFxuICAgICAgICAnNmNiOWE4ODc2ZDljYjg1MjA2MDlhZjNhZGQyNmNkMjBhMGE3Y2Q4YTk0MTExMzFjZTg1ZjQ0MTAwMDk5MjIzZSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICcxM2U4N2IwMjdkODUxNGQzNTkzOWYyZTY4OTJiMTk5MjIxNTQ1OTY5NDE4ODgzMzZkYzM1NjNlM2I4ZGJhOTQyJyxcbiAgICAgICAgJ2ZlZjVhM2M2ODA1OWE2ZGVjNWQ2MjQxMTRiZjFlOTFhYWMyYjlkYTU2OGQ2YWJlYjI1NzBkNTU2NDZiOGFkZjEnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnZWUxNjMwMjZlOWZkNmZlMDE3YzM4ZjA2YTViZTZmYzEyNTQyNGIzNzFjZTI3MDhlN2JmNDQ5MTY5MWU1NzY0YScsXG4gICAgICAgICcxYWNiMjUwZjI1NWRkNjFjNDNkOTRjY2M2NzBkMGY1OGY0OWFlM2ZhMTViOTY2MjNlNTQzMGRhMGFkNmM2MmIyJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2IyNjhmNWVmOWFkNTFlNGQ3OGRlM2E3NTBjMmRjODliMWU2MjZkNDM1MDU4Njc5OTk5MzJlNWRiMzNhZjNkODAnLFxuICAgICAgICAnNWYzMTBkNGIzYzk5YjllYmIxOWY3N2Q0MWMxZGVlMDE4Y2YwZDM0ZmQ0MTkxNjE0MDAzZTk0NWExMjE2ZTQyMydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdmZjA3ZjMxMThhOWRmMDM1ZTlmYWQ4NWViNmM3YmZlNDJiMDJmMDFjYTk5Y2VlYTNiZjdmZmRiYTkzYzQ3NTBkJyxcbiAgICAgICAgJzQzODEzNmQ2MDNlODU4YTNhNWM0NDBjMzhlY2NiYWRkYzFkMjk0MjExNGUyZWRkZDQ3NDBkMDk4Y2VkMWYwZDgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnOGQ4Yjk4NTVjN2MwNTJhMzQxNDZmZDIwZmZiNjU4YmVhNGI5ZjY5ZTBkODI1ZWJlYzE2ZThjM2NlMmI1MjZhMScsXG4gICAgICAgICdjZGI1NTllZWRjMmQ3OWY5MjZiYWY0NGZiODRlYTRkNDRiY2Y1MGZlZTUxZDdjZWIzMGUyZTdmNDYzMDM2NzU4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzUyZGIwYjUzODRkZmJmMDViZmE5ZDQ3MmQ3YWUyNmRmZTRiODUxY2VjYTkxYjFlYmE1NDI2MzE4MGRhMzJiNjMnLFxuICAgICAgICAnYzNiOTk3ZDA1MGVlNWQ0MjNlYmFmNjZhNmRiOWY1N2IzMTgwYzkwMjg3NTY3OWRlOTI0YjY5ZDg0YTdiMzc1J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2U2MmY5NDkwZDNkNTFkYTYzOTVlZmQyNGU4MDkxOWNjN2QwZjI5YzNmM2ZhNDhjNmZmZjU0M2JlY2JkNDMzNTInLFxuICAgICAgICAnNmQ4OWFkN2JhNDg3NmIwYjIyYzJjYTI4MGM2ODI4NjJmMzQyYzg1OTFmMWRhZjUxNzBlMDdiZmQ5Y2NhZmE3ZCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3ZjMwZWEyNDc2YjM5OWI0OTU3NTA5Yzg4Zjc3ZDAxOTFhZmEyZmY1Y2I3YjE0ZmQ2ZDhlN2Q2NWFhYWIxMTkzJyxcbiAgICAgICAgJ2NhNWVmN2Q0YjIzMWM5NGMzYjE1Mzg5YTVmNjMxMWU5ZGFmZjdiYjY3YjEwM2U5ODgwZWY0YmZmNjM3YWNhZWMnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNTA5OGZmMWUxZDlmMTRmYjQ2YTIxMGZhZGE2YzkwM2ZlZjBmYjdiNGExZGQxZDlhYzYwYTAzNjE4MDBiN2EwMCcsXG4gICAgICAgICc5NzMxMTQxZDgxZmM4ZjgwODRkMzdjNmU3NTQyMDA2YjNlZTFiNDBkNjBkZmU1MzYyYTViMTMyZmQxN2RkYzAnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzJiNzhjN2RlOWVlNTEyYTcyODk1YmU2YjljYmVmYTZlMmYzYzRjY2NlNDQ1Yzk2YjlmMmM4MWUyNzc4YWQ1OCcsXG4gICAgICAgICdlZTE4NDlmNTEzZGY3MWUzMmVmYzM4OTZlZTI4MjYwYzczYmI4MDU0N2FlMjI3NWJhNDk3MjM3Nzk0Yzg3NTNjJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2UyY2I3NGZkZGM4ZTlmYmNkMDc2ZWVmMmE3YzcyYjBjZTM3ZDUwZjA4MjY5ZGZjMDc0YjU4MTU1MDU0N2E0ZjcnLFxuICAgICAgICAnZDNhYTJlZDcxYzlkZDIyNDdhNjJkZjA2MjczNmViMGJhZGRlYTllMzYxMjJkMmJlODY0MWFiY2IwMDVjYzRhNCdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc4NDM4NDQ3NTY2ZDRkN2JlZGFkYzI5OTQ5NmFiMzU3NDI2MDA5YTM1ZjIzNWNiMTQxYmUwZDk5Y2QxMGFlM2E4JyxcbiAgICAgICAgJ2M0ZTEwMjA5MTY5ODBhNGRhNWQwMWFjNWU2YWQzMzA3MzRlZjBkNzkwNjYzMWM0ZjIzOTA0MjZiMmVkZDc5MWYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNDE2MmQ0ODhiODk0MDIwMzliNTg0YzZmYzZjMzA4ODcwNTg3ZDljNDZmNjYwYjg3OGFiNjVjODJjNzExZDY3ZScsXG4gICAgICAgICc2NzE2M2U5MDMyMzYyODlmNzc2ZjIyYzI1ZmI4YTNhZmMxNzMyZjJiODRiNGU5NWRiZGE0N2FlNWEwODUyNjQ5J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzNmYWQzZmE4NGNhZjBmMzRmMGY4OWJmZDJkY2Y1NGZjMTc1ZDc2N2FlYzNlNTA2ODRmM2JhNGE0YmY1ZjY4M2QnLFxuICAgICAgICAnY2QxYmM3Y2I2Y2M0MDdiYjJmMGNhNjQ3YzcxOGE3MzBjZjcxODcyZTdkMGQyYTUzZmEyMGVmY2RmZTYxODI2J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzY3NGYyNjAwYTMwMDdhMDA1NjhjMWE3Y2UwNWQwODE2YzFmYjg0YmYxMzcwNzk4ZjFjNjk1MzJmYWViMWE4NmInLFxuICAgICAgICAnMjk5ZDIxZjk0MTNmMzNiM2VkZjQzYjI1NzAwNDU4MGI3MGRiNTdkYTBiMTgyMjU5ZTA5ZWVjYzY5ZTBkMzhhNSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkMzJmNGRhNTRhZGU3NGFiYjgxYjgxNWFkMWZiM2IyNjNkODJkNmM2OTI3MTRiY2ZmODdkMjliZDVlZTlmMDhmJyxcbiAgICAgICAgJ2Y5NDI5ZTczOGI4ZTUzYjk2OGU5OTAxNmMwNTk3MDc3ODJlMTRmNDUzNTM1OWQ1ODJmYzQxNjkxMGIzZWVhODcnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzBlNGU2NzA0MzUzODU1NTZlNTkzNjU3MTM1ODQ1ZDM2ZmJiNjkzMWY3MmIwOGNiMWVkOTU0ZjFlM2NlM2ZmNicsXG4gICAgICAgICc0NjJmOWJjZTYxOTg5ODYzODQ5OTM1MDExM2JiYzliMTBhODc4ZDM1ZGE3MDc0MGRjNjk1YTU1OWViODhkYjdiJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2JlMjA2MjAwM2M1MWNjMzAwNDY4MjkwNDMzMGU0ZGVlN2YzZGNkMTBiMDFlNTgwYmYxOTcxYjA0ZDRjYWQyOTcnLFxuICAgICAgICAnNjIxODhiYzQ5ZDYxZTU0Mjg1NzNkNDhhNzRlMWM2NTViMWM2MTA5MDkwNTY4MmEwZDU1NThlZDcyZGNjYjliYydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc5MzE0NDQyM2FjZTM0NTFlZDI5ZTBmYjlhYzJhZjIxMWNiNmU4NGE2MDFkZjU5OTNjNDE5ODU5ZmZmNWRmMDRhJyxcbiAgICAgICAgJzdjMTBkZmIxNjRjMzQyNWY1YzcxYTNmOWQ3OTkyMDM4ZjEwNjUyMjRmNzJiYjlkMWQ5MDJhNmQxMzAzN2I0N2MnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnYjAxNWY4MDQ0ZjVmY2JkY2YyMWNhMjZkNmMzNGZiODE5NzgyOTIwNWM3YjdkMmE3Y2I2NjQxOGMxNTdiMTEyYycsXG4gICAgICAgICdhYjhjMWUwODZkMDRlODEzNzQ0YTY1NWIyZGY4ZDVmODNiM2NkYzZmYWEzMDg4YzFkM2FlYTE0NTRlM2ExZDVmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJ2Q1ZTllMWRhNjQ5ZDk3ZDg5ZTQ4NjgxMTdhNDY1YTNhNGY4YTE4ZGU1N2ExNDBkMzZiM2YyYWYzNDFhMjFiNTInLFxuICAgICAgICAnNGNiMDQ0MzdmMzkxZWQ3MzExMWExM2NjMWQ0ZGQwZGIxNjkzNDY1YzIyNDA0ODBkODk1NWU4NTkyZjI3NDQ3YSdcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICdkM2FlNDEwNDdkZDdjYTA2NWRiZjhlZDc3Yjk5MjQzOTk4MzAwNWNkNzJlMTZkNmY5OTZhNTMxNmQzNjk2NmJiJyxcbiAgICAgICAgJ2JkMWFlYjIxYWQyMmViYjIyYTEwZjAzMDM0MTdjNmQ5NjRmOGNkZDdkZjBhY2E2MTRiMTBkYzE0ZDEyNWFjNDYnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnNDYzZTI3NjNkODg1Zjk1OGZjNjZjZGQyMjgwMGYwYTQ4NzE5N2QwYTgyZTM3N2I0OWY4MGFmODdjODk3YjA2NScsXG4gICAgICAgICdiZmVmYWNkYjBlNWQwZmQ3ZGYzYTMxMWE5NGRlMDYyYjI2YjgwYzYxZmJjOTc1MDhiNzk5OTI2NzFlZjdjYTdmJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzc5ODVmZGZkMTI3YzA1NjdjNmY1M2VjMWJiNjNlYzMxNThlNTk3YzQwYmZlNzQ3YzgzY2RkZmM5MTA2NDE5MTcnLFxuICAgICAgICAnNjAzYzEyZGFmM2Q5ODYyZWYyYjI1ZmUxZGUyODlhZWQyNGVkMjkxZTBlYzY3MDg3MDNhNWJkNTY3ZjMyZWQwMydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3NGExYWQ2YjVmNzZlMzlkYjJkZDI0OTQxMGVhYzdmOTllNzRjNTljYjgzZDJkMGVkNWZmMTU0M2RhNzcwM2U5JyxcbiAgICAgICAgJ2NjNjE1N2VmMThjOWM2M2NkNjE5M2Q4MzYzMWJiZWEwMDkzZTA5Njg5NDJlOGMzM2Q1NzM3ZmQ3OTBlMGRiMDgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnMzA2ODJhNTA3MDMzNzVmNjAyZDQxNjY2NGJhMTliN2ZjOWJhYjQyYzcyNzQ3NDYzYTcxZDA4OTZiMjJmNmRhMycsXG4gICAgICAgICc1NTNlMDRmNmIwMThiNGZhNmM4ZjM5ZTdmMzExZDMxNzYyOTBkMGUwZjE5Y2E3M2YxNzcxNGQ5OTc3YTIyZmY4J1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzllMjE1OGYwZDdjMGQ1ZjI2YzM3OTFlZmVmYTc5NTk3NjU0ZTdhMmIyNDY0ZjUyYjFlZTZjMTM0Nzc2OWVmNTcnLFxuICAgICAgICAnNzEyZmNkZDFiOTA1M2YwOTAwM2EzNDgxZmE3NzYyZTlmZmQ3YzhlZjM1YTM4NTA5ZTJmYmYyNjI5MDA4MzczJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzE3NmUyNjk4OWE0M2M5Y2ZlYmE0MDI5YzIwMjUzOGMyODE3MmU1NjZlM2M0ZmNlNzMyMjg1N2YzYmUzMjdkNjYnLFxuICAgICAgICAnZWQ4Y2M5ZDA0YjI5ZWI4NzdkMjcwYjQ4NzhkYzQzYzE5YWVmZDMxZjRlZWUwOWVlN2I0NzgzNGMxZmE0YjFjMydcbiAgICAgIF0sXG4gICAgICBbXG4gICAgICAgICc3NWQ0NmVmZWEzNzcxZTZlNjhhYmI4OWExM2FkNzQ3ZWNmMTg5MjM5M2RmYzRmMWI3MDA0Nzg4YzUwMzc0ZGE4JyxcbiAgICAgICAgJzk4NTIzOTBhOTk1MDc2NzlmZDBiODZmZDJiMzlhODY4ZDdlZmMyMjE1MTM0NmUxYTNjYTQ3MjY1ODZhNmJlZDgnXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICAnODA5YTIwYzY3ZDY0OTAwZmZiNjk4YzRjODI1ZjZkNWYyMzEwZmIwNDUxYzg2OTM0NWI3MzE5ZjY0NTYwNTcyMScsXG4gICAgICAgICc5ZTk5NDk4MGQ5OTE3ZTIyYjc2YjA2MTkyN2ZhMDQxNDNkMDk2Y2NjNTQ5NjNlNmE1ZWJmYTVmM2Y4ZTI4NmMxJ1xuICAgICAgXSxcbiAgICAgIFtcbiAgICAgICAgJzFiMzg5MDNhNDNmN2YxMTRlZDQ1MDBiNGVhYzcwODNmZGVmZWNlMWNmMjljNjM1MjhkNTYzNDQ2Zjk3MmMxODAnLFxuICAgICAgICAnNDAzNmVkYzkzMWE2MGFlODg5MzUzZjc3ZmQ1M2RlNGEyNzA4YjI2YjZmNWRhNzJhZDMzOTQxMTlkYWY0MDhmOSdcbiAgICAgIF1cbiAgICBdXG4gIH1cbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IGV4cG9ydHM7XG52YXIgQk4gPSByZXF1aXJlKCdibi5qcycpO1xudmFyIG1pbkFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcbnZhciBtaW5VdGlscyA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1jcnlwdG8tdXRpbHMnKTtcblxudXRpbHMuYXNzZXJ0ID0gbWluQXNzZXJ0O1xudXRpbHMudG9BcnJheSA9IG1pblV0aWxzLnRvQXJyYXk7XG51dGlscy56ZXJvMiA9IG1pblV0aWxzLnplcm8yO1xudXRpbHMudG9IZXggPSBtaW5VdGlscy50b0hleDtcbnV0aWxzLmVuY29kZSA9IG1pblV0aWxzLmVuY29kZTtcblxuLy8gUmVwcmVzZW50IG51bSBpbiBhIHctTkFGIGZvcm1cbmZ1bmN0aW9uIGdldE5BRihudW0sIHcpIHtcbiAgdmFyIG5hZiA9IFtdO1xuICB2YXIgd3MgPSAxIDw8ICh3ICsgMSk7XG4gIHZhciBrID0gbnVtLmNsb25lKCk7XG4gIHdoaWxlIChrLmNtcG4oMSkgPj0gMCkge1xuICAgIHZhciB6O1xuICAgIGlmIChrLmlzT2RkKCkpIHtcbiAgICAgIHZhciBtb2QgPSBrLmFuZGxuKHdzIC0gMSk7XG4gICAgICBpZiAobW9kID4gKHdzID4+IDEpIC0gMSlcbiAgICAgICAgeiA9ICh3cyA+PiAxKSAtIG1vZDtcbiAgICAgIGVsc2VcbiAgICAgICAgeiA9IG1vZDtcbiAgICAgIGsuaXN1Ym4oeik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHogPSAwO1xuICAgIH1cbiAgICBuYWYucHVzaCh6KTtcblxuICAgIC8vIE9wdGltaXphdGlvbiwgc2hpZnQgYnkgd29yZCBpZiBwb3NzaWJsZVxuICAgIHZhciBzaGlmdCA9IChrLmNtcG4oMCkgIT09IDAgJiYgay5hbmRsbih3cyAtIDEpID09PSAwKSA/ICh3ICsgMSkgOiAxO1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgc2hpZnQ7IGkrKylcbiAgICAgIG5hZi5wdXNoKDApO1xuICAgIGsuaXVzaHJuKHNoaWZ0KTtcbiAgfVxuXG4gIHJldHVybiBuYWY7XG59XG51dGlscy5nZXROQUYgPSBnZXROQUY7XG5cbi8vIFJlcHJlc2VudCBrMSwgazIgaW4gYSBKb2ludCBTcGFyc2UgRm9ybVxuZnVuY3Rpb24gZ2V0SlNGKGsxLCBrMikge1xuICB2YXIganNmID0gW1xuICAgIFtdLFxuICAgIFtdXG4gIF07XG5cbiAgazEgPSBrMS5jbG9uZSgpO1xuICBrMiA9IGsyLmNsb25lKCk7XG4gIHZhciBkMSA9IDA7XG4gIHZhciBkMiA9IDA7XG4gIHdoaWxlIChrMS5jbXBuKC1kMSkgPiAwIHx8IGsyLmNtcG4oLWQyKSA+IDApIHtcblxuICAgIC8vIEZpcnN0IHBoYXNlXG4gICAgdmFyIG0xNCA9IChrMS5hbmRsbigzKSArIGQxKSAmIDM7XG4gICAgdmFyIG0yNCA9IChrMi5hbmRsbigzKSArIGQyKSAmIDM7XG4gICAgaWYgKG0xNCA9PT0gMylcbiAgICAgIG0xNCA9IC0xO1xuICAgIGlmIChtMjQgPT09IDMpXG4gICAgICBtMjQgPSAtMTtcbiAgICB2YXIgdTE7XG4gICAgaWYgKChtMTQgJiAxKSA9PT0gMCkge1xuICAgICAgdTEgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgbTggPSAoazEuYW5kbG4oNykgKyBkMSkgJiA3O1xuICAgICAgaWYgKChtOCA9PT0gMyB8fCBtOCA9PT0gNSkgJiYgbTI0ID09PSAyKVxuICAgICAgICB1MSA9IC1tMTQ7XG4gICAgICBlbHNlXG4gICAgICAgIHUxID0gbTE0O1xuICAgIH1cbiAgICBqc2ZbMF0ucHVzaCh1MSk7XG5cbiAgICB2YXIgdTI7XG4gICAgaWYgKChtMjQgJiAxKSA9PT0gMCkge1xuICAgICAgdTIgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgbTggPSAoazIuYW5kbG4oNykgKyBkMikgJiA3O1xuICAgICAgaWYgKChtOCA9PT0gMyB8fCBtOCA9PT0gNSkgJiYgbTE0ID09PSAyKVxuICAgICAgICB1MiA9IC1tMjQ7XG4gICAgICBlbHNlXG4gICAgICAgIHUyID0gbTI0O1xuICAgIH1cbiAgICBqc2ZbMV0ucHVzaCh1Mik7XG5cbiAgICAvLyBTZWNvbmQgcGhhc2VcbiAgICBpZiAoMiAqIGQxID09PSB1MSArIDEpXG4gICAgICBkMSA9IDEgLSBkMTtcbiAgICBpZiAoMiAqIGQyID09PSB1MiArIDEpXG4gICAgICBkMiA9IDEgLSBkMjtcbiAgICBrMS5pdXNocm4oMSk7XG4gICAgazIuaXVzaHJuKDEpO1xuICB9XG5cbiAgcmV0dXJuIGpzZjtcbn1cbnV0aWxzLmdldEpTRiA9IGdldEpTRjtcblxuZnVuY3Rpb24gY2FjaGVkUHJvcGVydHkob2JqLCBuYW1lLCBjb21wdXRlcikge1xuICB2YXIga2V5ID0gJ18nICsgbmFtZTtcbiAgb2JqLnByb3RvdHlwZVtuYW1lXSA9IGZ1bmN0aW9uIGNhY2hlZFByb3BlcnR5KCkge1xuICAgIHJldHVybiB0aGlzW2tleV0gIT09IHVuZGVmaW5lZCA/IHRoaXNba2V5XSA6XG4gICAgICAgICAgIHRoaXNba2V5XSA9IGNvbXB1dGVyLmNhbGwodGhpcyk7XG4gIH07XG59XG51dGlscy5jYWNoZWRQcm9wZXJ0eSA9IGNhY2hlZFByb3BlcnR5O1xuXG5mdW5jdGlvbiBwYXJzZUJ5dGVzKGJ5dGVzKSB7XG4gIHJldHVybiB0eXBlb2YgYnl0ZXMgPT09ICdzdHJpbmcnID8gdXRpbHMudG9BcnJheShieXRlcywgJ2hleCcpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBieXRlcztcbn1cbnV0aWxzLnBhcnNlQnl0ZXMgPSBwYXJzZUJ5dGVzO1xuXG5mdW5jdGlvbiBpbnRGcm9tTEUoYnl0ZXMpIHtcbiAgcmV0dXJuIG5ldyBCTihieXRlcywgJ2hleCcsICdsZScpO1xufVxudXRpbHMuaW50RnJvbUxFID0gaW50RnJvbUxFO1xuXG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gIFwiX2FyZ3NcIjogW1xuICAgIFtcbiAgICAgIFwiZWxsaXB0aWNANi40LjFcIixcbiAgICAgIFwiQzpcXFxcVXNlcnNcXFxcQWRtaW5pc3RyYXRvclxcXFxjb2RlXFxcXHhsc3gtcG9wdWxhdGVcIlxuICAgIF1cbiAgXSxcbiAgXCJfZGV2ZWxvcG1lbnRcIjogdHJ1ZSxcbiAgXCJfZnJvbVwiOiBcImVsbGlwdGljQDYuNC4xXCIsXG4gIFwiX2lkXCI6IFwiZWxsaXB0aWNANi40LjFcIixcbiAgXCJfaW5CdW5kbGVcIjogZmFsc2UsXG4gIFwiX2ludGVncml0eVwiOiBcInNoYTUxMi1Cc1hMejVzcVg4T0hjc2g3Q3FCTXp0eVhBUm1HUTNMV1B0R2pKaTZEaUpIcTVDL3F2aTlQM09xZ3N3S1NEZnRidTgrSW9JL1FEVEFtMmZGblE5U1pTUT09XCIsXG4gIFwiX2xvY2F0aW9uXCI6IFwiL2VsbGlwdGljXCIsXG4gIFwiX3BoYW50b21DaGlsZHJlblwiOiB7fSxcbiAgXCJfcmVxdWVzdGVkXCI6IHtcbiAgICBcInR5cGVcIjogXCJ2ZXJzaW9uXCIsXG4gICAgXCJyZWdpc3RyeVwiOiB0cnVlLFxuICAgIFwicmF3XCI6IFwiZWxsaXB0aWNANi40LjFcIixcbiAgICBcIm5hbWVcIjogXCJlbGxpcHRpY1wiLFxuICAgIFwiZXNjYXBlZE5hbWVcIjogXCJlbGxpcHRpY1wiLFxuICAgIFwicmF3U3BlY1wiOiBcIjYuNC4xXCIsXG4gICAgXCJzYXZlU3BlY1wiOiBudWxsLFxuICAgIFwiZmV0Y2hTcGVjXCI6IFwiNi40LjFcIlxuICB9LFxuICBcIl9yZXF1aXJlZEJ5XCI6IFtcbiAgICBcIi9icm93c2VyaWZ5LXNpZ25cIixcbiAgICBcIi9jcmVhdGUtZWNkaFwiXG4gIF0sXG4gIFwiX3Jlc29sdmVkXCI6IFwiaHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmcvZWxsaXB0aWMvLS9lbGxpcHRpYy02LjQuMS50Z3pcIixcbiAgXCJfc3BlY1wiOiBcIjYuNC4xXCIsXG4gIFwiX3doZXJlXCI6IFwiQzpcXFxcVXNlcnNcXFxcQWRtaW5pc3RyYXRvclxcXFxjb2RlXFxcXHhsc3gtcG9wdWxhdGVcIixcbiAgXCJhdXRob3JcIjoge1xuICAgIFwibmFtZVwiOiBcIkZlZG9yIEluZHV0bnlcIixcbiAgICBcImVtYWlsXCI6IFwiZmVkb3JAaW5kdXRueS5jb21cIlxuICB9LFxuICBcImJ1Z3NcIjoge1xuICAgIFwidXJsXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL2luZHV0bnkvZWxsaXB0aWMvaXNzdWVzXCJcbiAgfSxcbiAgXCJkZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiYm4uanNcIjogXCJeNC40LjBcIixcbiAgICBcImJyb3JhbmRcIjogXCJeMS4wLjFcIixcbiAgICBcImhhc2guanNcIjogXCJeMS4wLjBcIixcbiAgICBcImhtYWMtZHJiZ1wiOiBcIl4xLjAuMFwiLFxuICAgIFwiaW5oZXJpdHNcIjogXCJeMi4wLjFcIixcbiAgICBcIm1pbmltYWxpc3RpYy1hc3NlcnRcIjogXCJeMS4wLjBcIixcbiAgICBcIm1pbmltYWxpc3RpYy1jcnlwdG8tdXRpbHNcIjogXCJeMS4wLjBcIlxuICB9LFxuICBcImRlc2NyaXB0aW9uXCI6IFwiRUMgY3J5cHRvZ3JhcGh5XCIsXG4gIFwiZGV2RGVwZW5kZW5jaWVzXCI6IHtcbiAgICBcImJyZnNcIjogXCJeMS40LjNcIixcbiAgICBcImNvdmVyYWxsc1wiOiBcIl4yLjExLjNcIixcbiAgICBcImdydW50XCI6IFwiXjAuNC41XCIsXG4gICAgXCJncnVudC1icm93c2VyaWZ5XCI6IFwiXjUuMC4wXCIsXG4gICAgXCJncnVudC1jbGlcIjogXCJeMS4yLjBcIixcbiAgICBcImdydW50LWNvbnRyaWItY29ubmVjdFwiOiBcIl4xLjAuMFwiLFxuICAgIFwiZ3J1bnQtY29udHJpYi1jb3B5XCI6IFwiXjEuMC4wXCIsXG4gICAgXCJncnVudC1jb250cmliLXVnbGlmeVwiOiBcIl4xLjAuMVwiLFxuICAgIFwiZ3J1bnQtbW9jaGEtaXN0YW5idWxcIjogXCJeMy4wLjFcIixcbiAgICBcImdydW50LXNhdWNlbGFic1wiOiBcIl44LjYuMlwiLFxuICAgIFwiaXN0YW5idWxcIjogXCJeMC40LjJcIixcbiAgICBcImpzY3NcIjogXCJeMi45LjBcIixcbiAgICBcImpzaGludFwiOiBcIl4yLjYuMFwiLFxuICAgIFwibW9jaGFcIjogXCJeMi4xLjBcIlxuICB9LFxuICBcImZpbGVzXCI6IFtcbiAgICBcImxpYlwiXG4gIF0sXG4gIFwiaG9tZXBhZ2VcIjogXCJodHRwczovL2dpdGh1Yi5jb20vaW5kdXRueS9lbGxpcHRpY1wiLFxuICBcImtleXdvcmRzXCI6IFtcbiAgICBcIkVDXCIsXG4gICAgXCJFbGxpcHRpY1wiLFxuICAgIFwiY3VydmVcIixcbiAgICBcIkNyeXB0b2dyYXBoeVwiXG4gIF0sXG4gIFwibGljZW5zZVwiOiBcIk1JVFwiLFxuICBcIm1haW5cIjogXCJsaWIvZWxsaXB0aWMuanNcIixcbiAgXCJuYW1lXCI6IFwiZWxsaXB0aWNcIixcbiAgXCJyZXBvc2l0b3J5XCI6IHtcbiAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICBcInVybFwiOiBcImdpdCtzc2g6Ly9naXRAZ2l0aHViLmNvbS9pbmR1dG55L2VsbGlwdGljLmdpdFwiXG4gIH0sXG4gIFwic2NyaXB0c1wiOiB7XG4gICAgXCJqc2NzXCI6IFwianNjcyBiZW5jaG1hcmtzLyouanMgbGliLyouanMgbGliLyoqLyouanMgbGliLyoqLyoqLyouanMgdGVzdC9pbmRleC5qc1wiLFxuICAgIFwianNoaW50XCI6IFwianNjcyBiZW5jaG1hcmtzLyouanMgbGliLyouanMgbGliLyoqLyouanMgbGliLyoqLyoqLyouanMgdGVzdC9pbmRleC5qc1wiLFxuICAgIFwibGludFwiOiBcIm5wbSBydW4ganNjcyAmJiBucG0gcnVuIGpzaGludFwiLFxuICAgIFwidGVzdFwiOiBcIm5wbSBydW4gbGludCAmJiBucG0gcnVuIHVuaXRcIixcbiAgICBcInVuaXRcIjogXCJpc3RhbmJ1bCB0ZXN0IF9tb2NoYSAtLXJlcG9ydGVyPXNwZWMgdGVzdC9pbmRleC5qc1wiLFxuICAgIFwidmVyc2lvblwiOiBcImdydW50IGRpc3QgJiYgZ2l0IGFkZCBkaXN0L1wiXG4gIH0sXG4gIFwidmVyc2lvblwiOiBcIjYuNC4xXCJcbn1cbiIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgb2JqZWN0Q3JlYXRlID0gT2JqZWN0LmNyZWF0ZSB8fCBvYmplY3RDcmVhdGVQb2x5ZmlsbFxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBvYmplY3RLZXlzUG9seWZpbGxcbnZhciBiaW5kID0gRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgfHwgZnVuY3Rpb25CaW5kUG9seWZpbGxcblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMsICdfZXZlbnRzJykpIHtcbiAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICB9XG5cbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gdGhpcy5fbWF4TGlzdGVuZXJzIHx8IHVuZGVmaW5lZDtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjEwLnhcbkV2ZW50RW1pdHRlci5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycyA9IHVuZGVmaW5lZDtcblxuLy8gQnkgZGVmYXVsdCBFdmVudEVtaXR0ZXJzIHdpbGwgcHJpbnQgYSB3YXJuaW5nIGlmIG1vcmUgdGhhbiAxMCBsaXN0ZW5lcnMgYXJlXG4vLyBhZGRlZCB0byBpdC4gVGhpcyBpcyBhIHVzZWZ1bCBkZWZhdWx0IHdoaWNoIGhlbHBzIGZpbmRpbmcgbWVtb3J5IGxlYWtzLlxudmFyIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblxudmFyIGhhc0RlZmluZVByb3BlcnR5O1xudHJ5IHtcbiAgdmFyIG8gPSB7fTtcbiAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sICd4JywgeyB2YWx1ZTogMCB9KTtcbiAgaGFzRGVmaW5lUHJvcGVydHkgPSBvLnggPT09IDA7XG59IGNhdGNoIChlcnIpIHsgaGFzRGVmaW5lUHJvcGVydHkgPSBmYWxzZSB9XG5pZiAoaGFzRGVmaW5lUHJvcGVydHkpIHtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEV2ZW50RW1pdHRlciwgJ2RlZmF1bHRNYXhMaXN0ZW5lcnMnLCB7XG4gICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uKGFyZykge1xuICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGUgaW5wdXQgaXMgYSBwb3NpdGl2ZSBudW1iZXIgKHdob3NlIHZhbHVlIGlzIHplcm8gb3JcbiAgICAgIC8vIGdyZWF0ZXIgYW5kIG5vdCBhIE5hTikuXG4gICAgICBpZiAodHlwZW9mIGFyZyAhPT0gJ251bWJlcicgfHwgYXJnIDwgMCB8fCBhcmcgIT09IGFyZylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJkZWZhdWx0TWF4TGlzdGVuZXJzXCIgbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICAgICAgZGVmYXVsdE1heExpc3RlbmVycyA9IGFyZztcbiAgICB9XG4gIH0pO1xufSBlbHNlIHtcbiAgRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBkZWZhdWx0TWF4TGlzdGVuZXJzO1xufVxuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBzZXRNYXhMaXN0ZW5lcnMobikge1xuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPCAwIHx8IGlzTmFOKG4pKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiblwiIGFyZ3VtZW50IG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiAkZ2V0TWF4TGlzdGVuZXJzKHRoYXQpIHtcbiAgaWYgKHRoYXQuX21heExpc3RlbmVycyA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgcmV0dXJuIHRoYXQuX21heExpc3RlbmVycztcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5nZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBnZXRNYXhMaXN0ZW5lcnMoKSB7XG4gIHJldHVybiAkZ2V0TWF4TGlzdGVuZXJzKHRoaXMpO1xufTtcblxuLy8gVGhlc2Ugc3RhbmRhbG9uZSBlbWl0KiBmdW5jdGlvbnMgYXJlIHVzZWQgdG8gb3B0aW1pemUgY2FsbGluZyBvZiBldmVudFxuLy8gaGFuZGxlcnMgZm9yIGZhc3QgY2FzZXMgYmVjYXVzZSBlbWl0KCkgaXRzZWxmIG9mdGVuIGhhcyBhIHZhcmlhYmxlIG51bWJlciBvZlxuLy8gYXJndW1lbnRzIGFuZCBjYW4gYmUgZGVvcHRpbWl6ZWQgYmVjYXVzZSBvZiB0aGF0LiBUaGVzZSBmdW5jdGlvbnMgYWx3YXlzIGhhdmVcbi8vIHRoZSBzYW1lIG51bWJlciBvZiBhcmd1bWVudHMgYW5kIHRodXMgZG8gbm90IGdldCBkZW9wdGltaXplZCwgc28gdGhlIGNvZGVcbi8vIGluc2lkZSB0aGVtIGNhbiBleGVjdXRlIGZhc3Rlci5cbmZ1bmN0aW9uIGVtaXROb25lKGhhbmRsZXIsIGlzRm4sIHNlbGYpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZik7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRPbmUoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSkge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdFR3byhoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmcxLCBhcmcyKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmLCBhcmcxLCBhcmcyKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYsIGFyZzEsIGFyZzIpO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0VGhyZWUoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSwgYXJnMiwgYXJnMykge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxLCBhcmcyLCBhcmczKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBlbWl0TWFueShoYW5kbGVyLCBpc0ZuLCBzZWxmLCBhcmdzKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuYXBwbHkoc2VsZiwgYXJncyk7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkoc2VsZiwgYXJncyk7XG4gIH1cbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdCh0eXBlKSB7XG4gIHZhciBlciwgaGFuZGxlciwgbGVuLCBhcmdzLCBpLCBldmVudHM7XG4gIHZhciBkb0Vycm9yID0gKHR5cGUgPT09ICdlcnJvcicpO1xuXG4gIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgaWYgKGV2ZW50cylcbiAgICBkb0Vycm9yID0gKGRvRXJyb3IgJiYgZXZlbnRzLmVycm9yID09IG51bGwpO1xuICBlbHNlIGlmICghZG9FcnJvcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAoZG9FcnJvcikge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSlcbiAgICAgIGVyID0gYXJndW1lbnRzWzFdO1xuICAgIGlmIChlciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQXQgbGVhc3QgZ2l2ZSBzb21lIGtpbmQgb2YgY29udGV4dCB0byB0aGUgdXNlclxuICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5oYW5kbGVkIFwiZXJyb3JcIiBldmVudC4gKCcgKyBlciArICcpJyk7XG4gICAgICBlcnIuY29udGV4dCA9IGVyO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBoYW5kbGVyID0gZXZlbnRzW3R5cGVdO1xuXG4gIGlmICghaGFuZGxlcilcbiAgICByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIGlzRm4gPSB0eXBlb2YgaGFuZGxlciA9PT0gJ2Z1bmN0aW9uJztcbiAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgc3dpdGNoIChsZW4pIHtcbiAgICAgIC8vIGZhc3QgY2FzZXNcbiAgICBjYXNlIDE6XG4gICAgICBlbWl0Tm9uZShoYW5kbGVyLCBpc0ZuLCB0aGlzKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMjpcbiAgICAgIGVtaXRPbmUoaGFuZGxlciwgaXNGbiwgdGhpcywgYXJndW1lbnRzWzFdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMzpcbiAgICAgIGVtaXRUd28oaGFuZGxlciwgaXNGbiwgdGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA0OlxuICAgICAgZW1pdFRocmVlKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdLCBhcmd1bWVudHNbM10pO1xuICAgICAgYnJlYWs7XG4gICAgICAvLyBzbG93ZXJcbiAgICBkZWZhdWx0OlxuICAgICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICAgIGZvciAoaSA9IDE7IGkgPCBsZW47IGkrKylcbiAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICBlbWl0TWFueShoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuZnVuY3Rpb24gX2FkZExpc3RlbmVyKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIsIHByZXBlbmQpIHtcbiAgdmFyIG07XG4gIHZhciBldmVudHM7XG4gIHZhciBleGlzdGluZztcblxuICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgaWYgKCFldmVudHMpIHtcbiAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICB0YXJnZXQuX2V2ZW50c0NvdW50ID0gMDtcbiAgfSBlbHNlIHtcbiAgICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAgIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJcIi5cbiAgICBpZiAoZXZlbnRzLm5ld0xpc3RlbmVyKSB7XG4gICAgICB0YXJnZXQuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyID8gbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgICAgIC8vIFJlLWFzc2lnbiBgZXZlbnRzYCBiZWNhdXNlIGEgbmV3TGlzdGVuZXIgaGFuZGxlciBjb3VsZCBoYXZlIGNhdXNlZCB0aGVcbiAgICAgIC8vIHRoaXMuX2V2ZW50cyB0byBiZSBhc3NpZ25lZCB0byBhIG5ldyBvYmplY3RcbiAgICAgIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICAgIH1cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXTtcbiAgfVxuXG4gIGlmICghZXhpc3RpbmcpIHtcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgICsrdGFyZ2V0Ll9ldmVudHNDb3VudDtcbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIGV4aXN0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID1cbiAgICAgICAgICBwcmVwZW5kID8gW2xpc3RlbmVyLCBleGlzdGluZ10gOiBbZXhpc3RpbmcsIGxpc3RlbmVyXTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgICAgaWYgKHByZXBlbmQpIHtcbiAgICAgICAgZXhpc3RpbmcudW5zaGlmdChsaXN0ZW5lcik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleGlzdGluZy5wdXNoKGxpc3RlbmVyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICAgIGlmICghZXhpc3Rpbmcud2FybmVkKSB7XG4gICAgICBtID0gJGdldE1heExpc3RlbmVycyh0YXJnZXQpO1xuICAgICAgaWYgKG0gJiYgbSA+IDAgJiYgZXhpc3RpbmcubGVuZ3RoID4gbSkge1xuICAgICAgICBleGlzdGluZy53YXJuZWQgPSB0cnVlO1xuICAgICAgICB2YXIgdyA9IG5ldyBFcnJvcignUG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSBsZWFrIGRldGVjdGVkLiAnICtcbiAgICAgICAgICAgIGV4aXN0aW5nLmxlbmd0aCArICcgXCInICsgU3RyaW5nKHR5cGUpICsgJ1wiIGxpc3RlbmVycyAnICtcbiAgICAgICAgICAgICdhZGRlZC4gVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gJyArXG4gICAgICAgICAgICAnaW5jcmVhc2UgbGltaXQuJyk7XG4gICAgICAgIHcubmFtZSA9ICdNYXhMaXN0ZW5lcnNFeGNlZWRlZFdhcm5pbmcnO1xuICAgICAgICB3LmVtaXR0ZXIgPSB0YXJnZXQ7XG4gICAgICAgIHcudHlwZSA9IHR5cGU7XG4gICAgICAgIHcuY291bnQgPSBleGlzdGluZy5sZW5ndGg7XG4gICAgICAgIGlmICh0eXBlb2YgY29uc29sZSA9PT0gJ29iamVjdCcgJiYgY29uc29sZS53YXJuKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKCclczogJXMnLCB3Lm5hbWUsIHcubWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gYWRkTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZExpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIHRydWUpO1xuICAgIH07XG5cbmZ1bmN0aW9uIG9uY2VXcmFwcGVyKCkge1xuICBpZiAoIXRoaXMuZmlyZWQpIHtcbiAgICB0aGlzLnRhcmdldC5yZW1vdmVMaXN0ZW5lcih0aGlzLnR5cGUsIHRoaXMud3JhcEZuKTtcbiAgICB0aGlzLmZpcmVkID0gdHJ1ZTtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCk7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSk7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdKTtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCwgYXJndW1lbnRzWzBdLCBhcmd1bWVudHNbMV0sXG4gICAgICAgICAgICBhcmd1bWVudHNbMl0pO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBhcmdzW2ldID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB0aGlzLmxpc3RlbmVyLmFwcGx5KHRoaXMudGFyZ2V0LCBhcmdzKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gX29uY2VXcmFwKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIHN0YXRlID0geyBmaXJlZDogZmFsc2UsIHdyYXBGbjogdW5kZWZpbmVkLCB0YXJnZXQ6IHRhcmdldCwgdHlwZTogdHlwZSwgbGlzdGVuZXI6IGxpc3RlbmVyIH07XG4gIHZhciB3cmFwcGVkID0gYmluZC5jYWxsKG9uY2VXcmFwcGVyLCBzdGF0ZSk7XG4gIHdyYXBwZWQubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgc3RhdGUud3JhcEZuID0gd3JhcHBlZDtcbiAgcmV0dXJuIHdyYXBwZWQ7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uIG9uY2UodHlwZSwgbGlzdGVuZXIpIHtcbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIHRoaXMub24odHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5wcmVwZW5kT25jZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kT25jZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICB0aGlzLnByZXBlbmRMaXN0ZW5lcih0eXBlLCBfb25jZVdyYXAodGhpcywgdHlwZSwgbGlzdGVuZXIpKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbi8vIEVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZiBhbmQgb25seSBpZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgdmFyIGxpc3QsIGV2ZW50cywgcG9zaXRpb24sIGksIG9yaWdpbmFsTGlzdGVuZXI7XG5cbiAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdGVuZXJcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKCFldmVudHMpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBsaXN0ID0gZXZlbnRzW3R5cGVdO1xuICAgICAgaWYgKCFsaXN0KVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8IGxpc3QubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3QubGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBsaXN0ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHBvc2l0aW9uID0gLTE7XG5cbiAgICAgICAgZm9yIChpID0gbGlzdC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIGlmIChsaXN0W2ldID09PSBsaXN0ZW5lciB8fCBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICAgICAgb3JpZ2luYWxMaXN0ZW5lciA9IGxpc3RbaV0ubGlzdGVuZXI7XG4gICAgICAgICAgICBwb3NpdGlvbiA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gMClcbiAgICAgICAgICBsaXN0LnNoaWZ0KCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBzcGxpY2VPbmUobGlzdCwgcG9zaXRpb24pO1xuXG4gICAgICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICBldmVudHNbdHlwZV0gPSBsaXN0WzBdO1xuXG4gICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIG9yaWdpbmFsTGlzdGVuZXIgfHwgbGlzdGVuZXIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpIHtcbiAgICAgIHZhciBsaXN0ZW5lcnMsIGV2ZW50cywgaTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKCFldmVudHMpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gICAgICBpZiAoIWV2ZW50cy5yZW1vdmVMaXN0ZW5lcikge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgICB0aGlzLl9ldmVudHNDb3VudCA9IDA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnRzW3R5cGVdKSB7XG4gICAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB2YXIga2V5cyA9IG9iamVjdEtleXMoZXZlbnRzKTtcbiAgICAgICAgdmFyIGtleTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBrZXkgPSBrZXlzW2ldO1xuICAgICAgICAgIGlmIChrZXkgPT09ICdyZW1vdmVMaXN0ZW5lcicpIGNvbnRpbnVlO1xuICAgICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoJ3JlbW92ZUxpc3RlbmVyJyk7XG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IG9iamVjdENyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgbGlzdGVuZXJzID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gICAgICB9IGVsc2UgaWYgKGxpc3RlbmVycykge1xuICAgICAgICAvLyBMSUZPIG9yZGVyXG4gICAgICAgIGZvciAoaSA9IGxpc3RlbmVycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG5mdW5jdGlvbiBfbGlzdGVuZXJzKHRhcmdldCwgdHlwZSwgdW53cmFwKSB7XG4gIHZhciBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcblxuICBpZiAoIWV2ZW50cylcbiAgICByZXR1cm4gW107XG5cbiAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG4gIGlmICghZXZsaXN0ZW5lcilcbiAgICByZXR1cm4gW107XG5cbiAgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKVxuICAgIHJldHVybiB1bndyYXAgPyBbZXZsaXN0ZW5lci5saXN0ZW5lciB8fCBldmxpc3RlbmVyXSA6IFtldmxpc3RlbmVyXTtcblxuICByZXR1cm4gdW53cmFwID8gdW53cmFwTGlzdGVuZXJzKGV2bGlzdGVuZXIpIDogYXJyYXlDbG9uZShldmxpc3RlbmVyLCBldmxpc3RlbmVyLmxlbmd0aCk7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24gbGlzdGVuZXJzKHR5cGUpIHtcbiAgcmV0dXJuIF9saXN0ZW5lcnModGhpcywgdHlwZSwgdHJ1ZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJhd0xpc3RlbmVycyA9IGZ1bmN0aW9uIHJhd0xpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIubGlzdGVuZXJDb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxpc3RlbmVyQ291bnQuY2FsbChlbWl0dGVyLCB0eXBlKTtcbiAgfVxufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gbGlzdGVuZXJDb3VudDtcbmZ1bmN0aW9uIGxpc3RlbmVyQ291bnQodHlwZSkge1xuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMpIHtcbiAgICB2YXIgZXZsaXN0ZW5lciA9IGV2ZW50c1t0eXBlXTtcblxuICAgIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfSBlbHNlIGlmIChldmxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gZXZsaXN0ZW5lci5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIDA7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZXZlbnROYW1lcyA9IGZ1bmN0aW9uIGV2ZW50TmFtZXMoKSB7XG4gIHJldHVybiB0aGlzLl9ldmVudHNDb3VudCA+IDAgPyBSZWZsZWN0Lm93bktleXModGhpcy5fZXZlbnRzKSA6IFtdO1xufTtcblxuLy8gQWJvdXQgMS41eCBmYXN0ZXIgdGhhbiB0aGUgdHdvLWFyZyB2ZXJzaW9uIG9mIEFycmF5I3NwbGljZSgpLlxuZnVuY3Rpb24gc3BsaWNlT25lKGxpc3QsIGluZGV4KSB7XG4gIGZvciAodmFyIGkgPSBpbmRleCwgayA9IGkgKyAxLCBuID0gbGlzdC5sZW5ndGg7IGsgPCBuOyBpICs9IDEsIGsgKz0gMSlcbiAgICBsaXN0W2ldID0gbGlzdFtrXTtcbiAgbGlzdC5wb3AoKTtcbn1cblxuZnVuY3Rpb24gYXJyYXlDbG9uZShhcnIsIG4pIHtcbiAgdmFyIGNvcHkgPSBuZXcgQXJyYXkobik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKVxuICAgIGNvcHlbaV0gPSBhcnJbaV07XG4gIHJldHVybiBjb3B5O1xufVxuXG5mdW5jdGlvbiB1bndyYXBMaXN0ZW5lcnMoYXJyKSB7XG4gIHZhciByZXQgPSBuZXcgQXJyYXkoYXJyLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgKytpKSB7XG4gICAgcmV0W2ldID0gYXJyW2ldLmxpc3RlbmVyIHx8IGFycltpXTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBvYmplY3RDcmVhdGVQb2x5ZmlsbChwcm90bykge1xuICB2YXIgRiA9IGZ1bmN0aW9uKCkge307XG4gIEYucHJvdG90eXBlID0gcHJvdG87XG4gIHJldHVybiBuZXcgRjtcbn1cbmZ1bmN0aW9uIG9iamVjdEtleXNQb2x5ZmlsbChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIgayBpbiBvYmopIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrKSkge1xuICAgIGtleXMucHVzaChrKTtcbiAgfVxuICByZXR1cm4gaztcbn1cbmZ1bmN0aW9uIGZ1bmN0aW9uQmluZFBvbHlmaWxsKGNvbnRleHQpIHtcbiAgdmFyIGZuID0gdGhpcztcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZm4uYXBwbHkoY29udGV4dCwgYXJndW1lbnRzKTtcbiAgfTtcbn1cbiIsInZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxudmFyIE1ENSA9IHJlcXVpcmUoJ21kNS5qcycpXG5cbi8qIGVzbGludC1kaXNhYmxlIGNhbWVsY2FzZSAqL1xuZnVuY3Rpb24gRVZQX0J5dGVzVG9LZXkgKHBhc3N3b3JkLCBzYWx0LCBrZXlCaXRzLCBpdkxlbikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihwYXNzd29yZCkpIHBhc3N3b3JkID0gQnVmZmVyLmZyb20ocGFzc3dvcmQsICdiaW5hcnknKVxuICBpZiAoc2FsdCkge1xuICAgIGlmICghQnVmZmVyLmlzQnVmZmVyKHNhbHQpKSBzYWx0ID0gQnVmZmVyLmZyb20oc2FsdCwgJ2JpbmFyeScpXG4gICAgaWYgKHNhbHQubGVuZ3RoICE9PSA4KSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc2FsdCBzaG91bGQgYmUgQnVmZmVyIHdpdGggOCBieXRlIGxlbmd0aCcpXG4gIH1cblxuICB2YXIga2V5TGVuID0ga2V5Qml0cyAvIDhcbiAgdmFyIGtleSA9IEJ1ZmZlci5hbGxvYyhrZXlMZW4pXG4gIHZhciBpdiA9IEJ1ZmZlci5hbGxvYyhpdkxlbiB8fCAwKVxuICB2YXIgdG1wID0gQnVmZmVyLmFsbG9jKDApXG5cbiAgd2hpbGUgKGtleUxlbiA+IDAgfHwgaXZMZW4gPiAwKSB7XG4gICAgdmFyIGhhc2ggPSBuZXcgTUQ1KClcbiAgICBoYXNoLnVwZGF0ZSh0bXApXG4gICAgaGFzaC51cGRhdGUocGFzc3dvcmQpXG4gICAgaWYgKHNhbHQpIGhhc2gudXBkYXRlKHNhbHQpXG4gICAgdG1wID0gaGFzaC5kaWdlc3QoKVxuXG4gICAgdmFyIHVzZWQgPSAwXG5cbiAgICBpZiAoa2V5TGVuID4gMCkge1xuICAgICAgdmFyIGtleVN0YXJ0ID0ga2V5Lmxlbmd0aCAtIGtleUxlblxuICAgICAgdXNlZCA9IE1hdGgubWluKGtleUxlbiwgdG1wLmxlbmd0aClcbiAgICAgIHRtcC5jb3B5KGtleSwga2V5U3RhcnQsIDAsIHVzZWQpXG4gICAgICBrZXlMZW4gLT0gdXNlZFxuICAgIH1cblxuICAgIGlmICh1c2VkIDwgdG1wLmxlbmd0aCAmJiBpdkxlbiA+IDApIHtcbiAgICAgIHZhciBpdlN0YXJ0ID0gaXYubGVuZ3RoIC0gaXZMZW5cbiAgICAgIHZhciBsZW5ndGggPSBNYXRoLm1pbihpdkxlbiwgdG1wLmxlbmd0aCAtIHVzZWQpXG4gICAgICB0bXAuY29weShpdiwgaXZTdGFydCwgdXNlZCwgdXNlZCArIGxlbmd0aClcbiAgICAgIGl2TGVuIC09IGxlbmd0aFxuICAgIH1cbiAgfVxuXG4gIHRtcC5maWxsKDApXG4gIHJldHVybiB7IGtleToga2V5LCBpdjogaXYgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEVWUF9CeXRlc1RvS2V5XG4iLCIndXNlIHN0cmljdCdcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxudmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ3N0cmVhbScpLlRyYW5zZm9ybVxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxuXG5mdW5jdGlvbiB0aHJvd0lmTm90U3RyaW5nT3JCdWZmZXIgKHZhbCwgcHJlZml4KSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHZhbCkgJiYgdHlwZW9mIHZhbCAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKHByZWZpeCArICcgbXVzdCBiZSBhIHN0cmluZyBvciBhIGJ1ZmZlcicpXG4gIH1cbn1cblxuZnVuY3Rpb24gSGFzaEJhc2UgKGJsb2NrU2l6ZSkge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzKVxuXG4gIHRoaXMuX2Jsb2NrID0gQnVmZmVyLmFsbG9jVW5zYWZlKGJsb2NrU2l6ZSlcbiAgdGhpcy5fYmxvY2tTaXplID0gYmxvY2tTaXplXG4gIHRoaXMuX2Jsb2NrT2Zmc2V0ID0gMFxuICB0aGlzLl9sZW5ndGggPSBbMCwgMCwgMCwgMF1cblxuICB0aGlzLl9maW5hbGl6ZWQgPSBmYWxzZVxufVxuXG5pbmhlcml0cyhIYXNoQmFzZSwgVHJhbnNmb3JtKVxuXG5IYXNoQmFzZS5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNhbGxiYWNrKSB7XG4gIHZhciBlcnJvciA9IG51bGxcbiAgdHJ5IHtcbiAgICB0aGlzLnVwZGF0ZShjaHVuaywgZW5jb2RpbmcpXG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGVycm9yID0gZXJyXG4gIH1cblxuICBjYWxsYmFjayhlcnJvcilcbn1cblxuSGFzaEJhc2UucHJvdG90eXBlLl9mbHVzaCA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICB2YXIgZXJyb3IgPSBudWxsXG4gIHRyeSB7XG4gICAgdGhpcy5wdXNoKHRoaXMuZGlnZXN0KCkpXG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGVycm9yID0gZXJyXG4gIH1cblxuICBjYWxsYmFjayhlcnJvcilcbn1cblxuSGFzaEJhc2UucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhLCBlbmNvZGluZykge1xuICB0aHJvd0lmTm90U3RyaW5nT3JCdWZmZXIoZGF0YSwgJ0RhdGEnKVxuICBpZiAodGhpcy5fZmluYWxpemVkKSB0aHJvdyBuZXcgRXJyb3IoJ0RpZ2VzdCBhbHJlYWR5IGNhbGxlZCcpXG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGRhdGEpKSBkYXRhID0gQnVmZmVyLmZyb20oZGF0YSwgZW5jb2RpbmcpXG5cbiAgLy8gY29uc3VtZSBkYXRhXG4gIHZhciBibG9jayA9IHRoaXMuX2Jsb2NrXG4gIHZhciBvZmZzZXQgPSAwXG4gIHdoaWxlICh0aGlzLl9ibG9ja09mZnNldCArIGRhdGEubGVuZ3RoIC0gb2Zmc2V0ID49IHRoaXMuX2Jsb2NrU2l6ZSkge1xuICAgIGZvciAodmFyIGkgPSB0aGlzLl9ibG9ja09mZnNldDsgaSA8IHRoaXMuX2Jsb2NrU2l6ZTspIGJsb2NrW2krK10gPSBkYXRhW29mZnNldCsrXVxuICAgIHRoaXMuX3VwZGF0ZSgpXG4gICAgdGhpcy5fYmxvY2tPZmZzZXQgPSAwXG4gIH1cbiAgd2hpbGUgKG9mZnNldCA8IGRhdGEubGVuZ3RoKSBibG9ja1t0aGlzLl9ibG9ja09mZnNldCsrXSA9IGRhdGFbb2Zmc2V0KytdXG5cbiAgLy8gdXBkYXRlIGxlbmd0aFxuICBmb3IgKHZhciBqID0gMCwgY2FycnkgPSBkYXRhLmxlbmd0aCAqIDg7IGNhcnJ5ID4gMDsgKytqKSB7XG4gICAgdGhpcy5fbGVuZ3RoW2pdICs9IGNhcnJ5XG4gICAgY2FycnkgPSAodGhpcy5fbGVuZ3RoW2pdIC8gMHgwMTAwMDAwMDAwKSB8IDBcbiAgICBpZiAoY2FycnkgPiAwKSB0aGlzLl9sZW5ndGhbal0gLT0gMHgwMTAwMDAwMDAwICogY2FycnlcbiAgfVxuXG4gIHJldHVybiB0aGlzXG59XG5cbkhhc2hCYXNlLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ191cGRhdGUgaXMgbm90IGltcGxlbWVudGVkJylcbn1cblxuSGFzaEJhc2UucHJvdG90eXBlLmRpZ2VzdCA9IGZ1bmN0aW9uIChlbmNvZGluZykge1xuICBpZiAodGhpcy5fZmluYWxpemVkKSB0aHJvdyBuZXcgRXJyb3IoJ0RpZ2VzdCBhbHJlYWR5IGNhbGxlZCcpXG4gIHRoaXMuX2ZpbmFsaXplZCA9IHRydWVcblxuICB2YXIgZGlnZXN0ID0gdGhpcy5fZGlnZXN0KClcbiAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQpIGRpZ2VzdCA9IGRpZ2VzdC50b1N0cmluZyhlbmNvZGluZylcblxuICAvLyByZXNldCBzdGF0ZVxuICB0aGlzLl9ibG9jay5maWxsKDApXG4gIHRoaXMuX2Jsb2NrT2Zmc2V0ID0gMFxuICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7ICsraSkgdGhpcy5fbGVuZ3RoW2ldID0gMFxuXG4gIHJldHVybiBkaWdlc3Rcbn1cblxuSGFzaEJhc2UucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiAoKSB7XG4gIHRocm93IG5ldyBFcnJvcignX2RpZ2VzdCBpcyBub3QgaW1wbGVtZW50ZWQnKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEhhc2hCYXNlXG4iLCJ2YXIgaGFzaCA9IGV4cG9ydHM7XG5cbmhhc2gudXRpbHMgPSByZXF1aXJlKCcuL2hhc2gvdXRpbHMnKTtcbmhhc2guY29tbW9uID0gcmVxdWlyZSgnLi9oYXNoL2NvbW1vbicpO1xuaGFzaC5zaGEgPSByZXF1aXJlKCcuL2hhc2gvc2hhJyk7XG5oYXNoLnJpcGVtZCA9IHJlcXVpcmUoJy4vaGFzaC9yaXBlbWQnKTtcbmhhc2guaG1hYyA9IHJlcXVpcmUoJy4vaGFzaC9obWFjJyk7XG5cbi8vIFByb3h5IGhhc2ggZnVuY3Rpb25zIHRvIHRoZSBtYWluIG9iamVjdFxuaGFzaC5zaGExID0gaGFzaC5zaGEuc2hhMTtcbmhhc2guc2hhMjU2ID0gaGFzaC5zaGEuc2hhMjU2O1xuaGFzaC5zaGEyMjQgPSBoYXNoLnNoYS5zaGEyMjQ7XG5oYXNoLnNoYTM4NCA9IGhhc2guc2hhLnNoYTM4NDtcbmhhc2guc2hhNTEyID0gaGFzaC5zaGEuc2hhNTEyO1xuaGFzaC5yaXBlbWQxNjAgPSBoYXNoLnJpcGVtZC5yaXBlbWQxNjA7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbnZhciBhc3NlcnQgPSByZXF1aXJlKCdtaW5pbWFsaXN0aWMtYXNzZXJ0Jyk7XG5cbmZ1bmN0aW9uIEJsb2NrSGFzaCgpIHtcbiAgdGhpcy5wZW5kaW5nID0gbnVsbDtcbiAgdGhpcy5wZW5kaW5nVG90YWwgPSAwO1xuICB0aGlzLmJsb2NrU2l6ZSA9IHRoaXMuY29uc3RydWN0b3IuYmxvY2tTaXplO1xuICB0aGlzLm91dFNpemUgPSB0aGlzLmNvbnN0cnVjdG9yLm91dFNpemU7XG4gIHRoaXMuaG1hY1N0cmVuZ3RoID0gdGhpcy5jb25zdHJ1Y3Rvci5obWFjU3RyZW5ndGg7XG4gIHRoaXMucGFkTGVuZ3RoID0gdGhpcy5jb25zdHJ1Y3Rvci5wYWRMZW5ndGggLyA4O1xuICB0aGlzLmVuZGlhbiA9ICdiaWcnO1xuXG4gIHRoaXMuX2RlbHRhOCA9IHRoaXMuYmxvY2tTaXplIC8gODtcbiAgdGhpcy5fZGVsdGEzMiA9IHRoaXMuYmxvY2tTaXplIC8gMzI7XG59XG5leHBvcnRzLkJsb2NrSGFzaCA9IEJsb2NrSGFzaDtcblxuQmxvY2tIYXNoLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUobXNnLCBlbmMpIHtcbiAgLy8gQ29udmVydCBtZXNzYWdlIHRvIGFycmF5LCBwYWQgaXQsIGFuZCBqb2luIGludG8gMzJiaXQgYmxvY2tzXG4gIG1zZyA9IHV0aWxzLnRvQXJyYXkobXNnLCBlbmMpO1xuICBpZiAoIXRoaXMucGVuZGluZylcbiAgICB0aGlzLnBlbmRpbmcgPSBtc2c7XG4gIGVsc2VcbiAgICB0aGlzLnBlbmRpbmcgPSB0aGlzLnBlbmRpbmcuY29uY2F0KG1zZyk7XG4gIHRoaXMucGVuZGluZ1RvdGFsICs9IG1zZy5sZW5ndGg7XG5cbiAgLy8gRW5vdWdoIGRhdGEsIHRyeSB1cGRhdGluZ1xuICBpZiAodGhpcy5wZW5kaW5nLmxlbmd0aCA+PSB0aGlzLl9kZWx0YTgpIHtcbiAgICBtc2cgPSB0aGlzLnBlbmRpbmc7XG5cbiAgICAvLyBQcm9jZXNzIHBlbmRpbmcgZGF0YSBpbiBibG9ja3NcbiAgICB2YXIgciA9IG1zZy5sZW5ndGggJSB0aGlzLl9kZWx0YTg7XG4gICAgdGhpcy5wZW5kaW5nID0gbXNnLnNsaWNlKG1zZy5sZW5ndGggLSByLCBtc2cubGVuZ3RoKTtcbiAgICBpZiAodGhpcy5wZW5kaW5nLmxlbmd0aCA9PT0gMClcbiAgICAgIHRoaXMucGVuZGluZyA9IG51bGw7XG5cbiAgICBtc2cgPSB1dGlscy5qb2luMzIobXNnLCAwLCBtc2cubGVuZ3RoIC0gciwgdGhpcy5lbmRpYW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSArPSB0aGlzLl9kZWx0YTMyKVxuICAgICAgdGhpcy5fdXBkYXRlKG1zZywgaSwgaSArIHRoaXMuX2RlbHRhMzIpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5CbG9ja0hhc2gucHJvdG90eXBlLmRpZ2VzdCA9IGZ1bmN0aW9uIGRpZ2VzdChlbmMpIHtcbiAgdGhpcy51cGRhdGUodGhpcy5fcGFkKCkpO1xuICBhc3NlcnQodGhpcy5wZW5kaW5nID09PSBudWxsKTtcblxuICByZXR1cm4gdGhpcy5fZGlnZXN0KGVuYyk7XG59O1xuXG5CbG9ja0hhc2gucHJvdG90eXBlLl9wYWQgPSBmdW5jdGlvbiBwYWQoKSB7XG4gIHZhciBsZW4gPSB0aGlzLnBlbmRpbmdUb3RhbDtcbiAgdmFyIGJ5dGVzID0gdGhpcy5fZGVsdGE4O1xuICB2YXIgayA9IGJ5dGVzIC0gKChsZW4gKyB0aGlzLnBhZExlbmd0aCkgJSBieXRlcyk7XG4gIHZhciByZXMgPSBuZXcgQXJyYXkoayArIHRoaXMucGFkTGVuZ3RoKTtcbiAgcmVzWzBdID0gMHg4MDtcbiAgZm9yICh2YXIgaSA9IDE7IGkgPCBrOyBpKyspXG4gICAgcmVzW2ldID0gMDtcblxuICAvLyBBcHBlbmQgbGVuZ3RoXG4gIGxlbiA8PD0gMztcbiAgaWYgKHRoaXMuZW5kaWFuID09PSAnYmlnJykge1xuICAgIGZvciAodmFyIHQgPSA4OyB0IDwgdGhpcy5wYWRMZW5ndGg7IHQrKylcbiAgICAgIHJlc1tpKytdID0gMDtcblxuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IChsZW4gPj4+IDI0KSAmIDB4ZmY7XG4gICAgcmVzW2krK10gPSAobGVuID4+PiAxNikgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gOCkgJiAweGZmO1xuICAgIHJlc1tpKytdID0gbGVuICYgMHhmZjtcbiAgfSBlbHNlIHtcbiAgICByZXNbaSsrXSA9IGxlbiAmIDB4ZmY7XG4gICAgcmVzW2krK10gPSAobGVuID4+PiA4KSAmIDB4ZmY7XG4gICAgcmVzW2krK10gPSAobGVuID4+PiAxNikgJiAweGZmO1xuICAgIHJlc1tpKytdID0gKGxlbiA+Pj4gMjQpICYgMHhmZjtcbiAgICByZXNbaSsrXSA9IDA7XG4gICAgcmVzW2krK10gPSAwO1xuICAgIHJlc1tpKytdID0gMDtcbiAgICByZXNbaSsrXSA9IDA7XG5cbiAgICBmb3IgKHQgPSA4OyB0IDwgdGhpcy5wYWRMZW5ndGg7IHQrKylcbiAgICAgIHJlc1tpKytdID0gMDtcbiAgfVxuXG4gIHJldHVybiByZXM7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG5mdW5jdGlvbiBIbWFjKGhhc2gsIGtleSwgZW5jKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBIbWFjKSlcbiAgICByZXR1cm4gbmV3IEhtYWMoaGFzaCwga2V5LCBlbmMpO1xuICB0aGlzLkhhc2ggPSBoYXNoO1xuICB0aGlzLmJsb2NrU2l6ZSA9IGhhc2guYmxvY2tTaXplIC8gODtcbiAgdGhpcy5vdXRTaXplID0gaGFzaC5vdXRTaXplIC8gODtcbiAgdGhpcy5pbm5lciA9IG51bGw7XG4gIHRoaXMub3V0ZXIgPSBudWxsO1xuXG4gIHRoaXMuX2luaXQodXRpbHMudG9BcnJheShrZXksIGVuYykpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBIbWFjO1xuXG5IbWFjLnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uIGluaXQoa2V5KSB7XG4gIC8vIFNob3J0ZW4ga2V5LCBpZiBuZWVkZWRcbiAgaWYgKGtleS5sZW5ndGggPiB0aGlzLmJsb2NrU2l6ZSlcbiAgICBrZXkgPSBuZXcgdGhpcy5IYXNoKCkudXBkYXRlKGtleSkuZGlnZXN0KCk7XG4gIGFzc2VydChrZXkubGVuZ3RoIDw9IHRoaXMuYmxvY2tTaXplKTtcblxuICAvLyBBZGQgcGFkZGluZyB0byBrZXlcbiAgZm9yICh2YXIgaSA9IGtleS5sZW5ndGg7IGkgPCB0aGlzLmJsb2NrU2l6ZTsgaSsrKVxuICAgIGtleS5wdXNoKDApO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBrZXkubGVuZ3RoOyBpKyspXG4gICAga2V5W2ldIF49IDB4MzY7XG4gIHRoaXMuaW5uZXIgPSBuZXcgdGhpcy5IYXNoKCkudXBkYXRlKGtleSk7XG5cbiAgLy8gMHgzNiBeIDB4NWMgPSAweDZhXG4gIGZvciAoaSA9IDA7IGkgPCBrZXkubGVuZ3RoOyBpKyspXG4gICAga2V5W2ldIF49IDB4NmE7XG4gIHRoaXMub3V0ZXIgPSBuZXcgdGhpcy5IYXNoKCkudXBkYXRlKGtleSk7XG59O1xuXG5IbWFjLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUobXNnLCBlbmMpIHtcbiAgdGhpcy5pbm5lci51cGRhdGUobXNnLCBlbmMpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkhtYWMucHJvdG90eXBlLmRpZ2VzdCA9IGZ1bmN0aW9uIGRpZ2VzdChlbmMpIHtcbiAgdGhpcy5vdXRlci51cGRhdGUodGhpcy5pbm5lci5kaWdlc3QoKSk7XG4gIHJldHVybiB0aGlzLm91dGVyLmRpZ2VzdChlbmMpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG5cbnZhciByb3RsMzIgPSB1dGlscy5yb3RsMzI7XG52YXIgc3VtMzIgPSB1dGlscy5zdW0zMjtcbnZhciBzdW0zMl8zID0gdXRpbHMuc3VtMzJfMztcbnZhciBzdW0zMl80ID0gdXRpbHMuc3VtMzJfNDtcbnZhciBCbG9ja0hhc2ggPSBjb21tb24uQmxvY2tIYXNoO1xuXG5mdW5jdGlvbiBSSVBFTUQxNjAoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBSSVBFTUQxNjApKVxuICAgIHJldHVybiBuZXcgUklQRU1EMTYwKCk7XG5cbiAgQmxvY2tIYXNoLmNhbGwodGhpcyk7XG5cbiAgdGhpcy5oID0gWyAweDY3NDUyMzAxLCAweGVmY2RhYjg5LCAweDk4YmFkY2ZlLCAweDEwMzI1NDc2LCAweGMzZDJlMWYwIF07XG4gIHRoaXMuZW5kaWFuID0gJ2xpdHRsZSc7XG59XG51dGlscy5pbmhlcml0cyhSSVBFTUQxNjAsIEJsb2NrSGFzaCk7XG5leHBvcnRzLnJpcGVtZDE2MCA9IFJJUEVNRDE2MDtcblxuUklQRU1EMTYwLmJsb2NrU2l6ZSA9IDUxMjtcblJJUEVNRDE2MC5vdXRTaXplID0gMTYwO1xuUklQRU1EMTYwLmhtYWNTdHJlbmd0aCA9IDE5MjtcblJJUEVNRDE2MC5wYWRMZW5ndGggPSA2NDtcblxuUklQRU1EMTYwLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gdXBkYXRlKG1zZywgc3RhcnQpIHtcbiAgdmFyIEEgPSB0aGlzLmhbMF07XG4gIHZhciBCID0gdGhpcy5oWzFdO1xuICB2YXIgQyA9IHRoaXMuaFsyXTtcbiAgdmFyIEQgPSB0aGlzLmhbM107XG4gIHZhciBFID0gdGhpcy5oWzRdO1xuICB2YXIgQWggPSBBO1xuICB2YXIgQmggPSBCO1xuICB2YXIgQ2ggPSBDO1xuICB2YXIgRGggPSBEO1xuICB2YXIgRWggPSBFO1xuICBmb3IgKHZhciBqID0gMDsgaiA8IDgwOyBqKyspIHtcbiAgICB2YXIgVCA9IHN1bTMyKFxuICAgICAgcm90bDMyKFxuICAgICAgICBzdW0zMl80KEEsIGYoaiwgQiwgQywgRCksIG1zZ1tyW2pdICsgc3RhcnRdLCBLKGopKSxcbiAgICAgICAgc1tqXSksXG4gICAgICBFKTtcbiAgICBBID0gRTtcbiAgICBFID0gRDtcbiAgICBEID0gcm90bDMyKEMsIDEwKTtcbiAgICBDID0gQjtcbiAgICBCID0gVDtcbiAgICBUID0gc3VtMzIoXG4gICAgICByb3RsMzIoXG4gICAgICAgIHN1bTMyXzQoQWgsIGYoNzkgLSBqLCBCaCwgQ2gsIERoKSwgbXNnW3JoW2pdICsgc3RhcnRdLCBLaChqKSksXG4gICAgICAgIHNoW2pdKSxcbiAgICAgIEVoKTtcbiAgICBBaCA9IEVoO1xuICAgIEVoID0gRGg7XG4gICAgRGggPSByb3RsMzIoQ2gsIDEwKTtcbiAgICBDaCA9IEJoO1xuICAgIEJoID0gVDtcbiAgfVxuICBUID0gc3VtMzJfMyh0aGlzLmhbMV0sIEMsIERoKTtcbiAgdGhpcy5oWzFdID0gc3VtMzJfMyh0aGlzLmhbMl0sIEQsIEVoKTtcbiAgdGhpcy5oWzJdID0gc3VtMzJfMyh0aGlzLmhbM10sIEUsIEFoKTtcbiAgdGhpcy5oWzNdID0gc3VtMzJfMyh0aGlzLmhbNF0sIEEsIEJoKTtcbiAgdGhpcy5oWzRdID0gc3VtMzJfMyh0aGlzLmhbMF0sIEIsIENoKTtcbiAgdGhpcy5oWzBdID0gVDtcbn07XG5cblJJUEVNRDE2MC5wcm90b3R5cGUuX2RpZ2VzdCA9IGZ1bmN0aW9uIGRpZ2VzdChlbmMpIHtcbiAgaWYgKGVuYyA9PT0gJ2hleCcpXG4gICAgcmV0dXJuIHV0aWxzLnRvSGV4MzIodGhpcy5oLCAnbGl0dGxlJyk7XG4gIGVsc2VcbiAgICByZXR1cm4gdXRpbHMuc3BsaXQzMih0aGlzLmgsICdsaXR0bGUnKTtcbn07XG5cbmZ1bmN0aW9uIGYoaiwgeCwgeSwgeikge1xuICBpZiAoaiA8PSAxNSlcbiAgICByZXR1cm4geCBeIHkgXiB6O1xuICBlbHNlIGlmIChqIDw9IDMxKVxuICAgIHJldHVybiAoeCAmIHkpIHwgKCh+eCkgJiB6KTtcbiAgZWxzZSBpZiAoaiA8PSA0NylcbiAgICByZXR1cm4gKHggfCAofnkpKSBeIHo7XG4gIGVsc2UgaWYgKGogPD0gNjMpXG4gICAgcmV0dXJuICh4ICYgeikgfCAoeSAmICh+eikpO1xuICBlbHNlXG4gICAgcmV0dXJuIHggXiAoeSB8ICh+eikpO1xufVxuXG5mdW5jdGlvbiBLKGopIHtcbiAgaWYgKGogPD0gMTUpXG4gICAgcmV0dXJuIDB4MDAwMDAwMDA7XG4gIGVsc2UgaWYgKGogPD0gMzEpXG4gICAgcmV0dXJuIDB4NWE4Mjc5OTk7XG4gIGVsc2UgaWYgKGogPD0gNDcpXG4gICAgcmV0dXJuIDB4NmVkOWViYTE7XG4gIGVsc2UgaWYgKGogPD0gNjMpXG4gICAgcmV0dXJuIDB4OGYxYmJjZGM7XG4gIGVsc2VcbiAgICByZXR1cm4gMHhhOTUzZmQ0ZTtcbn1cblxuZnVuY3Rpb24gS2goaikge1xuICBpZiAoaiA8PSAxNSlcbiAgICByZXR1cm4gMHg1MGEyOGJlNjtcbiAgZWxzZSBpZiAoaiA8PSAzMSlcbiAgICByZXR1cm4gMHg1YzRkZDEyNDtcbiAgZWxzZSBpZiAoaiA8PSA0NylcbiAgICByZXR1cm4gMHg2ZDcwM2VmMztcbiAgZWxzZSBpZiAoaiA8PSA2MylcbiAgICByZXR1cm4gMHg3YTZkNzZlOTtcbiAgZWxzZVxuICAgIHJldHVybiAweDAwMDAwMDAwO1xufVxuXG52YXIgciA9IFtcbiAgMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSxcbiAgNywgNCwgMTMsIDEsIDEwLCA2LCAxNSwgMywgMTIsIDAsIDksIDUsIDIsIDE0LCAxMSwgOCxcbiAgMywgMTAsIDE0LCA0LCA5LCAxNSwgOCwgMSwgMiwgNywgMCwgNiwgMTMsIDExLCA1LCAxMixcbiAgMSwgOSwgMTEsIDEwLCAwLCA4LCAxMiwgNCwgMTMsIDMsIDcsIDE1LCAxNCwgNSwgNiwgMixcbiAgNCwgMCwgNSwgOSwgNywgMTIsIDIsIDEwLCAxNCwgMSwgMywgOCwgMTEsIDYsIDE1LCAxM1xuXTtcblxudmFyIHJoID0gW1xuICA1LCAxNCwgNywgMCwgOSwgMiwgMTEsIDQsIDEzLCA2LCAxNSwgOCwgMSwgMTAsIDMsIDEyLFxuICA2LCAxMSwgMywgNywgMCwgMTMsIDUsIDEwLCAxNCwgMTUsIDgsIDEyLCA0LCA5LCAxLCAyLFxuICAxNSwgNSwgMSwgMywgNywgMTQsIDYsIDksIDExLCA4LCAxMiwgMiwgMTAsIDAsIDQsIDEzLFxuICA4LCA2LCA0LCAxLCAzLCAxMSwgMTUsIDAsIDUsIDEyLCAyLCAxMywgOSwgNywgMTAsIDE0LFxuICAxMiwgMTUsIDEwLCA0LCAxLCA1LCA4LCA3LCA2LCAyLCAxMywgMTQsIDAsIDMsIDksIDExXG5dO1xuXG52YXIgcyA9IFtcbiAgMTEsIDE0LCAxNSwgMTIsIDUsIDgsIDcsIDksIDExLCAxMywgMTQsIDE1LCA2LCA3LCA5LCA4LFxuICA3LCA2LCA4LCAxMywgMTEsIDksIDcsIDE1LCA3LCAxMiwgMTUsIDksIDExLCA3LCAxMywgMTIsXG4gIDExLCAxMywgNiwgNywgMTQsIDksIDEzLCAxNSwgMTQsIDgsIDEzLCA2LCA1LCAxMiwgNywgNSxcbiAgMTEsIDEyLCAxNCwgMTUsIDE0LCAxNSwgOSwgOCwgOSwgMTQsIDUsIDYsIDgsIDYsIDUsIDEyLFxuICA5LCAxNSwgNSwgMTEsIDYsIDgsIDEzLCAxMiwgNSwgMTIsIDEzLCAxNCwgMTEsIDgsIDUsIDZcbl07XG5cbnZhciBzaCA9IFtcbiAgOCwgOSwgOSwgMTEsIDEzLCAxNSwgMTUsIDUsIDcsIDcsIDgsIDExLCAxNCwgMTQsIDEyLCA2LFxuICA5LCAxMywgMTUsIDcsIDEyLCA4LCA5LCAxMSwgNywgNywgMTIsIDcsIDYsIDE1LCAxMywgMTEsXG4gIDksIDcsIDE1LCAxMSwgOCwgNiwgNiwgMTQsIDEyLCAxMywgNSwgMTQsIDEzLCAxMywgNywgNSxcbiAgMTUsIDUsIDgsIDExLCAxNCwgMTQsIDYsIDE0LCA2LCA5LCAxMiwgOSwgMTIsIDUsIDE1LCA4LFxuICA4LCA1LCAxMiwgOSwgMTIsIDUsIDE0LCA2LCA4LCAxMywgNiwgNSwgMTUsIDEzLCAxMSwgMTFcbl07XG4iLCIndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuc2hhMSA9IHJlcXVpcmUoJy4vc2hhLzEnKTtcbmV4cG9ydHMuc2hhMjI0ID0gcmVxdWlyZSgnLi9zaGEvMjI0Jyk7XG5leHBvcnRzLnNoYTI1NiA9IHJlcXVpcmUoJy4vc2hhLzI1NicpO1xuZXhwb3J0cy5zaGEzODQgPSByZXF1aXJlKCcuL3NoYS8zODQnKTtcbmV4cG9ydHMuc2hhNTEyID0gcmVxdWlyZSgnLi9zaGEvNTEyJyk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgY29tbW9uID0gcmVxdWlyZSgnLi4vY29tbW9uJyk7XG52YXIgc2hhQ29tbW9uID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxudmFyIHJvdGwzMiA9IHV0aWxzLnJvdGwzMjtcbnZhciBzdW0zMiA9IHV0aWxzLnN1bTMyO1xudmFyIHN1bTMyXzUgPSB1dGlscy5zdW0zMl81O1xudmFyIGZ0XzEgPSBzaGFDb21tb24uZnRfMTtcbnZhciBCbG9ja0hhc2ggPSBjb21tb24uQmxvY2tIYXNoO1xuXG52YXIgc2hhMV9LID0gW1xuICAweDVBODI3OTk5LCAweDZFRDlFQkExLFxuICAweDhGMUJCQ0RDLCAweENBNjJDMUQ2XG5dO1xuXG5mdW5jdGlvbiBTSEExKCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMSkpXG4gICAgcmV0dXJuIG5ldyBTSEExKCk7XG5cbiAgQmxvY2tIYXNoLmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFtcbiAgICAweDY3NDUyMzAxLCAweGVmY2RhYjg5LCAweDk4YmFkY2ZlLFxuICAgIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjAgXTtcbiAgdGhpcy5XID0gbmV3IEFycmF5KDgwKTtcbn1cblxudXRpbHMuaW5oZXJpdHMoU0hBMSwgQmxvY2tIYXNoKTtcbm1vZHVsZS5leHBvcnRzID0gU0hBMTtcblxuU0hBMS5ibG9ja1NpemUgPSA1MTI7XG5TSEExLm91dFNpemUgPSAxNjA7XG5TSEExLmhtYWNTdHJlbmd0aCA9IDgwO1xuU0hBMS5wYWRMZW5ndGggPSA2NDtcblxuU0hBMS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspXG4gICAgV1tpXSA9IG1zZ1tzdGFydCArIGldO1xuXG4gIGZvcig7IGkgPCBXLmxlbmd0aDsgaSsrKVxuICAgIFdbaV0gPSByb3RsMzIoV1tpIC0gM10gXiBXW2kgLSA4XSBeIFdbaSAtIDE0XSBeIFdbaSAtIDE2XSwgMSk7XG5cbiAgdmFyIGEgPSB0aGlzLmhbMF07XG4gIHZhciBiID0gdGhpcy5oWzFdO1xuICB2YXIgYyA9IHRoaXMuaFsyXTtcbiAgdmFyIGQgPSB0aGlzLmhbM107XG4gIHZhciBlID0gdGhpcy5oWzRdO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBXLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHMgPSB+fihpIC8gMjApO1xuICAgIHZhciB0ID0gc3VtMzJfNShyb3RsMzIoYSwgNSksIGZ0XzEocywgYiwgYywgZCksIGUsIFdbaV0sIHNoYTFfS1tzXSk7XG4gICAgZSA9IGQ7XG4gICAgZCA9IGM7XG4gICAgYyA9IHJvdGwzMihiLCAzMCk7XG4gICAgYiA9IGE7XG4gICAgYSA9IHQ7XG4gIH1cblxuICB0aGlzLmhbMF0gPSBzdW0zMih0aGlzLmhbMF0sIGEpO1xuICB0aGlzLmhbMV0gPSBzdW0zMih0aGlzLmhbMV0sIGIpO1xuICB0aGlzLmhbMl0gPSBzdW0zMih0aGlzLmhbMl0sIGMpO1xuICB0aGlzLmhbM10gPSBzdW0zMih0aGlzLmhbM10sIGQpO1xuICB0aGlzLmhbNF0gPSBzdW0zMih0aGlzLmhbNF0sIGUpO1xufTtcblxuU0hBMS5wcm90b3R5cGUuX2RpZ2VzdCA9IGZ1bmN0aW9uIGRpZ2VzdChlbmMpIHtcbiAgaWYgKGVuYyA9PT0gJ2hleCcpXG4gICAgcmV0dXJuIHV0aWxzLnRvSGV4MzIodGhpcy5oLCAnYmlnJyk7XG4gIGVsc2VcbiAgICByZXR1cm4gdXRpbHMuc3BsaXQzMih0aGlzLmgsICdiaWcnKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgU0hBMjU2ID0gcmVxdWlyZSgnLi8yNTYnKTtcblxuZnVuY3Rpb24gU0hBMjI0KCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMjI0KSlcbiAgICByZXR1cm4gbmV3IFNIQTIyNCgpO1xuXG4gIFNIQTI1Ni5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHhjMTA1OWVkOCwgMHgzNjdjZDUwNywgMHgzMDcwZGQxNywgMHhmNzBlNTkzOSxcbiAgICAweGZmYzAwYjMxLCAweDY4NTgxNTExLCAweDY0Zjk4ZmE3LCAweGJlZmE0ZmE0IF07XG59XG51dGlscy5pbmhlcml0cyhTSEEyMjQsIFNIQTI1Nik7XG5tb2R1bGUuZXhwb3J0cyA9IFNIQTIyNDtcblxuU0hBMjI0LmJsb2NrU2l6ZSA9IDUxMjtcblNIQTIyNC5vdXRTaXplID0gMjI0O1xuU0hBMjI0LmhtYWNTdHJlbmd0aCA9IDE5MjtcblNIQTIyNC5wYWRMZW5ndGggPSA2NDtcblxuU0hBMjI0LnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICAvLyBKdXN0IHRydW5jYXRlIG91dHB1dFxuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmguc2xpY2UoMCwgNyksICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaC5zbGljZSgwLCA3KSwgJ2JpZycpO1xufTtcblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4uL2NvbW1vbicpO1xudmFyIHNoYUNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWFzc2VydCcpO1xuXG52YXIgc3VtMzIgPSB1dGlscy5zdW0zMjtcbnZhciBzdW0zMl80ID0gdXRpbHMuc3VtMzJfNDtcbnZhciBzdW0zMl81ID0gdXRpbHMuc3VtMzJfNTtcbnZhciBjaDMyID0gc2hhQ29tbW9uLmNoMzI7XG52YXIgbWFqMzIgPSBzaGFDb21tb24ubWFqMzI7XG52YXIgczBfMjU2ID0gc2hhQ29tbW9uLnMwXzI1NjtcbnZhciBzMV8yNTYgPSBzaGFDb21tb24uczFfMjU2O1xudmFyIGcwXzI1NiA9IHNoYUNvbW1vbi5nMF8yNTY7XG52YXIgZzFfMjU2ID0gc2hhQ29tbW9uLmcxXzI1NjtcblxudmFyIEJsb2NrSGFzaCA9IGNvbW1vbi5CbG9ja0hhc2g7XG5cbnZhciBzaGEyNTZfSyA9IFtcbiAgMHg0MjhhMmY5OCwgMHg3MTM3NDQ5MSwgMHhiNWMwZmJjZiwgMHhlOWI1ZGJhNSxcbiAgMHgzOTU2YzI1YiwgMHg1OWYxMTFmMSwgMHg5MjNmODJhNCwgMHhhYjFjNWVkNSxcbiAgMHhkODA3YWE5OCwgMHgxMjgzNWIwMSwgMHgyNDMxODViZSwgMHg1NTBjN2RjMyxcbiAgMHg3MmJlNWQ3NCwgMHg4MGRlYjFmZSwgMHg5YmRjMDZhNywgMHhjMTliZjE3NCxcbiAgMHhlNDliNjljMSwgMHhlZmJlNDc4NiwgMHgwZmMxOWRjNiwgMHgyNDBjYTFjYyxcbiAgMHgyZGU5MmM2ZiwgMHg0YTc0ODRhYSwgMHg1Y2IwYTlkYywgMHg3NmY5ODhkYSxcbiAgMHg5ODNlNTE1MiwgMHhhODMxYzY2ZCwgMHhiMDAzMjdjOCwgMHhiZjU5N2ZjNyxcbiAgMHhjNmUwMGJmMywgMHhkNWE3OTE0NywgMHgwNmNhNjM1MSwgMHgxNDI5Mjk2NyxcbiAgMHgyN2I3MGE4NSwgMHgyZTFiMjEzOCwgMHg0ZDJjNmRmYywgMHg1MzM4MGQxMyxcbiAgMHg2NTBhNzM1NCwgMHg3NjZhMGFiYiwgMHg4MWMyYzkyZSwgMHg5MjcyMmM4NSxcbiAgMHhhMmJmZThhMSwgMHhhODFhNjY0YiwgMHhjMjRiOGI3MCwgMHhjNzZjNTFhMyxcbiAgMHhkMTkyZTgxOSwgMHhkNjk5MDYyNCwgMHhmNDBlMzU4NSwgMHgxMDZhYTA3MCxcbiAgMHgxOWE0YzExNiwgMHgxZTM3NmMwOCwgMHgyNzQ4Nzc0YywgMHgzNGIwYmNiNSxcbiAgMHgzOTFjMGNiMywgMHg0ZWQ4YWE0YSwgMHg1YjljY2E0ZiwgMHg2ODJlNmZmMyxcbiAgMHg3NDhmODJlZSwgMHg3OGE1NjM2ZiwgMHg4NGM4NzgxNCwgMHg4Y2M3MDIwOCxcbiAgMHg5MGJlZmZmYSwgMHhhNDUwNmNlYiwgMHhiZWY5YTNmNywgMHhjNjcxNzhmMlxuXTtcblxuZnVuY3Rpb24gU0hBMjU2KCkge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0hBMjU2KSlcbiAgICByZXR1cm4gbmV3IFNIQTI1NigpO1xuXG4gIEJsb2NrSGFzaC5jYWxsKHRoaXMpO1xuICB0aGlzLmggPSBbXG4gICAgMHg2YTA5ZTY2NywgMHhiYjY3YWU4NSwgMHgzYzZlZjM3MiwgMHhhNTRmZjUzYSxcbiAgICAweDUxMGU1MjdmLCAweDliMDU2ODhjLCAweDFmODNkOWFiLCAweDViZTBjZDE5XG4gIF07XG4gIHRoaXMuayA9IHNoYTI1Nl9LO1xuICB0aGlzLlcgPSBuZXcgQXJyYXkoNjQpO1xufVxudXRpbHMuaW5oZXJpdHMoU0hBMjU2LCBCbG9ja0hhc2gpO1xubW9kdWxlLmV4cG9ydHMgPSBTSEEyNTY7XG5cblNIQTI1Ni5ibG9ja1NpemUgPSA1MTI7XG5TSEEyNTYub3V0U2l6ZSA9IDI1NjtcblNIQTI1Ni5obWFjU3RyZW5ndGggPSAxOTI7XG5TSEEyNTYucGFkTGVuZ3RoID0gNjQ7XG5cblNIQTI1Ni5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIF91cGRhdGUobXNnLCBzdGFydCkge1xuICB2YXIgVyA9IHRoaXMuVztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspXG4gICAgV1tpXSA9IG1zZ1tzdGFydCArIGldO1xuICBmb3IgKDsgaSA8IFcubGVuZ3RoOyBpKyspXG4gICAgV1tpXSA9IHN1bTMyXzQoZzFfMjU2KFdbaSAtIDJdKSwgV1tpIC0gN10sIGcwXzI1NihXW2kgLSAxNV0pLCBXW2kgLSAxNl0pO1xuXG4gIHZhciBhID0gdGhpcy5oWzBdO1xuICB2YXIgYiA9IHRoaXMuaFsxXTtcbiAgdmFyIGMgPSB0aGlzLmhbMl07XG4gIHZhciBkID0gdGhpcy5oWzNdO1xuICB2YXIgZSA9IHRoaXMuaFs0XTtcbiAgdmFyIGYgPSB0aGlzLmhbNV07XG4gIHZhciBnID0gdGhpcy5oWzZdO1xuICB2YXIgaCA9IHRoaXMuaFs3XTtcblxuICBhc3NlcnQodGhpcy5rLmxlbmd0aCA9PT0gVy5sZW5ndGgpO1xuICBmb3IgKGkgPSAwOyBpIDwgVy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBUMSA9IHN1bTMyXzUoaCwgczFfMjU2KGUpLCBjaDMyKGUsIGYsIGcpLCB0aGlzLmtbaV0sIFdbaV0pO1xuICAgIHZhciBUMiA9IHN1bTMyKHMwXzI1NihhKSwgbWFqMzIoYSwgYiwgYykpO1xuICAgIGggPSBnO1xuICAgIGcgPSBmO1xuICAgIGYgPSBlO1xuICAgIGUgPSBzdW0zMihkLCBUMSk7XG4gICAgZCA9IGM7XG4gICAgYyA9IGI7XG4gICAgYiA9IGE7XG4gICAgYSA9IHN1bTMyKFQxLCBUMik7XG4gIH1cblxuICB0aGlzLmhbMF0gPSBzdW0zMih0aGlzLmhbMF0sIGEpO1xuICB0aGlzLmhbMV0gPSBzdW0zMih0aGlzLmhbMV0sIGIpO1xuICB0aGlzLmhbMl0gPSBzdW0zMih0aGlzLmhbMl0sIGMpO1xuICB0aGlzLmhbM10gPSBzdW0zMih0aGlzLmhbM10sIGQpO1xuICB0aGlzLmhbNF0gPSBzdW0zMih0aGlzLmhbNF0sIGUpO1xuICB0aGlzLmhbNV0gPSBzdW0zMih0aGlzLmhbNV0sIGYpO1xuICB0aGlzLmhbNl0gPSBzdW0zMih0aGlzLmhbNl0sIGcpO1xuICB0aGlzLmhbN10gPSBzdW0zMih0aGlzLmhbN10sIGgpO1xufTtcblxuU0hBMjU2LnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmgsICdiaWcnKTtcbiAgZWxzZVxuICAgIHJldHVybiB1dGlscy5zcGxpdDMyKHRoaXMuaCwgJ2JpZycpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcblxudmFyIFNIQTUxMiA9IHJlcXVpcmUoJy4vNTEyJyk7XG5cbmZ1bmN0aW9uIFNIQTM4NCgpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNIQTM4NCkpXG4gICAgcmV0dXJuIG5ldyBTSEEzODQoKTtcblxuICBTSEE1MTIuY2FsbCh0aGlzKTtcbiAgdGhpcy5oID0gW1xuICAgIDB4Y2JiYjlkNWQsIDB4YzEwNTllZDgsXG4gICAgMHg2MjlhMjkyYSwgMHgzNjdjZDUwNyxcbiAgICAweDkxNTkwMTVhLCAweDMwNzBkZDE3LFxuICAgIDB4MTUyZmVjZDgsIDB4ZjcwZTU5MzksXG4gICAgMHg2NzMzMjY2NywgMHhmZmMwMGIzMSxcbiAgICAweDhlYjQ0YTg3LCAweDY4NTgxNTExLFxuICAgIDB4ZGIwYzJlMGQsIDB4NjRmOThmYTcsXG4gICAgMHg0N2I1NDgxZCwgMHhiZWZhNGZhNCBdO1xufVxudXRpbHMuaW5oZXJpdHMoU0hBMzg0LCBTSEE1MTIpO1xubW9kdWxlLmV4cG9ydHMgPSBTSEEzODQ7XG5cblNIQTM4NC5ibG9ja1NpemUgPSAxMDI0O1xuU0hBMzg0Lm91dFNpemUgPSAzODQ7XG5TSEEzODQuaG1hY1N0cmVuZ3RoID0gMTkyO1xuU0hBMzg0LnBhZExlbmd0aCA9IDEyODtcblxuU0hBMzg0LnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gZGlnZXN0KGVuYykge1xuICBpZiAoZW5jID09PSAnaGV4JylcbiAgICByZXR1cm4gdXRpbHMudG9IZXgzMih0aGlzLmguc2xpY2UoMCwgMTIpLCAnYmlnJyk7XG4gIGVsc2VcbiAgICByZXR1cm4gdXRpbHMuc3BsaXQzMih0aGlzLmguc2xpY2UoMCwgMTIpLCAnYmlnJyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4uL2NvbW1vbicpO1xudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcblxudmFyIHJvdHI2NF9oaSA9IHV0aWxzLnJvdHI2NF9oaTtcbnZhciByb3RyNjRfbG8gPSB1dGlscy5yb3RyNjRfbG87XG52YXIgc2hyNjRfaGkgPSB1dGlscy5zaHI2NF9oaTtcbnZhciBzaHI2NF9sbyA9IHV0aWxzLnNocjY0X2xvO1xudmFyIHN1bTY0ID0gdXRpbHMuc3VtNjQ7XG52YXIgc3VtNjRfaGkgPSB1dGlscy5zdW02NF9oaTtcbnZhciBzdW02NF9sbyA9IHV0aWxzLnN1bTY0X2xvO1xudmFyIHN1bTY0XzRfaGkgPSB1dGlscy5zdW02NF80X2hpO1xudmFyIHN1bTY0XzRfbG8gPSB1dGlscy5zdW02NF80X2xvO1xudmFyIHN1bTY0XzVfaGkgPSB1dGlscy5zdW02NF81X2hpO1xudmFyIHN1bTY0XzVfbG8gPSB1dGlscy5zdW02NF81X2xvO1xuXG52YXIgQmxvY2tIYXNoID0gY29tbW9uLkJsb2NrSGFzaDtcblxudmFyIHNoYTUxMl9LID0gW1xuICAweDQyOGEyZjk4LCAweGQ3MjhhZTIyLCAweDcxMzc0NDkxLCAweDIzZWY2NWNkLFxuICAweGI1YzBmYmNmLCAweGVjNGQzYjJmLCAweGU5YjVkYmE1LCAweDgxODlkYmJjLFxuICAweDM5NTZjMjViLCAweGYzNDhiNTM4LCAweDU5ZjExMWYxLCAweGI2MDVkMDE5LFxuICAweDkyM2Y4MmE0LCAweGFmMTk0ZjliLCAweGFiMWM1ZWQ1LCAweGRhNmQ4MTE4LFxuICAweGQ4MDdhYTk4LCAweGEzMDMwMjQyLCAweDEyODM1YjAxLCAweDQ1NzA2ZmJlLFxuICAweDI0MzE4NWJlLCAweDRlZTRiMjhjLCAweDU1MGM3ZGMzLCAweGQ1ZmZiNGUyLFxuICAweDcyYmU1ZDc0LCAweGYyN2I4OTZmLCAweDgwZGViMWZlLCAweDNiMTY5NmIxLFxuICAweDliZGMwNmE3LCAweDI1YzcxMjM1LCAweGMxOWJmMTc0LCAweGNmNjkyNjk0LFxuICAweGU0OWI2OWMxLCAweDllZjE0YWQyLCAweGVmYmU0Nzg2LCAweDM4NGYyNWUzLFxuICAweDBmYzE5ZGM2LCAweDhiOGNkNWI1LCAweDI0MGNhMWNjLCAweDc3YWM5YzY1LFxuICAweDJkZTkyYzZmLCAweDU5MmIwMjc1LCAweDRhNzQ4NGFhLCAweDZlYTZlNDgzLFxuICAweDVjYjBhOWRjLCAweGJkNDFmYmQ0LCAweDc2Zjk4OGRhLCAweDgzMTE1M2I1LFxuICAweDk4M2U1MTUyLCAweGVlNjZkZmFiLCAweGE4MzFjNjZkLCAweDJkYjQzMjEwLFxuICAweGIwMDMyN2M4LCAweDk4ZmIyMTNmLCAweGJmNTk3ZmM3LCAweGJlZWYwZWU0LFxuICAweGM2ZTAwYmYzLCAweDNkYTg4ZmMyLCAweGQ1YTc5MTQ3LCAweDkzMGFhNzI1LFxuICAweDA2Y2E2MzUxLCAweGUwMDM4MjZmLCAweDE0MjkyOTY3LCAweDBhMGU2ZTcwLFxuICAweDI3YjcwYTg1LCAweDQ2ZDIyZmZjLCAweDJlMWIyMTM4LCAweDVjMjZjOTI2LFxuICAweDRkMmM2ZGZjLCAweDVhYzQyYWVkLCAweDUzMzgwZDEzLCAweDlkOTViM2RmLFxuICAweDY1MGE3MzU0LCAweDhiYWY2M2RlLCAweDc2NmEwYWJiLCAweDNjNzdiMmE4LFxuICAweDgxYzJjOTJlLCAweDQ3ZWRhZWU2LCAweDkyNzIyYzg1LCAweDE0ODIzNTNiLFxuICAweGEyYmZlOGExLCAweDRjZjEwMzY0LCAweGE4MWE2NjRiLCAweGJjNDIzMDAxLFxuICAweGMyNGI4YjcwLCAweGQwZjg5NzkxLCAweGM3NmM1MWEzLCAweDA2NTRiZTMwLFxuICAweGQxOTJlODE5LCAweGQ2ZWY1MjE4LCAweGQ2OTkwNjI0LCAweDU1NjVhOTEwLFxuICAweGY0MGUzNTg1LCAweDU3NzEyMDJhLCAweDEwNmFhMDcwLCAweDMyYmJkMWI4LFxuICAweDE5YTRjMTE2LCAweGI4ZDJkMGM4LCAweDFlMzc2YzA4LCAweDUxNDFhYjUzLFxuICAweDI3NDg3NzRjLCAweGRmOGVlYjk5LCAweDM0YjBiY2I1LCAweGUxOWI0OGE4LFxuICAweDM5MWMwY2IzLCAweGM1Yzk1YTYzLCAweDRlZDhhYTRhLCAweGUzNDE4YWNiLFxuICAweDViOWNjYTRmLCAweDc3NjNlMzczLCAweDY4MmU2ZmYzLCAweGQ2YjJiOGEzLFxuICAweDc0OGY4MmVlLCAweDVkZWZiMmZjLCAweDc4YTU2MzZmLCAweDQzMTcyZjYwLFxuICAweDg0Yzg3ODE0LCAweGExZjBhYjcyLCAweDhjYzcwMjA4LCAweDFhNjQzOWVjLFxuICAweDkwYmVmZmZhLCAweDIzNjMxZTI4LCAweGE0NTA2Y2ViLCAweGRlODJiZGU5LFxuICAweGJlZjlhM2Y3LCAweGIyYzY3OTE1LCAweGM2NzE3OGYyLCAweGUzNzI1MzJiLFxuICAweGNhMjczZWNlLCAweGVhMjY2MTljLCAweGQxODZiOGM3LCAweDIxYzBjMjA3LFxuICAweGVhZGE3ZGQ2LCAweGNkZTBlYjFlLCAweGY1N2Q0ZjdmLCAweGVlNmVkMTc4LFxuICAweDA2ZjA2N2FhLCAweDcyMTc2ZmJhLCAweDBhNjM3ZGM1LCAweGEyYzg5OGE2LFxuICAweDExM2Y5ODA0LCAweGJlZjkwZGFlLCAweDFiNzEwYjM1LCAweDEzMWM0NzFiLFxuICAweDI4ZGI3N2Y1LCAweDIzMDQ3ZDg0LCAweDMyY2FhYjdiLCAweDQwYzcyNDkzLFxuICAweDNjOWViZTBhLCAweDE1YzliZWJjLCAweDQzMWQ2N2M0LCAweDljMTAwZDRjLFxuICAweDRjYzVkNGJlLCAweGNiM2U0MmI2LCAweDU5N2YyOTljLCAweGZjNjU3ZTJhLFxuICAweDVmY2I2ZmFiLCAweDNhZDZmYWVjLCAweDZjNDQxOThjLCAweDRhNDc1ODE3XG5dO1xuXG5mdW5jdGlvbiBTSEE1MTIoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTSEE1MTIpKVxuICAgIHJldHVybiBuZXcgU0hBNTEyKCk7XG5cbiAgQmxvY2tIYXNoLmNhbGwodGhpcyk7XG4gIHRoaXMuaCA9IFtcbiAgICAweDZhMDllNjY3LCAweGYzYmNjOTA4LFxuICAgIDB4YmI2N2FlODUsIDB4ODRjYWE3M2IsXG4gICAgMHgzYzZlZjM3MiwgMHhmZTk0ZjgyYixcbiAgICAweGE1NGZmNTNhLCAweDVmMWQzNmYxLFxuICAgIDB4NTEwZTUyN2YsIDB4YWRlNjgyZDEsXG4gICAgMHg5YjA1Njg4YywgMHgyYjNlNmMxZixcbiAgICAweDFmODNkOWFiLCAweGZiNDFiZDZiLFxuICAgIDB4NWJlMGNkMTksIDB4MTM3ZTIxNzkgXTtcbiAgdGhpcy5rID0gc2hhNTEyX0s7XG4gIHRoaXMuVyA9IG5ldyBBcnJheSgxNjApO1xufVxudXRpbHMuaW5oZXJpdHMoU0hBNTEyLCBCbG9ja0hhc2gpO1xubW9kdWxlLmV4cG9ydHMgPSBTSEE1MTI7XG5cblNIQTUxMi5ibG9ja1NpemUgPSAxMDI0O1xuU0hBNTEyLm91dFNpemUgPSA1MTI7XG5TSEE1MTIuaG1hY1N0cmVuZ3RoID0gMTkyO1xuU0hBNTEyLnBhZExlbmd0aCA9IDEyODtcblxuU0hBNTEyLnByb3RvdHlwZS5fcHJlcGFyZUJsb2NrID0gZnVuY3Rpb24gX3ByZXBhcmVCbG9jayhtc2csIHN0YXJ0KSB7XG4gIHZhciBXID0gdGhpcy5XO1xuXG4gIC8vIDMyIHggMzJiaXQgd29yZHNcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAzMjsgaSsrKVxuICAgIFdbaV0gPSBtc2dbc3RhcnQgKyBpXTtcbiAgZm9yICg7IGkgPCBXLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgdmFyIGMwX2hpID0gZzFfNTEyX2hpKFdbaSAtIDRdLCBXW2kgLSAzXSk7ICAvLyBpIC0gMlxuICAgIHZhciBjMF9sbyA9IGcxXzUxMl9sbyhXW2kgLSA0XSwgV1tpIC0gM10pO1xuICAgIHZhciBjMV9oaSA9IFdbaSAtIDE0XTsgIC8vIGkgLSA3XG4gICAgdmFyIGMxX2xvID0gV1tpIC0gMTNdO1xuICAgIHZhciBjMl9oaSA9IGcwXzUxMl9oaShXW2kgLSAzMF0sIFdbaSAtIDI5XSk7ICAvLyBpIC0gMTVcbiAgICB2YXIgYzJfbG8gPSBnMF81MTJfbG8oV1tpIC0gMzBdLCBXW2kgLSAyOV0pO1xuICAgIHZhciBjM19oaSA9IFdbaSAtIDMyXTsgIC8vIGkgLSAxNlxuICAgIHZhciBjM19sbyA9IFdbaSAtIDMxXTtcblxuICAgIFdbaV0gPSBzdW02NF80X2hpKFxuICAgICAgYzBfaGksIGMwX2xvLFxuICAgICAgYzFfaGksIGMxX2xvLFxuICAgICAgYzJfaGksIGMyX2xvLFxuICAgICAgYzNfaGksIGMzX2xvKTtcbiAgICBXW2kgKyAxXSA9IHN1bTY0XzRfbG8oXG4gICAgICBjMF9oaSwgYzBfbG8sXG4gICAgICBjMV9oaSwgYzFfbG8sXG4gICAgICBjMl9oaSwgYzJfbG8sXG4gICAgICBjM19oaSwgYzNfbG8pO1xuICB9XG59O1xuXG5TSEE1MTIucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiBfdXBkYXRlKG1zZywgc3RhcnQpIHtcbiAgdGhpcy5fcHJlcGFyZUJsb2NrKG1zZywgc3RhcnQpO1xuXG4gIHZhciBXID0gdGhpcy5XO1xuXG4gIHZhciBhaCA9IHRoaXMuaFswXTtcbiAgdmFyIGFsID0gdGhpcy5oWzFdO1xuICB2YXIgYmggPSB0aGlzLmhbMl07XG4gIHZhciBibCA9IHRoaXMuaFszXTtcbiAgdmFyIGNoID0gdGhpcy5oWzRdO1xuICB2YXIgY2wgPSB0aGlzLmhbNV07XG4gIHZhciBkaCA9IHRoaXMuaFs2XTtcbiAgdmFyIGRsID0gdGhpcy5oWzddO1xuICB2YXIgZWggPSB0aGlzLmhbOF07XG4gIHZhciBlbCA9IHRoaXMuaFs5XTtcbiAgdmFyIGZoID0gdGhpcy5oWzEwXTtcbiAgdmFyIGZsID0gdGhpcy5oWzExXTtcbiAgdmFyIGdoID0gdGhpcy5oWzEyXTtcbiAgdmFyIGdsID0gdGhpcy5oWzEzXTtcbiAgdmFyIGhoID0gdGhpcy5oWzE0XTtcbiAgdmFyIGhsID0gdGhpcy5oWzE1XTtcblxuICBhc3NlcnQodGhpcy5rLmxlbmd0aCA9PT0gVy5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IFcubGVuZ3RoOyBpICs9IDIpIHtcbiAgICB2YXIgYzBfaGkgPSBoaDtcbiAgICB2YXIgYzBfbG8gPSBobDtcbiAgICB2YXIgYzFfaGkgPSBzMV81MTJfaGkoZWgsIGVsKTtcbiAgICB2YXIgYzFfbG8gPSBzMV81MTJfbG8oZWgsIGVsKTtcbiAgICB2YXIgYzJfaGkgPSBjaDY0X2hpKGVoLCBlbCwgZmgsIGZsLCBnaCwgZ2wpO1xuICAgIHZhciBjMl9sbyA9IGNoNjRfbG8oZWgsIGVsLCBmaCwgZmwsIGdoLCBnbCk7XG4gICAgdmFyIGMzX2hpID0gdGhpcy5rW2ldO1xuICAgIHZhciBjM19sbyA9IHRoaXMua1tpICsgMV07XG4gICAgdmFyIGM0X2hpID0gV1tpXTtcbiAgICB2YXIgYzRfbG8gPSBXW2kgKyAxXTtcblxuICAgIHZhciBUMV9oaSA9IHN1bTY0XzVfaGkoXG4gICAgICBjMF9oaSwgYzBfbG8sXG4gICAgICBjMV9oaSwgYzFfbG8sXG4gICAgICBjMl9oaSwgYzJfbG8sXG4gICAgICBjM19oaSwgYzNfbG8sXG4gICAgICBjNF9oaSwgYzRfbG8pO1xuICAgIHZhciBUMV9sbyA9IHN1bTY0XzVfbG8oXG4gICAgICBjMF9oaSwgYzBfbG8sXG4gICAgICBjMV9oaSwgYzFfbG8sXG4gICAgICBjMl9oaSwgYzJfbG8sXG4gICAgICBjM19oaSwgYzNfbG8sXG4gICAgICBjNF9oaSwgYzRfbG8pO1xuXG4gICAgYzBfaGkgPSBzMF81MTJfaGkoYWgsIGFsKTtcbiAgICBjMF9sbyA9IHMwXzUxMl9sbyhhaCwgYWwpO1xuICAgIGMxX2hpID0gbWFqNjRfaGkoYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCk7XG4gICAgYzFfbG8gPSBtYWo2NF9sbyhhaCwgYWwsIGJoLCBibCwgY2gsIGNsKTtcblxuICAgIHZhciBUMl9oaSA9IHN1bTY0X2hpKGMwX2hpLCBjMF9sbywgYzFfaGksIGMxX2xvKTtcbiAgICB2YXIgVDJfbG8gPSBzdW02NF9sbyhjMF9oaSwgYzBfbG8sIGMxX2hpLCBjMV9sbyk7XG5cbiAgICBoaCA9IGdoO1xuICAgIGhsID0gZ2w7XG5cbiAgICBnaCA9IGZoO1xuICAgIGdsID0gZmw7XG5cbiAgICBmaCA9IGVoO1xuICAgIGZsID0gZWw7XG5cbiAgICBlaCA9IHN1bTY0X2hpKGRoLCBkbCwgVDFfaGksIFQxX2xvKTtcbiAgICBlbCA9IHN1bTY0X2xvKGRsLCBkbCwgVDFfaGksIFQxX2xvKTtcblxuICAgIGRoID0gY2g7XG4gICAgZGwgPSBjbDtcblxuICAgIGNoID0gYmg7XG4gICAgY2wgPSBibDtcblxuICAgIGJoID0gYWg7XG4gICAgYmwgPSBhbDtcblxuICAgIGFoID0gc3VtNjRfaGkoVDFfaGksIFQxX2xvLCBUMl9oaSwgVDJfbG8pO1xuICAgIGFsID0gc3VtNjRfbG8oVDFfaGksIFQxX2xvLCBUMl9oaSwgVDJfbG8pO1xuICB9XG5cbiAgc3VtNjQodGhpcy5oLCAwLCBhaCwgYWwpO1xuICBzdW02NCh0aGlzLmgsIDIsIGJoLCBibCk7XG4gIHN1bTY0KHRoaXMuaCwgNCwgY2gsIGNsKTtcbiAgc3VtNjQodGhpcy5oLCA2LCBkaCwgZGwpO1xuICBzdW02NCh0aGlzLmgsIDgsIGVoLCBlbCk7XG4gIHN1bTY0KHRoaXMuaCwgMTAsIGZoLCBmbCk7XG4gIHN1bTY0KHRoaXMuaCwgMTIsIGdoLCBnbCk7XG4gIHN1bTY0KHRoaXMuaCwgMTQsIGhoLCBobCk7XG59O1xuXG5TSEE1MTIucHJvdG90eXBlLl9kaWdlc3QgPSBmdW5jdGlvbiBkaWdlc3QoZW5jKSB7XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB1dGlscy50b0hleDMyKHRoaXMuaCwgJ2JpZycpO1xuICBlbHNlXG4gICAgcmV0dXJuIHV0aWxzLnNwbGl0MzIodGhpcy5oLCAnYmlnJyk7XG59O1xuXG5mdW5jdGlvbiBjaDY0X2hpKHhoLCB4bCwgeWgsIHlsLCB6aCkge1xuICB2YXIgciA9ICh4aCAmIHloKSBeICgofnhoKSAmIHpoKTtcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBjaDY0X2xvKHhoLCB4bCwgeWgsIHlsLCB6aCwgemwpIHtcbiAgdmFyIHIgPSAoeGwgJiB5bCkgXiAoKH54bCkgJiB6bCk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gbWFqNjRfaGkoeGgsIHhsLCB5aCwgeWwsIHpoKSB7XG4gIHZhciByID0gKHhoICYgeWgpIF4gKHhoICYgemgpIF4gKHloICYgemgpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIG1hajY0X2xvKHhoLCB4bCwgeWgsIHlsLCB6aCwgemwpIHtcbiAgdmFyIHIgPSAoeGwgJiB5bCkgXiAoeGwgJiB6bCkgXiAoeWwgJiB6bCk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gczBfNTEyX2hpKHhoLCB4bCkge1xuICB2YXIgYzBfaGkgPSByb3RyNjRfaGkoeGgsIHhsLCAyOCk7XG4gIHZhciBjMV9oaSA9IHJvdHI2NF9oaSh4bCwgeGgsIDIpOyAgLy8gMzRcbiAgdmFyIGMyX2hpID0gcm90cjY0X2hpKHhsLCB4aCwgNyk7ICAvLyAzOVxuXG4gIHZhciByID0gYzBfaGkgXiBjMV9oaSBeIGMyX2hpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHMwXzUxMl9sbyh4aCwgeGwpIHtcbiAgdmFyIGMwX2xvID0gcm90cjY0X2xvKHhoLCB4bCwgMjgpO1xuICB2YXIgYzFfbG8gPSByb3RyNjRfbG8oeGwsIHhoLCAyKTsgIC8vIDM0XG4gIHZhciBjMl9sbyA9IHJvdHI2NF9sbyh4bCwgeGgsIDcpOyAgLy8gMzlcblxuICB2YXIgciA9IGMwX2xvIF4gYzFfbG8gXiBjMl9sbztcbiAgaWYgKHIgPCAwKVxuICAgIHIgKz0gMHgxMDAwMDAwMDA7XG4gIHJldHVybiByO1xufVxuXG5mdW5jdGlvbiBzMV81MTJfaGkoeGgsIHhsKSB7XG4gIHZhciBjMF9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDE0KTtcbiAgdmFyIGMxX2hpID0gcm90cjY0X2hpKHhoLCB4bCwgMTgpO1xuICB2YXIgYzJfaGkgPSByb3RyNjRfaGkoeGwsIHhoLCA5KTsgIC8vIDQxXG5cbiAgdmFyIHIgPSBjMF9oaSBeIGMxX2hpIF4gYzJfaGk7XG4gIGlmIChyIDwgMClcbiAgICByICs9IDB4MTAwMDAwMDAwO1xuICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gczFfNTEyX2xvKHhoLCB4bCkge1xuICB2YXIgYzBfbG8gPSByb3RyNjRfbG8oeGgsIHhsLCAxNCk7XG4gIHZhciBjMV9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDE4KTtcbiAgdmFyIGMyX2xvID0gcm90cjY0X2xvKHhsLCB4aCwgOSk7ICAvLyA0MVxuXG4gIHZhciByID0gYzBfbG8gXiBjMV9sbyBeIGMyX2xvO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIGcwXzUxMl9oaSh4aCwgeGwpIHtcbiAgdmFyIGMwX2hpID0gcm90cjY0X2hpKHhoLCB4bCwgMSk7XG4gIHZhciBjMV9oaSA9IHJvdHI2NF9oaSh4aCwgeGwsIDgpO1xuICB2YXIgYzJfaGkgPSBzaHI2NF9oaSh4aCwgeGwsIDcpO1xuXG4gIHZhciByID0gYzBfaGkgXiBjMV9oaSBeIGMyX2hpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIGcwXzUxMl9sbyh4aCwgeGwpIHtcbiAgdmFyIGMwX2xvID0gcm90cjY0X2xvKHhoLCB4bCwgMSk7XG4gIHZhciBjMV9sbyA9IHJvdHI2NF9sbyh4aCwgeGwsIDgpO1xuICB2YXIgYzJfbG8gPSBzaHI2NF9sbyh4aCwgeGwsIDcpO1xuXG4gIHZhciByID0gYzBfbG8gXiBjMV9sbyBeIGMyX2xvO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIGcxXzUxMl9oaSh4aCwgeGwpIHtcbiAgdmFyIGMwX2hpID0gcm90cjY0X2hpKHhoLCB4bCwgMTkpO1xuICB2YXIgYzFfaGkgPSByb3RyNjRfaGkoeGwsIHhoLCAyOSk7ICAvLyA2MVxuICB2YXIgYzJfaGkgPSBzaHI2NF9oaSh4aCwgeGwsIDYpO1xuXG4gIHZhciByID0gYzBfaGkgXiBjMV9oaSBeIGMyX2hpO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIGcxXzUxMl9sbyh4aCwgeGwpIHtcbiAgdmFyIGMwX2xvID0gcm90cjY0X2xvKHhoLCB4bCwgMTkpO1xuICB2YXIgYzFfbG8gPSByb3RyNjRfbG8oeGwsIHhoLCAyOSk7ICAvLyA2MVxuICB2YXIgYzJfbG8gPSBzaHI2NF9sbyh4aCwgeGwsIDYpO1xuXG4gIHZhciByID0gYzBfbG8gXiBjMV9sbyBeIGMyX2xvO1xuICBpZiAociA8IDApXG4gICAgciArPSAweDEwMDAwMDAwMDtcbiAgcmV0dXJuIHI7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgcm90cjMyID0gdXRpbHMucm90cjMyO1xuXG5mdW5jdGlvbiBmdF8xKHMsIHgsIHksIHopIHtcbiAgaWYgKHMgPT09IDApXG4gICAgcmV0dXJuIGNoMzIoeCwgeSwgeik7XG4gIGlmIChzID09PSAxIHx8IHMgPT09IDMpXG4gICAgcmV0dXJuIHAzMih4LCB5LCB6KTtcbiAgaWYgKHMgPT09IDIpXG4gICAgcmV0dXJuIG1hajMyKHgsIHksIHopO1xufVxuZXhwb3J0cy5mdF8xID0gZnRfMTtcblxuZnVuY3Rpb24gY2gzMih4LCB5LCB6KSB7XG4gIHJldHVybiAoeCAmIHkpIF4gKCh+eCkgJiB6KTtcbn1cbmV4cG9ydHMuY2gzMiA9IGNoMzI7XG5cbmZ1bmN0aW9uIG1hajMyKHgsIHksIHopIHtcbiAgcmV0dXJuICh4ICYgeSkgXiAoeCAmIHopIF4gKHkgJiB6KTtcbn1cbmV4cG9ydHMubWFqMzIgPSBtYWozMjtcblxuZnVuY3Rpb24gcDMyKHgsIHksIHopIHtcbiAgcmV0dXJuIHggXiB5IF4gejtcbn1cbmV4cG9ydHMucDMyID0gcDMyO1xuXG5mdW5jdGlvbiBzMF8yNTYoeCkge1xuICByZXR1cm4gcm90cjMyKHgsIDIpIF4gcm90cjMyKHgsIDEzKSBeIHJvdHIzMih4LCAyMik7XG59XG5leHBvcnRzLnMwXzI1NiA9IHMwXzI1NjtcblxuZnVuY3Rpb24gczFfMjU2KHgpIHtcbiAgcmV0dXJuIHJvdHIzMih4LCA2KSBeIHJvdHIzMih4LCAxMSkgXiByb3RyMzIoeCwgMjUpO1xufVxuZXhwb3J0cy5zMV8yNTYgPSBzMV8yNTY7XG5cbmZ1bmN0aW9uIGcwXzI1Nih4KSB7XG4gIHJldHVybiByb3RyMzIoeCwgNykgXiByb3RyMzIoeCwgMTgpIF4gKHggPj4+IDMpO1xufVxuZXhwb3J0cy5nMF8yNTYgPSBnMF8yNTY7XG5cbmZ1bmN0aW9uIGcxXzI1Nih4KSB7XG4gIHJldHVybiByb3RyMzIoeCwgMTcpIF4gcm90cjMyKHgsIDE5KSBeICh4ID4+PiAxMCk7XG59XG5leHBvcnRzLmcxXzI1NiA9IGcxXzI1NjtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmV4cG9ydHMuaW5oZXJpdHMgPSBpbmhlcml0cztcblxuZnVuY3Rpb24gaXNTdXJyb2dhdGVQYWlyKG1zZywgaSkge1xuICBpZiAoKG1zZy5jaGFyQ29kZUF0KGkpICYgMHhGQzAwKSAhPT0gMHhEODAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChpIDwgMCB8fCBpICsgMSA+PSBtc2cubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiAobXNnLmNoYXJDb2RlQXQoaSArIDEpICYgMHhGQzAwKSA9PT0gMHhEQzAwO1xufVxuXG5mdW5jdGlvbiB0b0FycmF5KG1zZywgZW5jKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KG1zZykpXG4gICAgcmV0dXJuIG1zZy5zbGljZSgpO1xuICBpZiAoIW1zZylcbiAgICByZXR1cm4gW107XG4gIHZhciByZXMgPSBbXTtcbiAgaWYgKHR5cGVvZiBtc2cgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKCFlbmMpIHtcbiAgICAgIC8vIEluc3BpcmVkIGJ5IHN0cmluZ1RvVXRmOEJ5dGVBcnJheSgpIGluIGNsb3N1cmUtbGlicmFyeSBieSBHb29nbGVcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvY2xvc3VyZS1saWJyYXJ5L2Jsb2IvODU5OGQ4NzI0MmFmNTlhYWMyMzMyNzA3NDJjODk4NGUyYjJiZGJlMC9jbG9zdXJlL2dvb2cvY3J5cHQvY3J5cHQuanMjTDExNy1MMTQzXG4gICAgICAvLyBBcGFjaGUgTGljZW5zZSAyLjBcbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvY2xvc3VyZS1saWJyYXJ5L2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAgICAgIHZhciBwID0gMDtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjID0gbXNnLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIGlmIChjIDwgMTI4KSB7XG4gICAgICAgICAgcmVzW3ArK10gPSBjO1xuICAgICAgICB9IGVsc2UgaWYgKGMgPCAyMDQ4KSB7XG4gICAgICAgICAgcmVzW3ArK10gPSAoYyA+PiA2KSB8IDE5MjtcbiAgICAgICAgICByZXNbcCsrXSA9IChjICYgNjMpIHwgMTI4O1xuICAgICAgICB9IGVsc2UgaWYgKGlzU3Vycm9nYXRlUGFpcihtc2csIGkpKSB7XG4gICAgICAgICAgYyA9IDB4MTAwMDAgKyAoKGMgJiAweDAzRkYpIDw8IDEwKSArIChtc2cuY2hhckNvZGVBdCgrK2kpICYgMHgwM0ZGKTtcbiAgICAgICAgICByZXNbcCsrXSA9IChjID4+IDE4KSB8IDI0MDtcbiAgICAgICAgICByZXNbcCsrXSA9ICgoYyA+PiAxMikgJiA2MykgfCAxMjg7XG4gICAgICAgICAgcmVzW3ArK10gPSAoKGMgPj4gNikgJiA2MykgfCAxMjg7XG4gICAgICAgICAgcmVzW3ArK10gPSAoYyAmIDYzKSB8IDEyODtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNbcCsrXSA9IChjID4+IDEyKSB8IDIyNDtcbiAgICAgICAgICByZXNbcCsrXSA9ICgoYyA+PiA2KSAmIDYzKSB8IDEyODtcbiAgICAgICAgICByZXNbcCsrXSA9IChjICYgNjMpIHwgMTI4O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChlbmMgPT09ICdoZXgnKSB7XG4gICAgICBtc2cgPSBtc2cucmVwbGFjZSgvW15hLXowLTldKy9pZywgJycpO1xuICAgICAgaWYgKG1zZy5sZW5ndGggJSAyICE9PSAwKVxuICAgICAgICBtc2cgPSAnMCcgKyBtc2c7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSArPSAyKVxuICAgICAgICByZXMucHVzaChwYXJzZUludChtc2dbaV0gKyBtc2dbaSArIDFdLCAxNikpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKVxuICAgICAgcmVzW2ldID0gbXNnW2ldIHwgMDtcbiAgfVxuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy50b0FycmF5ID0gdG9BcnJheTtcblxuZnVuY3Rpb24gdG9IZXgobXNnKSB7XG4gIHZhciByZXMgPSAnJztcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyspXG4gICAgcmVzICs9IHplcm8yKG1zZ1tpXS50b1N0cmluZygxNikpO1xuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy50b0hleCA9IHRvSGV4O1xuXG5mdW5jdGlvbiBodG9ubCh3KSB7XG4gIHZhciByZXMgPSAodyA+Pj4gMjQpIHxcbiAgICAgICAgICAgICgodyA+Pj4gOCkgJiAweGZmMDApIHxcbiAgICAgICAgICAgICgodyA8PCA4KSAmIDB4ZmYwMDAwKSB8XG4gICAgICAgICAgICAoKHcgJiAweGZmKSA8PCAyNCk7XG4gIHJldHVybiByZXMgPj4+IDA7XG59XG5leHBvcnRzLmh0b25sID0gaHRvbmw7XG5cbmZ1bmN0aW9uIHRvSGV4MzIobXNnLCBlbmRpYW4pIHtcbiAgdmFyIHJlcyA9ICcnO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG1zZy5sZW5ndGg7IGkrKykge1xuICAgIHZhciB3ID0gbXNnW2ldO1xuICAgIGlmIChlbmRpYW4gPT09ICdsaXR0bGUnKVxuICAgICAgdyA9IGh0b25sKHcpO1xuICAgIHJlcyArPSB6ZXJvOCh3LnRvU3RyaW5nKDE2KSk7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbmV4cG9ydHMudG9IZXgzMiA9IHRvSGV4MzI7XG5cbmZ1bmN0aW9uIHplcm8yKHdvcmQpIHtcbiAgaWYgKHdvcmQubGVuZ3RoID09PSAxKVxuICAgIHJldHVybiAnMCcgKyB3b3JkO1xuICBlbHNlXG4gICAgcmV0dXJuIHdvcmQ7XG59XG5leHBvcnRzLnplcm8yID0gemVybzI7XG5cbmZ1bmN0aW9uIHplcm84KHdvcmQpIHtcbiAgaWYgKHdvcmQubGVuZ3RoID09PSA3KVxuICAgIHJldHVybiAnMCcgKyB3b3JkO1xuICBlbHNlIGlmICh3b3JkLmxlbmd0aCA9PT0gNilcbiAgICByZXR1cm4gJzAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSA1KVxuICAgIHJldHVybiAnMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSA0KVxuICAgIHJldHVybiAnMDAwMCcgKyB3b3JkO1xuICBlbHNlIGlmICh3b3JkLmxlbmd0aCA9PT0gMylcbiAgICByZXR1cm4gJzAwMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSAyKVxuICAgIHJldHVybiAnMDAwMDAwJyArIHdvcmQ7XG4gIGVsc2UgaWYgKHdvcmQubGVuZ3RoID09PSAxKVxuICAgIHJldHVybiAnMDAwMDAwMCcgKyB3b3JkO1xuICBlbHNlXG4gICAgcmV0dXJuIHdvcmQ7XG59XG5leHBvcnRzLnplcm84ID0gemVybzg7XG5cbmZ1bmN0aW9uIGpvaW4zMihtc2csIHN0YXJ0LCBlbmQsIGVuZGlhbikge1xuICB2YXIgbGVuID0gZW5kIC0gc3RhcnQ7XG4gIGFzc2VydChsZW4gJSA0ID09PSAwKTtcbiAgdmFyIHJlcyA9IG5ldyBBcnJheShsZW4gLyA0KTtcbiAgZm9yICh2YXIgaSA9IDAsIGsgPSBzdGFydDsgaSA8IHJlcy5sZW5ndGg7IGkrKywgayArPSA0KSB7XG4gICAgdmFyIHc7XG4gICAgaWYgKGVuZGlhbiA9PT0gJ2JpZycpXG4gICAgICB3ID0gKG1zZ1trXSA8PCAyNCkgfCAobXNnW2sgKyAxXSA8PCAxNikgfCAobXNnW2sgKyAyXSA8PCA4KSB8IG1zZ1trICsgM107XG4gICAgZWxzZVxuICAgICAgdyA9IChtc2dbayArIDNdIDw8IDI0KSB8IChtc2dbayArIDJdIDw8IDE2KSB8IChtc2dbayArIDFdIDw8IDgpIHwgbXNnW2tdO1xuICAgIHJlc1tpXSA9IHcgPj4+IDA7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbmV4cG9ydHMuam9pbjMyID0gam9pbjMyO1xuXG5mdW5jdGlvbiBzcGxpdDMyKG1zZywgZW5kaWFuKSB7XG4gIHZhciByZXMgPSBuZXcgQXJyYXkobXNnLmxlbmd0aCAqIDQpO1xuICBmb3IgKHZhciBpID0gMCwgayA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyssIGsgKz0gNCkge1xuICAgIHZhciBtID0gbXNnW2ldO1xuICAgIGlmIChlbmRpYW4gPT09ICdiaWcnKSB7XG4gICAgICByZXNba10gPSBtID4+PiAyNDtcbiAgICAgIHJlc1trICsgMV0gPSAobSA+Pj4gMTYpICYgMHhmZjtcbiAgICAgIHJlc1trICsgMl0gPSAobSA+Pj4gOCkgJiAweGZmO1xuICAgICAgcmVzW2sgKyAzXSA9IG0gJiAweGZmO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXNbayArIDNdID0gbSA+Pj4gMjQ7XG4gICAgICByZXNbayArIDJdID0gKG0gPj4+IDE2KSAmIDB4ZmY7XG4gICAgICByZXNbayArIDFdID0gKG0gPj4+IDgpICYgMHhmZjtcbiAgICAgIHJlc1trXSA9IG0gJiAweGZmO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzO1xufVxuZXhwb3J0cy5zcGxpdDMyID0gc3BsaXQzMjtcblxuZnVuY3Rpb24gcm90cjMyKHcsIGIpIHtcbiAgcmV0dXJuICh3ID4+PiBiKSB8ICh3IDw8ICgzMiAtIGIpKTtcbn1cbmV4cG9ydHMucm90cjMyID0gcm90cjMyO1xuXG5mdW5jdGlvbiByb3RsMzIodywgYikge1xuICByZXR1cm4gKHcgPDwgYikgfCAodyA+Pj4gKDMyIC0gYikpO1xufVxuZXhwb3J0cy5yb3RsMzIgPSByb3RsMzI7XG5cbmZ1bmN0aW9uIHN1bTMyKGEsIGIpIHtcbiAgcmV0dXJuIChhICsgYikgPj4+IDA7XG59XG5leHBvcnRzLnN1bTMyID0gc3VtMzI7XG5cbmZ1bmN0aW9uIHN1bTMyXzMoYSwgYiwgYykge1xuICByZXR1cm4gKGEgKyBiICsgYykgPj4+IDA7XG59XG5leHBvcnRzLnN1bTMyXzMgPSBzdW0zMl8zO1xuXG5mdW5jdGlvbiBzdW0zMl80KGEsIGIsIGMsIGQpIHtcbiAgcmV0dXJuIChhICsgYiArIGMgKyBkKSA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtMzJfNCA9IHN1bTMyXzQ7XG5cbmZ1bmN0aW9uIHN1bTMyXzUoYSwgYiwgYywgZCwgZSkge1xuICByZXR1cm4gKGEgKyBiICsgYyArIGQgKyBlKSA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtMzJfNSA9IHN1bTMyXzU7XG5cbmZ1bmN0aW9uIHN1bTY0KGJ1ZiwgcG9zLCBhaCwgYWwpIHtcbiAgdmFyIGJoID0gYnVmW3Bvc107XG4gIHZhciBibCA9IGJ1Zltwb3MgKyAxXTtcblxuICB2YXIgbG8gPSAoYWwgKyBibCkgPj4+IDA7XG4gIHZhciBoaSA9IChsbyA8IGFsID8gMSA6IDApICsgYWggKyBiaDtcbiAgYnVmW3Bvc10gPSBoaSA+Pj4gMDtcbiAgYnVmW3BvcyArIDFdID0gbG87XG59XG5leHBvcnRzLnN1bTY0ID0gc3VtNjQ7XG5cbmZ1bmN0aW9uIHN1bTY0X2hpKGFoLCBhbCwgYmgsIGJsKSB7XG4gIHZhciBsbyA9IChhbCArIGJsKSA+Pj4gMDtcbiAgdmFyIGhpID0gKGxvIDwgYWwgPyAxIDogMCkgKyBhaCArIGJoO1xuICByZXR1cm4gaGkgPj4+IDA7XG59XG5leHBvcnRzLnN1bTY0X2hpID0gc3VtNjRfaGk7XG5cbmZ1bmN0aW9uIHN1bTY0X2xvKGFoLCBhbCwgYmgsIGJsKSB7XG4gIHZhciBsbyA9IGFsICsgYmw7XG4gIHJldHVybiBsbyA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtNjRfbG8gPSBzdW02NF9sbztcblxuZnVuY3Rpb24gc3VtNjRfNF9oaShhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwpIHtcbiAgdmFyIGNhcnJ5ID0gMDtcbiAgdmFyIGxvID0gYWw7XG4gIGxvID0gKGxvICsgYmwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGFsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgY2wpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGNsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZGwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGRsID8gMSA6IDA7XG5cbiAgdmFyIGhpID0gYWggKyBiaCArIGNoICsgZGggKyBjYXJyeTtcbiAgcmV0dXJuIGhpID4+PiAwO1xufVxuZXhwb3J0cy5zdW02NF80X2hpID0gc3VtNjRfNF9oaTtcblxuZnVuY3Rpb24gc3VtNjRfNF9sbyhhaCwgYWwsIGJoLCBibCwgY2gsIGNsLCBkaCwgZGwpIHtcbiAgdmFyIGxvID0gYWwgKyBibCArIGNsICsgZGw7XG4gIHJldHVybiBsbyA+Pj4gMDtcbn1cbmV4cG9ydHMuc3VtNjRfNF9sbyA9IHN1bTY0XzRfbG87XG5cbmZ1bmN0aW9uIHN1bTY0XzVfaGkoYWgsIGFsLCBiaCwgYmwsIGNoLCBjbCwgZGgsIGRsLCBlaCwgZWwpIHtcbiAgdmFyIGNhcnJ5ID0gMDtcbiAgdmFyIGxvID0gYWw7XG4gIGxvID0gKGxvICsgYmwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGFsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgY2wpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGNsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZGwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGRsID8gMSA6IDA7XG4gIGxvID0gKGxvICsgZWwpID4+PiAwO1xuICBjYXJyeSArPSBsbyA8IGVsID8gMSA6IDA7XG5cbiAgdmFyIGhpID0gYWggKyBiaCArIGNoICsgZGggKyBlaCArIGNhcnJ5O1xuICByZXR1cm4gaGkgPj4+IDA7XG59XG5leHBvcnRzLnN1bTY0XzVfaGkgPSBzdW02NF81X2hpO1xuXG5mdW5jdGlvbiBzdW02NF81X2xvKGFoLCBhbCwgYmgsIGJsLCBjaCwgY2wsIGRoLCBkbCwgZWgsIGVsKSB7XG4gIHZhciBsbyA9IGFsICsgYmwgKyBjbCArIGRsICsgZWw7XG5cbiAgcmV0dXJuIGxvID4+PiAwO1xufVxuZXhwb3J0cy5zdW02NF81X2xvID0gc3VtNjRfNV9sbztcblxuZnVuY3Rpb24gcm90cjY0X2hpKGFoLCBhbCwgbnVtKSB7XG4gIHZhciByID0gKGFsIDw8ICgzMiAtIG51bSkpIHwgKGFoID4+PiBudW0pO1xuICByZXR1cm4gciA+Pj4gMDtcbn1cbmV4cG9ydHMucm90cjY0X2hpID0gcm90cjY0X2hpO1xuXG5mdW5jdGlvbiByb3RyNjRfbG8oYWgsIGFsLCBudW0pIHtcbiAgdmFyIHIgPSAoYWggPDwgKDMyIC0gbnVtKSkgfCAoYWwgPj4+IG51bSk7XG4gIHJldHVybiByID4+PiAwO1xufVxuZXhwb3J0cy5yb3RyNjRfbG8gPSByb3RyNjRfbG87XG5cbmZ1bmN0aW9uIHNocjY0X2hpKGFoLCBhbCwgbnVtKSB7XG4gIHJldHVybiBhaCA+Pj4gbnVtO1xufVxuZXhwb3J0cy5zaHI2NF9oaSA9IHNocjY0X2hpO1xuXG5mdW5jdGlvbiBzaHI2NF9sbyhhaCwgYWwsIG51bSkge1xuICB2YXIgciA9IChhaCA8PCAoMzIgLSBudW0pKSB8IChhbCA+Pj4gbnVtKTtcbiAgcmV0dXJuIHIgPj4+IDA7XG59XG5leHBvcnRzLnNocjY0X2xvID0gc2hyNjRfbG87XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBoYXNoID0gcmVxdWlyZSgnaGFzaC5qcycpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnbWluaW1hbGlzdGljLWNyeXB0by11dGlscycpO1xudmFyIGFzc2VydCA9IHJlcXVpcmUoJ21pbmltYWxpc3RpYy1hc3NlcnQnKTtcblxuZnVuY3Rpb24gSG1hY0RSQkcob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgSG1hY0RSQkcpKVxuICAgIHJldHVybiBuZXcgSG1hY0RSQkcob3B0aW9ucyk7XG4gIHRoaXMuaGFzaCA9IG9wdGlvbnMuaGFzaDtcbiAgdGhpcy5wcmVkUmVzaXN0ID0gISFvcHRpb25zLnByZWRSZXNpc3Q7XG5cbiAgdGhpcy5vdXRMZW4gPSB0aGlzLmhhc2gub3V0U2l6ZTtcbiAgdGhpcy5taW5FbnRyb3B5ID0gb3B0aW9ucy5taW5FbnRyb3B5IHx8IHRoaXMuaGFzaC5obWFjU3RyZW5ndGg7XG5cbiAgdGhpcy5fcmVzZWVkID0gbnVsbDtcbiAgdGhpcy5yZXNlZWRJbnRlcnZhbCA9IG51bGw7XG4gIHRoaXMuSyA9IG51bGw7XG4gIHRoaXMuViA9IG51bGw7XG5cbiAgdmFyIGVudHJvcHkgPSB1dGlscy50b0FycmF5KG9wdGlvbnMuZW50cm9weSwgb3B0aW9ucy5lbnRyb3B5RW5jIHx8ICdoZXgnKTtcbiAgdmFyIG5vbmNlID0gdXRpbHMudG9BcnJheShvcHRpb25zLm5vbmNlLCBvcHRpb25zLm5vbmNlRW5jIHx8ICdoZXgnKTtcbiAgdmFyIHBlcnMgPSB1dGlscy50b0FycmF5KG9wdGlvbnMucGVycywgb3B0aW9ucy5wZXJzRW5jIHx8ICdoZXgnKTtcbiAgYXNzZXJ0KGVudHJvcHkubGVuZ3RoID49ICh0aGlzLm1pbkVudHJvcHkgLyA4KSxcbiAgICAgICAgICdOb3QgZW5vdWdoIGVudHJvcHkuIE1pbmltdW0gaXM6ICcgKyB0aGlzLm1pbkVudHJvcHkgKyAnIGJpdHMnKTtcbiAgdGhpcy5faW5pdChlbnRyb3B5LCBub25jZSwgcGVycyk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEhtYWNEUkJHO1xuXG5IbWFjRFJCRy5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbiBpbml0KGVudHJvcHksIG5vbmNlLCBwZXJzKSB7XG4gIHZhciBzZWVkID0gZW50cm9weS5jb25jYXQobm9uY2UpLmNvbmNhdChwZXJzKTtcblxuICB0aGlzLksgPSBuZXcgQXJyYXkodGhpcy5vdXRMZW4gLyA4KTtcbiAgdGhpcy5WID0gbmV3IEFycmF5KHRoaXMub3V0TGVuIC8gOCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5WLmxlbmd0aDsgaSsrKSB7XG4gICAgdGhpcy5LW2ldID0gMHgwMDtcbiAgICB0aGlzLlZbaV0gPSAweDAxO1xuICB9XG5cbiAgdGhpcy5fdXBkYXRlKHNlZWQpO1xuICB0aGlzLl9yZXNlZWQgPSAxO1xuICB0aGlzLnJlc2VlZEludGVydmFsID0gMHgxMDAwMDAwMDAwMDAwOyAgLy8gMl40OFxufTtcblxuSG1hY0RSQkcucHJvdG90eXBlLl9obWFjID0gZnVuY3Rpb24gaG1hYygpIHtcbiAgcmV0dXJuIG5ldyBoYXNoLmhtYWModGhpcy5oYXNoLCB0aGlzLkspO1xufTtcblxuSG1hY0RSQkcucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUoc2VlZCkge1xuICB2YXIga21hYyA9IHRoaXMuX2htYWMoKVxuICAgICAgICAgICAgICAgICAudXBkYXRlKHRoaXMuVilcbiAgICAgICAgICAgICAgICAgLnVwZGF0ZShbIDB4MDAgXSk7XG4gIGlmIChzZWVkKVxuICAgIGttYWMgPSBrbWFjLnVwZGF0ZShzZWVkKTtcbiAgdGhpcy5LID0ga21hYy5kaWdlc3QoKTtcbiAgdGhpcy5WID0gdGhpcy5faG1hYygpLnVwZGF0ZSh0aGlzLlYpLmRpZ2VzdCgpO1xuICBpZiAoIXNlZWQpXG4gICAgcmV0dXJuO1xuXG4gIHRoaXMuSyA9IHRoaXMuX2htYWMoKVxuICAgICAgICAgICAgICAgLnVwZGF0ZSh0aGlzLlYpXG4gICAgICAgICAgICAgICAudXBkYXRlKFsgMHgwMSBdKVxuICAgICAgICAgICAgICAgLnVwZGF0ZShzZWVkKVxuICAgICAgICAgICAgICAgLmRpZ2VzdCgpO1xuICB0aGlzLlYgPSB0aGlzLl9obWFjKCkudXBkYXRlKHRoaXMuVikuZGlnZXN0KCk7XG59O1xuXG5IbWFjRFJCRy5wcm90b3R5cGUucmVzZWVkID0gZnVuY3Rpb24gcmVzZWVkKGVudHJvcHksIGVudHJvcHlFbmMsIGFkZCwgYWRkRW5jKSB7XG4gIC8vIE9wdGlvbmFsIGVudHJvcHkgZW5jXG4gIGlmICh0eXBlb2YgZW50cm9weUVuYyAhPT0gJ3N0cmluZycpIHtcbiAgICBhZGRFbmMgPSBhZGQ7XG4gICAgYWRkID0gZW50cm9weUVuYztcbiAgICBlbnRyb3B5RW5jID0gbnVsbDtcbiAgfVxuXG4gIGVudHJvcHkgPSB1dGlscy50b0FycmF5KGVudHJvcHksIGVudHJvcHlFbmMpO1xuICBhZGQgPSB1dGlscy50b0FycmF5KGFkZCwgYWRkRW5jKTtcblxuICBhc3NlcnQoZW50cm9weS5sZW5ndGggPj0gKHRoaXMubWluRW50cm9weSAvIDgpLFxuICAgICAgICAgJ05vdCBlbm91Z2ggZW50cm9weS4gTWluaW11bSBpczogJyArIHRoaXMubWluRW50cm9weSArICcgYml0cycpO1xuXG4gIHRoaXMuX3VwZGF0ZShlbnRyb3B5LmNvbmNhdChhZGQgfHwgW10pKTtcbiAgdGhpcy5fcmVzZWVkID0gMTtcbn07XG5cbkhtYWNEUkJHLnByb3RvdHlwZS5nZW5lcmF0ZSA9IGZ1bmN0aW9uIGdlbmVyYXRlKGxlbiwgZW5jLCBhZGQsIGFkZEVuYykge1xuICBpZiAodGhpcy5fcmVzZWVkID4gdGhpcy5yZXNlZWRJbnRlcnZhbClcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Jlc2VlZCBpcyByZXF1aXJlZCcpO1xuXG4gIC8vIE9wdGlvbmFsIGVuY29kaW5nXG4gIGlmICh0eXBlb2YgZW5jICE9PSAnc3RyaW5nJykge1xuICAgIGFkZEVuYyA9IGFkZDtcbiAgICBhZGQgPSBlbmM7XG4gICAgZW5jID0gbnVsbDtcbiAgfVxuXG4gIC8vIE9wdGlvbmFsIGFkZGl0aW9uYWwgZGF0YVxuICBpZiAoYWRkKSB7XG4gICAgYWRkID0gdXRpbHMudG9BcnJheShhZGQsIGFkZEVuYyB8fCAnaGV4Jyk7XG4gICAgdGhpcy5fdXBkYXRlKGFkZCk7XG4gIH1cblxuICB2YXIgdGVtcCA9IFtdO1xuICB3aGlsZSAodGVtcC5sZW5ndGggPCBsZW4pIHtcbiAgICB0aGlzLlYgPSB0aGlzLl9obWFjKCkudXBkYXRlKHRoaXMuVikuZGlnZXN0KCk7XG4gICAgdGVtcCA9IHRlbXAuY29uY2F0KHRoaXMuVik7XG4gIH1cblxuICB2YXIgcmVzID0gdGVtcC5zbGljZSgwLCBsZW4pO1xuICB0aGlzLl91cGRhdGUoYWRkKTtcbiAgdGhpcy5fcmVzZWVkKys7XG4gIHJldHVybiB1dGlscy5lbmNvZGUocmVzLCBlbmMpO1xufTtcbiIsImV4cG9ydHMucmVhZCA9IGZ1bmN0aW9uIChidWZmZXIsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtXG4gIHZhciBlTGVuID0gKG5CeXRlcyAqIDgpIC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBuQml0cyA9IC03XG4gIHZhciBpID0gaXNMRSA/IChuQnl0ZXMgLSAxKSA6IDBcbiAgdmFyIGQgPSBpc0xFID8gLTEgOiAxXG4gIHZhciBzID0gYnVmZmVyW29mZnNldCArIGldXG5cbiAgaSArPSBkXG5cbiAgZSA9IHMgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgcyA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gZUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBlID0gKGUgKiAyNTYpICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgZSA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gbUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gKG0gKiAyNTYpICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgaWYgKGUgPT09IDApIHtcbiAgICBlID0gMSAtIGVCaWFzXG4gIH0gZWxzZSBpZiAoZSA9PT0gZU1heCkge1xuICAgIHJldHVybiBtID8gTmFOIDogKChzID8gLTEgOiAxKSAqIEluZmluaXR5KVxuICB9IGVsc2Uge1xuICAgIG0gPSBtICsgTWF0aC5wb3coMiwgbUxlbilcbiAgICBlID0gZSAtIGVCaWFzXG4gIH1cbiAgcmV0dXJuIChzID8gLTEgOiAxKSAqIG0gKiBNYXRoLnBvdygyLCBlIC0gbUxlbilcbn1cblxuZXhwb3J0cy53cml0ZSA9IGZ1bmN0aW9uIChidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbSwgY1xuICB2YXIgZUxlbiA9IChuQnl0ZXMgKiA4KSAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgcnQgPSAobUxlbiA9PT0gMjMgPyBNYXRoLnBvdygyLCAtMjQpIC0gTWF0aC5wb3coMiwgLTc3KSA6IDApXG4gIHZhciBpID0gaXNMRSA/IDAgOiAobkJ5dGVzIC0gMSlcbiAgdmFyIGQgPSBpc0xFID8gMSA6IC0xXG4gIHZhciBzID0gdmFsdWUgPCAwIHx8ICh2YWx1ZSA9PT0gMCAmJiAxIC8gdmFsdWUgPCAwKSA/IDEgOiAwXG5cbiAgdmFsdWUgPSBNYXRoLmFicyh2YWx1ZSlcblxuICBpZiAoaXNOYU4odmFsdWUpIHx8IHZhbHVlID09PSBJbmZpbml0eSkge1xuICAgIG0gPSBpc05hTih2YWx1ZSkgPyAxIDogMFxuICAgIGUgPSBlTWF4XG4gIH0gZWxzZSB7XG4gICAgZSA9IE1hdGguZmxvb3IoTWF0aC5sb2codmFsdWUpIC8gTWF0aC5MTjIpXG4gICAgaWYgKHZhbHVlICogKGMgPSBNYXRoLnBvdygyLCAtZSkpIDwgMSkge1xuICAgICAgZS0tXG4gICAgICBjICo9IDJcbiAgICB9XG4gICAgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICB2YWx1ZSArPSBydCAvIGNcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgKz0gcnQgKiBNYXRoLnBvdygyLCAxIC0gZUJpYXMpXG4gICAgfVxuICAgIGlmICh2YWx1ZSAqIGMgPj0gMikge1xuICAgICAgZSsrXG4gICAgICBjIC89IDJcbiAgICB9XG5cbiAgICBpZiAoZSArIGVCaWFzID49IGVNYXgpIHtcbiAgICAgIG0gPSAwXG4gICAgICBlID0gZU1heFxuICAgIH0gZWxzZSBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIG0gPSAoKHZhbHVlICogYykgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gZSArIGVCaWFzXG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSB2YWx1ZSAqIE1hdGgucG93KDIsIGVCaWFzIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IDBcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KSB7fVxuXG4gIGUgPSAoZSA8PCBtTGVuKSB8IG1cbiAgZUxlbiArPSBtTGVuXG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCkge31cblxuICBidWZmZXJbb2Zmc2V0ICsgaSAtIGRdIHw9IHMgKiAxMjhcbn1cbiIsIid1c2Ugc3RyaWN0JztcbnZhciBNdXRhdGlvbiA9IGdsb2JhbC5NdXRhdGlvbk9ic2VydmVyIHx8IGdsb2JhbC5XZWJLaXRNdXRhdGlvbk9ic2VydmVyO1xuXG52YXIgc2NoZWR1bGVEcmFpbjtcblxue1xuICBpZiAoTXV0YXRpb24pIHtcbiAgICB2YXIgY2FsbGVkID0gMDtcbiAgICB2YXIgb2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb24obmV4dFRpY2spO1xuICAgIHZhciBlbGVtZW50ID0gZ2xvYmFsLmRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCcnKTtcbiAgICBvYnNlcnZlci5vYnNlcnZlKGVsZW1lbnQsIHtcbiAgICAgIGNoYXJhY3RlckRhdGE6IHRydWVcbiAgICB9KTtcbiAgICBzY2hlZHVsZURyYWluID0gZnVuY3Rpb24gKCkge1xuICAgICAgZWxlbWVudC5kYXRhID0gKGNhbGxlZCA9ICsrY2FsbGVkICUgMik7XG4gICAgfTtcbiAgfSBlbHNlIGlmICghZ2xvYmFsLnNldEltbWVkaWF0ZSAmJiB0eXBlb2YgZ2xvYmFsLk1lc3NhZ2VDaGFubmVsICE9PSAndW5kZWZpbmVkJykge1xuICAgIHZhciBjaGFubmVsID0gbmV3IGdsb2JhbC5NZXNzYWdlQ2hhbm5lbCgpO1xuICAgIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gbmV4dFRpY2s7XG4gICAgc2NoZWR1bGVEcmFpbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoMCk7XG4gICAgfTtcbiAgfSBlbHNlIGlmICgnZG9jdW1lbnQnIGluIGdsb2JhbCAmJiAnb25yZWFkeXN0YXRlY2hhbmdlJyBpbiBnbG9iYWwuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0JykpIHtcbiAgICBzY2hlZHVsZURyYWluID0gZnVuY3Rpb24gKCkge1xuXG4gICAgICAvLyBDcmVhdGUgYSA8c2NyaXB0PiBlbGVtZW50OyBpdHMgcmVhZHlzdGF0ZWNoYW5nZSBldmVudCB3aWxsIGJlIGZpcmVkIGFzeW5jaHJvbm91c2x5IG9uY2UgaXQgaXMgaW5zZXJ0ZWRcbiAgICAgIC8vIGludG8gdGhlIGRvY3VtZW50LiBEbyBzbywgdGh1cyBxdWV1aW5nIHVwIHRoZSB0YXNrLiBSZW1lbWJlciB0byBjbGVhbiB1cCBvbmNlIGl0J3MgYmVlbiBjYWxsZWQuXG4gICAgICB2YXIgc2NyaXB0RWwgPSBnbG9iYWwuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG4gICAgICBzY3JpcHRFbC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIG5leHRUaWNrKCk7XG5cbiAgICAgICAgc2NyaXB0RWwub25yZWFkeXN0YXRlY2hhbmdlID0gbnVsbDtcbiAgICAgICAgc2NyaXB0RWwucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChzY3JpcHRFbCk7XG4gICAgICAgIHNjcmlwdEVsID0gbnVsbDtcbiAgICAgIH07XG4gICAgICBnbG9iYWwuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKHNjcmlwdEVsKTtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIHNjaGVkdWxlRHJhaW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICBzZXRUaW1lb3V0KG5leHRUaWNrLCAwKTtcbiAgICB9O1xuICB9XG59XG5cbnZhciBkcmFpbmluZztcbnZhciBxdWV1ZSA9IFtdO1xuLy9uYW1lZCBuZXh0VGljayBmb3IgbGVzcyBjb25mdXNpbmcgc3RhY2sgdHJhY2VzXG5mdW5jdGlvbiBuZXh0VGljaygpIHtcbiAgZHJhaW5pbmcgPSB0cnVlO1xuICB2YXIgaSwgb2xkUXVldWU7XG4gIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gIHdoaWxlIChsZW4pIHtcbiAgICBvbGRRdWV1ZSA9IHF1ZXVlO1xuICAgIHF1ZXVlID0gW107XG4gICAgaSA9IC0xO1xuICAgIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICAgIG9sZFF1ZXVlW2ldKCk7XG4gICAgfVxuICAgIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgfVxuICBkcmFpbmluZyA9IGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGltbWVkaWF0ZTtcbmZ1bmN0aW9uIGltbWVkaWF0ZSh0YXNrKSB7XG4gIGlmIChxdWV1ZS5wdXNoKHRhc2spID09PSAxICYmICFkcmFpbmluZykge1xuICAgIHNjaGVkdWxlRHJhaW4oKTtcbiAgfVxufVxuIiwiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgICAgY29uc3RydWN0b3I6IHtcbiAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICB9XG4gICAgfSk7XG4gIH07XG59IGVsc2Uge1xuICAvLyBvbGQgc2Nob29sIHNoaW0gZm9yIG9sZCBicm93c2Vyc1xuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICBUZW1wQ3Rvci5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlXG4gICAgY3Rvci5wcm90b3R5cGUgPSBuZXcgVGVtcEN0b3IoKVxuICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICB9XG59XG4iLCIvKiFcbiAqIERldGVybWluZSBpZiBhbiBvYmplY3QgaXMgYSBCdWZmZXJcbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8aHR0cHM6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG5cbi8vIFRoZSBfaXNCdWZmZXIgY2hlY2sgaXMgZm9yIFNhZmFyaSA1LTcgc3VwcG9ydCwgYmVjYXVzZSBpdCdzIG1pc3Npbmdcbi8vIE9iamVjdC5wcm90b3R5cGUuY29uc3RydWN0b3IuIFJlbW92ZSB0aGlzIGV2ZW50dWFsbHlcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9iaikge1xuICByZXR1cm4gb2JqICE9IG51bGwgJiYgKGlzQnVmZmVyKG9iaikgfHwgaXNTbG93QnVmZmVyKG9iaikgfHwgISFvYmouX2lzQnVmZmVyKVxufVxuXG5mdW5jdGlvbiBpc0J1ZmZlciAob2JqKSB7XG4gIHJldHVybiAhIW9iai5jb25zdHJ1Y3RvciAmJiB0eXBlb2Ygb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyID09PSAnZnVuY3Rpb24nICYmIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlcihvYmopXG59XG5cbi8vIEZvciBOb2RlIHYwLjEwIHN1cHBvcnQuIFJlbW92ZSB0aGlzIGV2ZW50dWFsbHkuXG5mdW5jdGlvbiBpc1Nsb3dCdWZmZXIgKG9iaikge1xuICByZXR1cm4gdHlwZW9mIG9iai5yZWFkRmxvYXRMRSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2Ygb2JqLnNsaWNlID09PSAnZnVuY3Rpb24nICYmIGlzQnVmZmVyKG9iai5zbGljZSgwLCAwKSlcbn1cbiIsInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKGFycikge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChhcnIpID09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIHN1cHBvcnQgPSByZXF1aXJlKCcuL3N1cHBvcnQnKTtcbi8vIHByaXZhdGUgcHJvcGVydHlcbnZhciBfa2V5U3RyID0gXCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPVwiO1xuXG5cbi8vIHB1YmxpYyBtZXRob2QgZm9yIGVuY29kaW5nXG5leHBvcnRzLmVuY29kZSA9IGZ1bmN0aW9uKGlucHV0KSB7XG4gICAgdmFyIG91dHB1dCA9IFtdO1xuICAgIHZhciBjaHIxLCBjaHIyLCBjaHIzLCBlbmMxLCBlbmMyLCBlbmMzLCBlbmM0O1xuICAgIHZhciBpID0gMCwgbGVuID0gaW5wdXQubGVuZ3RoLCByZW1haW5pbmdCeXRlcyA9IGxlbjtcblxuICAgIHZhciBpc0FycmF5ID0gdXRpbHMuZ2V0VHlwZU9mKGlucHV0KSAhPT0gXCJzdHJpbmdcIjtcbiAgICB3aGlsZSAoaSA8IGlucHV0Lmxlbmd0aCkge1xuICAgICAgICByZW1haW5pbmdCeXRlcyA9IGxlbiAtIGk7XG5cbiAgICAgICAgaWYgKCFpc0FycmF5KSB7XG4gICAgICAgICAgICBjaHIxID0gaW5wdXQuY2hhckNvZGVBdChpKyspO1xuICAgICAgICAgICAgY2hyMiA9IGkgPCBsZW4gPyBpbnB1dC5jaGFyQ29kZUF0KGkrKykgOiAwO1xuICAgICAgICAgICAgY2hyMyA9IGkgPCBsZW4gPyBpbnB1dC5jaGFyQ29kZUF0KGkrKykgOiAwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2hyMSA9IGlucHV0W2krK107XG4gICAgICAgICAgICBjaHIyID0gaSA8IGxlbiA/IGlucHV0W2krK10gOiAwO1xuICAgICAgICAgICAgY2hyMyA9IGkgPCBsZW4gPyBpbnB1dFtpKytdIDogMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGVuYzEgPSBjaHIxID4+IDI7XG4gICAgICAgIGVuYzIgPSAoKGNocjEgJiAzKSA8PCA0KSB8IChjaHIyID4+IDQpO1xuICAgICAgICBlbmMzID0gcmVtYWluaW5nQnl0ZXMgPiAxID8gKCgoY2hyMiAmIDE1KSA8PCAyKSB8IChjaHIzID4+IDYpKSA6IDY0O1xuICAgICAgICBlbmM0ID0gcmVtYWluaW5nQnl0ZXMgPiAyID8gKGNocjMgJiA2MykgOiA2NDtcblxuICAgICAgICBvdXRwdXQucHVzaChfa2V5U3RyLmNoYXJBdChlbmMxKSArIF9rZXlTdHIuY2hhckF0KGVuYzIpICsgX2tleVN0ci5jaGFyQXQoZW5jMykgKyBfa2V5U3RyLmNoYXJBdChlbmM0KSk7XG5cbiAgICB9XG5cbiAgICByZXR1cm4gb3V0cHV0LmpvaW4oXCJcIik7XG59O1xuXG4vLyBwdWJsaWMgbWV0aG9kIGZvciBkZWNvZGluZ1xuZXhwb3J0cy5kZWNvZGUgPSBmdW5jdGlvbihpbnB1dCkge1xuICAgIHZhciBjaHIxLCBjaHIyLCBjaHIzO1xuICAgIHZhciBlbmMxLCBlbmMyLCBlbmMzLCBlbmM0O1xuICAgIHZhciBpID0gMCwgcmVzdWx0SW5kZXggPSAwO1xuXG4gICAgdmFyIGRhdGFVcmxQcmVmaXggPSBcImRhdGE6XCI7XG5cbiAgICBpZiAoaW5wdXQuc3Vic3RyKDAsIGRhdGFVcmxQcmVmaXgubGVuZ3RoKSA9PT0gZGF0YVVybFByZWZpeCkge1xuICAgICAgICAvLyBUaGlzIGlzIGEgY29tbW9uIGVycm9yOiBwZW9wbGUgZ2l2ZSBhIGRhdGEgdXJsXG4gICAgICAgIC8vIChkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1IuLi4pIHdpdGggYSB7YmFzZTY0OiB0cnVlfSBhbmRcbiAgICAgICAgLy8gd29uZGVycyB3aHkgdGhpbmdzIGRvbid0IHdvcmsuXG4gICAgICAgIC8vIFdlIGNhbiBkZXRlY3QgdGhhdCB0aGUgc3RyaW5nIGlucHV0IGxvb2tzIGxpa2UgYSBkYXRhIHVybCBidXQgd2VcbiAgICAgICAgLy8gKmNhbid0KiBiZSBzdXJlIGl0IGlzIG9uZTogcmVtb3ZpbmcgZXZlcnl0aGluZyB1cCB0byB0aGUgY29tbWEgd291bGRcbiAgICAgICAgLy8gYmUgdG9vIGRhbmdlcm91cy5cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBiYXNlNjQgaW5wdXQsIGl0IGxvb2tzIGxpa2UgYSBkYXRhIHVybC5cIik7XG4gICAgfVxuXG4gICAgaW5wdXQgPSBpbnB1dC5yZXBsYWNlKC9bXkEtWmEtejAtOVxcK1xcL1xcPV0vZywgXCJcIik7XG5cbiAgICB2YXIgdG90YWxMZW5ndGggPSBpbnB1dC5sZW5ndGggKiAzIC8gNDtcbiAgICBpZihpbnB1dC5jaGFyQXQoaW5wdXQubGVuZ3RoIC0gMSkgPT09IF9rZXlTdHIuY2hhckF0KDY0KSkge1xuICAgICAgICB0b3RhbExlbmd0aC0tO1xuICAgIH1cbiAgICBpZihpbnB1dC5jaGFyQXQoaW5wdXQubGVuZ3RoIC0gMikgPT09IF9rZXlTdHIuY2hhckF0KDY0KSkge1xuICAgICAgICB0b3RhbExlbmd0aC0tO1xuICAgIH1cbiAgICBpZiAodG90YWxMZW5ndGggJSAxICE9PSAwKSB7XG4gICAgICAgIC8vIHRvdGFsTGVuZ3RoIGlzIG5vdCBhbiBpbnRlZ2VyLCB0aGUgbGVuZ3RoIGRvZXMgbm90IG1hdGNoIGEgdmFsaWRcbiAgICAgICAgLy8gYmFzZTY0IGNvbnRlbnQuIFRoYXQgY2FuIGhhcHBlbiBpZjpcbiAgICAgICAgLy8gLSB0aGUgaW5wdXQgaXMgbm90IGEgYmFzZTY0IGNvbnRlbnRcbiAgICAgICAgLy8gLSB0aGUgaW5wdXQgaXMgKmFsbW9zdCogYSBiYXNlNjQgY29udGVudCwgd2l0aCBhIGV4dHJhIGNoYXJzIGF0IHRoZVxuICAgICAgICAvLyAgIGJlZ2lubmluZyBvciBhdCB0aGUgZW5kXG4gICAgICAgIC8vIC0gdGhlIGlucHV0IHVzZXMgYSBiYXNlNjQgdmFyaWFudCAoYmFzZTY0dXJsIGZvciBleGFtcGxlKVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGJhc2U2NCBpbnB1dCwgYmFkIGNvbnRlbnQgbGVuZ3RoLlwiKTtcbiAgICB9XG4gICAgdmFyIG91dHB1dDtcbiAgICBpZiAoc3VwcG9ydC51aW50OGFycmF5KSB7XG4gICAgICAgIG91dHB1dCA9IG5ldyBVaW50OEFycmF5KHRvdGFsTGVuZ3RofDApO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIG91dHB1dCA9IG5ldyBBcnJheSh0b3RhbExlbmd0aHwwKTtcbiAgICB9XG5cbiAgICB3aGlsZSAoaSA8IGlucHV0Lmxlbmd0aCkge1xuXG4gICAgICAgIGVuYzEgPSBfa2V5U3RyLmluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpO1xuICAgICAgICBlbmMyID0gX2tleVN0ci5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTtcbiAgICAgICAgZW5jMyA9IF9rZXlTdHIuaW5kZXhPZihpbnB1dC5jaGFyQXQoaSsrKSk7XG4gICAgICAgIGVuYzQgPSBfa2V5U3RyLmluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpO1xuXG4gICAgICAgIGNocjEgPSAoZW5jMSA8PCAyKSB8IChlbmMyID4+IDQpO1xuICAgICAgICBjaHIyID0gKChlbmMyICYgMTUpIDw8IDQpIHwgKGVuYzMgPj4gMik7XG4gICAgICAgIGNocjMgPSAoKGVuYzMgJiAzKSA8PCA2KSB8IGVuYzQ7XG5cbiAgICAgICAgb3V0cHV0W3Jlc3VsdEluZGV4KytdID0gY2hyMTtcblxuICAgICAgICBpZiAoZW5jMyAhPT0gNjQpIHtcbiAgICAgICAgICAgIG91dHB1dFtyZXN1bHRJbmRleCsrXSA9IGNocjI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVuYzQgIT09IDY0KSB7XG4gICAgICAgICAgICBvdXRwdXRbcmVzdWx0SW5kZXgrK10gPSBjaHIzO1xuICAgICAgICB9XG5cbiAgICB9XG5cbiAgICByZXR1cm4gb3V0cHV0O1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGV4dGVybmFsID0gcmVxdWlyZShcIi4vZXh0ZXJuYWxcIik7XG52YXIgRGF0YVdvcmtlciA9IHJlcXVpcmUoJy4vc3RyZWFtL0RhdGFXb3JrZXInKTtcbnZhciBEYXRhTGVuZ3RoUHJvYmUgPSByZXF1aXJlKCcuL3N0cmVhbS9EYXRhTGVuZ3RoUHJvYmUnKTtcbnZhciBDcmMzMlByb2JlID0gcmVxdWlyZSgnLi9zdHJlYW0vQ3JjMzJQcm9iZScpO1xudmFyIERhdGFMZW5ndGhQcm9iZSA9IHJlcXVpcmUoJy4vc3RyZWFtL0RhdGFMZW5ndGhQcm9iZScpO1xuXG4vKipcbiAqIFJlcHJlc2VudCBhIGNvbXByZXNzZWQgb2JqZWN0LCB3aXRoIGV2ZXJ5dGhpbmcgbmVlZGVkIHRvIGRlY29tcHJlc3MgaXQuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7bnVtYmVyfSBjb21wcmVzc2VkU2l6ZSB0aGUgc2l6ZSBvZiB0aGUgZGF0YSBjb21wcmVzc2VkLlxuICogQHBhcmFtIHtudW1iZXJ9IHVuY29tcHJlc3NlZFNpemUgdGhlIHNpemUgb2YgdGhlIGRhdGEgYWZ0ZXIgZGVjb21wcmVzc2lvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBjcmMzMiB0aGUgY3JjMzIgb2YgdGhlIGRlY29tcHJlc3NlZCBmaWxlLlxuICogQHBhcmFtIHtvYmplY3R9IGNvbXByZXNzaW9uIHRoZSB0eXBlIG9mIGNvbXByZXNzaW9uLCBzZWUgbGliL2NvbXByZXNzaW9ucy5qcy5cbiAqIEBwYXJhbSB7U3RyaW5nfEFycmF5QnVmZmVyfFVpbnQ4QXJyYXl8QnVmZmVyfSBkYXRhIHRoZSBjb21wcmVzc2VkIGRhdGEuXG4gKi9cbmZ1bmN0aW9uIENvbXByZXNzZWRPYmplY3QoY29tcHJlc3NlZFNpemUsIHVuY29tcHJlc3NlZFNpemUsIGNyYzMyLCBjb21wcmVzc2lvbiwgZGF0YSkge1xuICAgIHRoaXMuY29tcHJlc3NlZFNpemUgPSBjb21wcmVzc2VkU2l6ZTtcbiAgICB0aGlzLnVuY29tcHJlc3NlZFNpemUgPSB1bmNvbXByZXNzZWRTaXplO1xuICAgIHRoaXMuY3JjMzIgPSBjcmMzMjtcbiAgICB0aGlzLmNvbXByZXNzaW9uID0gY29tcHJlc3Npb247XG4gICAgdGhpcy5jb21wcmVzc2VkQ29udGVudCA9IGRhdGE7XG59XG5cbkNvbXByZXNzZWRPYmplY3QucHJvdG90eXBlID0ge1xuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIHdvcmtlciB0byBnZXQgdGhlIHVuY29tcHJlc3NlZCBjb250ZW50LlxuICAgICAqIEByZXR1cm4ge0dlbmVyaWNXb3JrZXJ9IHRoZSB3b3JrZXIuXG4gICAgICovXG4gICAgZ2V0Q29udGVudFdvcmtlciA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHdvcmtlciA9IG5ldyBEYXRhV29ya2VyKGV4dGVybmFsLlByb21pc2UucmVzb2x2ZSh0aGlzLmNvbXByZXNzZWRDb250ZW50KSlcbiAgICAgICAgLnBpcGUodGhpcy5jb21wcmVzc2lvbi51bmNvbXByZXNzV29ya2VyKCkpXG4gICAgICAgIC5waXBlKG5ldyBEYXRhTGVuZ3RoUHJvYmUoXCJkYXRhX2xlbmd0aFwiKSk7XG5cbiAgICAgICAgdmFyIHRoYXQgPSB0aGlzO1xuICAgICAgICB3b3JrZXIub24oXCJlbmRcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYodGhpcy5zdHJlYW1JbmZvWydkYXRhX2xlbmd0aCddICE9PSB0aGF0LnVuY29tcHJlc3NlZFNpemUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJCdWcgOiB1bmNvbXByZXNzZWQgZGF0YSBzaXplIG1pc21hdGNoXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHdvcmtlcjtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIHdvcmtlciB0byBnZXQgdGhlIGNvbXByZXNzZWQgY29udGVudC5cbiAgICAgKiBAcmV0dXJuIHtHZW5lcmljV29ya2VyfSB0aGUgd29ya2VyLlxuICAgICAqL1xuICAgIGdldENvbXByZXNzZWRXb3JrZXIgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgRGF0YVdvcmtlcihleHRlcm5hbC5Qcm9taXNlLnJlc29sdmUodGhpcy5jb21wcmVzc2VkQ29udGVudCkpXG4gICAgICAgIC53aXRoU3RyZWFtSW5mbyhcImNvbXByZXNzZWRTaXplXCIsIHRoaXMuY29tcHJlc3NlZFNpemUpXG4gICAgICAgIC53aXRoU3RyZWFtSW5mbyhcInVuY29tcHJlc3NlZFNpemVcIiwgdGhpcy51bmNvbXByZXNzZWRTaXplKVxuICAgICAgICAud2l0aFN0cmVhbUluZm8oXCJjcmMzMlwiLCB0aGlzLmNyYzMyKVxuICAgICAgICAud2l0aFN0cmVhbUluZm8oXCJjb21wcmVzc2lvblwiLCB0aGlzLmNvbXByZXNzaW9uKVxuICAgICAgICA7XG4gICAgfVxufTtcblxuLyoqXG4gKiBDaGFpbiB0aGUgZ2l2ZW4gd29ya2VyIHdpdGggb3RoZXIgd29ya2VycyB0byBjb21wcmVzcyB0aGUgY29udGVudCB3aXRoIHRoZVxuICogZ2l2ZW4gY29tcHJlc2lvbi5cbiAqIEBwYXJhbSB7R2VuZXJpY1dvcmtlcn0gdW5jb21wcmVzc2VkV29ya2VyIHRoZSB3b3JrZXIgdG8gcGlwZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBjb21wcmVzc2lvbiB0aGUgY29tcHJlc3Npb24gb2JqZWN0LlxuICogQHBhcmFtIHtPYmplY3R9IGNvbXByZXNzaW9uT3B0aW9ucyB0aGUgb3B0aW9ucyB0byB1c2Ugd2hlbiBjb21wcmVzc2luZy5cbiAqIEByZXR1cm4ge0dlbmVyaWNXb3JrZXJ9IHRoZSBuZXcgd29ya2VyIGNvbXByZXNzaW5nIHRoZSBjb250ZW50LlxuICovXG5Db21wcmVzc2VkT2JqZWN0LmNyZWF0ZVdvcmtlckZyb20gPSBmdW5jdGlvbiAodW5jb21wcmVzc2VkV29ya2VyLCBjb21wcmVzc2lvbiwgY29tcHJlc3Npb25PcHRpb25zKSB7XG4gICAgcmV0dXJuIHVuY29tcHJlc3NlZFdvcmtlclxuICAgIC5waXBlKG5ldyBDcmMzMlByb2JlKCkpXG4gICAgLnBpcGUobmV3IERhdGFMZW5ndGhQcm9iZShcInVuY29tcHJlc3NlZFNpemVcIikpXG4gICAgLnBpcGUoY29tcHJlc3Npb24uY29tcHJlc3NXb3JrZXIoY29tcHJlc3Npb25PcHRpb25zKSlcbiAgICAucGlwZShuZXcgRGF0YUxlbmd0aFByb2JlKFwiY29tcHJlc3NlZFNpemVcIikpXG4gICAgLndpdGhTdHJlYW1JbmZvKFwiY29tcHJlc3Npb25cIiwgY29tcHJlc3Npb24pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBDb21wcmVzc2VkT2JqZWN0O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2VuZXJpY1dvcmtlciA9IHJlcXVpcmUoXCIuL3N0cmVhbS9HZW5lcmljV29ya2VyXCIpO1xuXG5leHBvcnRzLlNUT1JFID0ge1xuICAgIG1hZ2ljOiBcIlxceDAwXFx4MDBcIixcbiAgICBjb21wcmVzc1dvcmtlciA6IGZ1bmN0aW9uIChjb21wcmVzc2lvbk9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBHZW5lcmljV29ya2VyKFwiU1RPUkUgY29tcHJlc3Npb25cIik7XG4gICAgfSxcbiAgICB1bmNvbXByZXNzV29ya2VyIDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbmV3IEdlbmVyaWNXb3JrZXIoXCJTVE9SRSBkZWNvbXByZXNzaW9uXCIpO1xuICAgIH1cbn07XG5leHBvcnRzLkRFRkxBVEUgPSByZXF1aXJlKCcuL2ZsYXRlJyk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcblxuLyoqXG4gKiBUaGUgZm9sbG93aW5nIGZ1bmN0aW9ucyBjb21lIGZyb20gcGFrbywgZnJvbSBwYWtvL2xpYi96bGliL2NyYzMyLmpzXG4gKiByZWxlYXNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UsIHNlZSBwYWtvIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlY2EvcGFrby9cbiAqL1xuXG4vLyBVc2Ugb3JkaW5hcnkgYXJyYXksIHNpbmNlIHVudHlwZWQgbWFrZXMgbm8gYm9vc3QgaGVyZVxuZnVuY3Rpb24gbWFrZVRhYmxlKCkge1xuICAgIHZhciBjLCB0YWJsZSA9IFtdO1xuXG4gICAgZm9yKHZhciBuID0wOyBuIDwgMjU2OyBuKyspe1xuICAgICAgICBjID0gbjtcbiAgICAgICAgZm9yKHZhciBrID0wOyBrIDwgODsgaysrKXtcbiAgICAgICAgICAgIGMgPSAoKGMmMSkgPyAoMHhFREI4ODMyMCBeIChjID4+PiAxKSkgOiAoYyA+Pj4gMSkpO1xuICAgICAgICB9XG4gICAgICAgIHRhYmxlW25dID0gYztcbiAgICB9XG5cbiAgICByZXR1cm4gdGFibGU7XG59XG5cbi8vIENyZWF0ZSB0YWJsZSBvbiBsb2FkLiBKdXN0IDI1NSBzaWduZWQgbG9uZ3MuIE5vdCBhIHByb2JsZW0uXG52YXIgY3JjVGFibGUgPSBtYWtlVGFibGUoKTtcblxuXG5mdW5jdGlvbiBjcmMzMihjcmMsIGJ1ZiwgbGVuLCBwb3MpIHtcbiAgICB2YXIgdCA9IGNyY1RhYmxlLCBlbmQgPSBwb3MgKyBsZW47XG5cbiAgICBjcmMgPSBjcmMgXiAoLTEpO1xuXG4gICAgZm9yICh2YXIgaSA9IHBvczsgaSA8IGVuZDsgaSsrICkge1xuICAgICAgICBjcmMgPSAoY3JjID4+PiA4KSBeIHRbKGNyYyBeIGJ1ZltpXSkgJiAweEZGXTtcbiAgICB9XG5cbiAgICByZXR1cm4gKGNyYyBeICgtMSkpOyAvLyA+Pj4gMDtcbn1cblxuLy8gVGhhdCdzIGFsbCBmb3IgdGhlIHBha28gZnVuY3Rpb25zLlxuXG4vKipcbiAqIENvbXB1dGUgdGhlIGNyYzMyIG9mIGEgc3RyaW5nLlxuICogVGhpcyBpcyBhbG1vc3QgdGhlIHNhbWUgYXMgdGhlIGZ1bmN0aW9uIGNyYzMyLCBidXQgZm9yIHN0cmluZ3MuIFVzaW5nIHRoZVxuICogc2FtZSBmdW5jdGlvbiBmb3IgdGhlIHR3byB1c2UgY2FzZXMgbGVhZHMgdG8gaG9ycmlibGUgcGVyZm9ybWFuY2VzLlxuICogQHBhcmFtIHtOdW1iZXJ9IGNyYyB0aGUgc3RhcnRpbmcgdmFsdWUgb2YgdGhlIGNyYy5cbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgdGhlIHN0cmluZyB0byB1c2UuXG4gKiBAcGFyYW0ge051bWJlcn0gbGVuIHRoZSBsZW5ndGggb2YgdGhlIHN0cmluZy5cbiAqIEBwYXJhbSB7TnVtYmVyfSBwb3MgdGhlIHN0YXJ0aW5nIHBvc2l0aW9uIGZvciB0aGUgY3JjMzIgY29tcHV0YXRpb24uXG4gKiBAcmV0dXJuIHtOdW1iZXJ9IHRoZSBjb21wdXRlZCBjcmMzMi5cbiAqL1xuZnVuY3Rpb24gY3JjMzJzdHIoY3JjLCBzdHIsIGxlbiwgcG9zKSB7XG4gICAgdmFyIHQgPSBjcmNUYWJsZSwgZW5kID0gcG9zICsgbGVuO1xuXG4gICAgY3JjID0gY3JjIF4gKC0xKTtcblxuICAgIGZvciAodmFyIGkgPSBwb3M7IGkgPCBlbmQ7IGkrKyApIHtcbiAgICAgICAgY3JjID0gKGNyYyA+Pj4gOCkgXiB0WyhjcmMgXiBzdHIuY2hhckNvZGVBdChpKSkgJiAweEZGXTtcbiAgICB9XG5cbiAgICByZXR1cm4gKGNyYyBeICgtMSkpOyAvLyA+Pj4gMDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBjcmMzMndyYXBwZXIoaW5wdXQsIGNyYykge1xuICAgIGlmICh0eXBlb2YgaW5wdXQgPT09IFwidW5kZWZpbmVkXCIgfHwgIWlucHV0Lmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICB2YXIgaXNBcnJheSA9IHV0aWxzLmdldFR5cGVPZihpbnB1dCkgIT09IFwic3RyaW5nXCI7XG5cbiAgICBpZihpc0FycmF5KSB7XG4gICAgICAgIHJldHVybiBjcmMzMihjcmN8MCwgaW5wdXQsIGlucHV0Lmxlbmd0aCwgMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGNyYzMyc3RyKGNyY3wwLCBpbnB1dCwgaW5wdXQubGVuZ3RoLCAwKTtcbiAgICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuZXhwb3J0cy5iYXNlNjQgPSBmYWxzZTtcbmV4cG9ydHMuYmluYXJ5ID0gZmFsc2U7XG5leHBvcnRzLmRpciA9IGZhbHNlO1xuZXhwb3J0cy5jcmVhdGVGb2xkZXJzID0gdHJ1ZTtcbmV4cG9ydHMuZGF0ZSA9IG51bGw7XG5leHBvcnRzLmNvbXByZXNzaW9uID0gbnVsbDtcbmV4cG9ydHMuY29tcHJlc3Npb25PcHRpb25zID0gbnVsbDtcbmV4cG9ydHMuY29tbWVudCA9IG51bGw7XG5leHBvcnRzLnVuaXhQZXJtaXNzaW9ucyA9IG51bGw7XG5leHBvcnRzLmRvc1Blcm1pc3Npb25zID0gbnVsbDtcbiIsIi8qIGdsb2JhbCBQcm9taXNlICovXG4ndXNlIHN0cmljdCc7XG5cbi8vIGxvYWQgdGhlIGdsb2JhbCBvYmplY3QgZmlyc3Q6XG4vLyAtIGl0IHNob3VsZCBiZSBiZXR0ZXIgaW50ZWdyYXRlZCBpbiB0aGUgc3lzdGVtICh1bmhhbmRsZWRSZWplY3Rpb24gaW4gbm9kZSlcbi8vIC0gdGhlIGVudmlyb25tZW50IG1heSBoYXZlIGEgY3VzdG9tIFByb21pc2UgaW1wbGVtZW50YXRpb24gKHNlZSB6b25lLmpzKVxudmFyIEVTNlByb21pc2UgPSBudWxsO1xuaWYgKHR5cGVvZiBQcm9taXNlICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgRVM2UHJvbWlzZSA9IFByb21pc2U7XG59IGVsc2Uge1xuICAgIEVTNlByb21pc2UgPSByZXF1aXJlKFwibGllXCIpO1xufVxuXG4vKipcbiAqIExldCB0aGUgdXNlciB1c2UvY2hhbmdlIHNvbWUgaW1wbGVtZW50YXRpb25zLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBQcm9taXNlOiBFUzZQcm9taXNlXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIFVTRV9UWVBFREFSUkFZID0gKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJykgJiYgKHR5cGVvZiBVaW50MTZBcnJheSAhPT0gJ3VuZGVmaW5lZCcpICYmICh0eXBlb2YgVWludDMyQXJyYXkgIT09ICd1bmRlZmluZWQnKTtcblxudmFyIHBha28gPSByZXF1aXJlKFwicGFrb1wiKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoXCIuL3V0aWxzXCIpO1xudmFyIEdlbmVyaWNXb3JrZXIgPSByZXF1aXJlKFwiLi9zdHJlYW0vR2VuZXJpY1dvcmtlclwiKTtcblxudmFyIEFSUkFZX1RZUEUgPSBVU0VfVFlQRURBUlJBWSA/IFwidWludDhhcnJheVwiIDogXCJhcnJheVwiO1xuXG5leHBvcnRzLm1hZ2ljID0gXCJcXHgwOFxceDAwXCI7XG5cbi8qKlxuICogQ3JlYXRlIGEgd29ya2VyIHRoYXQgdXNlcyBwYWtvIHRvIGluZmxhdGUvZGVmbGF0ZS5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtTdHJpbmd9IGFjdGlvbiB0aGUgbmFtZSBvZiB0aGUgcGFrbyBmdW5jdGlvbiB0byBjYWxsIDogZWl0aGVyIFwiRGVmbGF0ZVwiIG9yIFwiSW5mbGF0ZVwiLlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgdGhlIG9wdGlvbnMgdG8gdXNlIHdoZW4gKGRlKWNvbXByZXNzaW5nLlxuICovXG5mdW5jdGlvbiBGbGF0ZVdvcmtlcihhY3Rpb24sIG9wdGlvbnMpIHtcbiAgICBHZW5lcmljV29ya2VyLmNhbGwodGhpcywgXCJGbGF0ZVdvcmtlci9cIiArIGFjdGlvbik7XG5cbiAgICB0aGlzLl9wYWtvID0gbnVsbDtcbiAgICB0aGlzLl9wYWtvQWN0aW9uID0gYWN0aW9uO1xuICAgIHRoaXMuX3Bha29PcHRpb25zID0gb3B0aW9ucztcbiAgICAvLyB0aGUgYG1ldGFgIG9iamVjdCBmcm9tIHRoZSBsYXN0IGNodW5rIHJlY2VpdmVkXG4gICAgLy8gdGhpcyBhbGxvdyB0aGlzIHdvcmtlciB0byBwYXNzIGFyb3VuZCBtZXRhZGF0YVxuICAgIHRoaXMubWV0YSA9IHt9O1xufVxuXG51dGlscy5pbmhlcml0cyhGbGF0ZVdvcmtlciwgR2VuZXJpY1dvcmtlcik7XG5cbi8qKlxuICogQHNlZSBHZW5lcmljV29ya2VyLnByb2Nlc3NDaHVua1xuICovXG5GbGF0ZVdvcmtlci5wcm90b3R5cGUucHJvY2Vzc0NodW5rID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgdGhpcy5tZXRhID0gY2h1bmsubWV0YTtcbiAgICBpZiAodGhpcy5fcGFrbyA9PT0gbnVsbCkge1xuICAgICAgICB0aGlzLl9jcmVhdGVQYWtvKCk7XG4gICAgfVxuICAgIHRoaXMuX3Bha28ucHVzaCh1dGlscy50cmFuc2Zvcm1UbyhBUlJBWV9UWVBFLCBjaHVuay5kYXRhKSwgZmFsc2UpO1xufTtcblxuLyoqXG4gKiBAc2VlIEdlbmVyaWNXb3JrZXIuZmx1c2hcbiAqL1xuRmxhdGVXb3JrZXIucHJvdG90eXBlLmZsdXNoID0gZnVuY3Rpb24gKCkge1xuICAgIEdlbmVyaWNXb3JrZXIucHJvdG90eXBlLmZsdXNoLmNhbGwodGhpcyk7XG4gICAgaWYgKHRoaXMuX3Bha28gPT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5fY3JlYXRlUGFrbygpO1xuICAgIH1cbiAgICB0aGlzLl9wYWtvLnB1c2goW10sIHRydWUpO1xufTtcbi8qKlxuICogQHNlZSBHZW5lcmljV29ya2VyLmNsZWFuVXBcbiAqL1xuRmxhdGVXb3JrZXIucHJvdG90eXBlLmNsZWFuVXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgR2VuZXJpY1dvcmtlci5wcm90b3R5cGUuY2xlYW5VcC5jYWxsKHRoaXMpO1xuICAgIHRoaXMuX3Bha28gPSBudWxsO1xufTtcblxuLyoqXG4gKiBDcmVhdGUgdGhlIF9wYWtvIG9iamVjdC5cbiAqIFRPRE86IGxhenktbG9hZGluZyB0aGlzIG9iamVjdCBpc24ndCB0aGUgYmVzdCBzb2x1dGlvbiBidXQgaXQncyB0aGVcbiAqIHF1aWNrZXN0LiBUaGUgYmVzdCBzb2x1dGlvbiBpcyB0byBsYXp5LWxvYWQgdGhlIHdvcmtlciBsaXN0LiBTZWUgYWxzbyB0aGVcbiAqIGlzc3VlICM0NDYuXG4gKi9cbkZsYXRlV29ya2VyLnByb3RvdHlwZS5fY3JlYXRlUGFrbyA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLl9wYWtvID0gbmV3IHBha29bdGhpcy5fcGFrb0FjdGlvbl0oe1xuICAgICAgICByYXc6IHRydWUsXG4gICAgICAgIGxldmVsOiB0aGlzLl9wYWtvT3B0aW9ucy5sZXZlbCB8fCAtMSAvLyBkZWZhdWx0IGNvbXByZXNzaW9uXG4gICAgfSk7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHRoaXMuX3Bha28ub25EYXRhID0gZnVuY3Rpb24oZGF0YSkge1xuICAgICAgICBzZWxmLnB1c2goe1xuICAgICAgICAgICAgZGF0YSA6IGRhdGEsXG4gICAgICAgICAgICBtZXRhIDogc2VsZi5tZXRhXG4gICAgICAgIH0pO1xuICAgIH07XG59O1xuXG5leHBvcnRzLmNvbXByZXNzV29ya2VyID0gZnVuY3Rpb24gKGNvbXByZXNzaW9uT3B0aW9ucykge1xuICAgIHJldHVybiBuZXcgRmxhdGVXb3JrZXIoXCJEZWZsYXRlXCIsIGNvbXByZXNzaW9uT3B0aW9ucyk7XG59O1xuZXhwb3J0cy51bmNvbXByZXNzV29ya2VyID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBuZXcgRmxhdGVXb3JrZXIoXCJJbmZsYXRlXCIsIHt9KTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgR2VuZXJpY1dvcmtlciA9IHJlcXVpcmUoJy4uL3N0cmVhbS9HZW5lcmljV29ya2VyJyk7XG52YXIgdXRmOCA9IHJlcXVpcmUoJy4uL3V0ZjgnKTtcbnZhciBjcmMzMiA9IHJlcXVpcmUoJy4uL2NyYzMyJyk7XG52YXIgc2lnbmF0dXJlID0gcmVxdWlyZSgnLi4vc2lnbmF0dXJlJyk7XG5cbi8qKlxuICogVHJhbnNmb3JtIGFuIGludGVnZXIgaW50byBhIHN0cmluZyBpbiBoZXhhZGVjaW1hbC5cbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge251bWJlcn0gZGVjIHRoZSBudW1iZXIgdG8gY29udmVydC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBieXRlcyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGdlbmVyYXRlLlxuICogQHJldHVybnMge3N0cmluZ30gdGhlIHJlc3VsdC5cbiAqL1xudmFyIGRlY1RvSGV4ID0gZnVuY3Rpb24oZGVjLCBieXRlcykge1xuICAgIHZhciBoZXggPSBcIlwiLCBpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBieXRlczsgaSsrKSB7XG4gICAgICAgIGhleCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGRlYyAmIDB4ZmYpO1xuICAgICAgICBkZWMgPSBkZWMgPj4+IDg7XG4gICAgfVxuICAgIHJldHVybiBoZXg7XG59O1xuXG4vKipcbiAqIEdlbmVyYXRlIHRoZSBVTklYIHBhcnQgb2YgdGhlIGV4dGVybmFsIGZpbGUgYXR0cmlidXRlcy5cbiAqIEBwYXJhbSB7T2JqZWN0fSB1bml4UGVybWlzc2lvbnMgdGhlIHVuaXggcGVybWlzc2lvbnMgb3IgbnVsbC5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNEaXIgdHJ1ZSBpZiB0aGUgZW50cnkgaXMgYSBkaXJlY3RvcnksIGZhbHNlIG90aGVyd2lzZS5cbiAqIEByZXR1cm4ge051bWJlcn0gYSAzMiBiaXQgaW50ZWdlci5cbiAqXG4gKiBhZGFwdGVkIGZyb20gaHR0cDovL3VuaXguc3RhY2tleGNoYW5nZS5jb20vcXVlc3Rpb25zLzE0NzA1L3RoZS16aXAtZm9ybWF0cy1leHRlcm5hbC1maWxlLWF0dHJpYnV0ZSA6XG4gKlxuICogVFRUVHNzdHJ3eHJ3eHJ3eDAwMDAwMDAwMDBBRFZTSFJcbiAqIF5eXl5fX19fX19fX19fX19fX19fX19fX19fX19fX19fIGZpbGUgdHlwZSwgc2VlIHppcGluZm8uYyAoVU5YXyopXG4gKiAgICAgXl5eX19fX19fX19fX19fX19fX19fX19fX19fXyBzZXR1aWQsIHNldGdpZCwgc3RpY2t5XG4gKiAgICAgICAgXl5eXl5eXl5eX19fX19fX19fX19fX19fXyBwZXJtaXNzaW9uc1xuICogICAgICAgICAgICAgICAgIF5eXl5eXl5eXl5fX19fX18gbm90IHVzZWQgP1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICBeXl5eXl4gRE9TIGF0dHJpYnV0ZSBiaXRzIDogQXJjaGl2ZSwgRGlyZWN0b3J5LCBWb2x1bWUgbGFiZWwsIFN5c3RlbSBmaWxlLCBIaWRkZW4sIFJlYWQgb25seVxuICovXG52YXIgZ2VuZXJhdGVVbml4RXh0ZXJuYWxGaWxlQXR0ciA9IGZ1bmN0aW9uICh1bml4UGVybWlzc2lvbnMsIGlzRGlyKSB7XG5cbiAgICB2YXIgcmVzdWx0ID0gdW5peFBlcm1pc3Npb25zO1xuICAgIGlmICghdW5peFBlcm1pc3Npb25zKSB7XG4gICAgICAgIC8vIEkgY2FuJ3QgdXNlIG9jdGFsIHZhbHVlcyBpbiBzdHJpY3QgbW9kZSwgaGVuY2UgdGhlIGhleGEuXG4gICAgICAgIC8vICAwNDA3NzUgPT4gMHg0MWZkXG4gICAgICAgIC8vIDAxMDA2NjQgPT4gMHg4MWI0XG4gICAgICAgIHJlc3VsdCA9IGlzRGlyID8gMHg0MWZkIDogMHg4MWI0O1xuICAgIH1cbiAgICByZXR1cm4gKHJlc3VsdCAmIDB4RkZGRikgPDwgMTY7XG59O1xuXG4vKipcbiAqIEdlbmVyYXRlIHRoZSBET1MgcGFydCBvZiB0aGUgZXh0ZXJuYWwgZmlsZSBhdHRyaWJ1dGVzLlxuICogQHBhcmFtIHtPYmplY3R9IGRvc1Blcm1pc3Npb25zIHRoZSBkb3MgcGVybWlzc2lvbnMgb3IgbnVsbC5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNEaXIgdHJ1ZSBpZiB0aGUgZW50cnkgaXMgYSBkaXJlY3RvcnksIGZhbHNlIG90aGVyd2lzZS5cbiAqIEByZXR1cm4ge051bWJlcn0gYSAzMiBiaXQgaW50ZWdlci5cbiAqXG4gKiBCaXQgMCAgICAgUmVhZC1Pbmx5XG4gKiBCaXQgMSAgICAgSGlkZGVuXG4gKiBCaXQgMiAgICAgU3lzdGVtXG4gKiBCaXQgMyAgICAgVm9sdW1lIExhYmVsXG4gKiBCaXQgNCAgICAgRGlyZWN0b3J5XG4gKiBCaXQgNSAgICAgQXJjaGl2ZVxuICovXG52YXIgZ2VuZXJhdGVEb3NFeHRlcm5hbEZpbGVBdHRyID0gZnVuY3Rpb24gKGRvc1Blcm1pc3Npb25zLCBpc0Rpcikge1xuXG4gICAgLy8gdGhlIGRpciBmbGFnIGlzIGFscmVhZHkgc2V0IGZvciBjb21wYXRpYmlsaXR5XG4gICAgcmV0dXJuIChkb3NQZXJtaXNzaW9ucyB8fCAwKSAgJiAweDNGO1xufTtcblxuLyoqXG4gKiBHZW5lcmF0ZSB0aGUgdmFyaW91cyBwYXJ0cyB1c2VkIGluIHRoZSBjb25zdHJ1Y3Rpb24gb2YgdGhlIGZpbmFsIHppcCBmaWxlLlxuICogQHBhcmFtIHtPYmplY3R9IHN0cmVhbUluZm8gdGhlIGhhc2ggd2l0aCBpbmZvcm1hdGlvbnMgYWJvdXQgdGhlIGNvbXByZXNzZWQgZmlsZS5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gc3RyZWFtZWRDb250ZW50IGlzIHRoZSBjb250ZW50IHN0cmVhbWVkID9cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gc3RyZWFtaW5nRW5kZWQgaXMgdGhlIHN0cmVhbSBmaW5pc2hlZCA/XG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IHRoZSBjdXJyZW50IG9mZnNldCBmcm9tIHRoZSBzdGFydCBvZiB0aGUgemlwIGZpbGUuXG4gKiBAcGFyYW0ge1N0cmluZ30gcGxhdGZvcm0gbGV0J3MgcHJldGVuZCB3ZSBhcmUgdGhpcyBwbGF0Zm9ybSAoY2hhbmdlIHBsYXRmb3JtIGRlcGVuZGVudHMgZmllbGRzKVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZW5jb2RlRmlsZU5hbWUgdGhlIGZ1bmN0aW9uIHRvIGVuY29kZSB0aGUgZmlsZSBuYW1lIC8gY29tbWVudC5cbiAqIEByZXR1cm4ge09iamVjdH0gdGhlIHppcCBwYXJ0cy5cbiAqL1xudmFyIGdlbmVyYXRlWmlwUGFydHMgPSBmdW5jdGlvbihzdHJlYW1JbmZvLCBzdHJlYW1lZENvbnRlbnQsIHN0cmVhbWluZ0VuZGVkLCBvZmZzZXQsIHBsYXRmb3JtLCBlbmNvZGVGaWxlTmFtZSkge1xuICAgIHZhciBmaWxlID0gc3RyZWFtSW5mb1snZmlsZSddLFxuICAgIGNvbXByZXNzaW9uID0gc3RyZWFtSW5mb1snY29tcHJlc3Npb24nXSxcbiAgICB1c2VDdXN0b21FbmNvZGluZyA9IGVuY29kZUZpbGVOYW1lICE9PSB1dGY4LnV0ZjhlbmNvZGUsXG4gICAgZW5jb2RlZEZpbGVOYW1lID0gdXRpbHMudHJhbnNmb3JtVG8oXCJzdHJpbmdcIiwgZW5jb2RlRmlsZU5hbWUoZmlsZS5uYW1lKSksXG4gICAgdXRmRW5jb2RlZEZpbGVOYW1lID0gdXRpbHMudHJhbnNmb3JtVG8oXCJzdHJpbmdcIiwgdXRmOC51dGY4ZW5jb2RlKGZpbGUubmFtZSkpLFxuICAgIGNvbW1lbnQgPSBmaWxlLmNvbW1lbnQsXG4gICAgZW5jb2RlZENvbW1lbnQgPSB1dGlscy50cmFuc2Zvcm1UbyhcInN0cmluZ1wiLCBlbmNvZGVGaWxlTmFtZShjb21tZW50KSksXG4gICAgdXRmRW5jb2RlZENvbW1lbnQgPSB1dGlscy50cmFuc2Zvcm1UbyhcInN0cmluZ1wiLCB1dGY4LnV0ZjhlbmNvZGUoY29tbWVudCkpLFxuICAgIHVzZVVURjhGb3JGaWxlTmFtZSA9IHV0ZkVuY29kZWRGaWxlTmFtZS5sZW5ndGggIT09IGZpbGUubmFtZS5sZW5ndGgsXG4gICAgdXNlVVRGOEZvckNvbW1lbnQgPSB1dGZFbmNvZGVkQ29tbWVudC5sZW5ndGggIT09IGNvbW1lbnQubGVuZ3RoLFxuICAgIGRvc1RpbWUsXG4gICAgZG9zRGF0ZSxcbiAgICBleHRyYUZpZWxkcyA9IFwiXCIsXG4gICAgdW5pY29kZVBhdGhFeHRyYUZpZWxkID0gXCJcIixcbiAgICB1bmljb2RlQ29tbWVudEV4dHJhRmllbGQgPSBcIlwiLFxuICAgIGRpciA9IGZpbGUuZGlyLFxuICAgIGRhdGUgPSBmaWxlLmRhdGU7XG5cblxuICAgIHZhciBkYXRhSW5mbyA9IHtcbiAgICAgICAgY3JjMzIgOiAwLFxuICAgICAgICBjb21wcmVzc2VkU2l6ZSA6IDAsXG4gICAgICAgIHVuY29tcHJlc3NlZFNpemUgOiAwXG4gICAgfTtcblxuICAgIC8vIGlmIHRoZSBjb250ZW50IGlzIHN0cmVhbWVkLCB0aGUgc2l6ZXMvY3JjMzIgYXJlIG9ubHkgYXZhaWxhYmxlIEFGVEVSXG4gICAgLy8gdGhlIGVuZCBvZiB0aGUgc3RyZWFtLlxuICAgIGlmICghc3RyZWFtZWRDb250ZW50IHx8IHN0cmVhbWluZ0VuZGVkKSB7XG4gICAgICAgIGRhdGFJbmZvLmNyYzMyID0gc3RyZWFtSW5mb1snY3JjMzInXTtcbiAgICAgICAgZGF0YUluZm8uY29tcHJlc3NlZFNpemUgPSBzdHJlYW1JbmZvWydjb21wcmVzc2VkU2l6ZSddO1xuICAgICAgICBkYXRhSW5mby51bmNvbXByZXNzZWRTaXplID0gc3RyZWFtSW5mb1sndW5jb21wcmVzc2VkU2l6ZSddO1xuICAgIH1cblxuICAgIHZhciBiaXRmbGFnID0gMDtcbiAgICBpZiAoc3RyZWFtZWRDb250ZW50KSB7XG4gICAgICAgIC8vIEJpdCAzOiB0aGUgc2l6ZXMvY3JjMzIgYXJlIHNldCB0byB6ZXJvIGluIHRoZSBsb2NhbCBoZWFkZXIuXG4gICAgICAgIC8vIFRoZSBjb3JyZWN0IHZhbHVlcyBhcmUgcHV0IGluIHRoZSBkYXRhIGRlc2NyaXB0b3IgaW1tZWRpYXRlbHlcbiAgICAgICAgLy8gZm9sbG93aW5nIHRoZSBjb21wcmVzc2VkIGRhdGEuXG4gICAgICAgIGJpdGZsYWcgfD0gMHgwMDA4O1xuICAgIH1cbiAgICBpZiAoIXVzZUN1c3RvbUVuY29kaW5nICYmICh1c2VVVEY4Rm9yRmlsZU5hbWUgfHwgdXNlVVRGOEZvckNvbW1lbnQpKSB7XG4gICAgICAgIC8vIEJpdCAxMTogTGFuZ3VhZ2UgZW5jb2RpbmcgZmxhZyAoRUZTKS5cbiAgICAgICAgYml0ZmxhZyB8PSAweDA4MDA7XG4gICAgfVxuXG5cbiAgICB2YXIgZXh0RmlsZUF0dHIgPSAwO1xuICAgIHZhciB2ZXJzaW9uTWFkZUJ5ID0gMDtcbiAgICBpZiAoZGlyKSB7XG4gICAgICAgIC8vIGRvcyBvciB1bml4LCB3ZSBzZXQgdGhlIGRvcyBkaXIgZmxhZ1xuICAgICAgICBleHRGaWxlQXR0ciB8PSAweDAwMDEwO1xuICAgIH1cbiAgICBpZihwbGF0Zm9ybSA9PT0gXCJVTklYXCIpIHtcbiAgICAgICAgdmVyc2lvbk1hZGVCeSA9IDB4MDMxRTsgLy8gVU5JWCwgdmVyc2lvbiAzLjBcbiAgICAgICAgZXh0RmlsZUF0dHIgfD0gZ2VuZXJhdGVVbml4RXh0ZXJuYWxGaWxlQXR0cihmaWxlLnVuaXhQZXJtaXNzaW9ucywgZGlyKTtcbiAgICB9IGVsc2UgeyAvLyBET1Mgb3Igb3RoZXIsIGZhbGxiYWNrIHRvIERPU1xuICAgICAgICB2ZXJzaW9uTWFkZUJ5ID0gMHgwMDE0OyAvLyBET1MsIHZlcnNpb24gMi4wXG4gICAgICAgIGV4dEZpbGVBdHRyIHw9IGdlbmVyYXRlRG9zRXh0ZXJuYWxGaWxlQXR0cihmaWxlLmRvc1Blcm1pc3Npb25zLCBkaXIpO1xuICAgIH1cblxuICAgIC8vIGRhdGVcbiAgICAvLyBAc2VlIGh0dHA6Ly93d3cuZGVsb3JpZS5jb20vZGpncHAvZG9jL3JiaW50ZXIvaXQvNTIvMTMuaHRtbFxuICAgIC8vIEBzZWUgaHR0cDovL3d3dy5kZWxvcmllLmNvbS9kamdwcC9kb2MvcmJpbnRlci9pdC82NS8xNi5odG1sXG4gICAgLy8gQHNlZSBodHRwOi8vd3d3LmRlbG9yaWUuY29tL2RqZ3BwL2RvYy9yYmludGVyL2l0LzY2LzE2Lmh0bWxcblxuICAgIGRvc1RpbWUgPSBkYXRlLmdldFVUQ0hvdXJzKCk7XG4gICAgZG9zVGltZSA9IGRvc1RpbWUgPDwgNjtcbiAgICBkb3NUaW1lID0gZG9zVGltZSB8IGRhdGUuZ2V0VVRDTWludXRlcygpO1xuICAgIGRvc1RpbWUgPSBkb3NUaW1lIDw8IDU7XG4gICAgZG9zVGltZSA9IGRvc1RpbWUgfCBkYXRlLmdldFVUQ1NlY29uZHMoKSAvIDI7XG5cbiAgICBkb3NEYXRlID0gZGF0ZS5nZXRVVENGdWxsWWVhcigpIC0gMTk4MDtcbiAgICBkb3NEYXRlID0gZG9zRGF0ZSA8PCA0O1xuICAgIGRvc0RhdGUgPSBkb3NEYXRlIHwgKGRhdGUuZ2V0VVRDTW9udGgoKSArIDEpO1xuICAgIGRvc0RhdGUgPSBkb3NEYXRlIDw8IDU7XG4gICAgZG9zRGF0ZSA9IGRvc0RhdGUgfCBkYXRlLmdldFVUQ0RhdGUoKTtcblxuICAgIGlmICh1c2VVVEY4Rm9yRmlsZU5hbWUpIHtcbiAgICAgICAgLy8gc2V0IHRoZSB1bmljb2RlIHBhdGggZXh0cmEgZmllbGQuIHVuemlwIG5lZWRzIGF0IGxlYXN0IG9uZSBleHRyYVxuICAgICAgICAvLyBmaWVsZCB0byBjb3JyZWN0bHkgaGFuZGxlIHVuaWNvZGUgcGF0aCwgc28gdXNpbmcgdGhlIHBhdGggaXMgYXMgZ29vZFxuICAgICAgICAvLyBhcyBhbnkgb3RoZXIgaW5mb3JtYXRpb24uIFRoaXMgY291bGQgaW1wcm92ZSB0aGUgc2l0dWF0aW9uIHdpdGhcbiAgICAgICAgLy8gb3RoZXIgYXJjaGl2ZSBtYW5hZ2VycyB0b28uXG4gICAgICAgIC8vIFRoaXMgZmllbGQgaXMgdXN1YWxseSB1c2VkIHdpdGhvdXQgdGhlIHV0ZjggZmxhZywgd2l0aCBhIG5vblxuICAgICAgICAvLyB1bmljb2RlIHBhdGggaW4gdGhlIGhlYWRlciAod2lucmFyLCB3aW56aXApLiBUaGlzIGhlbHBzIChhIGJpdClcbiAgICAgICAgLy8gd2l0aCB0aGUgbWVzc3kgV2luZG93cycgZGVmYXVsdCBjb21wcmVzc2VkIGZvbGRlcnMgZmVhdHVyZSBidXRcbiAgICAgICAgLy8gYnJlYWtzIG9uIHA3emlwIHdoaWNoIGRvZXNuJ3Qgc2VlayB0aGUgdW5pY29kZSBwYXRoIGV4dHJhIGZpZWxkLlxuICAgICAgICAvLyBTbyBmb3Igbm93LCBVVEYtOCBldmVyeXdoZXJlICFcbiAgICAgICAgdW5pY29kZVBhdGhFeHRyYUZpZWxkID1cbiAgICAgICAgICAgIC8vIFZlcnNpb25cbiAgICAgICAgICAgIGRlY1RvSGV4KDEsIDEpICtcbiAgICAgICAgICAgIC8vIE5hbWVDUkMzMlxuICAgICAgICAgICAgZGVjVG9IZXgoY3JjMzIoZW5jb2RlZEZpbGVOYW1lKSwgNCkgK1xuICAgICAgICAgICAgLy8gVW5pY29kZU5hbWVcbiAgICAgICAgICAgIHV0ZkVuY29kZWRGaWxlTmFtZTtcblxuICAgICAgICBleHRyYUZpZWxkcyArPVxuICAgICAgICAgICAgLy8gSW5mby1aSVAgVW5pY29kZSBQYXRoIEV4dHJhIEZpZWxkXG4gICAgICAgICAgICBcIlxceDc1XFx4NzBcIiArXG4gICAgICAgICAgICAvLyBzaXplXG4gICAgICAgICAgICBkZWNUb0hleCh1bmljb2RlUGF0aEV4dHJhRmllbGQubGVuZ3RoLCAyKSArXG4gICAgICAgICAgICAvLyBjb250ZW50XG4gICAgICAgICAgICB1bmljb2RlUGF0aEV4dHJhRmllbGQ7XG4gICAgfVxuXG4gICAgaWYodXNlVVRGOEZvckNvbW1lbnQpIHtcblxuICAgICAgICB1bmljb2RlQ29tbWVudEV4dHJhRmllbGQgPVxuICAgICAgICAgICAgLy8gVmVyc2lvblxuICAgICAgICAgICAgZGVjVG9IZXgoMSwgMSkgK1xuICAgICAgICAgICAgLy8gQ29tbWVudENSQzMyXG4gICAgICAgICAgICBkZWNUb0hleChjcmMzMihlbmNvZGVkQ29tbWVudCksIDQpICtcbiAgICAgICAgICAgIC8vIFVuaWNvZGVOYW1lXG4gICAgICAgICAgICB1dGZFbmNvZGVkQ29tbWVudDtcblxuICAgICAgICBleHRyYUZpZWxkcyArPVxuICAgICAgICAgICAgLy8gSW5mby1aSVAgVW5pY29kZSBQYXRoIEV4dHJhIEZpZWxkXG4gICAgICAgICAgICBcIlxceDc1XFx4NjNcIiArXG4gICAgICAgICAgICAvLyBzaXplXG4gICAgICAgICAgICBkZWNUb0hleCh1bmljb2RlQ29tbWVudEV4dHJhRmllbGQubGVuZ3RoLCAyKSArXG4gICAgICAgICAgICAvLyBjb250ZW50XG4gICAgICAgICAgICB1bmljb2RlQ29tbWVudEV4dHJhRmllbGQ7XG4gICAgfVxuXG4gICAgdmFyIGhlYWRlciA9IFwiXCI7XG5cbiAgICAvLyB2ZXJzaW9uIG5lZWRlZCB0byBleHRyYWN0XG4gICAgaGVhZGVyICs9IFwiXFx4MEFcXHgwMFwiO1xuICAgIC8vIGdlbmVyYWwgcHVycG9zZSBiaXQgZmxhZ1xuICAgIGhlYWRlciArPSBkZWNUb0hleChiaXRmbGFnLCAyKTtcbiAgICAvLyBjb21wcmVzc2lvbiBtZXRob2RcbiAgICBoZWFkZXIgKz0gY29tcHJlc3Npb24ubWFnaWM7XG4gICAgLy8gbGFzdCBtb2QgZmlsZSB0aW1lXG4gICAgaGVhZGVyICs9IGRlY1RvSGV4KGRvc1RpbWUsIDIpO1xuICAgIC8vIGxhc3QgbW9kIGZpbGUgZGF0ZVxuICAgIGhlYWRlciArPSBkZWNUb0hleChkb3NEYXRlLCAyKTtcbiAgICAvLyBjcmMtMzJcbiAgICBoZWFkZXIgKz0gZGVjVG9IZXgoZGF0YUluZm8uY3JjMzIsIDQpO1xuICAgIC8vIGNvbXByZXNzZWQgc2l6ZVxuICAgIGhlYWRlciArPSBkZWNUb0hleChkYXRhSW5mby5jb21wcmVzc2VkU2l6ZSwgNCk7XG4gICAgLy8gdW5jb21wcmVzc2VkIHNpemVcbiAgICBoZWFkZXIgKz0gZGVjVG9IZXgoZGF0YUluZm8udW5jb21wcmVzc2VkU2l6ZSwgNCk7XG4gICAgLy8gZmlsZSBuYW1lIGxlbmd0aFxuICAgIGhlYWRlciArPSBkZWNUb0hleChlbmNvZGVkRmlsZU5hbWUubGVuZ3RoLCAyKTtcbiAgICAvLyBleHRyYSBmaWVsZCBsZW5ndGhcbiAgICBoZWFkZXIgKz0gZGVjVG9IZXgoZXh0cmFGaWVsZHMubGVuZ3RoLCAyKTtcblxuXG4gICAgdmFyIGZpbGVSZWNvcmQgPSBzaWduYXR1cmUuTE9DQUxfRklMRV9IRUFERVIgKyBoZWFkZXIgKyBlbmNvZGVkRmlsZU5hbWUgKyBleHRyYUZpZWxkcztcblxuICAgIHZhciBkaXJSZWNvcmQgPSBzaWduYXR1cmUuQ0VOVFJBTF9GSUxFX0hFQURFUiArXG4gICAgICAgIC8vIHZlcnNpb24gbWFkZSBieSAoMDA6IERPUylcbiAgICAgICAgZGVjVG9IZXgodmVyc2lvbk1hZGVCeSwgMikgK1xuICAgICAgICAvLyBmaWxlIGhlYWRlciAoY29tbW9uIHRvIGZpbGUgYW5kIGNlbnRyYWwgZGlyZWN0b3J5KVxuICAgICAgICBoZWFkZXIgK1xuICAgICAgICAvLyBmaWxlIGNvbW1lbnQgbGVuZ3RoXG4gICAgICAgIGRlY1RvSGV4KGVuY29kZWRDb21tZW50Lmxlbmd0aCwgMikgK1xuICAgICAgICAvLyBkaXNrIG51bWJlciBzdGFydFxuICAgICAgICBcIlxceDAwXFx4MDBcIiArXG4gICAgICAgIC8vIGludGVybmFsIGZpbGUgYXR0cmlidXRlcyBUT0RPXG4gICAgICAgIFwiXFx4MDBcXHgwMFwiICtcbiAgICAgICAgLy8gZXh0ZXJuYWwgZmlsZSBhdHRyaWJ1dGVzXG4gICAgICAgIGRlY1RvSGV4KGV4dEZpbGVBdHRyLCA0KSArXG4gICAgICAgIC8vIHJlbGF0aXZlIG9mZnNldCBvZiBsb2NhbCBoZWFkZXJcbiAgICAgICAgZGVjVG9IZXgob2Zmc2V0LCA0KSArXG4gICAgICAgIC8vIGZpbGUgbmFtZVxuICAgICAgICBlbmNvZGVkRmlsZU5hbWUgK1xuICAgICAgICAvLyBleHRyYSBmaWVsZFxuICAgICAgICBleHRyYUZpZWxkcyArXG4gICAgICAgIC8vIGZpbGUgY29tbWVudFxuICAgICAgICBlbmNvZGVkQ29tbWVudDtcblxuICAgIHJldHVybiB7XG4gICAgICAgIGZpbGVSZWNvcmQ6IGZpbGVSZWNvcmQsXG4gICAgICAgIGRpclJlY29yZDogZGlyUmVjb3JkXG4gICAgfTtcbn07XG5cbi8qKlxuICogR2VuZXJhdGUgdGhlIEVPQ0QgcmVjb3JkLlxuICogQHBhcmFtIHtOdW1iZXJ9IGVudHJpZXNDb3VudCB0aGUgbnVtYmVyIG9mIGVudHJpZXMgaW4gdGhlIHppcCBmaWxlLlxuICogQHBhcmFtIHtOdW1iZXJ9IGNlbnRyYWxEaXJMZW5ndGggdGhlIGxlbmd0aCAoaW4gYnl0ZXMpIG9mIHRoZSBjZW50cmFsIGRpci5cbiAqIEBwYXJhbSB7TnVtYmVyfSBsb2NhbERpckxlbmd0aCB0aGUgbGVuZ3RoIChpbiBieXRlcykgb2YgdGhlIGxvY2FsIGRpci5cbiAqIEBwYXJhbSB7U3RyaW5nfSBjb21tZW50IHRoZSB6aXAgZmlsZSBjb21tZW50IGFzIGEgYmluYXJ5IHN0cmluZy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVuY29kZUZpbGVOYW1lIHRoZSBmdW5jdGlvbiB0byBlbmNvZGUgdGhlIGNvbW1lbnQuXG4gKiBAcmV0dXJuIHtTdHJpbmd9IHRoZSBFT0NEIHJlY29yZC5cbiAqL1xudmFyIGdlbmVyYXRlQ2VudHJhbERpcmVjdG9yeUVuZCA9IGZ1bmN0aW9uIChlbnRyaWVzQ291bnQsIGNlbnRyYWxEaXJMZW5ndGgsIGxvY2FsRGlyTGVuZ3RoLCBjb21tZW50LCBlbmNvZGVGaWxlTmFtZSkge1xuICAgIHZhciBkaXJFbmQgPSBcIlwiO1xuICAgIHZhciBlbmNvZGVkQ29tbWVudCA9IHV0aWxzLnRyYW5zZm9ybVRvKFwic3RyaW5nXCIsIGVuY29kZUZpbGVOYW1lKGNvbW1lbnQpKTtcblxuICAgIC8vIGVuZCBvZiBjZW50cmFsIGRpciBzaWduYXR1cmVcbiAgICBkaXJFbmQgPSBzaWduYXR1cmUuQ0VOVFJBTF9ESVJFQ1RPUllfRU5EICtcbiAgICAgICAgLy8gbnVtYmVyIG9mIHRoaXMgZGlza1xuICAgICAgICBcIlxceDAwXFx4MDBcIiArXG4gICAgICAgIC8vIG51bWJlciBvZiB0aGUgZGlzayB3aXRoIHRoZSBzdGFydCBvZiB0aGUgY2VudHJhbCBkaXJlY3RvcnlcbiAgICAgICAgXCJcXHgwMFxceDAwXCIgK1xuICAgICAgICAvLyB0b3RhbCBudW1iZXIgb2YgZW50cmllcyBpbiB0aGUgY2VudHJhbCBkaXJlY3Rvcnkgb24gdGhpcyBkaXNrXG4gICAgICAgIGRlY1RvSGV4KGVudHJpZXNDb3VudCwgMikgK1xuICAgICAgICAvLyB0b3RhbCBudW1iZXIgb2YgZW50cmllcyBpbiB0aGUgY2VudHJhbCBkaXJlY3RvcnlcbiAgICAgICAgZGVjVG9IZXgoZW50cmllc0NvdW50LCAyKSArXG4gICAgICAgIC8vIHNpemUgb2YgdGhlIGNlbnRyYWwgZGlyZWN0b3J5ICAgNCBieXRlc1xuICAgICAgICBkZWNUb0hleChjZW50cmFsRGlyTGVuZ3RoLCA0KSArXG4gICAgICAgIC8vIG9mZnNldCBvZiBzdGFydCBvZiBjZW50cmFsIGRpcmVjdG9yeSB3aXRoIHJlc3BlY3QgdG8gdGhlIHN0YXJ0aW5nIGRpc2sgbnVtYmVyXG4gICAgICAgIGRlY1RvSGV4KGxvY2FsRGlyTGVuZ3RoLCA0KSArXG4gICAgICAgIC8vIC5aSVAgZmlsZSBjb21tZW50IGxlbmd0aFxuICAgICAgICBkZWNUb0hleChlbmNvZGVkQ29tbWVudC5sZW5ndGgsIDIpICtcbiAgICAgICAgLy8gLlpJUCBmaWxlIGNvbW1lbnRcbiAgICAgICAgZW5jb2RlZENvbW1lbnQ7XG5cbiAgICByZXR1cm4gZGlyRW5kO1xufTtcblxuLyoqXG4gKiBHZW5lcmF0ZSBkYXRhIGRlc2NyaXB0b3JzIGZvciBhIGZpbGUgZW50cnkuXG4gKiBAcGFyYW0ge09iamVjdH0gc3RyZWFtSW5mbyB0aGUgaGFzaCBnZW5lcmF0ZWQgYnkgYSB3b3JrZXIsIGNvbnRhaW5pbmcgaW5mb3JtYXRpb25zXG4gKiBvbiB0aGUgZmlsZSBlbnRyeS5cbiAqIEByZXR1cm4ge1N0cmluZ30gdGhlIGRhdGEgZGVzY3JpcHRvcnMuXG4gKi9cbnZhciBnZW5lcmF0ZURhdGFEZXNjcmlwdG9ycyA9IGZ1bmN0aW9uIChzdHJlYW1JbmZvKSB7XG4gICAgdmFyIGRlc2NyaXB0b3IgPSBcIlwiO1xuICAgIGRlc2NyaXB0b3IgPSBzaWduYXR1cmUuREFUQV9ERVNDUklQVE9SICtcbiAgICAgICAgLy8gY3JjLTMyICAgICAgICAgICAgICAgICAgICAgICAgICA0IGJ5dGVzXG4gICAgICAgIGRlY1RvSGV4KHN0cmVhbUluZm9bJ2NyYzMyJ10sIDQpICtcbiAgICAgICAgLy8gY29tcHJlc3NlZCBzaXplICAgICAgICAgICAgICAgICA0IGJ5dGVzXG4gICAgICAgIGRlY1RvSGV4KHN0cmVhbUluZm9bJ2NvbXByZXNzZWRTaXplJ10sIDQpICtcbiAgICAgICAgLy8gdW5jb21wcmVzc2VkIHNpemUgICAgICAgICAgICAgICA0IGJ5dGVzXG4gICAgICAgIGRlY1RvSGV4KHN0cmVhbUluZm9bJ3VuY29tcHJlc3NlZFNpemUnXSwgNCk7XG5cbiAgICByZXR1cm4gZGVzY3JpcHRvcjtcbn07XG5cblxuLyoqXG4gKiBBIHdvcmtlciB0byBjb25jYXRlbmF0ZSBvdGhlciB3b3JrZXJzIHRvIGNyZWF0ZSBhIHppcCBmaWxlLlxuICogQHBhcmFtIHtCb29sZWFufSBzdHJlYW1GaWxlcyBgdHJ1ZWAgdG8gc3RyZWFtIHRoZSBjb250ZW50IG9mIHRoZSBmaWxlcyxcbiAqIGBmYWxzZWAgdG8gYWNjdW11bGF0ZSBpdC5cbiAqIEBwYXJhbSB7U3RyaW5nfSBjb21tZW50IHRoZSBjb21tZW50IHRvIHVzZS5cbiAqIEBwYXJhbSB7U3RyaW5nfSBwbGF0Zm9ybSB0aGUgcGxhdGZvcm0gdG8gdXNlLCBcIlVOSVhcIiBvciBcIkRPU1wiLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZW5jb2RlRmlsZU5hbWUgdGhlIGZ1bmN0aW9uIHRvIGVuY29kZSBmaWxlIG5hbWVzIGFuZCBjb21tZW50cy5cbiAqL1xuZnVuY3Rpb24gWmlwRmlsZVdvcmtlcihzdHJlYW1GaWxlcywgY29tbWVudCwgcGxhdGZvcm0sIGVuY29kZUZpbGVOYW1lKSB7XG4gICAgR2VuZXJpY1dvcmtlci5jYWxsKHRoaXMsIFwiWmlwRmlsZVdvcmtlclwiKTtcbiAgICAvLyBUaGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gc28gZmFyLiBUaGlzIGRvZXNuJ3QgY291bnQgYWNjdW11bGF0ZWQgY2h1bmtzLlxuICAgIHRoaXMuYnl0ZXNXcml0dGVuID0gMDtcbiAgICAvLyBUaGUgY29tbWVudCBvZiB0aGUgemlwIGZpbGVcbiAgICB0aGlzLnppcENvbW1lbnQgPSBjb21tZW50O1xuICAgIC8vIFRoZSBwbGF0Zm9ybSBcImdlbmVyYXRpbmdcIiB0aGUgemlwIGZpbGUuXG4gICAgdGhpcy56aXBQbGF0Zm9ybSA9IHBsYXRmb3JtO1xuICAgIC8vIHRoZSBmdW5jdGlvbiB0byBlbmNvZGUgZmlsZSBuYW1lcyBhbmQgY29tbWVudHMuXG4gICAgdGhpcy5lbmNvZGVGaWxlTmFtZSA9IGVuY29kZUZpbGVOYW1lO1xuICAgIC8vIFNob3VsZCB3ZSBzdHJlYW0gdGhlIGNvbnRlbnQgb2YgdGhlIGZpbGVzID9cbiAgICB0aGlzLnN0cmVhbUZpbGVzID0gc3RyZWFtRmlsZXM7XG4gICAgLy8gSWYgYHN0cmVhbUZpbGVzYCBpcyBmYWxzZSwgd2Ugd2lsbCBuZWVkIHRvIGFjY3VtdWxhdGUgdGhlIGNvbnRlbnQgb2YgdGhlXG4gICAgLy8gZmlsZXMgdG8gY2FsY3VsYXRlIHNpemVzIC8gY3JjMzIgKGFuZCB3cml0ZSB0aGVtICpiZWZvcmUqIHRoZSBjb250ZW50KS5cbiAgICAvLyBUaGlzIGJvb2xlYW4gaW5kaWNhdGVzIGlmIHdlIGFyZSBhY2N1bXVsYXRpbmcgY2h1bmtzIChpdCB3aWxsIGNoYW5nZSBhIGxvdFxuICAgIC8vIGR1cmluZyB0aGUgbGlmZXRpbWUgb2YgdGhpcyB3b3JrZXIpLlxuICAgIHRoaXMuYWNjdW11bGF0ZSA9IGZhbHNlO1xuICAgIC8vIFRoZSBidWZmZXIgcmVjZWl2aW5nIGNodW5rcyB3aGVuIGFjY3VtdWxhdGluZyBjb250ZW50LlxuICAgIHRoaXMuY29udGVudEJ1ZmZlciA9IFtdO1xuICAgIC8vIFRoZSBsaXN0IG9mIGdlbmVyYXRlZCBkaXJlY3RvcnkgcmVjb3Jkcy5cbiAgICB0aGlzLmRpclJlY29yZHMgPSBbXTtcbiAgICAvLyBUaGUgb2Zmc2V0IChpbiBieXRlcykgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSB6aXAgZmlsZSBmb3IgdGhlIGN1cnJlbnQgc291cmNlLlxuICAgIHRoaXMuY3VycmVudFNvdXJjZU9mZnNldCA9IDA7XG4gICAgLy8gVGhlIHRvdGFsIG51bWJlciBvZiBlbnRyaWVzIGluIHRoaXMgemlwIGZpbGUuXG4gICAgdGhpcy5lbnRyaWVzQ291bnQgPSAwO1xuICAgIC8vIHRoZSBuYW1lIG9mIHRoZSBmaWxlIGN1cnJlbnRseSBiZWluZyBhZGRlZCwgbnVsbCB3aGVuIGhhbmRsaW5nIHRoZSBlbmQgb2YgdGhlIHppcCBmaWxlLlxuICAgIC8vIFVzZWQgZm9yIHRoZSBlbWl0ZWQgbWV0YWRhdGEuXG4gICAgdGhpcy5jdXJyZW50RmlsZSA9IG51bGw7XG5cblxuXG4gICAgdGhpcy5fc291cmNlcyA9IFtdO1xufVxudXRpbHMuaW5oZXJpdHMoWmlwRmlsZVdvcmtlciwgR2VuZXJpY1dvcmtlcik7XG5cbi8qKlxuICogQHNlZSBHZW5lcmljV29ya2VyLnB1c2hcbiAqL1xuWmlwRmlsZVdvcmtlci5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIChjaHVuaykge1xuXG4gICAgdmFyIGN1cnJlbnRGaWxlUGVyY2VudCA9IGNodW5rLm1ldGEucGVyY2VudCB8fCAwO1xuICAgIHZhciBlbnRyaWVzQ291bnQgPSB0aGlzLmVudHJpZXNDb3VudDtcbiAgICB2YXIgcmVtYWluaW5nRmlsZXMgPSB0aGlzLl9zb3VyY2VzLmxlbmd0aDtcblxuICAgIGlmKHRoaXMuYWNjdW11bGF0ZSkge1xuICAgICAgICB0aGlzLmNvbnRlbnRCdWZmZXIucHVzaChjaHVuayk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5ieXRlc1dyaXR0ZW4gKz0gY2h1bmsuZGF0YS5sZW5ndGg7XG5cbiAgICAgICAgR2VuZXJpY1dvcmtlci5wcm90b3R5cGUucHVzaC5jYWxsKHRoaXMsIHtcbiAgICAgICAgICAgIGRhdGEgOiBjaHVuay5kYXRhLFxuICAgICAgICAgICAgbWV0YSA6IHtcbiAgICAgICAgICAgICAgICBjdXJyZW50RmlsZSA6IHRoaXMuY3VycmVudEZpbGUsXG4gICAgICAgICAgICAgICAgcGVyY2VudCA6IGVudHJpZXNDb3VudCA/IChjdXJyZW50RmlsZVBlcmNlbnQgKyAxMDAgKiAoZW50cmllc0NvdW50IC0gcmVtYWluaW5nRmlsZXMgLSAxKSkgLyBlbnRyaWVzQ291bnQgOiAxMDBcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufTtcblxuLyoqXG4gKiBUaGUgd29ya2VyIHN0YXJ0ZWQgYSBuZXcgc291cmNlIChhbiBvdGhlciB3b3JrZXIpLlxuICogQHBhcmFtIHtPYmplY3R9IHN0cmVhbUluZm8gdGhlIHN0cmVhbUluZm8gb2JqZWN0IGZyb20gdGhlIG5ldyBzb3VyY2UuXG4gKi9cblppcEZpbGVXb3JrZXIucHJvdG90eXBlLm9wZW5lZFNvdXJjZSA9IGZ1bmN0aW9uIChzdHJlYW1JbmZvKSB7XG4gICAgdGhpcy5jdXJyZW50U291cmNlT2Zmc2V0ID0gdGhpcy5ieXRlc1dyaXR0ZW47XG4gICAgdGhpcy5jdXJyZW50RmlsZSA9IHN0cmVhbUluZm9bJ2ZpbGUnXS5uYW1lO1xuXG4gICAgdmFyIHN0cmVhbWVkQ29udGVudCA9IHRoaXMuc3RyZWFtRmlsZXMgJiYgIXN0cmVhbUluZm9bJ2ZpbGUnXS5kaXI7XG5cbiAgICAvLyBkb24ndCBzdHJlYW0gZm9sZGVycyAoYmVjYXVzZSB0aGV5IGRvbid0IGhhdmUgYW55IGNvbnRlbnQpXG4gICAgaWYoc3RyZWFtZWRDb250ZW50KSB7XG4gICAgICAgIHZhciByZWNvcmQgPSBnZW5lcmF0ZVppcFBhcnRzKHN0cmVhbUluZm8sIHN0cmVhbWVkQ29udGVudCwgZmFsc2UsIHRoaXMuY3VycmVudFNvdXJjZU9mZnNldCwgdGhpcy56aXBQbGF0Zm9ybSwgdGhpcy5lbmNvZGVGaWxlTmFtZSk7XG4gICAgICAgIHRoaXMucHVzaCh7XG4gICAgICAgICAgICBkYXRhIDogcmVjb3JkLmZpbGVSZWNvcmQsXG4gICAgICAgICAgICBtZXRhIDoge3BlcmNlbnQ6MH1cbiAgICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gd2UgbmVlZCB0byB3YWl0IGZvciB0aGUgd2hvbGUgZmlsZSBiZWZvcmUgcHVzaGluZyBhbnl0aGluZ1xuICAgICAgICB0aGlzLmFjY3VtdWxhdGUgPSB0cnVlO1xuICAgIH1cbn07XG5cbi8qKlxuICogVGhlIHdvcmtlciBmaW5pc2hlZCBhIHNvdXJjZSAoYW4gb3RoZXIgd29ya2VyKS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBzdHJlYW1JbmZvIHRoZSBzdHJlYW1JbmZvIG9iamVjdCBmcm9tIHRoZSBmaW5pc2hlZCBzb3VyY2UuXG4gKi9cblppcEZpbGVXb3JrZXIucHJvdG90eXBlLmNsb3NlZFNvdXJjZSA9IGZ1bmN0aW9uIChzdHJlYW1JbmZvKSB7XG4gICAgdGhpcy5hY2N1bXVsYXRlID0gZmFsc2U7XG4gICAgdmFyIHN0cmVhbWVkQ29udGVudCA9IHRoaXMuc3RyZWFtRmlsZXMgJiYgIXN0cmVhbUluZm9bJ2ZpbGUnXS5kaXI7XG4gICAgdmFyIHJlY29yZCA9IGdlbmVyYXRlWmlwUGFydHMoc3RyZWFtSW5mbywgc3RyZWFtZWRDb250ZW50LCB0cnVlLCB0aGlzLmN1cnJlbnRTb3VyY2VPZmZzZXQsIHRoaXMuemlwUGxhdGZvcm0sIHRoaXMuZW5jb2RlRmlsZU5hbWUpO1xuXG4gICAgdGhpcy5kaXJSZWNvcmRzLnB1c2gocmVjb3JkLmRpclJlY29yZCk7XG4gICAgaWYoc3RyZWFtZWRDb250ZW50KSB7XG4gICAgICAgIC8vIGFmdGVyIHRoZSBzdHJlYW1lZCBmaWxlLCB3ZSBwdXQgZGF0YSBkZXNjcmlwdG9yc1xuICAgICAgICB0aGlzLnB1c2goe1xuICAgICAgICAgICAgZGF0YSA6IGdlbmVyYXRlRGF0YURlc2NyaXB0b3JzKHN0cmVhbUluZm8pLFxuICAgICAgICAgICAgbWV0YSA6IHtwZXJjZW50OjEwMH1cbiAgICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gdGhlIGNvbnRlbnQgd2Fzbid0IHN0cmVhbWVkLCB3ZSBuZWVkIHRvIHB1c2ggZXZlcnl0aGluZyBub3dcbiAgICAgICAgLy8gZmlyc3QgdGhlIGZpbGUgcmVjb3JkLCB0aGVuIHRoZSBjb250ZW50XG4gICAgICAgIHRoaXMucHVzaCh7XG4gICAgICAgICAgICBkYXRhIDogcmVjb3JkLmZpbGVSZWNvcmQsXG4gICAgICAgICAgICBtZXRhIDoge3BlcmNlbnQ6MH1cbiAgICAgICAgfSk7XG4gICAgICAgIHdoaWxlKHRoaXMuY29udGVudEJ1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMucHVzaCh0aGlzLmNvbnRlbnRCdWZmZXIuc2hpZnQoKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5jdXJyZW50RmlsZSA9IG51bGw7XG59O1xuXG4vKipcbiAqIEBzZWUgR2VuZXJpY1dvcmtlci5mbHVzaFxuICovXG5aaXBGaWxlV29ya2VyLnByb3RvdHlwZS5mbHVzaCA9IGZ1bmN0aW9uICgpIHtcblxuICAgIHZhciBsb2NhbERpckxlbmd0aCA9IHRoaXMuYnl0ZXNXcml0dGVuO1xuICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLmRpclJlY29yZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpcy5wdXNoKHtcbiAgICAgICAgICAgIGRhdGEgOiB0aGlzLmRpclJlY29yZHNbaV0sXG4gICAgICAgICAgICBtZXRhIDoge3BlcmNlbnQ6MTAwfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgdmFyIGNlbnRyYWxEaXJMZW5ndGggPSB0aGlzLmJ5dGVzV3JpdHRlbiAtIGxvY2FsRGlyTGVuZ3RoO1xuXG4gICAgdmFyIGRpckVuZCA9IGdlbmVyYXRlQ2VudHJhbERpcmVjdG9yeUVuZCh0aGlzLmRpclJlY29yZHMubGVuZ3RoLCBjZW50cmFsRGlyTGVuZ3RoLCBsb2NhbERpckxlbmd0aCwgdGhpcy56aXBDb21tZW50LCB0aGlzLmVuY29kZUZpbGVOYW1lKTtcblxuICAgIHRoaXMucHVzaCh7XG4gICAgICAgIGRhdGEgOiBkaXJFbmQsXG4gICAgICAgIG1ldGEgOiB7cGVyY2VudDoxMDB9XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFByZXBhcmUgdGhlIG5leHQgc291cmNlIHRvIGJlIHJlYWQuXG4gKi9cblppcEZpbGVXb3JrZXIucHJvdG90eXBlLnByZXBhcmVOZXh0U291cmNlID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucHJldmlvdXMgPSB0aGlzLl9zb3VyY2VzLnNoaWZ0KCk7XG4gICAgdGhpcy5vcGVuZWRTb3VyY2UodGhpcy5wcmV2aW91cy5zdHJlYW1JbmZvKTtcbiAgICBpZiAodGhpcy5pc1BhdXNlZCkge1xuICAgICAgICB0aGlzLnByZXZpb3VzLnBhdXNlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5wcmV2aW91cy5yZXN1bWUoKTtcbiAgICB9XG59O1xuXG4vKipcbiAqIEBzZWUgR2VuZXJpY1dvcmtlci5yZWdpc3RlclByZXZpb3VzXG4gKi9cblppcEZpbGVXb3JrZXIucHJvdG90eXBlLnJlZ2lzdGVyUHJldmlvdXMgPSBmdW5jdGlvbiAocHJldmlvdXMpIHtcbiAgICB0aGlzLl9zb3VyY2VzLnB1c2gocHJldmlvdXMpO1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHByZXZpb3VzLm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgICAgIHNlbGYucHJvY2Vzc0NodW5rKGNodW5rKTtcbiAgICB9KTtcbiAgICBwcmV2aW91cy5vbignZW5kJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLmNsb3NlZFNvdXJjZShzZWxmLnByZXZpb3VzLnN0cmVhbUluZm8pO1xuICAgICAgICBpZihzZWxmLl9zb3VyY2VzLmxlbmd0aCkge1xuICAgICAgICAgICAgc2VsZi5wcmVwYXJlTmV4dFNvdXJjZSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZi5lbmQoKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHByZXZpb3VzLm9uKCdlcnJvcicsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHNlbGYuZXJyb3IoZSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEBzZWUgR2VuZXJpY1dvcmtlci5yZXN1bWVcbiAqL1xuWmlwRmlsZVdvcmtlci5wcm90b3R5cGUucmVzdW1lID0gZnVuY3Rpb24gKCkge1xuICAgIGlmKCFHZW5lcmljV29ya2VyLnByb3RvdHlwZS5yZXN1bWUuY2FsbCh0aGlzKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLnByZXZpb3VzICYmIHRoaXMuX3NvdXJjZXMubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMucHJlcGFyZU5leHRTb3VyY2UoKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmICghdGhpcy5wcmV2aW91cyAmJiAhdGhpcy5fc291cmNlcy5sZW5ndGggJiYgIXRoaXMuZ2VuZXJhdGVkRXJyb3IpIHtcbiAgICAgICAgdGhpcy5lbmQoKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxufTtcblxuLyoqXG4gKiBAc2VlIEdlbmVyaWNXb3JrZXIuZXJyb3JcbiAqL1xuWmlwRmlsZVdvcmtlci5wcm90b3R5cGUuZXJyb3IgPSBmdW5jdGlvbiAoZSkge1xuICAgIHZhciBzb3VyY2VzID0gdGhpcy5fc291cmNlcztcbiAgICBpZighR2VuZXJpY1dvcmtlci5wcm90b3R5cGUuZXJyb3IuY2FsbCh0aGlzLCBlKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvcih2YXIgaSA9IDA7IGkgPCBzb3VyY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzb3VyY2VzW2ldLmVycm9yKGUpO1xuICAgICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgICAgIC8vIHRoZSBgZXJyb3JgIGV4cGxvZGVkLCBub3RoaW5nIHRvIGRvXG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59O1xuXG4vKipcbiAqIEBzZWUgR2VuZXJpY1dvcmtlci5sb2NrXG4gKi9cblppcEZpbGVXb3JrZXIucHJvdG90eXBlLmxvY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgR2VuZXJpY1dvcmtlci5wcm90b3R5cGUubG9jay5jYWxsKHRoaXMpO1xuICAgIHZhciBzb3VyY2VzID0gdGhpcy5fc291cmNlcztcbiAgICBmb3IodmFyIGkgPSAwOyBpIDwgc291cmNlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBzb3VyY2VzW2ldLmxvY2soKTtcbiAgICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFppcEZpbGVXb3JrZXI7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBjb21wcmVzc2lvbnMgPSByZXF1aXJlKCcuLi9jb21wcmVzc2lvbnMnKTtcbnZhciBaaXBGaWxlV29ya2VyID0gcmVxdWlyZSgnLi9aaXBGaWxlV29ya2VyJyk7XG5cbi8qKlxuICogRmluZCB0aGUgY29tcHJlc3Npb24gdG8gdXNlLlxuICogQHBhcmFtIHtTdHJpbmd9IGZpbGVDb21wcmVzc2lvbiB0aGUgY29tcHJlc3Npb24gZGVmaW5lZCBhdCB0aGUgZmlsZSBsZXZlbCwgaWYgYW55LlxuICogQHBhcmFtIHtTdHJpbmd9IHppcENvbXByZXNzaW9uIHRoZSBjb21wcmVzc2lvbiBkZWZpbmVkIGF0IHRoZSBsb2FkKCkgbGV2ZWwuXG4gKiBAcmV0dXJuIHtPYmplY3R9IHRoZSBjb21wcmVzc2lvbiBvYmplY3QgdG8gdXNlLlxuICovXG52YXIgZ2V0Q29tcHJlc3Npb24gPSBmdW5jdGlvbiAoZmlsZUNvbXByZXNzaW9uLCB6aXBDb21wcmVzc2lvbikge1xuXG4gICAgdmFyIGNvbXByZXNzaW9uTmFtZSA9IGZpbGVDb21wcmVzc2lvbiB8fCB6aXBDb21wcmVzc2lvbjtcbiAgICB2YXIgY29tcHJlc3Npb24gPSBjb21wcmVzc2lvbnNbY29tcHJlc3Npb25OYW1lXTtcbiAgICBpZiAoIWNvbXByZXNzaW9uKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihjb21wcmVzc2lvbk5hbWUgKyBcIiBpcyBub3QgYSB2YWxpZCBjb21wcmVzc2lvbiBtZXRob2QgIVwiKTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbXByZXNzaW9uO1xufTtcblxuLyoqXG4gKiBDcmVhdGUgYSB3b3JrZXIgdG8gZ2VuZXJhdGUgYSB6aXAgZmlsZS5cbiAqIEBwYXJhbSB7SlNaaXB9IHppcCB0aGUgSlNaaXAgaW5zdGFuY2UgYXQgdGhlIHJpZ2h0IHJvb3QgbGV2ZWwuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyB0byBnZW5lcmF0ZSB0aGUgemlwIGZpbGUuXG4gKiBAcGFyYW0ge1N0cmluZ30gY29tbWVudCB0aGUgY29tbWVudCB0byB1c2UuXG4gKi9cbmV4cG9ydHMuZ2VuZXJhdGVXb3JrZXIgPSBmdW5jdGlvbiAoemlwLCBvcHRpb25zLCBjb21tZW50KSB7XG5cbiAgICB2YXIgemlwRmlsZVdvcmtlciA9IG5ldyBaaXBGaWxlV29ya2VyKG9wdGlvbnMuc3RyZWFtRmlsZXMsIGNvbW1lbnQsIG9wdGlvbnMucGxhdGZvcm0sIG9wdGlvbnMuZW5jb2RlRmlsZU5hbWUpO1xuICAgIHZhciBlbnRyaWVzQ291bnQgPSAwO1xuICAgIHRyeSB7XG5cbiAgICAgICAgemlwLmZvckVhY2goZnVuY3Rpb24gKHJlbGF0aXZlUGF0aCwgZmlsZSkge1xuICAgICAgICAgICAgZW50cmllc0NvdW50Kys7XG4gICAgICAgICAgICB2YXIgY29tcHJlc3Npb24gPSBnZXRDb21wcmVzc2lvbihmaWxlLm9wdGlvbnMuY29tcHJlc3Npb24sIG9wdGlvbnMuY29tcHJlc3Npb24pO1xuICAgICAgICAgICAgdmFyIGNvbXByZXNzaW9uT3B0aW9ucyA9IGZpbGUub3B0aW9ucy5jb21wcmVzc2lvbk9wdGlvbnMgfHwgb3B0aW9ucy5jb21wcmVzc2lvbk9wdGlvbnMgfHwge307XG4gICAgICAgICAgICB2YXIgZGlyID0gZmlsZS5kaXIsIGRhdGUgPSBmaWxlLmRhdGU7XG5cbiAgICAgICAgICAgIGZpbGUuX2NvbXByZXNzV29ya2VyKGNvbXByZXNzaW9uLCBjb21wcmVzc2lvbk9wdGlvbnMpXG4gICAgICAgICAgICAud2l0aFN0cmVhbUluZm8oXCJmaWxlXCIsIHtcbiAgICAgICAgICAgICAgICBuYW1lIDogcmVsYXRpdmVQYXRoLFxuICAgICAgICAgICAgICAgIGRpciA6IGRpcixcbiAgICAgICAgICAgICAgICBkYXRlIDogZGF0ZSxcbiAgICAgICAgICAgICAgICBjb21tZW50IDogZmlsZS5jb21tZW50IHx8IFwiXCIsXG4gICAgICAgICAgICAgICAgdW5peFBlcm1pc3Npb25zIDogZmlsZS51bml4UGVybWlzc2lvbnMsXG4gICAgICAgICAgICAgICAgZG9zUGVybWlzc2lvbnMgOiBmaWxlLmRvc1Blcm1pc3Npb25zXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnBpcGUoemlwRmlsZVdvcmtlcik7XG4gICAgICAgIH0pO1xuICAgICAgICB6aXBGaWxlV29ya2VyLmVudHJpZXNDb3VudCA9IGVudHJpZXNDb3VudDtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHppcEZpbGVXb3JrZXIuZXJyb3IoZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHppcEZpbGVXb3JrZXI7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIFJlcHJlc2VudGF0aW9uIGEgb2YgemlwIGZpbGUgaW4ganNcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBKU1ppcCgpIHtcbiAgICAvLyBpZiB0aGlzIGNvbnN0cnVjdG9yIGlzwqB1c2VkIHdpdGhvdXTCoGBuZXdgLCBpdMKgYWRkcyBgbmV3YCBiZWZvcmXCoGl0c2VsZjpcbiAgICBpZighKHRoaXMgaW5zdGFuY2VvZiBKU1ppcCkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBKU1ppcCgpO1xuICAgIH1cblxuICAgIGlmKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIGNvbnN0cnVjdG9yIHdpdGggcGFyYW1ldGVycyBoYXMgYmVlbiByZW1vdmVkIGluIEpTWmlwIDMuMCwgcGxlYXNlIGNoZWNrIHRoZSB1cGdyYWRlIGd1aWRlLlwiKTtcbiAgICB9XG5cbiAgICAvLyBvYmplY3QgY29udGFpbmluZyB0aGUgZmlsZXMgOlxuICAgIC8vIHtcbiAgICAvLyAgIFwiZm9sZGVyL1wiIDogey4uLn0sXG4gICAgLy8gICBcImZvbGRlci9kYXRhLnR4dFwiIDogey4uLn1cbiAgICAvLyB9XG4gICAgdGhpcy5maWxlcyA9IHt9O1xuXG4gICAgdGhpcy5jb21tZW50ID0gbnVsbDtcblxuICAgIC8vIFdoZXJlIHdlIGFyZSBpbiB0aGUgaGllcmFyY2h5XG4gICAgdGhpcy5yb290ID0gXCJcIjtcbiAgICB0aGlzLmNsb25lID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBuZXdPYmogPSBuZXcgSlNaaXAoKTtcbiAgICAgICAgZm9yICh2YXIgaSBpbiB0aGlzKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXNbaV0gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgIG5ld09ialtpXSA9IHRoaXNbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ld09iajtcbiAgICB9O1xufVxuSlNaaXAucHJvdG90eXBlID0gcmVxdWlyZSgnLi9vYmplY3QnKTtcbkpTWmlwLnByb3RvdHlwZS5sb2FkQXN5bmMgPSByZXF1aXJlKCcuL2xvYWQnKTtcbkpTWmlwLnN1cHBvcnQgPSByZXF1aXJlKCcuL3N1cHBvcnQnKTtcbkpTWmlwLmRlZmF1bHRzID0gcmVxdWlyZSgnLi9kZWZhdWx0cycpO1xuXG4vLyBUT0RPIGZpbmQgYSBiZXR0ZXIgd2F5IHRvIGhhbmRsZSB0aGlzIHZlcnNpb24sXG4vLyBhIHJlcXVpcmUoJ3BhY2thZ2UuanNvbicpLnZlcnNpb24gZG9lc24ndCB3b3JrIHdpdGggd2VicGFjaywgc2VlICMzMjdcbkpTWmlwLnZlcnNpb24gPSBcIjMuMS41XCI7XG5cbkpTWmlwLmxvYWRBc3luYyA9IGZ1bmN0aW9uIChjb250ZW50LCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIG5ldyBKU1ppcCgpLmxvYWRBc3luYyhjb250ZW50LCBvcHRpb25zKTtcbn07XG5cbkpTWmlwLmV4dGVybmFsID0gcmVxdWlyZShcIi4vZXh0ZXJuYWxcIik7XG5tb2R1bGUuZXhwb3J0cyA9IEpTWmlwO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIGV4dGVybmFsID0gcmVxdWlyZShcIi4vZXh0ZXJuYWxcIik7XG52YXIgdXRmOCA9IHJlcXVpcmUoJy4vdXRmOCcpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIFppcEVudHJpZXMgPSByZXF1aXJlKCcuL3ppcEVudHJpZXMnKTtcbnZhciBDcmMzMlByb2JlID0gcmVxdWlyZSgnLi9zdHJlYW0vQ3JjMzJQcm9iZScpO1xudmFyIG5vZGVqc1V0aWxzID0gcmVxdWlyZShcIi4vbm9kZWpzVXRpbHNcIik7XG5cbi8qKlxuICogQ2hlY2sgdGhlIENSQzMyIG9mIGFuIGVudHJ5LlxuICogQHBhcmFtIHtaaXBFbnRyeX0gemlwRW50cnkgdGhlIHppcCBlbnRyeSB0byBjaGVjay5cbiAqIEByZXR1cm4ge1Byb21pc2V9IHRoZSByZXN1bHQuXG4gKi9cbmZ1bmN0aW9uIGNoZWNrRW50cnlDUkMzMih6aXBFbnRyeSkge1xuICAgIHJldHVybiBuZXcgZXh0ZXJuYWwuUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHZhciB3b3JrZXIgPSB6aXBFbnRyeS5kZWNvbXByZXNzZWQuZ2V0Q29udGVudFdvcmtlcigpLnBpcGUobmV3IENyYzMyUHJvYmUoKSk7XG4gICAgICAgIHdvcmtlci5vbihcImVycm9yXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICByZWplY3QoZSk7XG4gICAgICAgIH0pXG4gICAgICAgIC5vbihcImVuZFwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAod29ya2VyLnN0cmVhbUluZm8uY3JjMzIgIT09IHppcEVudHJ5LmRlY29tcHJlc3NlZC5jcmMzMikge1xuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoXCJDb3JydXB0ZWQgemlwIDogQ1JDMzIgbWlzbWF0Y2hcIikpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXN1bWUoKTtcbiAgICB9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihkYXRhLCBvcHRpb25zKSB7XG4gICAgdmFyIHppcCA9IHRoaXM7XG4gICAgb3B0aW9ucyA9IHV0aWxzLmV4dGVuZChvcHRpb25zIHx8IHt9LCB7XG4gICAgICAgIGJhc2U2NDogZmFsc2UsXG4gICAgICAgIGNoZWNrQ1JDMzI6IGZhbHNlLFxuICAgICAgICBvcHRpbWl6ZWRCaW5hcnlTdHJpbmc6IGZhbHNlLFxuICAgICAgICBjcmVhdGVGb2xkZXJzOiBmYWxzZSxcbiAgICAgICAgZGVjb2RlRmlsZU5hbWU6IHV0ZjgudXRmOGRlY29kZVxuICAgIH0pO1xuXG4gICAgaWYgKG5vZGVqc1V0aWxzLmlzTm9kZSAmJiBub2RlanNVdGlscy5pc1N0cmVhbShkYXRhKSkge1xuICAgICAgICByZXR1cm4gZXh0ZXJuYWwuUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiSlNaaXAgY2FuJ3QgYWNjZXB0IGEgc3RyZWFtIHdoZW4gbG9hZGluZyBhIHppcCBmaWxlLlwiKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHV0aWxzLnByZXBhcmVDb250ZW50KFwidGhlIGxvYWRlZCB6aXAgZmlsZVwiLCBkYXRhLCB0cnVlLCBvcHRpb25zLm9wdGltaXplZEJpbmFyeVN0cmluZywgb3B0aW9ucy5iYXNlNjQpXG4gICAgLnRoZW4oZnVuY3Rpb24oZGF0YSkge1xuICAgICAgICB2YXIgemlwRW50cmllcyA9IG5ldyBaaXBFbnRyaWVzKG9wdGlvbnMpO1xuICAgICAgICB6aXBFbnRyaWVzLmxvYWQoZGF0YSk7XG4gICAgICAgIHJldHVybiB6aXBFbnRyaWVzO1xuICAgIH0pLnRoZW4oZnVuY3Rpb24gY2hlY2tDUkMzMih6aXBFbnRyaWVzKSB7XG4gICAgICAgIHZhciBwcm9taXNlcyA9IFtleHRlcm5hbC5Qcm9taXNlLnJlc29sdmUoemlwRW50cmllcyldO1xuICAgICAgICB2YXIgZmlsZXMgPSB6aXBFbnRyaWVzLmZpbGVzO1xuICAgICAgICBpZiAob3B0aW9ucy5jaGVja0NSQzMyKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZpbGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChjaGVja0VudHJ5Q1JDMzIoZmlsZXNbaV0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZXh0ZXJuYWwuUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICAgIH0pLnRoZW4oZnVuY3Rpb24gYWRkRmlsZXMocmVzdWx0cykge1xuICAgICAgICB2YXIgemlwRW50cmllcyA9IHJlc3VsdHMuc2hpZnQoKTtcbiAgICAgICAgdmFyIGZpbGVzID0gemlwRW50cmllcy5maWxlcztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaWxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGlucHV0ID0gZmlsZXNbaV07XG4gICAgICAgICAgICB6aXAuZmlsZShpbnB1dC5maWxlTmFtZVN0ciwgaW5wdXQuZGVjb21wcmVzc2VkLCB7XG4gICAgICAgICAgICAgICAgYmluYXJ5OiB0cnVlLFxuICAgICAgICAgICAgICAgIG9wdGltaXplZEJpbmFyeVN0cmluZzogdHJ1ZSxcbiAgICAgICAgICAgICAgICBkYXRlOiBpbnB1dC5kYXRlLFxuICAgICAgICAgICAgICAgIGRpcjogaW5wdXQuZGlyLFxuICAgICAgICAgICAgICAgIGNvbW1lbnQgOiBpbnB1dC5maWxlQ29tbWVudFN0ci5sZW5ndGggPyBpbnB1dC5maWxlQ29tbWVudFN0ciA6IG51bGwsXG4gICAgICAgICAgICAgICAgdW5peFBlcm1pc3Npb25zIDogaW5wdXQudW5peFBlcm1pc3Npb25zLFxuICAgICAgICAgICAgICAgIGRvc1Blcm1pc3Npb25zIDogaW5wdXQuZG9zUGVybWlzc2lvbnMsXG4gICAgICAgICAgICAgICAgY3JlYXRlRm9sZGVyczogb3B0aW9ucy5jcmVhdGVGb2xkZXJzXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoemlwRW50cmllcy56aXBDb21tZW50Lmxlbmd0aCkge1xuICAgICAgICAgICAgemlwLmNvbW1lbnQgPSB6aXBFbnRyaWVzLnppcENvbW1lbnQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gemlwO1xuICAgIH0pO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgLyoqXG4gICAgICogVHJ1ZSBpZiB0aGlzIGlzIHJ1bm5pbmcgaW4gTm9kZWpzLCB3aWxsIGJlIHVuZGVmaW5lZCBpbiBhIGJyb3dzZXIuXG4gICAgICogSW4gYSBicm93c2VyLCBicm93c2VyaWZ5IHdvbid0IGluY2x1ZGUgdGhpcyBmaWxlIGFuZCB0aGUgd2hvbGUgbW9kdWxlXG4gICAgICogd2lsbCBiZSByZXNvbHZlZCBhbiBlbXB0eSBvYmplY3QuXG4gICAgICovXG4gICAgaXNOb2RlIDogdHlwZW9mIEJ1ZmZlciAhPT0gXCJ1bmRlZmluZWRcIixcbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgbm9kZWpzIEJ1ZmZlciBmcm9tIGFuIGV4aXN0aW5nIGNvbnRlbnQuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGRhdGEgdGhlIGRhdGEgdG8gcGFzcyB0byB0aGUgY29uc3RydWN0b3IuXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGVuY29kaW5nIHRoZSBlbmNvZGluZyB0byB1c2UuXG4gICAgICogQHJldHVybiB7QnVmZmVyfSBhIG5ldyBCdWZmZXIuXG4gICAgICovXG4gICAgbmV3QnVmZmVyRnJvbTogZnVuY3Rpb24oZGF0YSwgZW5jb2RpbmcpIHtcbiAgICAgICAgLy8gWFhYIFdlIGNhbid0IHVzZSBgQnVmZmVyLmZyb21gIHdoaWNoIGNvbWVzIGZyb20gYFVpbnQ4QXJyYXkuZnJvbWBcbiAgICAgICAgLy8gaW4gbm9kZWpzIHY0ICg8IHYuNC41KS4gSXQncyBub3QgdGhlIGV4cGVjdGVkIGltcGxlbWVudGF0aW9uIChhbmRcbiAgICAgICAgLy8gaGFzIGEgZGlmZmVyZW50IHNpZ25hdHVyZSkuXG4gICAgICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vbm9kZWpzL25vZGUvaXNzdWVzLzgwNTNcbiAgICAgICAgLy8gQSBjb25kaXRpb24gb24gbm9kZWpzJyB2ZXJzaW9uIHdvbid0IHNvbHZlIHRoZSBpc3N1ZSBhcyB3ZSBkb24ndFxuICAgICAgICAvLyBjb250cm9sIHRoZSBCdWZmZXIgcG9seWZpbGxzIHRoYXQgbWF5IG9yIG1heSBub3QgYmUgdXNlZC5cbiAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXIoZGF0YSwgZW5jb2RpbmcpO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IG5vZGVqcyBCdWZmZXIgd2l0aCB0aGUgc3BlY2lmaWVkIHNpemUuXG4gICAgICogQHBhcmFtIHtJbnRlZ2VyfSBzaXplIHRoZSBzaXplIG9mIHRoZSBidWZmZXIuXG4gICAgICogQHJldHVybiB7QnVmZmVyfSBhIG5ldyBCdWZmZXIuXG4gICAgICovXG4gICAgYWxsb2NCdWZmZXI6IGZ1bmN0aW9uIChzaXplKSB7XG4gICAgICAgIGlmIChCdWZmZXIuYWxsb2MpIHtcbiAgICAgICAgICAgIHJldHVybiBCdWZmZXIuYWxsb2Moc2l6ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEJ1ZmZlcihzaXplKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogRmluZCBvdXQgaWYgYW4gb2JqZWN0IGlzIGEgQnVmZmVyLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBiIHRoZSBvYmplY3QgdG8gdGVzdC5cbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufSB0cnVlIGlmIHRoZSBvYmplY3QgaXMgYSBCdWZmZXIsIGZhbHNlIG90aGVyd2lzZS5cbiAgICAgKi9cbiAgICBpc0J1ZmZlciA6IGZ1bmN0aW9uKGIpe1xuICAgICAgICByZXR1cm4gQnVmZmVyLmlzQnVmZmVyKGIpO1xuICAgIH0sXG5cbiAgICBpc1N0cmVhbSA6IGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgcmV0dXJuIG9iaiAmJlxuICAgICAgICAgICAgdHlwZW9mIG9iai5vbiA9PT0gXCJmdW5jdGlvblwiICYmXG4gICAgICAgICAgICB0eXBlb2Ygb2JqLnBhdXNlID09PSBcImZ1bmN0aW9uXCIgJiZcbiAgICAgICAgICAgIHR5cGVvZiBvYmoucmVzdW1lID09PSBcImZ1bmN0aW9uXCI7XG4gICAgfVxufTtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIEdlbmVyaWNXb3JrZXIgPSByZXF1aXJlKCcuLi9zdHJlYW0vR2VuZXJpY1dvcmtlcicpO1xuXG4vKipcbiAqIEEgd29ya2VyIHRoYXQgdXNlIGEgbm9kZWpzIHN0cmVhbSBhcyBzb3VyY2UuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7U3RyaW5nfSBmaWxlbmFtZSB0aGUgbmFtZSBvZiB0aGUgZmlsZSBlbnRyeSBmb3IgdGhpcyBzdHJlYW0uXG4gKiBAcGFyYW0ge1JlYWRhYmxlfSBzdHJlYW0gdGhlIG5vZGVqcyBzdHJlYW0uXG4gKi9cbmZ1bmN0aW9uIE5vZGVqc1N0cmVhbUlucHV0QWRhcHRlcihmaWxlbmFtZSwgc3RyZWFtKSB7XG4gICAgR2VuZXJpY1dvcmtlci5jYWxsKHRoaXMsIFwiTm9kZWpzIHN0cmVhbSBpbnB1dCBhZGFwdGVyIGZvciBcIiArIGZpbGVuYW1lKTtcbiAgICB0aGlzLl91cHN0cmVhbUVuZGVkID0gZmFsc2U7XG4gICAgdGhpcy5fYmluZFN0cmVhbShzdHJlYW0pO1xufVxuXG51dGlscy5pbmhlcml0cyhOb2RlanNTdHJlYW1JbnB1dEFkYXB0ZXIsIEdlbmVyaWNXb3JrZXIpO1xuXG4vKipcbiAqIFByZXBhcmUgdGhlIHN0cmVhbSBhbmQgYmluZCB0aGUgY2FsbGJhY2tzIG9uIGl0LlxuICogRG8gdGhpcyBBU0FQIG9uIG5vZGUgMC4xMCAhIEEgbGF6eSBiaW5kaW5nIGRvZXNuJ3QgYWx3YXlzIHdvcmsuXG4gKiBAcGFyYW0ge1N0cmVhbX0gc3RyZWFtIHRoZSBub2RlanMgc3RyZWFtIHRvIHVzZS5cbiAqL1xuTm9kZWpzU3RyZWFtSW5wdXRBZGFwdGVyLnByb3RvdHlwZS5fYmluZFN0cmVhbSA9IGZ1bmN0aW9uIChzdHJlYW0pIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy5fc3RyZWFtID0gc3RyZWFtO1xuICAgIHN0cmVhbS5wYXVzZSgpO1xuICAgIHN0cmVhbVxuICAgIC5vbihcImRhdGFcIiwgZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgICAgIHNlbGYucHVzaCh7XG4gICAgICAgICAgICBkYXRhOiBjaHVuayxcbiAgICAgICAgICAgIG1ldGEgOiB7XG4gICAgICAgICAgICAgICAgcGVyY2VudCA6IDBcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSlcbiAgICAub24oXCJlcnJvclwiLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICBpZihzZWxmLmlzUGF1c2VkKSB7XG4gICAgICAgICAgICB0aGlzLmdlbmVyYXRlZEVycm9yID0gZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNlbGYuZXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICB9KVxuICAgIC5vbihcImVuZFwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmKHNlbGYuaXNQYXVzZWQpIHtcbiAgICAgICAgICAgIHNlbGYuX3Vwc3RyZWFtRW5kZWQgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZi5lbmQoKTtcbiAgICAgICAgfVxuICAgIH0pO1xufTtcbk5vZGVqc1N0cmVhbUlucHV0QWRhcHRlci5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYoIUdlbmVyaWNXb3JrZXIucHJvdG90eXBlLnBhdXNlLmNhbGwodGhpcykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0aGlzLl9zdHJlYW0ucGF1c2UoKTtcbiAgICByZXR1cm4gdHJ1ZTtcbn07XG5Ob2RlanNTdHJlYW1JbnB1dEFkYXB0ZXIucHJvdG90eXBlLnJlc3VtZSA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZighR2VuZXJpY1dvcmtlci5wcm90b3R5cGUucmVzdW1lLmNhbGwodGhpcykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmKHRoaXMuX3Vwc3RyZWFtRW5kZWQpIHtcbiAgICAgICAgdGhpcy5lbmQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9zdHJlYW0ucmVzdW1lKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE5vZGVqc1N0cmVhbUlucHV0QWRhcHRlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFJlYWRhYmxlID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtJykuUmVhZGFibGU7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG51dGlscy5pbmhlcml0cyhOb2RlanNTdHJlYW1PdXRwdXRBZGFwdGVyLCBSZWFkYWJsZSk7XG5cbi8qKlxuKiBBIG5vZGVqcyBzdHJlYW0gdXNpbmcgYSB3b3JrZXIgYXMgc291cmNlLlxuKiBAc2VlIHRoZSBTb3VyY2VXcmFwcGVyIGluIGh0dHA6Ly9ub2RlanMub3JnL2FwaS9zdHJlYW0uaHRtbFxuKiBAY29uc3RydWN0b3JcbiogQHBhcmFtIHtTdHJlYW1IZWxwZXJ9IGhlbHBlciB0aGUgaGVscGVyIHdyYXBwaW5nIHRoZSB3b3JrZXJcbiogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgdGhlIG5vZGVqcyBzdHJlYW0gb3B0aW9uc1xuKiBAcGFyYW0ge0Z1bmN0aW9ufSB1cGRhdGVDYiB0aGUgdXBkYXRlIGNhbGxiYWNrLlxuKi9cbmZ1bmN0aW9uIE5vZGVqc1N0cmVhbU91dHB1dEFkYXB0ZXIoaGVscGVyLCBvcHRpb25zLCB1cGRhdGVDYikge1xuICAgIFJlYWRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG4gICAgdGhpcy5faGVscGVyID0gaGVscGVyO1xuXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIGhlbHBlci5vbihcImRhdGFcIiwgZnVuY3Rpb24gKGRhdGEsIG1ldGEpIHtcbiAgICAgICAgaWYgKCFzZWxmLnB1c2goZGF0YSkpIHtcbiAgICAgICAgICAgIHNlbGYuX2hlbHBlci5wYXVzZSgpO1xuICAgICAgICB9XG4gICAgICAgIGlmKHVwZGF0ZUNiKSB7XG4gICAgICAgICAgICB1cGRhdGVDYihtZXRhKTtcbiAgICAgICAgfVxuICAgIH0pXG4gICAgLm9uKFwiZXJyb3JcIiwgZnVuY3Rpb24oZSkge1xuICAgICAgICBzZWxmLmVtaXQoJ2Vycm9yJywgZSk7XG4gICAgfSlcbiAgICAub24oXCJlbmRcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLnB1c2gobnVsbCk7XG4gICAgfSk7XG59XG5cblxuTm9kZWpzU3RyZWFtT3V0cHV0QWRhcHRlci5wcm90b3R5cGUuX3JlYWQgPSBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9oZWxwZXIucmVzdW1lKCk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE5vZGVqc1N0cmVhbU91dHB1dEFkYXB0ZXI7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgdXRmOCA9IHJlcXVpcmUoJy4vdXRmOCcpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIEdlbmVyaWNXb3JrZXIgPSByZXF1aXJlKCcuL3N0cmVhbS9HZW5lcmljV29ya2VyJyk7XG52YXIgU3RyZWFtSGVscGVyID0gcmVxdWlyZSgnLi9zdHJlYW0vU3RyZWFtSGVscGVyJyk7XG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuL2RlZmF1bHRzJyk7XG52YXIgQ29tcHJlc3NlZE9iamVjdCA9IHJlcXVpcmUoJy4vY29tcHJlc3NlZE9iamVjdCcpO1xudmFyIFppcE9iamVjdCA9IHJlcXVpcmUoJy4vemlwT2JqZWN0Jyk7XG52YXIgZ2VuZXJhdGUgPSByZXF1aXJlKFwiLi9nZW5lcmF0ZVwiKTtcbnZhciBub2RlanNVdGlscyA9IHJlcXVpcmUoXCIuL25vZGVqc1V0aWxzXCIpO1xudmFyIE5vZGVqc1N0cmVhbUlucHV0QWRhcHRlciA9IHJlcXVpcmUoXCIuL25vZGVqcy9Ob2RlanNTdHJlYW1JbnB1dEFkYXB0ZXJcIik7XG5cblxuLyoqXG4gKiBBZGQgYSBmaWxlIGluIHRoZSBjdXJyZW50IGZvbGRlci5cbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSB0aGUgbmFtZSBvZiB0aGUgZmlsZVxuICogQHBhcmFtIHtTdHJpbmd8QXJyYXlCdWZmZXJ8VWludDhBcnJheXxCdWZmZXJ9IGRhdGEgdGhlIGRhdGEgb2YgdGhlIGZpbGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcmlnaW5hbE9wdGlvbnMgdGhlIG9wdGlvbnMgb2YgdGhlIGZpbGVcbiAqIEByZXR1cm4ge09iamVjdH0gdGhlIG5ldyBmaWxlLlxuICovXG52YXIgZmlsZUFkZCA9IGZ1bmN0aW9uKG5hbWUsIGRhdGEsIG9yaWdpbmFsT3B0aW9ucykge1xuICAgIC8vIGJlIHN1cmUgc3ViIGZvbGRlcnMgZXhpc3RcbiAgICB2YXIgZGF0YVR5cGUgPSB1dGlscy5nZXRUeXBlT2YoZGF0YSksXG4gICAgICAgIHBhcmVudDtcblxuXG4gICAgLypcbiAgICAgKiBDb3JyZWN0IG9wdGlvbnMuXG4gICAgICovXG5cbiAgICB2YXIgbyA9IHV0aWxzLmV4dGVuZChvcmlnaW5hbE9wdGlvbnMgfHwge30sIGRlZmF1bHRzKTtcbiAgICBvLmRhdGUgPSBvLmRhdGUgfHwgbmV3IERhdGUoKTtcbiAgICBpZiAoby5jb21wcmVzc2lvbiAhPT0gbnVsbCkge1xuICAgICAgICBvLmNvbXByZXNzaW9uID0gby5jb21wcmVzc2lvbi50b1VwcGVyQ2FzZSgpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygby51bml4UGVybWlzc2lvbnMgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgby51bml4UGVybWlzc2lvbnMgPSBwYXJzZUludChvLnVuaXhQZXJtaXNzaW9ucywgOCk7XG4gICAgfVxuXG4gICAgLy8gVU5YX0lGRElSICAwMDQwMDAwIHNlZSB6aXBpbmZvLmNcbiAgICBpZiAoby51bml4UGVybWlzc2lvbnMgJiYgKG8udW5peFBlcm1pc3Npb25zICYgMHg0MDAwKSkge1xuICAgICAgICBvLmRpciA9IHRydWU7XG4gICAgfVxuICAgIC8vIEJpdCA0ICAgIERpcmVjdG9yeVxuICAgIGlmIChvLmRvc1Blcm1pc3Npb25zICYmIChvLmRvc1Blcm1pc3Npb25zICYgMHgwMDEwKSkge1xuICAgICAgICBvLmRpciA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKG8uZGlyKSB7XG4gICAgICAgIG5hbWUgPSBmb3JjZVRyYWlsaW5nU2xhc2gobmFtZSk7XG4gICAgfVxuICAgIGlmIChvLmNyZWF0ZUZvbGRlcnMgJiYgKHBhcmVudCA9IHBhcmVudEZvbGRlcihuYW1lKSkpIHtcbiAgICAgICAgZm9sZGVyQWRkLmNhbGwodGhpcywgcGFyZW50LCB0cnVlKTtcbiAgICB9XG5cbiAgICB2YXIgaXNVbmljb2RlU3RyaW5nID0gZGF0YVR5cGUgPT09IFwic3RyaW5nXCIgJiYgby5iaW5hcnkgPT09IGZhbHNlICYmIG8uYmFzZTY0ID09PSBmYWxzZTtcbiAgICBpZiAoIW9yaWdpbmFsT3B0aW9ucyB8fCB0eXBlb2Ygb3JpZ2luYWxPcHRpb25zLmJpbmFyeSA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICBvLmJpbmFyeSA9ICFpc1VuaWNvZGVTdHJpbmc7XG4gICAgfVxuXG5cbiAgICB2YXIgaXNDb21wcmVzc2VkRW1wdHkgPSAoZGF0YSBpbnN0YW5jZW9mIENvbXByZXNzZWRPYmplY3QpICYmIGRhdGEudW5jb21wcmVzc2VkU2l6ZSA9PT0gMDtcblxuICAgIGlmIChpc0NvbXByZXNzZWRFbXB0eSB8fCBvLmRpciB8fCAhZGF0YSB8fCBkYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBvLmJhc2U2NCA9IGZhbHNlO1xuICAgICAgICBvLmJpbmFyeSA9IHRydWU7XG4gICAgICAgIGRhdGEgPSBcIlwiO1xuICAgICAgICBvLmNvbXByZXNzaW9uID0gXCJTVE9SRVwiO1xuICAgICAgICBkYXRhVHlwZSA9IFwic3RyaW5nXCI7XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBDb252ZXJ0IGNvbnRlbnQgdG8gZml0LlxuICAgICAqL1xuXG4gICAgdmFyIHppcE9iamVjdENvbnRlbnQgPSBudWxsO1xuICAgIGlmIChkYXRhIGluc3RhbmNlb2YgQ29tcHJlc3NlZE9iamVjdCB8fCBkYXRhIGluc3RhbmNlb2YgR2VuZXJpY1dvcmtlcikge1xuICAgICAgICB6aXBPYmplY3RDb250ZW50ID0gZGF0YTtcbiAgICB9IGVsc2UgaWYgKG5vZGVqc1V0aWxzLmlzTm9kZSAmJiBub2RlanNVdGlscy5pc1N0cmVhbShkYXRhKSkge1xuICAgICAgICB6aXBPYmplY3RDb250ZW50ID0gbmV3IE5vZGVqc1N0cmVhbUlucHV0QWRhcHRlcihuYW1lLCBkYXRhKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB6aXBPYmplY3RDb250ZW50ID0gdXRpbHMucHJlcGFyZUNvbnRlbnQobmFtZSwgZGF0YSwgby5iaW5hcnksIG8ub3B0aW1pemVkQmluYXJ5U3RyaW5nLCBvLmJhc2U2NCk7XG4gICAgfVxuXG4gICAgdmFyIG9iamVjdCA9IG5ldyBaaXBPYmplY3QobmFtZSwgemlwT2JqZWN0Q29udGVudCwgbyk7XG4gICAgdGhpcy5maWxlc1tuYW1lXSA9IG9iamVjdDtcbiAgICAvKlxuICAgIFRPRE86IHdlIGNhbid0IHRocm93IGFuIGV4Y2VwdGlvbiBiZWNhdXNlIHdlIGhhdmUgYXN5bmMgcHJvbWlzZXNcbiAgICAod2UgY2FuIGhhdmUgYSBwcm9taXNlIG9mIGEgRGF0ZSgpIGZvciBleGFtcGxlKSBidXQgcmV0dXJuaW5nIGFcbiAgICBwcm9taXNlIGlzIHVzZWxlc3MgYmVjYXVzZSBmaWxlKG5hbWUsIGRhdGEpIHJldHVybnMgdGhlIEpTWmlwXG4gICAgb2JqZWN0IGZvciBjaGFpbmluZy4gU2hvdWxkIHdlIGJyZWFrIHRoYXQgdG8gYWxsb3cgdGhlIHVzZXJcbiAgICB0byBjYXRjaCB0aGUgZXJyb3IgP1xuXG4gICAgcmV0dXJuIGV4dGVybmFsLlByb21pc2UucmVzb2x2ZSh6aXBPYmplY3RDb250ZW50KVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9KTtcbiAgICAqL1xufTtcblxuLyoqXG4gKiBGaW5kIHRoZSBwYXJlbnQgZm9sZGVyIG9mIHRoZSBwYXRoLlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIHRoZSBwYXRoIHRvIHVzZVxuICogQHJldHVybiB7c3RyaW5nfSB0aGUgcGFyZW50IGZvbGRlciwgb3IgXCJcIlxuICovXG52YXIgcGFyZW50Rm9sZGVyID0gZnVuY3Rpb24gKHBhdGgpIHtcbiAgICBpZiAocGF0aC5zbGljZSgtMSkgPT09ICcvJykge1xuICAgICAgICBwYXRoID0gcGF0aC5zdWJzdHJpbmcoMCwgcGF0aC5sZW5ndGggLSAxKTtcbiAgICB9XG4gICAgdmFyIGxhc3RTbGFzaCA9IHBhdGgubGFzdEluZGV4T2YoJy8nKTtcbiAgICByZXR1cm4gKGxhc3RTbGFzaCA+IDApID8gcGF0aC5zdWJzdHJpbmcoMCwgbGFzdFNsYXNoKSA6IFwiXCI7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIHBhdGggd2l0aCBhIHNsYXNoIGF0IHRoZSBlbmQuXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtTdHJpbmd9IHBhdGggdGhlIHBhdGggdG8gY2hlY2suXG4gKiBAcmV0dXJuIHtTdHJpbmd9IHRoZSBwYXRoIHdpdGggYSB0cmFpbGluZyBzbGFzaC5cbiAqL1xudmFyIGZvcmNlVHJhaWxpbmdTbGFzaCA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgICAvLyBDaGVjayB0aGUgbmFtZSBlbmRzIHdpdGggYSAvXG4gICAgaWYgKHBhdGguc2xpY2UoLTEpICE9PSBcIi9cIikge1xuICAgICAgICBwYXRoICs9IFwiL1wiOyAvLyBJRSBkb2Vzbid0IGxpa2Ugc3Vic3RyKC0xKVxuICAgIH1cbiAgICByZXR1cm4gcGF0aDtcbn07XG5cbi8qKlxuICogQWRkIGEgKHN1YikgZm9sZGVyIGluIHRoZSBjdXJyZW50IGZvbGRlci5cbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSB0aGUgZm9sZGVyJ3MgbmFtZVxuICogQHBhcmFtIHtib29sZWFuPX0gW2NyZWF0ZUZvbGRlcnNdIElmIHRydWUsIGF1dG9tYXRpY2FsbHkgY3JlYXRlIHN1YlxuICogIGZvbGRlcnMuIERlZmF1bHRzIHRvIGZhbHNlLlxuICogQHJldHVybiB7T2JqZWN0fSB0aGUgbmV3IGZvbGRlci5cbiAqL1xudmFyIGZvbGRlckFkZCA9IGZ1bmN0aW9uKG5hbWUsIGNyZWF0ZUZvbGRlcnMpIHtcbiAgICBjcmVhdGVGb2xkZXJzID0gKHR5cGVvZiBjcmVhdGVGb2xkZXJzICE9PSAndW5kZWZpbmVkJykgPyBjcmVhdGVGb2xkZXJzIDogZGVmYXVsdHMuY3JlYXRlRm9sZGVycztcblxuICAgIG5hbWUgPSBmb3JjZVRyYWlsaW5nU2xhc2gobmFtZSk7XG5cbiAgICAvLyBEb2VzIHRoaXMgZm9sZGVyIGFscmVhZHkgZXhpc3Q/XG4gICAgaWYgKCF0aGlzLmZpbGVzW25hbWVdKSB7XG4gICAgICAgIGZpbGVBZGQuY2FsbCh0aGlzLCBuYW1lLCBudWxsLCB7XG4gICAgICAgICAgICBkaXI6IHRydWUsXG4gICAgICAgICAgICBjcmVhdGVGb2xkZXJzOiBjcmVhdGVGb2xkZXJzXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5maWxlc1tuYW1lXTtcbn07XG5cbi8qKlxuKiBDcm9zcy13aW5kb3csIGNyb3NzLU5vZGUtY29udGV4dCByZWd1bGFyIGV4cHJlc3Npb24gZGV0ZWN0aW9uXG4qIEBwYXJhbSAge09iamVjdH0gIG9iamVjdCBBbnl0aGluZ1xuKiBAcmV0dXJuIHtCb29sZWFufSAgICAgICAgdHJ1ZSBpZiB0aGUgb2JqZWN0IGlzIGEgcmVndWxhciBleHByZXNzaW9uLFxuKiBmYWxzZSBvdGhlcndpc2VcbiovXG5mdW5jdGlvbiBpc1JlZ0V4cChvYmplY3QpIHtcbiAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT09IFwiW29iamVjdCBSZWdFeHBdXCI7XG59XG5cbi8vIHJldHVybiB0aGUgYWN0dWFsIHByb3RvdHlwZSBvZiBKU1ppcFxudmFyIG91dCA9IHtcbiAgICAvKipcbiAgICAgKiBAc2VlIGxvYWRBc3luY1xuICAgICAqL1xuICAgIGxvYWQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIG1ldGhvZCBoYXMgYmVlbiByZW1vdmVkIGluIEpTWmlwIDMuMCwgcGxlYXNlIGNoZWNrIHRoZSB1cGdyYWRlIGd1aWRlLlwiKTtcbiAgICB9LFxuXG5cbiAgICAvKipcbiAgICAgKiBDYWxsIGEgY2FsbGJhY2sgZnVuY3Rpb24gZm9yIGVhY2ggZW50cnkgYXQgdGhpcyBmb2xkZXIgbGV2ZWwuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2IgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uOlxuICAgICAqIGZ1bmN0aW9uIChyZWxhdGl2ZVBhdGgsIGZpbGUpIHsuLi59XG4gICAgICogSXQgdGFrZXMgMiBhcmd1bWVudHMgOiB0aGUgcmVsYXRpdmUgcGF0aCBhbmQgdGhlIGZpbGUuXG4gICAgICovXG4gICAgZm9yRWFjaDogZnVuY3Rpb24oY2IpIHtcbiAgICAgICAgdmFyIGZpbGVuYW1lLCByZWxhdGl2ZVBhdGgsIGZpbGU7XG4gICAgICAgIGZvciAoZmlsZW5hbWUgaW4gdGhpcy5maWxlcykge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmZpbGVzLmhhc093blByb3BlcnR5KGZpbGVuYW1lKSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZmlsZSA9IHRoaXMuZmlsZXNbZmlsZW5hbWVdO1xuICAgICAgICAgICAgcmVsYXRpdmVQYXRoID0gZmlsZW5hbWUuc2xpY2UodGhpcy5yb290Lmxlbmd0aCwgZmlsZW5hbWUubGVuZ3RoKTtcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZVBhdGggJiYgZmlsZW5hbWUuc2xpY2UoMCwgdGhpcy5yb290Lmxlbmd0aCkgPT09IHRoaXMucm9vdCkgeyAvLyB0aGUgZmlsZSBpcyBpbiB0aGUgY3VycmVudCByb290XG4gICAgICAgICAgICAgICAgY2IocmVsYXRpdmVQYXRoLCBmaWxlKTsgLy8gVE9ETyByZXZlcnNlIHRoZSBwYXJhbWV0ZXJzID8gbmVlZCB0byBiZSBjbGVhbiBBTkQgY29uc2lzdGVudCB3aXRoIHRoZSBmaWx0ZXIgc2VhcmNoIGZuLi4uXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogRmlsdGVyIG5lc3RlZCBmaWxlcy9mb2xkZXJzIHdpdGggdGhlIHNwZWNpZmllZCBmdW5jdGlvbi5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZWFyY2ggdGhlIHByZWRpY2F0ZSB0byB1c2UgOlxuICAgICAqIGZ1bmN0aW9uIChyZWxhdGl2ZVBhdGgsIGZpbGUpIHsuLi59XG4gICAgICogSXQgdGFrZXMgMiBhcmd1bWVudHMgOiB0aGUgcmVsYXRpdmUgcGF0aCBhbmQgdGhlIGZpbGUuXG4gICAgICogQHJldHVybiB7QXJyYXl9IEFuIGFycmF5IG9mIG1hdGNoaW5nIGVsZW1lbnRzLlxuICAgICAqL1xuICAgIGZpbHRlcjogZnVuY3Rpb24oc2VhcmNoKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uIChyZWxhdGl2ZVBhdGgsIGVudHJ5KSB7XG4gICAgICAgICAgICBpZiAoc2VhcmNoKHJlbGF0aXZlUGF0aCwgZW50cnkpKSB7IC8vIHRoZSBmaWxlIG1hdGNoZXMgdGhlIGZ1bmN0aW9uXG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goZW50cnkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBmaWxlIHRvIHRoZSB6aXAgZmlsZSwgb3Igc2VhcmNoIGEgZmlsZS5cbiAgICAgKiBAcGFyYW0gICB7c3RyaW5nfFJlZ0V4cH0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZmlsZSB0byBhZGQgKGlmIGRhdGEgaXMgZGVmaW5lZCksXG4gICAgICogdGhlIG5hbWUgb2YgdGhlIGZpbGUgdG8gZmluZCAoaWYgbm8gZGF0YSkgb3IgYSByZWdleCB0byBtYXRjaCBmaWxlcy5cbiAgICAgKiBAcGFyYW0gICB7U3RyaW5nfEFycmF5QnVmZmVyfFVpbnQ4QXJyYXl8QnVmZmVyfSBkYXRhICBUaGUgZmlsZSBkYXRhLCBlaXRoZXIgcmF3IG9yIGJhc2U2NCBlbmNvZGVkXG4gICAgICogQHBhcmFtICAge09iamVjdH0gbyAgICAgRmlsZSBvcHRpb25zXG4gICAgICogQHJldHVybiAge0pTWmlwfE9iamVjdHxBcnJheX0gdGhpcyBKU1ppcCBvYmplY3QgKHdoZW4gYWRkaW5nIGEgZmlsZSksXG4gICAgICogYSBmaWxlICh3aGVuIHNlYXJjaGluZyBieSBzdHJpbmcpIG9yIGFuIGFycmF5IG9mIGZpbGVzICh3aGVuIHNlYXJjaGluZyBieSByZWdleCkuXG4gICAgICovXG4gICAgZmlsZTogZnVuY3Rpb24obmFtZSwgZGF0YSwgbykge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgaWYgKGlzUmVnRXhwKG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlZ2V4cCA9IG5hbWU7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyKGZ1bmN0aW9uKHJlbGF0aXZlUGF0aCwgZmlsZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gIWZpbGUuZGlyICYmIHJlZ2V4cC50ZXN0KHJlbGF0aXZlUGF0aCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHsgLy8gdGV4dFxuICAgICAgICAgICAgICAgIHZhciBvYmogPSB0aGlzLmZpbGVzW3RoaXMucm9vdCArIG5hbWVdO1xuICAgICAgICAgICAgICAgIGlmIChvYmogJiYgIW9iai5kaXIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9iajtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7IC8vIG1vcmUgdGhhbiBvbmUgYXJndW1lbnQgOiB3ZSBoYXZlIGRhdGEgIVxuICAgICAgICAgICAgbmFtZSA9IHRoaXMucm9vdCArIG5hbWU7XG4gICAgICAgICAgICBmaWxlQWRkLmNhbGwodGhpcywgbmFtZSwgZGF0YSwgbyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEFkZCBhIGRpcmVjdG9yeSB0byB0aGUgemlwIGZpbGUsIG9yIHNlYXJjaC5cbiAgICAgKiBAcGFyYW0gICB7U3RyaW5nfFJlZ0V4cH0gYXJnIFRoZSBuYW1lIG9mIHRoZSBkaXJlY3RvcnkgdG8gYWRkLCBvciBhIHJlZ2V4IHRvIHNlYXJjaCBmb2xkZXJzLlxuICAgICAqIEByZXR1cm4gIHtKU1ppcH0gYW4gb2JqZWN0IHdpdGggdGhlIG5ldyBkaXJlY3RvcnkgYXMgdGhlIHJvb3QsIG9yIGFuIGFycmF5IGNvbnRhaW5pbmcgbWF0Y2hpbmcgZm9sZGVycy5cbiAgICAgKi9cbiAgICBmb2xkZXI6IGZ1bmN0aW9uKGFyZykge1xuICAgICAgICBpZiAoIWFyZykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNSZWdFeHAoYXJnKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyKGZ1bmN0aW9uKHJlbGF0aXZlUGF0aCwgZmlsZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmaWxlLmRpciAmJiBhcmcudGVzdChyZWxhdGl2ZVBhdGgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBlbHNlLCBuYW1lIGlzIGEgbmV3IGZvbGRlclxuICAgICAgICB2YXIgbmFtZSA9IHRoaXMucm9vdCArIGFyZztcbiAgICAgICAgdmFyIG5ld0ZvbGRlciA9IGZvbGRlckFkZC5jYWxsKHRoaXMsIG5hbWUpO1xuXG4gICAgICAgIC8vIEFsbG93IGNoYWluaW5nIGJ5IHJldHVybmluZyBhIG5ldyBvYmplY3Qgd2l0aCB0aGlzIGZvbGRlciBhcyB0aGUgcm9vdFxuICAgICAgICB2YXIgcmV0ID0gdGhpcy5jbG9uZSgpO1xuICAgICAgICByZXQucm9vdCA9IG5ld0ZvbGRlci5uYW1lO1xuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBEZWxldGUgYSBmaWxlLCBvciBhIGRpcmVjdG9yeSBhbmQgYWxsIHN1Yi1maWxlcywgZnJvbSB0aGUgemlwXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgdGhlIG5hbWUgb2YgdGhlIGZpbGUgdG8gZGVsZXRlXG4gICAgICogQHJldHVybiB7SlNaaXB9IHRoaXMgSlNaaXAgb2JqZWN0XG4gICAgICovXG4gICAgcmVtb3ZlOiBmdW5jdGlvbihuYW1lKSB7XG4gICAgICAgIG5hbWUgPSB0aGlzLnJvb3QgKyBuYW1lO1xuICAgICAgICB2YXIgZmlsZSA9IHRoaXMuZmlsZXNbbmFtZV07XG4gICAgICAgIGlmICghZmlsZSkge1xuICAgICAgICAgICAgLy8gTG9vayBmb3IgYW55IGZvbGRlcnNcbiAgICAgICAgICAgIGlmIChuYW1lLnNsaWNlKC0xKSAhPT0gXCIvXCIpIHtcbiAgICAgICAgICAgICAgICBuYW1lICs9IFwiL1wiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZmlsZSA9IHRoaXMuZmlsZXNbbmFtZV07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZmlsZSAmJiAhZmlsZS5kaXIpIHtcbiAgICAgICAgICAgIC8vIGZpbGVcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmZpbGVzW25hbWVdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gbWF5YmUgYSBmb2xkZXIsIGRlbGV0ZSByZWN1cnNpdmVseVxuICAgICAgICAgICAgdmFyIGtpZHMgPSB0aGlzLmZpbHRlcihmdW5jdGlvbihyZWxhdGl2ZVBhdGgsIGZpbGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmlsZS5uYW1lLnNsaWNlKDAsIG5hbWUubGVuZ3RoKSA9PT0gbmFtZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBraWRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlsZXNba2lkc1tpXS5uYW1lXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZW5lcmF0ZSB0aGUgY29tcGxldGUgemlwIGZpbGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyB0aGUgb3B0aW9ucyB0byBnZW5lcmF0ZSB0aGUgemlwIGZpbGUgOlxuICAgICAqIC0gY29tcHJlc3Npb24sIFwiU1RPUkVcIiBieSBkZWZhdWx0LlxuICAgICAqIC0gdHlwZSwgXCJiYXNlNjRcIiBieSBkZWZhdWx0LiBWYWx1ZXMgYXJlIDogc3RyaW5nLCBiYXNlNjQsIHVpbnQ4YXJyYXksIGFycmF5YnVmZmVyLCBibG9iLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ3xVaW50OEFycmF5fEFycmF5QnVmZmVyfEJ1ZmZlcnxCbG9ifSB0aGUgemlwIGZpbGVcbiAgICAgKi9cbiAgICBnZW5lcmF0ZTogZnVuY3Rpb24ob3B0aW9ucykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIG1ldGhvZCBoYXMgYmVlbiByZW1vdmVkIGluIEpTWmlwIDMuMCwgcGxlYXNlIGNoZWNrIHRoZSB1cGdyYWRlIGd1aWRlLlwiKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2VuZXJhdGUgdGhlIGNvbXBsZXRlIHppcCBmaWxlIGFzIGFuIGludGVybmFsIHN0cmVhbS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyB0aGUgb3B0aW9ucyB0byBnZW5lcmF0ZSB0aGUgemlwIGZpbGUgOlxuICAgICAqIC0gY29tcHJlc3Npb24sIFwiU1RPUkVcIiBieSBkZWZhdWx0LlxuICAgICAqIC0gdHlwZSwgXCJiYXNlNjRcIiBieSBkZWZhdWx0LiBWYWx1ZXMgYXJlIDogc3RyaW5nLCBiYXNlNjQsIHVpbnQ4YXJyYXksIGFycmF5YnVmZmVyLCBibG9iLlxuICAgICAqIEByZXR1cm4ge1N0cmVhbUhlbHBlcn0gdGhlIHN0cmVhbWVkIHppcCBmaWxlLlxuICAgICAqL1xuICAgIGdlbmVyYXRlSW50ZXJuYWxTdHJlYW06IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICAgIHZhciB3b3JrZXIsIG9wdHMgPSB7fTtcbiAgICAgIHRyeSB7XG4gICAgICAgICAgb3B0cyA9IHV0aWxzLmV4dGVuZChvcHRpb25zIHx8IHt9LCB7XG4gICAgICAgICAgICAgIHN0cmVhbUZpbGVzOiBmYWxzZSxcbiAgICAgICAgICAgICAgY29tcHJlc3Npb246IFwiU1RPUkVcIixcbiAgICAgICAgICAgICAgY29tcHJlc3Npb25PcHRpb25zIDogbnVsbCxcbiAgICAgICAgICAgICAgdHlwZTogXCJcIixcbiAgICAgICAgICAgICAgcGxhdGZvcm06IFwiRE9TXCIsXG4gICAgICAgICAgICAgIGNvbW1lbnQ6IG51bGwsXG4gICAgICAgICAgICAgIG1pbWVUeXBlOiAnYXBwbGljYXRpb24vemlwJyxcbiAgICAgICAgICAgICAgZW5jb2RlRmlsZU5hbWU6IHV0ZjgudXRmOGVuY29kZVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgb3B0cy50eXBlID0gb3B0cy50eXBlLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgb3B0cy5jb21wcmVzc2lvbiA9IG9wdHMuY29tcHJlc3Npb24udG9VcHBlckNhc2UoKTtcblxuICAgICAgICAgIC8vIFwiYmluYXJ5c3RyaW5nXCIgaXMgcHJlZmVyZWQgYnV0IHRoZSBpbnRlcm5hbHMgdXNlIFwic3RyaW5nXCIuXG4gICAgICAgICAgaWYob3B0cy50eXBlID09PSBcImJpbmFyeXN0cmluZ1wiKSB7XG4gICAgICAgICAgICBvcHRzLnR5cGUgPSBcInN0cmluZ1wiO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghb3B0cy50eXBlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBvdXRwdXQgdHlwZSBzcGVjaWZpZWQuXCIpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHV0aWxzLmNoZWNrU3VwcG9ydChvcHRzLnR5cGUpO1xuXG4gICAgICAgICAgLy8gYWNjZXB0IG5vZGVqcyBgcHJvY2Vzcy5wbGF0Zm9ybWBcbiAgICAgICAgICBpZihcbiAgICAgICAgICAgICAgb3B0cy5wbGF0Zm9ybSA9PT0gJ2RhcndpbicgfHxcbiAgICAgICAgICAgICAgb3B0cy5wbGF0Zm9ybSA9PT0gJ2ZyZWVic2QnIHx8XG4gICAgICAgICAgICAgIG9wdHMucGxhdGZvcm0gPT09ICdsaW51eCcgfHxcbiAgICAgICAgICAgICAgb3B0cy5wbGF0Zm9ybSA9PT0gJ3N1bm9zJ1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgICBvcHRzLnBsYXRmb3JtID0gXCJVTklYXCI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChvcHRzLnBsYXRmb3JtID09PSAnd2luMzInKSB7XG4gICAgICAgICAgICAgIG9wdHMucGxhdGZvcm0gPSBcIkRPU1wiO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBjb21tZW50ID0gb3B0cy5jb21tZW50IHx8IHRoaXMuY29tbWVudCB8fCBcIlwiO1xuICAgICAgICAgIHdvcmtlciA9IGdlbmVyYXRlLmdlbmVyYXRlV29ya2VyKHRoaXMsIG9wdHMsIGNvbW1lbnQpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB3b3JrZXIgPSBuZXcgR2VuZXJpY1dvcmtlcihcImVycm9yXCIpO1xuICAgICAgICB3b3JrZXIuZXJyb3IoZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3IFN0cmVhbUhlbHBlcih3b3JrZXIsIG9wdHMudHlwZSB8fCBcInN0cmluZ1wiLCBvcHRzLm1pbWVUeXBlKTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlIHRoZSBjb21wbGV0ZSB6aXAgZmlsZSBhc3luY2hyb25vdXNseS5cbiAgICAgKiBAc2VlIGdlbmVyYXRlSW50ZXJuYWxTdHJlYW1cbiAgICAgKi9cbiAgICBnZW5lcmF0ZUFzeW5jOiBmdW5jdGlvbihvcHRpb25zLCBvblVwZGF0ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZW5lcmF0ZUludGVybmFsU3RyZWFtKG9wdGlvbnMpLmFjY3VtdWxhdGUob25VcGRhdGUpO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogR2VuZXJhdGUgdGhlIGNvbXBsZXRlIHppcCBmaWxlIGFzeW5jaHJvbm91c2x5LlxuICAgICAqIEBzZWUgZ2VuZXJhdGVJbnRlcm5hbFN0cmVhbVxuICAgICAqL1xuICAgIGdlbmVyYXRlTm9kZVN0cmVhbTogZnVuY3Rpb24ob3B0aW9ucywgb25VcGRhdGUpIHtcbiAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gICAgICAgIGlmICghb3B0aW9ucy50eXBlKSB7XG4gICAgICAgICAgICBvcHRpb25zLnR5cGUgPSBcIm5vZGVidWZmZXJcIjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5nZW5lcmF0ZUludGVybmFsU3RyZWFtKG9wdGlvbnMpLnRvTm9kZWpzU3RyZWFtKG9uVXBkYXRlKTtcbiAgICB9XG59O1xubW9kdWxlLmV4cG9ydHMgPSBvdXQ7XG4iLCIvKlxuICogVGhpcyBmaWxlIGlzIHVzZWQgYnkgbW9kdWxlIGJ1bmRsZXJzIChicm93c2VyaWZ5L3dlYnBhY2svZXRjKSB3aGVuXG4gKiBpbmNsdWRpbmcgYSBzdHJlYW0gaW1wbGVtZW50YXRpb24uIFdlIHVzZSBcInJlYWRhYmxlLXN0cmVhbVwiIHRvIGdldCBhXG4gKiBjb25zaXN0ZW50IGJlaGF2aW9yIGJldHdlZW4gbm9kZWpzIHZlcnNpb25zIGJ1dCBidW5kbGVycyBvZnRlbiBoYXZlIGEgc2hpbVxuICogZm9yIFwic3RyZWFtXCIuIFVzaW5nIHRoaXMgc2hpbSBncmVhdGx5IGltcHJvdmUgdGhlIGNvbXBhdGliaWxpdHkgYW5kIGdyZWF0bHlcbiAqIHJlZHVjZSB0aGUgZmluYWwgc2l6ZSBvZiB0aGUgYnVuZGxlIChvbmx5IG9uZSBzdHJlYW0gaW1wbGVtZW50YXRpb24sIG5vdFxuICogdHdvKS5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwic3RyZWFtXCIpO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIERhdGFSZWFkZXIgPSByZXF1aXJlKCcuL0RhdGFSZWFkZXInKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG5cbmZ1bmN0aW9uIEFycmF5UmVhZGVyKGRhdGEpIHtcbiAgICBEYXRhUmVhZGVyLmNhbGwodGhpcywgZGF0YSk7XG5cdGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLmRhdGEubGVuZ3RoOyBpKyspIHtcblx0XHRkYXRhW2ldID0gZGF0YVtpXSAmIDB4RkY7XG5cdH1cbn1cbnV0aWxzLmluaGVyaXRzKEFycmF5UmVhZGVyLCBEYXRhUmVhZGVyKTtcbi8qKlxuICogQHNlZSBEYXRhUmVhZGVyLmJ5dGVBdFxuICovXG5BcnJheVJlYWRlci5wcm90b3R5cGUuYnl0ZUF0ID0gZnVuY3Rpb24oaSkge1xuICAgIHJldHVybiB0aGlzLmRhdGFbdGhpcy56ZXJvICsgaV07XG59O1xuLyoqXG4gKiBAc2VlIERhdGFSZWFkZXIubGFzdEluZGV4T2ZTaWduYXR1cmVcbiAqL1xuQXJyYXlSZWFkZXIucHJvdG90eXBlLmxhc3RJbmRleE9mU2lnbmF0dXJlID0gZnVuY3Rpb24oc2lnKSB7XG4gICAgdmFyIHNpZzAgPSBzaWcuY2hhckNvZGVBdCgwKSxcbiAgICAgICAgc2lnMSA9IHNpZy5jaGFyQ29kZUF0KDEpLFxuICAgICAgICBzaWcyID0gc2lnLmNoYXJDb2RlQXQoMiksXG4gICAgICAgIHNpZzMgPSBzaWcuY2hhckNvZGVBdCgzKTtcbiAgICBmb3IgKHZhciBpID0gdGhpcy5sZW5ndGggLSA0OyBpID49IDA7IC0taSkge1xuICAgICAgICBpZiAodGhpcy5kYXRhW2ldID09PSBzaWcwICYmIHRoaXMuZGF0YVtpICsgMV0gPT09IHNpZzEgJiYgdGhpcy5kYXRhW2kgKyAyXSA9PT0gc2lnMiAmJiB0aGlzLmRhdGFbaSArIDNdID09PSBzaWczKSB7XG4gICAgICAgICAgICByZXR1cm4gaSAtIHRoaXMuemVybztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiAtMTtcbn07XG4vKipcbiAqIEBzZWUgRGF0YVJlYWRlci5yZWFkQW5kQ2hlY2tTaWduYXR1cmVcbiAqL1xuQXJyYXlSZWFkZXIucHJvdG90eXBlLnJlYWRBbmRDaGVja1NpZ25hdHVyZSA9IGZ1bmN0aW9uIChzaWcpIHtcbiAgICB2YXIgc2lnMCA9IHNpZy5jaGFyQ29kZUF0KDApLFxuICAgICAgICBzaWcxID0gc2lnLmNoYXJDb2RlQXQoMSksXG4gICAgICAgIHNpZzIgPSBzaWcuY2hhckNvZGVBdCgyKSxcbiAgICAgICAgc2lnMyA9IHNpZy5jaGFyQ29kZUF0KDMpLFxuICAgICAgICBkYXRhID0gdGhpcy5yZWFkRGF0YSg0KTtcbiAgICByZXR1cm4gc2lnMCA9PT0gZGF0YVswXSAmJiBzaWcxID09PSBkYXRhWzFdICYmIHNpZzIgPT09IGRhdGFbMl0gJiYgc2lnMyA9PT0gZGF0YVszXTtcbn07XG4vKipcbiAqIEBzZWUgRGF0YVJlYWRlci5yZWFkRGF0YVxuICovXG5BcnJheVJlYWRlci5wcm90b3R5cGUucmVhZERhdGEgPSBmdW5jdGlvbihzaXplKSB7XG4gICAgdGhpcy5jaGVja09mZnNldChzaXplKTtcbiAgICBpZihzaXplID09PSAwKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgdmFyIHJlc3VsdCA9IHRoaXMuZGF0YS5zbGljZSh0aGlzLnplcm8gKyB0aGlzLmluZGV4LCB0aGlzLnplcm8gKyB0aGlzLmluZGV4ICsgc2l6ZSk7XG4gICAgdGhpcy5pbmRleCArPSBzaXplO1xuICAgIHJldHVybiByZXN1bHQ7XG59O1xubW9kdWxlLmV4cG9ydHMgPSBBcnJheVJlYWRlcjtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG5cbmZ1bmN0aW9uIERhdGFSZWFkZXIoZGF0YSkge1xuICAgIHRoaXMuZGF0YSA9IGRhdGE7IC8vIHR5cGUgOiBzZWUgaW1wbGVtZW50YXRpb25cbiAgICB0aGlzLmxlbmd0aCA9IGRhdGEubGVuZ3RoO1xuICAgIHRoaXMuaW5kZXggPSAwO1xuICAgIHRoaXMuemVybyA9IDA7XG59XG5EYXRhUmVhZGVyLnByb3RvdHlwZSA9IHtcbiAgICAvKipcbiAgICAgKiBDaGVjayB0aGF0IHRoZSBvZmZzZXQgd2lsbCBub3QgZ28gdG9vIGZhci5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gb2Zmc2V0IHRoZSBhZGRpdGlvbmFsIG9mZnNldCB0byBjaGVjay5cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gYW4gRXJyb3IgaWYgdGhlIG9mZnNldCBpcyBvdXQgb2YgYm91bmRzLlxuICAgICAqL1xuICAgIGNoZWNrT2Zmc2V0OiBmdW5jdGlvbihvZmZzZXQpIHtcbiAgICAgICAgdGhpcy5jaGVja0luZGV4KHRoaXMuaW5kZXggKyBvZmZzZXQpO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogQ2hlY2sgdGhhdCB0aGUgc3BlY2lmaWVkIGluZGV4IHdpbGwgbm90IGJlIHRvbyBmYXIuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5ld0luZGV4IHRoZSBpbmRleCB0byBjaGVjay5cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gYW4gRXJyb3IgaWYgdGhlIGluZGV4IGlzIG91dCBvZiBib3VuZHMuXG4gICAgICovXG4gICAgY2hlY2tJbmRleDogZnVuY3Rpb24obmV3SW5kZXgpIHtcbiAgICAgICAgaWYgKHRoaXMubGVuZ3RoIDwgdGhpcy56ZXJvICsgbmV3SW5kZXggfHwgbmV3SW5kZXggPCAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFbmQgb2YgZGF0YSByZWFjaGVkIChkYXRhIGxlbmd0aCA9IFwiICsgdGhpcy5sZW5ndGggKyBcIiwgYXNrZWQgaW5kZXggPSBcIiArIChuZXdJbmRleCkgKyBcIikuIENvcnJ1cHRlZCB6aXAgP1wiKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogQ2hhbmdlIHRoZSBpbmRleC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbmV3SW5kZXggVGhlIG5ldyBpbmRleC5cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gaWYgdGhlIG5ldyBpbmRleCBpcyBvdXQgb2YgdGhlIGRhdGEuXG4gICAgICovXG4gICAgc2V0SW5kZXg6IGZ1bmN0aW9uKG5ld0luZGV4KSB7XG4gICAgICAgIHRoaXMuY2hlY2tJbmRleChuZXdJbmRleCk7XG4gICAgICAgIHRoaXMuaW5kZXggPSBuZXdJbmRleDtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFNraXAgdGhlIG5leHQgbiBieXRlcy5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIHNraXAuXG4gICAgICogQHRocm93cyB7RXJyb3J9IGlmIHRoZSBuZXcgaW5kZXggaXMgb3V0IG9mIHRoZSBkYXRhLlxuICAgICAqL1xuICAgIHNraXA6IGZ1bmN0aW9uKG4pIHtcbiAgICAgICAgdGhpcy5zZXRJbmRleCh0aGlzLmluZGV4ICsgbik7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGJ5dGUgYXQgdGhlIHNwZWNpZmllZCBpbmRleC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gaSB0aGUgaW5kZXggdG8gdXNlLlxuICAgICAqIEByZXR1cm4ge251bWJlcn0gYSBieXRlLlxuICAgICAqL1xuICAgIGJ5dGVBdDogZnVuY3Rpb24oaSkge1xuICAgICAgICAvLyBzZWUgaW1wbGVtZW50YXRpb25zXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIG5leHQgbnVtYmVyIHdpdGggYSBnaXZlbiBieXRlIHNpemUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHNpemUgdGhlIG51bWJlciBvZiBieXRlcyB0byByZWFkLlxuICAgICAqIEByZXR1cm4ge251bWJlcn0gdGhlIGNvcnJlc3BvbmRpbmcgbnVtYmVyLlxuICAgICAqL1xuICAgIHJlYWRJbnQ6IGZ1bmN0aW9uKHNpemUpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IDAsXG4gICAgICAgICAgICBpO1xuICAgICAgICB0aGlzLmNoZWNrT2Zmc2V0KHNpemUpO1xuICAgICAgICBmb3IgKGkgPSB0aGlzLmluZGV4ICsgc2l6ZSAtIDE7IGkgPj0gdGhpcy5pbmRleDsgaS0tKSB7XG4gICAgICAgICAgICByZXN1bHQgPSAocmVzdWx0IDw8IDgpICsgdGhpcy5ieXRlQXQoaSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pbmRleCArPSBzaXplO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBuZXh0IHN0cmluZyB3aXRoIGEgZ2l2ZW4gYnl0ZSBzaXplLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gcmVhZC5cbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IHRoZSBjb3JyZXNwb25kaW5nIHN0cmluZy5cbiAgICAgKi9cbiAgICByZWFkU3RyaW5nOiBmdW5jdGlvbihzaXplKSB7XG4gICAgICAgIHJldHVybiB1dGlscy50cmFuc2Zvcm1UbyhcInN0cmluZ1wiLCB0aGlzLnJlYWREYXRhKHNpemUpKTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIEdldCByYXcgZGF0YSB3aXRob3V0IGNvbnZlcnNpb24sIDxzaXplPiBieXRlcy5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc2l6ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIHJlYWQuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSB0aGUgcmF3IGRhdGEsIGltcGxlbWVudGF0aW9uIHNwZWNpZmljLlxuICAgICAqL1xuICAgIHJlYWREYXRhOiBmdW5jdGlvbihzaXplKSB7XG4gICAgICAgIC8vIHNlZSBpbXBsZW1lbnRhdGlvbnNcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIEZpbmQgdGhlIGxhc3Qgb2NjdXJlbmNlIG9mIGEgemlwIHNpZ25hdHVyZSAoNCBieXRlcykuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHNpZyB0aGUgc2lnbmF0dXJlIHRvIGZpbmQuXG4gICAgICogQHJldHVybiB7bnVtYmVyfSB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgb2NjdXJlbmNlLCAtMSBpZiBub3QgZm91bmQuXG4gICAgICovXG4gICAgbGFzdEluZGV4T2ZTaWduYXR1cmU6IGZ1bmN0aW9uKHNpZykge1xuICAgICAgICAvLyBzZWUgaW1wbGVtZW50YXRpb25zXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBSZWFkIHRoZSBzaWduYXR1cmUgKDQgYnl0ZXMpIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCBjb21wYXJlIGl0IHdpdGggc2lnLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzaWcgdGhlIGV4cGVjdGVkIHNpZ25hdHVyZVxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59IHRydWUgaWYgdGhlIHNpZ25hdHVyZSBtYXRjaGVzLCBmYWxzZSBvdGhlcndpc2UuXG4gICAgICovXG4gICAgcmVhZEFuZENoZWNrU2lnbmF0dXJlOiBmdW5jdGlvbihzaWcpIHtcbiAgICAgICAgLy8gc2VlIGltcGxlbWVudGF0aW9uc1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBuZXh0IGRhdGUuXG4gICAgICogQHJldHVybiB7RGF0ZX0gdGhlIGRhdGUuXG4gICAgICovXG4gICAgcmVhZERhdGU6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgZG9zdGltZSA9IHRoaXMucmVhZEludCg0KTtcbiAgICAgICAgcmV0dXJuIG5ldyBEYXRlKERhdGUuVVRDKFxuICAgICAgICAoKGRvc3RpbWUgPj4gMjUpICYgMHg3ZikgKyAxOTgwLCAvLyB5ZWFyXG4gICAgICAgICgoZG9zdGltZSA+PiAyMSkgJiAweDBmKSAtIDEsIC8vIG1vbnRoXG4gICAgICAgIChkb3N0aW1lID4+IDE2KSAmIDB4MWYsIC8vIGRheVxuICAgICAgICAoZG9zdGltZSA+PiAxMSkgJiAweDFmLCAvLyBob3VyXG4gICAgICAgIChkb3N0aW1lID4+IDUpICYgMHgzZiwgLy8gbWludXRlXG4gICAgICAgIChkb3N0aW1lICYgMHgxZikgPDwgMSkpOyAvLyBzZWNvbmRcbiAgICB9XG59O1xubW9kdWxlLmV4cG9ydHMgPSBEYXRhUmVhZGVyO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIFVpbnQ4QXJyYXlSZWFkZXIgPSByZXF1aXJlKCcuL1VpbnQ4QXJyYXlSZWFkZXInKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG5cbmZ1bmN0aW9uIE5vZGVCdWZmZXJSZWFkZXIoZGF0YSkge1xuICAgIFVpbnQ4QXJyYXlSZWFkZXIuY2FsbCh0aGlzLCBkYXRhKTtcbn1cbnV0aWxzLmluaGVyaXRzKE5vZGVCdWZmZXJSZWFkZXIsIFVpbnQ4QXJyYXlSZWFkZXIpO1xuXG4vKipcbiAqIEBzZWUgRGF0YVJlYWRlci5yZWFkRGF0YVxuICovXG5Ob2RlQnVmZmVyUmVhZGVyLnByb3RvdHlwZS5yZWFkRGF0YSA9IGZ1bmN0aW9uKHNpemUpIHtcbiAgICB0aGlzLmNoZWNrT2Zmc2V0KHNpemUpO1xuICAgIHZhciByZXN1bHQgPSB0aGlzLmRhdGEuc2xpY2UodGhpcy56ZXJvICsgdGhpcy5pbmRleCwgdGhpcy56ZXJvICsgdGhpcy5pbmRleCArIHNpemUpO1xuICAgIHRoaXMuaW5kZXggKz0gc2l6ZTtcbiAgICByZXR1cm4gcmVzdWx0O1xufTtcbm1vZHVsZS5leHBvcnRzID0gTm9kZUJ1ZmZlclJlYWRlcjtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBEYXRhUmVhZGVyID0gcmVxdWlyZSgnLi9EYXRhUmVhZGVyJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xuXG5mdW5jdGlvbiBTdHJpbmdSZWFkZXIoZGF0YSkge1xuICAgIERhdGFSZWFkZXIuY2FsbCh0aGlzLCBkYXRhKTtcbn1cbnV0aWxzLmluaGVyaXRzKFN0cmluZ1JlYWRlciwgRGF0YVJlYWRlcik7XG4vKipcbiAqIEBzZWUgRGF0YVJlYWRlci5ieXRlQXRcbiAqL1xuU3RyaW5nUmVhZGVyLnByb3RvdHlwZS5ieXRlQXQgPSBmdW5jdGlvbihpKSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMuemVybyArIGkpO1xufTtcbi8qKlxuICogQHNlZSBEYXRhUmVhZGVyLmxhc3RJbmRleE9mU2lnbmF0dXJlXG4gKi9cblN0cmluZ1JlYWRlci5wcm90b3R5cGUubGFzdEluZGV4T2ZTaWduYXR1cmUgPSBmdW5jdGlvbihzaWcpIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhLmxhc3RJbmRleE9mKHNpZykgLSB0aGlzLnplcm87XG59O1xuLyoqXG4gKiBAc2VlIERhdGFSZWFkZXIucmVhZEFuZENoZWNrU2lnbmF0dXJlXG4gKi9cblN0cmluZ1JlYWRlci5wcm90b3R5cGUucmVhZEFuZENoZWNrU2lnbmF0dXJlID0gZnVuY3Rpb24gKHNpZykge1xuICAgIHZhciBkYXRhID0gdGhpcy5yZWFkRGF0YSg0KTtcbiAgICByZXR1cm4gc2lnID09PSBkYXRhO1xufTtcbi8qKlxuICogQHNlZSBEYXRhUmVhZGVyLnJlYWREYXRhXG4gKi9cblN0cmluZ1JlYWRlci5wcm90b3R5cGUucmVhZERhdGEgPSBmdW5jdGlvbihzaXplKSB7XG4gICAgdGhpcy5jaGVja09mZnNldChzaXplKTtcbiAgICAvLyB0aGlzIHdpbGwgd29yayBiZWNhdXNlIHRoZSBjb25zdHJ1Y3RvciBhcHBsaWVkIHRoZSBcIiYgMHhmZlwiIG1hc2suXG4gICAgdmFyIHJlc3VsdCA9IHRoaXMuZGF0YS5zbGljZSh0aGlzLnplcm8gKyB0aGlzLmluZGV4LCB0aGlzLnplcm8gKyB0aGlzLmluZGV4ICsgc2l6ZSk7XG4gICAgdGhpcy5pbmRleCArPSBzaXplO1xuICAgIHJldHVybiByZXN1bHQ7XG59O1xubW9kdWxlLmV4cG9ydHMgPSBTdHJpbmdSZWFkZXI7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgQXJyYXlSZWFkZXIgPSByZXF1aXJlKCcuL0FycmF5UmVhZGVyJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xuXG5mdW5jdGlvbiBVaW50OEFycmF5UmVhZGVyKGRhdGEpIHtcbiAgICBBcnJheVJlYWRlci5jYWxsKHRoaXMsIGRhdGEpO1xufVxudXRpbHMuaW5oZXJpdHMoVWludDhBcnJheVJlYWRlciwgQXJyYXlSZWFkZXIpO1xuLyoqXG4gKiBAc2VlIERhdGFSZWFkZXIucmVhZERhdGFcbiAqL1xuVWludDhBcnJheVJlYWRlci5wcm90b3R5cGUucmVhZERhdGEgPSBmdW5jdGlvbihzaXplKSB7XG4gICAgdGhpcy5jaGVja09mZnNldChzaXplKTtcbiAgICBpZihzaXplID09PSAwKSB7XG4gICAgICAgIC8vIGluIElFMTAsIHdoZW4gdXNpbmcgc3ViYXJyYXkoaWR4LCBpZHgpLCB3ZSBnZXQgdGhlIGFycmF5IFsweDAwXSBpbnN0ZWFkIG9mIFtdLlxuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoMCk7XG4gICAgfVxuICAgIHZhciByZXN1bHQgPSB0aGlzLmRhdGEuc3ViYXJyYXkodGhpcy56ZXJvICsgdGhpcy5pbmRleCwgdGhpcy56ZXJvICsgdGhpcy5pbmRleCArIHNpemUpO1xuICAgIHRoaXMuaW5kZXggKz0gc2l6ZTtcbiAgICByZXR1cm4gcmVzdWx0O1xufTtcbm1vZHVsZS5leHBvcnRzID0gVWludDhBcnJheVJlYWRlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBzdXBwb3J0ID0gcmVxdWlyZSgnLi4vc3VwcG9ydCcpO1xudmFyIEFycmF5UmVhZGVyID0gcmVxdWlyZSgnLi9BcnJheVJlYWRlcicpO1xudmFyIFN0cmluZ1JlYWRlciA9IHJlcXVpcmUoJy4vU3RyaW5nUmVhZGVyJyk7XG52YXIgTm9kZUJ1ZmZlclJlYWRlciA9IHJlcXVpcmUoJy4vTm9kZUJ1ZmZlclJlYWRlcicpO1xudmFyIFVpbnQ4QXJyYXlSZWFkZXIgPSByZXF1aXJlKCcuL1VpbnQ4QXJyYXlSZWFkZXInKTtcblxuLyoqXG4gKiBDcmVhdGUgYSByZWFkZXIgYWRhcHRlZCB0byB0aGUgZGF0YS5cbiAqIEBwYXJhbSB7U3RyaW5nfEFycmF5QnVmZmVyfFVpbnQ4QXJyYXl8QnVmZmVyfSBkYXRhIHRoZSBkYXRhIHRvIHJlYWQuXG4gKiBAcmV0dXJuIHtEYXRhUmVhZGVyfSB0aGUgZGF0YSByZWFkZXIuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICB2YXIgdHlwZSA9IHV0aWxzLmdldFR5cGVPZihkYXRhKTtcbiAgICB1dGlscy5jaGVja1N1cHBvcnQodHlwZSk7XG4gICAgaWYgKHR5cGUgPT09IFwic3RyaW5nXCIgJiYgIXN1cHBvcnQudWludDhhcnJheSkge1xuICAgICAgICByZXR1cm4gbmV3IFN0cmluZ1JlYWRlcihkYXRhKTtcbiAgICB9XG4gICAgaWYgKHR5cGUgPT09IFwibm9kZWJ1ZmZlclwiKSB7XG4gICAgICAgIHJldHVybiBuZXcgTm9kZUJ1ZmZlclJlYWRlcihkYXRhKTtcbiAgICB9XG4gICAgaWYgKHN1cHBvcnQudWludDhhcnJheSkge1xuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXlSZWFkZXIodXRpbHMudHJhbnNmb3JtVG8oXCJ1aW50OGFycmF5XCIsIGRhdGEpKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBBcnJheVJlYWRlcih1dGlscy50cmFuc2Zvcm1UbyhcImFycmF5XCIsIGRhdGEpKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5leHBvcnRzLkxPQ0FMX0ZJTEVfSEVBREVSID0gXCJQS1xceDAzXFx4MDRcIjtcbmV4cG9ydHMuQ0VOVFJBTF9GSUxFX0hFQURFUiA9IFwiUEtcXHgwMVxceDAyXCI7XG5leHBvcnRzLkNFTlRSQUxfRElSRUNUT1JZX0VORCA9IFwiUEtcXHgwNVxceDA2XCI7XG5leHBvcnRzLlpJUDY0X0NFTlRSQUxfRElSRUNUT1JZX0xPQ0FUT1IgPSBcIlBLXFx4MDZcXHgwN1wiO1xuZXhwb3J0cy5aSVA2NF9DRU5UUkFMX0RJUkVDVE9SWV9FTkQgPSBcIlBLXFx4MDZcXHgwNlwiO1xuZXhwb3J0cy5EQVRBX0RFU0NSSVBUT1IgPSBcIlBLXFx4MDdcXHgwOFwiO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgR2VuZXJpY1dvcmtlciA9IHJlcXVpcmUoJy4vR2VuZXJpY1dvcmtlcicpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcblxuLyoqXG4gKiBBIHdvcmtlciB3aGljaCBjb252ZXJ0IGNodW5rcyB0byBhIHNwZWNpZmllZCB0eXBlLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge1N0cmluZ30gZGVzdFR5cGUgdGhlIGRlc3RpbmF0aW9uIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIENvbnZlcnRXb3JrZXIoZGVzdFR5cGUpIHtcbiAgICBHZW5lcmljV29ya2VyLmNhbGwodGhpcywgXCJDb252ZXJ0V29ya2VyIHRvIFwiICsgZGVzdFR5cGUpO1xuICAgIHRoaXMuZGVzdFR5cGUgPSBkZXN0VHlwZTtcbn1cbnV0aWxzLmluaGVyaXRzKENvbnZlcnRXb3JrZXIsIEdlbmVyaWNXb3JrZXIpO1xuXG4vKipcbiAqIEBzZWUgR2VuZXJpY1dvcmtlci5wcm9jZXNzQ2h1bmtcbiAqL1xuQ29udmVydFdvcmtlci5wcm90b3R5cGUucHJvY2Vzc0NodW5rID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgdGhpcy5wdXNoKHtcbiAgICAgICAgZGF0YSA6IHV0aWxzLnRyYW5zZm9ybVRvKHRoaXMuZGVzdFR5cGUsIGNodW5rLmRhdGEpLFxuICAgICAgICBtZXRhIDogY2h1bmsubWV0YVxuICAgIH0pO1xufTtcbm1vZHVsZS5leHBvcnRzID0gQ29udmVydFdvcmtlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEdlbmVyaWNXb3JrZXIgPSByZXF1aXJlKCcuL0dlbmVyaWNXb3JrZXInKTtcbnZhciBjcmMzMiA9IHJlcXVpcmUoJy4uL2NyYzMyJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xuXG4vKipcbiAqIEEgd29ya2VyIHdoaWNoIGNhbGN1bGF0ZSB0aGUgY3JjMzIgb2YgdGhlIGRhdGEgZmxvd2luZyB0aHJvdWdoLlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIENyYzMyUHJvYmUoKSB7XG4gICAgR2VuZXJpY1dvcmtlci5jYWxsKHRoaXMsIFwiQ3JjMzJQcm9iZVwiKTtcbiAgICB0aGlzLndpdGhTdHJlYW1JbmZvKFwiY3JjMzJcIiwgMCk7XG59XG51dGlscy5pbmhlcml0cyhDcmMzMlByb2JlLCBHZW5lcmljV29ya2VyKTtcblxuLyoqXG4gKiBAc2VlIEdlbmVyaWNXb3JrZXIucHJvY2Vzc0NodW5rXG4gKi9cbkNyYzMyUHJvYmUucHJvdG90eXBlLnByb2Nlc3NDaHVuayA9IGZ1bmN0aW9uIChjaHVuaykge1xuICAgIHRoaXMuc3RyZWFtSW5mby5jcmMzMiA9IGNyYzMyKGNodW5rLmRhdGEsIHRoaXMuc3RyZWFtSW5mby5jcmMzMiB8fCAwKTtcbiAgICB0aGlzLnB1c2goY2h1bmspO1xufTtcbm1vZHVsZS5leHBvcnRzID0gQ3JjMzJQcm9iZTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBHZW5lcmljV29ya2VyID0gcmVxdWlyZSgnLi9HZW5lcmljV29ya2VyJyk7XG5cbi8qKlxuICogQSB3b3JrZXIgd2hpY2ggY2FsY3VsYXRlIHRoZSB0b3RhbCBsZW5ndGggb2YgdGhlIGRhdGEgZmxvd2luZyB0aHJvdWdoLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge1N0cmluZ30gcHJvcE5hbWUgdGhlIG5hbWUgdXNlZCB0byBleHBvc2UgdGhlIGxlbmd0aFxuICovXG5mdW5jdGlvbiBEYXRhTGVuZ3RoUHJvYmUocHJvcE5hbWUpIHtcbiAgICBHZW5lcmljV29ya2VyLmNhbGwodGhpcywgXCJEYXRhTGVuZ3RoUHJvYmUgZm9yIFwiICsgcHJvcE5hbWUpO1xuICAgIHRoaXMucHJvcE5hbWUgPSBwcm9wTmFtZTtcbiAgICB0aGlzLndpdGhTdHJlYW1JbmZvKHByb3BOYW1lLCAwKTtcbn1cbnV0aWxzLmluaGVyaXRzKERhdGFMZW5ndGhQcm9iZSwgR2VuZXJpY1dvcmtlcik7XG5cbi8qKlxuICogQHNlZSBHZW5lcmljV29ya2VyLnByb2Nlc3NDaHVua1xuICovXG5EYXRhTGVuZ3RoUHJvYmUucHJvdG90eXBlLnByb2Nlc3NDaHVuayA9IGZ1bmN0aW9uIChjaHVuaykge1xuICAgIGlmKGNodW5rKSB7XG4gICAgICAgIHZhciBsZW5ndGggPSB0aGlzLnN0cmVhbUluZm9bdGhpcy5wcm9wTmFtZV0gfHwgMDtcbiAgICAgICAgdGhpcy5zdHJlYW1JbmZvW3RoaXMucHJvcE5hbWVdID0gbGVuZ3RoICsgY2h1bmsuZGF0YS5sZW5ndGg7XG4gICAgfVxuICAgIEdlbmVyaWNXb3JrZXIucHJvdG90eXBlLnByb2Nlc3NDaHVuay5jYWxsKHRoaXMsIGNodW5rKTtcbn07XG5tb2R1bGUuZXhwb3J0cyA9IERhdGFMZW5ndGhQcm9iZTtcblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xudmFyIEdlbmVyaWNXb3JrZXIgPSByZXF1aXJlKCcuL0dlbmVyaWNXb3JrZXInKTtcblxuLy8gdGhlIHNpemUgb2YgdGhlIGdlbmVyYXRlZCBjaHVua3Ncbi8vIFRPRE8gZXhwb3NlIHRoaXMgYXMgYSBwdWJsaWMgdmFyaWFibGVcbnZhciBERUZBVUxUX0JMT0NLX1NJWkUgPSAxNiAqIDEwMjQ7XG5cbi8qKlxuICogQSB3b3JrZXIgdGhhdCByZWFkcyBhIGNvbnRlbnQgYW5kIGVtaXRzIGNodW5rcy5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtQcm9taXNlfSBkYXRhUCB0aGUgcHJvbWlzZSBvZiB0aGUgZGF0YSB0byBzcGxpdFxuICovXG5mdW5jdGlvbiBEYXRhV29ya2VyKGRhdGFQKSB7XG4gICAgR2VuZXJpY1dvcmtlci5jYWxsKHRoaXMsIFwiRGF0YVdvcmtlclwiKTtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy5kYXRhSXNSZWFkeSA9IGZhbHNlO1xuICAgIHRoaXMuaW5kZXggPSAwO1xuICAgIHRoaXMubWF4ID0gMDtcbiAgICB0aGlzLmRhdGEgPSBudWxsO1xuICAgIHRoaXMudHlwZSA9IFwiXCI7XG5cbiAgICB0aGlzLl90aWNrU2NoZWR1bGVkID0gZmFsc2U7XG5cbiAgICBkYXRhUC50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIHNlbGYuZGF0YUlzUmVhZHkgPSB0cnVlO1xuICAgICAgICBzZWxmLmRhdGEgPSBkYXRhO1xuICAgICAgICBzZWxmLm1heCA9IGRhdGEgJiYgZGF0YS5sZW5ndGggfHwgMDtcbiAgICAgICAgc2VsZi50eXBlID0gdXRpbHMuZ2V0VHlwZU9mKGRhdGEpO1xuICAgICAgICBpZighc2VsZi5pc1BhdXNlZCkge1xuICAgICAgICAgICAgc2VsZi5fdGlja0FuZFJlcGVhdCgpO1xuICAgICAgICB9XG4gICAgfSwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgc2VsZi5lcnJvcihlKTtcbiAgICB9KTtcbn1cblxudXRpbHMuaW5oZXJpdHMoRGF0YVdvcmtlciwgR2VuZXJpY1dvcmtlcik7XG5cbi8qKlxuICogQHNlZSBHZW5lcmljV29ya2VyLmNsZWFuVXBcbiAqL1xuRGF0YVdvcmtlci5wcm90b3R5cGUuY2xlYW5VcCA9IGZ1bmN0aW9uICgpIHtcbiAgICBHZW5lcmljV29ya2VyLnByb3RvdHlwZS5jbGVhblVwLmNhbGwodGhpcyk7XG4gICAgdGhpcy5kYXRhID0gbnVsbDtcbn07XG5cbi8qKlxuICogQHNlZSBHZW5lcmljV29ya2VyLnJlc3VtZVxuICovXG5EYXRhV29ya2VyLnByb3RvdHlwZS5yZXN1bWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYoIUdlbmVyaWNXb3JrZXIucHJvdG90eXBlLnJlc3VtZS5jYWxsKHRoaXMpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuX3RpY2tTY2hlZHVsZWQgJiYgdGhpcy5kYXRhSXNSZWFkeSkge1xuICAgICAgICB0aGlzLl90aWNrU2NoZWR1bGVkID0gdHJ1ZTtcbiAgICAgICAgdXRpbHMuZGVsYXkodGhpcy5fdGlja0FuZFJlcGVhdCwgW10sIHRoaXMpO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKlxuICogVHJpZ2dlciBhIHRpY2sgYSBzY2hlZHVsZSBhbiBvdGhlciBjYWxsIHRvIHRoaXMgZnVuY3Rpb24uXG4gKi9cbkRhdGFXb3JrZXIucHJvdG90eXBlLl90aWNrQW5kUmVwZWF0ID0gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fdGlja1NjaGVkdWxlZCA9IGZhbHNlO1xuICAgIGlmKHRoaXMuaXNQYXVzZWQgfHwgdGhpcy5pc0ZpbmlzaGVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fdGljaygpO1xuICAgIGlmKCF0aGlzLmlzRmluaXNoZWQpIHtcbiAgICAgICAgdXRpbHMuZGVsYXkodGhpcy5fdGlja0FuZFJlcGVhdCwgW10sIHRoaXMpO1xuICAgICAgICB0aGlzLl90aWNrU2NoZWR1bGVkID0gdHJ1ZTtcbiAgICB9XG59O1xuXG4vKipcbiAqIFJlYWQgYW5kIHB1c2ggYSBjaHVuay5cbiAqL1xuRGF0YVdvcmtlci5wcm90b3R5cGUuX3RpY2sgPSBmdW5jdGlvbigpIHtcblxuICAgIGlmKHRoaXMuaXNQYXVzZWQgfHwgdGhpcy5pc0ZpbmlzaGVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB2YXIgc2l6ZSA9IERFRkFVTFRfQkxPQ0tfU0laRTtcbiAgICB2YXIgZGF0YSA9IG51bGwsIG5leHRJbmRleCA9IE1hdGgubWluKHRoaXMubWF4LCB0aGlzLmluZGV4ICsgc2l6ZSk7XG4gICAgaWYgKHRoaXMuaW5kZXggPj0gdGhpcy5tYXgpIHtcbiAgICAgICAgLy8gRU9GXG4gICAgICAgIHJldHVybiB0aGlzLmVuZCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHN3aXRjaCh0aGlzLnR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgXCJzdHJpbmdcIjpcbiAgICAgICAgICAgICAgICBkYXRhID0gdGhpcy5kYXRhLnN1YnN0cmluZyh0aGlzLmluZGV4LCBuZXh0SW5kZXgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwidWludDhhcnJheVwiOlxuICAgICAgICAgICAgICAgIGRhdGEgPSB0aGlzLmRhdGEuc3ViYXJyYXkodGhpcy5pbmRleCwgbmV4dEluZGV4KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcImFycmF5XCI6XG4gICAgICAgICAgICBjYXNlIFwibm9kZWJ1ZmZlclwiOlxuICAgICAgICAgICAgICAgIGRhdGEgPSB0aGlzLmRhdGEuc2xpY2UodGhpcy5pbmRleCwgbmV4dEluZGV4KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW5kZXggPSBuZXh0SW5kZXg7XG4gICAgICAgIHJldHVybiB0aGlzLnB1c2goe1xuICAgICAgICAgICAgZGF0YSA6IGRhdGEsXG4gICAgICAgICAgICBtZXRhIDoge1xuICAgICAgICAgICAgICAgIHBlcmNlbnQgOiB0aGlzLm1heCA/IHRoaXMuaW5kZXggLyB0aGlzLm1heCAqIDEwMCA6IDBcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBEYXRhV29ya2VyO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIEEgd29ya2VyIHRoYXQgZG9lcyBub3RoaW5nIGJ1dCBwYXNzaW5nIGNodW5rcyB0byB0aGUgbmV4dCBvbmUuIFRoaXMgaXMgbGlrZVxuICogYSBub2RlanMgc3RyZWFtIGJ1dCB3aXRoIHNvbWUgZGlmZmVyZW5jZXMuIE9uIHRoZSBnb29kIHNpZGUgOlxuICogLSBpdCB3b3JrcyBvbiBJRSA2LTkgd2l0aG91dCBhbnkgaXNzdWUgLyBwb2x5ZmlsbFxuICogLSBpdCB3ZWlnaHRzIGxlc3MgdGhhbiB0aGUgZnVsbCBkZXBlbmRlbmNpZXMgYnVuZGxlZCB3aXRoIGJyb3dzZXJpZnlcbiAqIC0gaXQgZm9yd2FyZHMgZXJyb3JzIChubyBuZWVkIHRvIGRlY2xhcmUgYW4gZXJyb3IgaGFuZGxlciBFVkVSWVdIRVJFKVxuICpcbiAqIEEgY2h1bmsgaXMgYW4gb2JqZWN0IHdpdGggMiBhdHRyaWJ1dGVzIDogYG1ldGFgIGFuZCBgZGF0YWAuIFRoZSBmb3JtZXIgaXMgYW5cbiAqIG9iamVjdCBjb250YWluaW5nIGFueXRoaW5nIChgcGVyY2VudGAgZm9yIGV4YW1wbGUpLCBzZWUgZWFjaCB3b3JrZXIgZm9yIG1vcmVcbiAqIGRldGFpbHMuIFRoZSBsYXR0ZXIgaXMgdGhlIHJlYWwgZGF0YSAoU3RyaW5nLCBVaW50OEFycmF5LCBldGMpLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgdGhlIG5hbWUgb2YgdGhlIHN0cmVhbSAobWFpbmx5IHVzZWQgZm9yIGRlYnVnZ2luZyBwdXJwb3NlcylcbiAqL1xuZnVuY3Rpb24gR2VuZXJpY1dvcmtlcihuYW1lKSB7XG4gICAgLy8gdGhlIG5hbWUgb2YgdGhlIHdvcmtlclxuICAgIHRoaXMubmFtZSA9IG5hbWUgfHwgXCJkZWZhdWx0XCI7XG4gICAgLy8gYW4gb2JqZWN0IGNvbnRhaW5pbmcgbWV0YWRhdGEgYWJvdXQgdGhlIHdvcmtlcnMgY2hhaW5cbiAgICB0aGlzLnN0cmVhbUluZm8gPSB7fTtcbiAgICAvLyBhbiBlcnJvciB3aGljaCBoYXBwZW5lZCB3aGVuIHRoZSB3b3JrZXIgd2FzIHBhdXNlZFxuICAgIHRoaXMuZ2VuZXJhdGVkRXJyb3IgPSBudWxsO1xuICAgIC8vIGFuIG9iamVjdCBjb250YWluaW5nIG1ldGFkYXRhIHRvIGJlIG1lcmdlZCBieSB0aGlzIHdvcmtlciBpbnRvIHRoZSBnZW5lcmFsIG1ldGFkYXRhXG4gICAgdGhpcy5leHRyYVN0cmVhbUluZm8gPSB7fTtcbiAgICAvLyB0cnVlIGlmIHRoZSBzdHJlYW0gaXMgcGF1c2VkIChhbmQgc2hvdWxkIG5vdCBkbyBhbnl0aGluZyksIGZhbHNlIG90aGVyd2lzZVxuICAgIHRoaXMuaXNQYXVzZWQgPSB0cnVlO1xuICAgIC8vIHRydWUgaWYgdGhlIHN0cmVhbSBpcyBmaW5pc2hlZCAoYW5kIHNob3VsZCBub3QgZG8gYW55dGhpbmcpLCBmYWxzZSBvdGhlcndpc2VcbiAgICB0aGlzLmlzRmluaXNoZWQgPSBmYWxzZTtcbiAgICAvLyB0cnVlIGlmIHRoZSBzdHJlYW0gaXMgbG9ja2VkIHRvIHByZXZlbnQgZnVydGhlciBzdHJ1Y3R1cmUgdXBkYXRlcyAocGlwZSksIGZhbHNlIG90aGVyd2lzZVxuICAgIHRoaXMuaXNMb2NrZWQgPSBmYWxzZTtcbiAgICAvLyB0aGUgZXZlbnQgbGlzdGVuZXJzXG4gICAgdGhpcy5fbGlzdGVuZXJzID0ge1xuICAgICAgICAnZGF0YSc6W10sXG4gICAgICAgICdlbmQnOltdLFxuICAgICAgICAnZXJyb3InOltdXG4gICAgfTtcbiAgICAvLyB0aGUgcHJldmlvdXMgd29ya2VyLCBpZiBhbnlcbiAgICB0aGlzLnByZXZpb3VzID0gbnVsbDtcbn1cblxuR2VuZXJpY1dvcmtlci5wcm90b3R5cGUgPSB7XG4gICAgLyoqXG4gICAgICogUHVzaCBhIGNodW5rIHRvIHRoZSBuZXh0IHdvcmtlcnMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGNodW5rIHRoZSBjaHVuayB0byBwdXNoXG4gICAgICovXG4gICAgcHVzaCA6IGZ1bmN0aW9uIChjaHVuaykge1xuICAgICAgICB0aGlzLmVtaXQoXCJkYXRhXCIsIGNodW5rKTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIEVuZCB0aGUgc3RyZWFtLlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgdGhpcyBjYWxsIGVuZGVkIHRoZSB3b3JrZXIsIGZhbHNlIG90aGVyd2lzZS5cbiAgICAgKi9cbiAgICBlbmQgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmlzRmluaXNoZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZmx1c2goKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuZW1pdChcImVuZFwiKTtcbiAgICAgICAgICAgIHRoaXMuY2xlYW5VcCgpO1xuICAgICAgICAgICAgdGhpcy5pc0ZpbmlzaGVkID0gdHJ1ZTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdGhpcy5lbWl0KFwiZXJyb3JcIiwgZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBFbmQgdGhlIHN0cmVhbSB3aXRoIGFuIGVycm9yLlxuICAgICAqIEBwYXJhbSB7RXJyb3J9IGUgdGhlIGVycm9yIHdoaWNoIGNhdXNlZCB0aGUgcHJlbWF0dXJlIGVuZC5cbiAgICAgKiBAcmV0dXJuIHtCb29sZWFufSB0cnVlIGlmIHRoaXMgY2FsbCBlbmRlZCB0aGUgd29ya2VyIHdpdGggYW4gZXJyb3IsIGZhbHNlIG90aGVyd2lzZS5cbiAgICAgKi9cbiAgICBlcnJvciA6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGlmICh0aGlzLmlzRmluaXNoZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKHRoaXMuaXNQYXVzZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZ2VuZXJhdGVkRXJyb3IgPSBlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5pc0ZpbmlzaGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgdGhpcy5lbWl0KFwiZXJyb3JcIiwgZSk7XG5cbiAgICAgICAgICAgIC8vIGluIHRoZSB3b3JrZXJzIGNoYWluIGV4cGxvZGVkIGluIHRoZSBtaWRkbGUgb2YgdGhlIGNoYWluLFxuICAgICAgICAgICAgLy8gdGhlIGVycm9yIGV2ZW50IHdpbGwgZ28gZG93bndhcmQgYnV0IHdlIGFsc28gbmVlZCB0byBub3RpZnlcbiAgICAgICAgICAgIC8vIHdvcmtlcnMgdXB3YXJkIHRoYXQgdGhlcmUgaGFzIGJlZW4gYW4gZXJyb3IuXG4gICAgICAgICAgICBpZih0aGlzLnByZXZpb3VzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcmV2aW91cy5lcnJvcihlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jbGVhblVwKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBBZGQgYSBjYWxsYmFjayBvbiBhbiBldmVudC5cbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSB0aGUgbmFtZSBvZiB0aGUgZXZlbnQgKGRhdGEsIGVuZCwgZXJyb3IpXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgdGhlIGZ1bmN0aW9uIHRvIGNhbGwgd2hlbiB0aGUgZXZlbnQgaXMgdHJpZ2dlcmVkXG4gICAgICogQHJldHVybiB7R2VuZXJpY1dvcmtlcn0gdGhlIGN1cnJlbnQgb2JqZWN0IGZvciBjaGFpbmFiaWxpdHlcbiAgICAgKi9cbiAgICBvbiA6IGZ1bmN0aW9uIChuYW1lLCBsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLl9saXN0ZW5lcnNbbmFtZV0ucHVzaChsaXN0ZW5lcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogQ2xlYW4gYW55IHJlZmVyZW5jZXMgd2hlbiBhIHdvcmtlciBpcyBlbmRpbmcuXG4gICAgICovXG4gICAgY2xlYW5VcCA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zdHJlYW1JbmZvID0gdGhpcy5nZW5lcmF0ZWRFcnJvciA9IHRoaXMuZXh0cmFTdHJlYW1JbmZvID0gbnVsbDtcbiAgICAgICAgdGhpcy5fbGlzdGVuZXJzID0gW107XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIGFuIGV2ZW50LiBUaGlzIHdpbGwgY2FsbCByZWdpc3RlcmVkIGNhbGxiYWNrIHdpdGggdGhlIHByb3ZpZGVkIGFyZy5cbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSB0aGUgbmFtZSBvZiB0aGUgZXZlbnQgKGRhdGEsIGVuZCwgZXJyb3IpXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGFyZyB0aGUgYXJndW1lbnQgdG8gY2FsbCB0aGUgY2FsbGJhY2sgd2l0aC5cbiAgICAgKi9cbiAgICBlbWl0IDogZnVuY3Rpb24gKG5hbWUsIGFyZykge1xuICAgICAgICBpZiAodGhpcy5fbGlzdGVuZXJzW25hbWVdKSB7XG4gICAgICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5fbGlzdGVuZXJzW25hbWVdLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbGlzdGVuZXJzW25hbWVdW2ldLmNhbGwodGhpcywgYXJnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogQ2hhaW4gYSB3b3JrZXIgd2l0aCBhbiBvdGhlci5cbiAgICAgKiBAcGFyYW0ge1dvcmtlcn0gbmV4dCB0aGUgd29ya2VyIHJlY2VpdmluZyBldmVudHMgZnJvbSB0aGUgY3VycmVudCBvbmUuXG4gICAgICogQHJldHVybiB7d29ya2VyfSB0aGUgbmV4dCB3b3JrZXIgZm9yIGNoYWluYWJpbGl0eVxuICAgICAqL1xuICAgIHBpcGUgOiBmdW5jdGlvbiAobmV4dCkge1xuICAgICAgICByZXR1cm4gbmV4dC5yZWdpc3RlclByZXZpb3VzKHRoaXMpO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogU2FtZSBhcyBgcGlwZWAgaW4gdGhlIG90aGVyIGRpcmVjdGlvbi5cbiAgICAgKiBVc2luZyBhbiBBUEkgd2l0aCBgcGlwZShuZXh0KWAgaXMgdmVyeSBlYXN5LlxuICAgICAqIEltcGxlbWVudGluZyB0aGUgQVBJIHdpdGggdGhlIHBvaW50IG9mIHZpZXcgb2YgdGhlIG5leHQgb25lIHJlZ2lzdGVyaW5nXG4gICAgICogYSBzb3VyY2UgaXMgZWFzaWVyLCBzZWUgdGhlIFppcEZpbGVXb3JrZXIuXG4gICAgICogQHBhcmFtIHtXb3JrZXJ9IHByZXZpb3VzIHRoZSBwcmV2aW91cyB3b3JrZXIsIHNlbmRpbmcgZXZlbnRzIHRvIHRoaXMgb25lXG4gICAgICogQHJldHVybiB7V29ya2VyfSB0aGUgY3VycmVudCB3b3JrZXIgZm9yIGNoYWluYWJpbGl0eVxuICAgICAqL1xuICAgIHJlZ2lzdGVyUHJldmlvdXMgOiBmdW5jdGlvbiAocHJldmlvdXMpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNMb2NrZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBzdHJlYW0gJ1wiICsgdGhpcyArIFwiJyBoYXMgYWxyZWFkeSBiZWVuIHVzZWQuXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gc2hhcmluZyB0aGUgc3RyZWFtSW5mby4uLlxuICAgICAgICB0aGlzLnN0cmVhbUluZm8gPSBwcmV2aW91cy5zdHJlYW1JbmZvO1xuICAgICAgICAvLyAuLi4gYW5kIGFkZGluZyBvdXIgb3duIGJpdHNcbiAgICAgICAgdGhpcy5tZXJnZVN0cmVhbUluZm8oKTtcbiAgICAgICAgdGhpcy5wcmV2aW91cyA9ICBwcmV2aW91cztcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICBwcmV2aW91cy5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykge1xuICAgICAgICAgICAgc2VsZi5wcm9jZXNzQ2h1bmsoY2h1bmspO1xuICAgICAgICB9KTtcbiAgICAgICAgcHJldmlvdXMub24oJ2VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNlbGYuZW5kKCk7XG4gICAgICAgIH0pO1xuICAgICAgICBwcmV2aW91cy5vbignZXJyb3InLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgc2VsZi5lcnJvcihlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogUGF1c2UgdGhlIHN0cmVhbSBzbyBpdCBkb2Vzbid0IHNlbmQgZXZlbnRzIGFueW1vcmUuXG4gICAgICogQHJldHVybiB7Qm9vbGVhbn0gdHJ1ZSBpZiB0aGlzIGNhbGwgcGF1c2VkIHRoZSB3b3JrZXIsIGZhbHNlIG90aGVyd2lzZS5cbiAgICAgKi9cbiAgICBwYXVzZSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYodGhpcy5pc1BhdXNlZCB8fCB0aGlzLmlzRmluaXNoZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmlzUGF1c2VkID0gdHJ1ZTtcblxuICAgICAgICBpZih0aGlzLnByZXZpb3VzKSB7XG4gICAgICAgICAgICB0aGlzLnByZXZpb3VzLnBhdXNlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBSZXN1bWUgYSBwYXVzZWQgc3RyZWFtLlxuICAgICAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgdGhpcyBjYWxsIHJlc3VtZWQgdGhlIHdvcmtlciwgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgICAqL1xuICAgIHJlc3VtZSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYoIXRoaXMuaXNQYXVzZWQgfHwgdGhpcy5pc0ZpbmlzaGVkKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pc1BhdXNlZCA9IGZhbHNlO1xuXG4gICAgICAgIC8vIGlmIHRydWUsIHRoZSB3b3JrZXIgdHJpZWQgdG8gcmVzdW1lIGJ1dCBmYWlsZWRcbiAgICAgICAgdmFyIHdpdGhFcnJvciA9IGZhbHNlO1xuICAgICAgICBpZih0aGlzLmdlbmVyYXRlZEVycm9yKSB7XG4gICAgICAgICAgICB0aGlzLmVycm9yKHRoaXMuZ2VuZXJhdGVkRXJyb3IpO1xuICAgICAgICAgICAgd2l0aEVycm9yID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZih0aGlzLnByZXZpb3VzKSB7XG4gICAgICAgICAgICB0aGlzLnByZXZpb3VzLnJlc3VtZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuICF3aXRoRXJyb3I7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBGbHVzaCBhbnkgcmVtYWluaW5nIGJ5dGVzIGFzIHRoZSBzdHJlYW0gaXMgZW5kaW5nLlxuICAgICAqL1xuICAgIGZsdXNoIDogZnVuY3Rpb24gKCkge30sXG4gICAgLyoqXG4gICAgICogUHJvY2VzcyBhIGNodW5rLiBUaGlzIGlzIHVzdWFsbHkgdGhlIG1ldGhvZCBvdmVycmlkZGVuLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjaHVuayB0aGUgY2h1bmsgdG8gcHJvY2Vzcy5cbiAgICAgKi9cbiAgICBwcm9jZXNzQ2h1bmsgOiBmdW5jdGlvbihjaHVuaykge1xuICAgICAgICB0aGlzLnB1c2goY2h1bmspO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogQWRkIGEga2V5L3ZhbHVlIHRvIGJlIGFkZGVkIGluIHRoZSB3b3JrZXJzIGNoYWluIHN0cmVhbUluZm8gb25jZSBhY3RpdmF0ZWQuXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGtleSB0aGUga2V5IHRvIHVzZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSB2YWx1ZSB0aGUgYXNzb2NpYXRlZCB2YWx1ZVxuICAgICAqIEByZXR1cm4ge1dvcmtlcn0gdGhlIGN1cnJlbnQgd29ya2VyIGZvciBjaGFpbmFiaWxpdHlcbiAgICAgKi9cbiAgICB3aXRoU3RyZWFtSW5mbyA6IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuZXh0cmFTdHJlYW1JbmZvW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5tZXJnZVN0cmVhbUluZm8oKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBNZXJnZSB0aGlzIHdvcmtlcidzIHN0cmVhbUluZm8gaW50byB0aGUgY2hhaW4ncyBzdHJlYW1JbmZvLlxuICAgICAqL1xuICAgIG1lcmdlU3RyZWFtSW5mbyA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZm9yKHZhciBrZXkgaW4gdGhpcy5leHRyYVN0cmVhbUluZm8pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5leHRyYVN0cmVhbUluZm8uaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zdHJlYW1JbmZvW2tleV0gPSB0aGlzLmV4dHJhU3RyZWFtSW5mb1trZXldO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIExvY2sgdGhlIHN0cmVhbSB0byBwcmV2ZW50IGZ1cnRoZXIgdXBkYXRlcyBvbiB0aGUgd29ya2VycyBjaGFpbi5cbiAgICAgKiBBZnRlciBjYWxsaW5nIHRoaXMgbWV0aG9kLCBhbGwgY2FsbHMgdG8gcGlwZSB3aWxsIGZhaWwuXG4gICAgICovXG4gICAgbG9jazogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5pc0xvY2tlZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIHN0cmVhbSAnXCIgKyB0aGlzICsgXCInIGhhcyBhbHJlYWR5IGJlZW4gdXNlZC5cIik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pc0xvY2tlZCA9IHRydWU7XG4gICAgICAgIGlmICh0aGlzLnByZXZpb3VzKSB7XG4gICAgICAgICAgICB0aGlzLnByZXZpb3VzLmxvY2soKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIFByZXR0eSBwcmludCB0aGUgd29ya2VycyBjaGFpbi5cbiAgICAgKi9cbiAgICB0b1N0cmluZyA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG1lID0gXCJXb3JrZXIgXCIgKyB0aGlzLm5hbWU7XG4gICAgICAgIGlmICh0aGlzLnByZXZpb3VzKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wcmV2aW91cyArIFwiIC0+IFwiICsgbWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbWU7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEdlbmVyaWNXb3JrZXI7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG52YXIgQ29udmVydFdvcmtlciA9IHJlcXVpcmUoJy4vQ29udmVydFdvcmtlcicpO1xudmFyIEdlbmVyaWNXb3JrZXIgPSByZXF1aXJlKCcuL0dlbmVyaWNXb3JrZXInKTtcbnZhciBiYXNlNjQgPSByZXF1aXJlKCcuLi9iYXNlNjQnKTtcbnZhciBzdXBwb3J0ID0gcmVxdWlyZShcIi4uL3N1cHBvcnRcIik7XG52YXIgZXh0ZXJuYWwgPSByZXF1aXJlKFwiLi4vZXh0ZXJuYWxcIik7XG5cbnZhciBOb2RlanNTdHJlYW1PdXRwdXRBZGFwdGVyID0gbnVsbDtcbmlmIChzdXBwb3J0Lm5vZGVzdHJlYW0pIHtcbiAgICB0cnkge1xuICAgICAgICBOb2RlanNTdHJlYW1PdXRwdXRBZGFwdGVyID0gcmVxdWlyZSgnLi4vbm9kZWpzL05vZGVqc1N0cmVhbU91dHB1dEFkYXB0ZXInKTtcbiAgICB9IGNhdGNoKGUpIHt9XG59XG5cbi8qKlxuICogQXBwbHkgdGhlIGZpbmFsIHRyYW5zZm9ybWF0aW9uIG9mIHRoZSBkYXRhLiBJZiB0aGUgdXNlciB3YW50cyBhIEJsb2IgZm9yXG4gKiBleGFtcGxlLCBpdCdzIGVhc2llciB0byB3b3JrIHdpdGggYW4gVThpbnRBcnJheSBhbmQgZmluYWxseSBkbyB0aGVcbiAqIEFycmF5QnVmZmVyL0Jsb2IgY29udmVyc2lvbi5cbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIHRoZSBuYW1lIG9mIHRoZSBmaW5hbCB0eXBlXG4gKiBAcGFyYW0ge1N0cmluZ3xVaW50OEFycmF5fEJ1ZmZlcn0gY29udGVudCB0aGUgY29udGVudCB0byB0cmFuc2Zvcm1cbiAqIEBwYXJhbSB7U3RyaW5nfSBtaW1lVHlwZSB0aGUgbWltZSB0eXBlIG9mIHRoZSBjb250ZW50LCBpZiBhcHBsaWNhYmxlLlxuICogQHJldHVybiB7U3RyaW5nfFVpbnQ4QXJyYXl8QXJyYXlCdWZmZXJ8QnVmZmVyfEJsb2J9IHRoZSBjb250ZW50IGluIHRoZSByaWdodCBmb3JtYXQuXG4gKi9cbmZ1bmN0aW9uIHRyYW5zZm9ybVppcE91dHB1dCh0eXBlLCBjb250ZW50LCBtaW1lVHlwZSkge1xuICAgIHN3aXRjaCh0eXBlKSB7XG4gICAgICAgIGNhc2UgXCJibG9iXCIgOlxuICAgICAgICAgICAgcmV0dXJuIHV0aWxzLm5ld0Jsb2IodXRpbHMudHJhbnNmb3JtVG8oXCJhcnJheWJ1ZmZlclwiLCBjb250ZW50KSwgbWltZVR5cGUpO1xuICAgICAgICBjYXNlIFwiYmFzZTY0XCIgOlxuICAgICAgICAgICAgcmV0dXJuIGJhc2U2NC5lbmNvZGUoY29udGVudCk7XG4gICAgICAgIGRlZmF1bHQgOlxuICAgICAgICAgICAgcmV0dXJuIHV0aWxzLnRyYW5zZm9ybVRvKHR5cGUsIGNvbnRlbnQpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBDb25jYXRlbmF0ZSBhbiBhcnJheSBvZiBkYXRhIG9mIHRoZSBnaXZlbiB0eXBlLlxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgdGhlIHR5cGUgb2YgdGhlIGRhdGEgaW4gdGhlIGdpdmVuIGFycmF5LlxuICogQHBhcmFtIHtBcnJheX0gZGF0YUFycmF5IHRoZSBhcnJheSBjb250YWluaW5nIHRoZSBkYXRhIGNodW5rcyB0byBjb25jYXRlbmF0ZVxuICogQHJldHVybiB7U3RyaW5nfFVpbnQ4QXJyYXl8QnVmZmVyfSB0aGUgY29uY2F0ZW5hdGVkIGRhdGFcbiAqIEB0aHJvd3MgRXJyb3IgaWYgdGhlIGFza2VkIHR5cGUgaXMgdW5zdXBwb3J0ZWRcbiAqL1xuZnVuY3Rpb24gY29uY2F0ICh0eXBlLCBkYXRhQXJyYXkpIHtcbiAgICB2YXIgaSwgaW5kZXggPSAwLCByZXMgPSBudWxsLCB0b3RhbExlbmd0aCA9IDA7XG4gICAgZm9yKGkgPSAwOyBpIDwgZGF0YUFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRvdGFsTGVuZ3RoICs9IGRhdGFBcnJheVtpXS5sZW5ndGg7XG4gICAgfVxuICAgIHN3aXRjaCh0eXBlKSB7XG4gICAgICAgIGNhc2UgXCJzdHJpbmdcIjpcbiAgICAgICAgICAgIHJldHVybiBkYXRhQXJyYXkuam9pbihcIlwiKTtcbiAgICAgICAgICBjYXNlIFwiYXJyYXlcIjpcbiAgICAgICAgICAgIHJldHVybiBBcnJheS5wcm90b3R5cGUuY29uY2F0LmFwcGx5KFtdLCBkYXRhQXJyYXkpO1xuICAgICAgICBjYXNlIFwidWludDhhcnJheVwiOlxuICAgICAgICAgICAgcmVzID0gbmV3IFVpbnQ4QXJyYXkodG90YWxMZW5ndGgpO1xuICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgZGF0YUFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcmVzLnNldChkYXRhQXJyYXlbaV0sIGluZGV4KTtcbiAgICAgICAgICAgICAgICBpbmRleCArPSBkYXRhQXJyYXlbaV0ubGVuZ3RoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlcztcbiAgICAgICAgY2FzZSBcIm5vZGVidWZmZXJcIjpcbiAgICAgICAgICAgIHJldHVybiBCdWZmZXIuY29uY2F0KGRhdGFBcnJheSk7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjb25jYXQgOiB1bnN1cHBvcnRlZCB0eXBlICdcIiAgKyB0eXBlICsgXCInXCIpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBMaXN0ZW4gYSBTdHJlYW1IZWxwZXIsIGFjY3VtdWxhdGUgaXRzIGNvbnRlbnQgYW5kIGNvbmNhdGVuYXRlIGl0IGludG8gYVxuICogY29tcGxldGUgYmxvY2suXG4gKiBAcGFyYW0ge1N0cmVhbUhlbHBlcn0gaGVscGVyIHRoZSBoZWxwZXIgdG8gdXNlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gdXBkYXRlQ2FsbGJhY2sgYSBjYWxsYmFjayBjYWxsZWQgb24gZWFjaCB1cGRhdGUuIENhbGxlZFxuICogd2l0aCBvbmUgYXJnIDpcbiAqIC0gdGhlIG1ldGFkYXRhIGxpbmtlZCB0byB0aGUgdXBkYXRlIHJlY2VpdmVkLlxuICogQHJldHVybiBQcm9taXNlIHRoZSBwcm9taXNlIGZvciB0aGUgYWNjdW11bGF0aW9uLlxuICovXG5mdW5jdGlvbiBhY2N1bXVsYXRlKGhlbHBlciwgdXBkYXRlQ2FsbGJhY2spIHtcbiAgICByZXR1cm4gbmV3IGV4dGVybmFsLlByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCl7XG4gICAgICAgIHZhciBkYXRhQXJyYXkgPSBbXTtcbiAgICAgICAgdmFyIGNodW5rVHlwZSA9IGhlbHBlci5faW50ZXJuYWxUeXBlLFxuICAgICAgICAgICAgcmVzdWx0VHlwZSA9IGhlbHBlci5fb3V0cHV0VHlwZSxcbiAgICAgICAgICAgIG1pbWVUeXBlID0gaGVscGVyLl9taW1lVHlwZTtcbiAgICAgICAgaGVscGVyXG4gICAgICAgIC5vbignZGF0YScsIGZ1bmN0aW9uIChkYXRhLCBtZXRhKSB7XG4gICAgICAgICAgICBkYXRhQXJyYXkucHVzaChkYXRhKTtcbiAgICAgICAgICAgIGlmKHVwZGF0ZUNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlQ2FsbGJhY2sobWV0YSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5vbignZXJyb3InLCBmdW5jdGlvbihlcnIpIHtcbiAgICAgICAgICAgIGRhdGFBcnJheSA9IFtdO1xuICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgIH0pXG4gICAgICAgIC5vbignZW5kJywgZnVuY3Rpb24gKCl7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSB0cmFuc2Zvcm1aaXBPdXRwdXQocmVzdWx0VHlwZSwgY29uY2F0KGNodW5rVHlwZSwgZGF0YUFycmF5KSwgbWltZVR5cGUpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkYXRhQXJyYXkgPSBbXTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc3VtZSgpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIEFuIGhlbHBlciB0byBlYXNpbHkgdXNlIHdvcmtlcnMgb3V0c2lkZSBvZiBKU1ppcC5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtXb3JrZXJ9IHdvcmtlciB0aGUgd29ya2VyIHRvIHdyYXBcbiAqIEBwYXJhbSB7U3RyaW5nfSBvdXRwdXRUeXBlIHRoZSB0eXBlIG9mIGRhdGEgZXhwZWN0ZWQgYnkgdGhlIHVzZVxuICogQHBhcmFtIHtTdHJpbmd9IG1pbWVUeXBlIHRoZSBtaW1lIHR5cGUgb2YgdGhlIGNvbnRlbnQsIGlmIGFwcGxpY2FibGUuXG4gKi9cbmZ1bmN0aW9uIFN0cmVhbUhlbHBlcih3b3JrZXIsIG91dHB1dFR5cGUsIG1pbWVUeXBlKSB7XG4gICAgdmFyIGludGVybmFsVHlwZSA9IG91dHB1dFR5cGU7XG4gICAgc3dpdGNoKG91dHB1dFR5cGUpIHtcbiAgICAgICAgY2FzZSBcImJsb2JcIjpcbiAgICAgICAgY2FzZSBcImFycmF5YnVmZmVyXCI6XG4gICAgICAgICAgICBpbnRlcm5hbFR5cGUgPSBcInVpbnQ4YXJyYXlcIjtcbiAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJiYXNlNjRcIjpcbiAgICAgICAgICAgIGludGVybmFsVHlwZSA9IFwic3RyaW5nXCI7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAgIC8vIHRoZSB0eXBlIHVzZWQgaW50ZXJuYWxseVxuICAgICAgICB0aGlzLl9pbnRlcm5hbFR5cGUgPSBpbnRlcm5hbFR5cGU7XG4gICAgICAgIC8vIHRoZSB0eXBlIHVzZWQgdG8gb3V0cHV0IHJlc3VsdHNcbiAgICAgICAgdGhpcy5fb3V0cHV0VHlwZSA9IG91dHB1dFR5cGU7XG4gICAgICAgIC8vIHRoZSBtaW1lIHR5cGVcbiAgICAgICAgdGhpcy5fbWltZVR5cGUgPSBtaW1lVHlwZTtcbiAgICAgICAgdXRpbHMuY2hlY2tTdXBwb3J0KGludGVybmFsVHlwZSk7XG4gICAgICAgIHRoaXMuX3dvcmtlciA9IHdvcmtlci5waXBlKG5ldyBDb252ZXJ0V29ya2VyKGludGVybmFsVHlwZSkpO1xuICAgICAgICAvLyB0aGUgbGFzdCB3b3JrZXJzIGNhbiBiZSByZXdpcmVkIHdpdGhvdXQgaXNzdWVzIGJ1dCB3ZSBuZWVkIHRvXG4gICAgICAgIC8vIHByZXZlbnQgYW55IHVwZGF0ZXMgb24gcHJldmlvdXMgd29ya2Vycy5cbiAgICAgICAgd29ya2VyLmxvY2soKTtcbiAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgdGhpcy5fd29ya2VyID0gbmV3IEdlbmVyaWNXb3JrZXIoXCJlcnJvclwiKTtcbiAgICAgICAgdGhpcy5fd29ya2VyLmVycm9yKGUpO1xuICAgIH1cbn1cblxuU3RyZWFtSGVscGVyLnByb3RvdHlwZSA9IHtcbiAgICAvKipcbiAgICAgKiBMaXN0ZW4gYSBTdHJlYW1IZWxwZXIsIGFjY3VtdWxhdGUgaXRzIGNvbnRlbnQgYW5kIGNvbmNhdGVuYXRlIGl0IGludG8gYVxuICAgICAqIGNvbXBsZXRlIGJsb2NrLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHVwZGF0ZUNiIHRoZSB1cGRhdGUgY2FsbGJhY2suXG4gICAgICogQHJldHVybiBQcm9taXNlIHRoZSBwcm9taXNlIGZvciB0aGUgYWNjdW11bGF0aW9uLlxuICAgICAqL1xuICAgIGFjY3VtdWxhdGUgOiBmdW5jdGlvbiAodXBkYXRlQ2IpIHtcbiAgICAgICAgcmV0dXJuIGFjY3VtdWxhdGUodGhpcywgdXBkYXRlQ2IpO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogQWRkIGEgbGlzdGVuZXIgb24gYW4gZXZlbnQgdHJpZ2dlcmVkIG9uIGEgc3RyZWFtLlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBldnQgdGhlIG5hbWUgb2YgdGhlIGV2ZW50XG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gdGhlIGxpc3RlbmVyXG4gICAgICogQHJldHVybiB7U3RyZWFtSGVscGVyfSB0aGUgY3VycmVudCBoZWxwZXIuXG4gICAgICovXG4gICAgb24gOiBmdW5jdGlvbiAoZXZ0LCBmbikge1xuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgaWYoZXZ0ID09PSBcImRhdGFcIikge1xuICAgICAgICAgICAgdGhpcy5fd29ya2VyLm9uKGV2dCwgZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgICAgICAgICAgICAgZm4uY2FsbChzZWxmLCBjaHVuay5kYXRhLCBjaHVuay5tZXRhKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fd29ya2VyLm9uKGV2dCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHV0aWxzLmRlbGF5KGZuLCBhcmd1bWVudHMsIHNlbGYpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBSZXN1bWUgdGhlIGZsb3cgb2YgY2h1bmtzLlxuICAgICAqIEByZXR1cm4ge1N0cmVhbUhlbHBlcn0gdGhlIGN1cnJlbnQgaGVscGVyLlxuICAgICAqL1xuICAgIHJlc3VtZSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdXRpbHMuZGVsYXkodGhpcy5fd29ya2VyLnJlc3VtZSwgW10sIHRoaXMuX3dvcmtlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogUGF1c2UgdGhlIGZsb3cgb2YgY2h1bmtzLlxuICAgICAqIEByZXR1cm4ge1N0cmVhbUhlbHBlcn0gdGhlIGN1cnJlbnQgaGVscGVyLlxuICAgICAqL1xuICAgIHBhdXNlIDogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLl93b3JrZXIucGF1c2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBSZXR1cm4gYSBub2RlanMgc3RyZWFtIGZvciB0aGlzIGhlbHBlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB1cGRhdGVDYiB0aGUgdXBkYXRlIGNhbGxiYWNrLlxuICAgICAqIEByZXR1cm4ge05vZGVqc1N0cmVhbU91dHB1dEFkYXB0ZXJ9IHRoZSBub2RlanMgc3RyZWFtLlxuICAgICAqL1xuICAgIHRvTm9kZWpzU3RyZWFtIDogZnVuY3Rpb24gKHVwZGF0ZUNiKSB7XG4gICAgICAgIHV0aWxzLmNoZWNrU3VwcG9ydChcIm5vZGVzdHJlYW1cIik7XG4gICAgICAgIGlmICh0aGlzLl9vdXRwdXRUeXBlICE9PSBcIm5vZGVidWZmZXJcIikge1xuICAgICAgICAgICAgLy8gYW4gb2JqZWN0IHN0cmVhbSBjb250YWluaW5nIGJsb2IvYXJyYXlidWZmZXIvdWludDhhcnJheS9zdHJpbmdcbiAgICAgICAgICAgIC8vIGlzIHN0cmFuZ2UgYW5kIEkgZG9uJ3Qga25vdyBpZiBpdCB3b3VsZCBiZSB1c2VmdWwuXG4gICAgICAgICAgICAvLyBJIHlvdSBmaW5kIHRoaXMgY29tbWVudCBhbmQgaGF2ZSBhIGdvb2QgdXNlY2FzZSwgcGxlYXNlIG9wZW4gYVxuICAgICAgICAgICAgLy8gYnVnIHJlcG9ydCAhXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IodGhpcy5fb3V0cHV0VHlwZSArIFwiIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBtZXRob2RcIik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IE5vZGVqc1N0cmVhbU91dHB1dEFkYXB0ZXIodGhpcywge1xuICAgICAgICAgICAgb2JqZWN0TW9kZSA6IHRoaXMuX291dHB1dFR5cGUgIT09IFwibm9kZWJ1ZmZlclwiXG4gICAgICAgIH0sIHVwZGF0ZUNiKTtcbiAgICB9XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gU3RyZWFtSGVscGVyO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLmJhc2U2NCA9IHRydWU7XG5leHBvcnRzLmFycmF5ID0gdHJ1ZTtcbmV4cG9ydHMuc3RyaW5nID0gdHJ1ZTtcbmV4cG9ydHMuYXJyYXlidWZmZXIgPSB0eXBlb2YgQXJyYXlCdWZmZXIgIT09IFwidW5kZWZpbmVkXCIgJiYgdHlwZW9mIFVpbnQ4QXJyYXkgIT09IFwidW5kZWZpbmVkXCI7XG5leHBvcnRzLm5vZGVidWZmZXIgPSB0eXBlb2YgQnVmZmVyICE9PSBcInVuZGVmaW5lZFwiO1xuLy8gY29udGFpbnMgdHJ1ZSBpZiBKU1ppcCBjYW4gcmVhZC9nZW5lcmF0ZSBVaW50OEFycmF5LCBmYWxzZSBvdGhlcndpc2UuXG5leHBvcnRzLnVpbnQ4YXJyYXkgPSB0eXBlb2YgVWludDhBcnJheSAhPT0gXCJ1bmRlZmluZWRcIjtcblxuaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgIGV4cG9ydHMuYmxvYiA9IGZhbHNlO1xufVxuZWxzZSB7XG4gICAgdmFyIGJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcigwKTtcbiAgICB0cnkge1xuICAgICAgICBleHBvcnRzLmJsb2IgPSBuZXcgQmxvYihbYnVmZmVyXSwge1xuICAgICAgICAgICAgdHlwZTogXCJhcHBsaWNhdGlvbi96aXBcIlxuICAgICAgICB9KS5zaXplID09PSAwO1xuICAgIH1cbiAgICBjYXRjaCAoZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmFyIEJ1aWxkZXIgPSBzZWxmLkJsb2JCdWlsZGVyIHx8IHNlbGYuV2ViS2l0QmxvYkJ1aWxkZXIgfHwgc2VsZi5Nb3pCbG9iQnVpbGRlciB8fCBzZWxmLk1TQmxvYkJ1aWxkZXI7XG4gICAgICAgICAgICB2YXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKCk7XG4gICAgICAgICAgICBidWlsZGVyLmFwcGVuZChidWZmZXIpO1xuICAgICAgICAgICAgZXhwb3J0cy5ibG9iID0gYnVpbGRlci5nZXRCbG9iKCdhcHBsaWNhdGlvbi96aXAnKS5zaXplID09PSAwO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICBleHBvcnRzLmJsb2IgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxudHJ5IHtcbiAgICBleHBvcnRzLm5vZGVzdHJlYW0gPSAhIXJlcXVpcmUoJ3JlYWRhYmxlLXN0cmVhbScpLlJlYWRhYmxlO1xufSBjYXRjaChlKSB7XG4gICAgZXhwb3J0cy5ub2Rlc3RyZWFtID0gZmFsc2U7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbnZhciBzdXBwb3J0ID0gcmVxdWlyZSgnLi9zdXBwb3J0Jyk7XG52YXIgbm9kZWpzVXRpbHMgPSByZXF1aXJlKCcuL25vZGVqc1V0aWxzJyk7XG52YXIgR2VuZXJpY1dvcmtlciA9IHJlcXVpcmUoJy4vc3RyZWFtL0dlbmVyaWNXb3JrZXInKTtcblxuLyoqXG4gKiBUaGUgZm9sbG93aW5nIGZ1bmN0aW9ucyBjb21lIGZyb20gcGFrbywgZnJvbSBwYWtvL2xpYi91dGlscy9zdHJpbmdzXG4gKiByZWxlYXNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UsIHNlZSBwYWtvIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlY2EvcGFrby9cbiAqL1xuXG4vLyBUYWJsZSB3aXRoIHV0ZjggbGVuZ3RocyAoY2FsY3VsYXRlZCBieSBmaXJzdCBieXRlIG9mIHNlcXVlbmNlKVxuLy8gTm90ZSwgdGhhdCA1ICYgNi1ieXRlIHZhbHVlcyBhbmQgc29tZSA0LWJ5dGUgdmFsdWVzIGNhbiBub3QgYmUgcmVwcmVzZW50ZWQgaW4gSlMsXG4vLyBiZWNhdXNlIG1heCBwb3NzaWJsZSBjb2RlcG9pbnQgaXMgMHgxMGZmZmZcbnZhciBfdXRmOGxlbiA9IG5ldyBBcnJheSgyNTYpO1xuZm9yICh2YXIgaT0wOyBpPDI1NjsgaSsrKSB7XG4gIF91dGY4bGVuW2ldID0gKGkgPj0gMjUyID8gNiA6IGkgPj0gMjQ4ID8gNSA6IGkgPj0gMjQwID8gNCA6IGkgPj0gMjI0ID8gMyA6IGkgPj0gMTkyID8gMiA6IDEpO1xufVxuX3V0ZjhsZW5bMjU0XT1fdXRmOGxlblsyNTRdPTE7IC8vIEludmFsaWQgc2VxdWVuY2Ugc3RhcnRcblxuLy8gY29udmVydCBzdHJpbmcgdG8gYXJyYXkgKHR5cGVkLCB3aGVuIHBvc3NpYmxlKVxudmFyIHN0cmluZzJidWYgPSBmdW5jdGlvbiAoc3RyKSB7XG4gICAgdmFyIGJ1ZiwgYywgYzIsIG1fcG9zLCBpLCBzdHJfbGVuID0gc3RyLmxlbmd0aCwgYnVmX2xlbiA9IDA7XG5cbiAgICAvLyBjb3VudCBiaW5hcnkgc2l6ZVxuICAgIGZvciAobV9wb3MgPSAwOyBtX3BvcyA8IHN0cl9sZW47IG1fcG9zKyspIHtcbiAgICAgICAgYyA9IHN0ci5jaGFyQ29kZUF0KG1fcG9zKTtcbiAgICAgICAgaWYgKChjICYgMHhmYzAwKSA9PT0gMHhkODAwICYmIChtX3BvcysxIDwgc3RyX2xlbikpIHtcbiAgICAgICAgICAgIGMyID0gc3RyLmNoYXJDb2RlQXQobV9wb3MrMSk7XG4gICAgICAgICAgICBpZiAoKGMyICYgMHhmYzAwKSA9PT0gMHhkYzAwKSB7XG4gICAgICAgICAgICAgICAgYyA9IDB4MTAwMDAgKyAoKGMgLSAweGQ4MDApIDw8IDEwKSArIChjMiAtIDB4ZGMwMCk7XG4gICAgICAgICAgICAgICAgbV9wb3MrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBidWZfbGVuICs9IGMgPCAweDgwID8gMSA6IGMgPCAweDgwMCA/IDIgOiBjIDwgMHgxMDAwMCA/IDMgOiA0O1xuICAgIH1cblxuICAgIC8vIGFsbG9jYXRlIGJ1ZmZlclxuICAgIGlmIChzdXBwb3J0LnVpbnQ4YXJyYXkpIHtcbiAgICAgICAgYnVmID0gbmV3IFVpbnQ4QXJyYXkoYnVmX2xlbik7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgYnVmID0gbmV3IEFycmF5KGJ1Zl9sZW4pO1xuICAgIH1cblxuICAgIC8vIGNvbnZlcnRcbiAgICBmb3IgKGk9MCwgbV9wb3MgPSAwOyBpIDwgYnVmX2xlbjsgbV9wb3MrKykge1xuICAgICAgICBjID0gc3RyLmNoYXJDb2RlQXQobV9wb3MpO1xuICAgICAgICBpZiAoKGMgJiAweGZjMDApID09PSAweGQ4MDAgJiYgKG1fcG9zKzEgPCBzdHJfbGVuKSkge1xuICAgICAgICAgICAgYzIgPSBzdHIuY2hhckNvZGVBdChtX3BvcysxKTtcbiAgICAgICAgICAgIGlmICgoYzIgJiAweGZjMDApID09PSAweGRjMDApIHtcbiAgICAgICAgICAgICAgICBjID0gMHgxMDAwMCArICgoYyAtIDB4ZDgwMCkgPDwgMTApICsgKGMyIC0gMHhkYzAwKTtcbiAgICAgICAgICAgICAgICBtX3BvcysrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChjIDwgMHg4MCkge1xuICAgICAgICAgICAgLyogb25lIGJ5dGUgKi9cbiAgICAgICAgICAgIGJ1ZltpKytdID0gYztcbiAgICAgICAgfSBlbHNlIGlmIChjIDwgMHg4MDApIHtcbiAgICAgICAgICAgIC8qIHR3byBieXRlcyAqL1xuICAgICAgICAgICAgYnVmW2krK10gPSAweEMwIHwgKGMgPj4+IDYpO1xuICAgICAgICAgICAgYnVmW2krK10gPSAweDgwIHwgKGMgJiAweDNmKTtcbiAgICAgICAgfSBlbHNlIGlmIChjIDwgMHgxMDAwMCkge1xuICAgICAgICAgICAgLyogdGhyZWUgYnl0ZXMgKi9cbiAgICAgICAgICAgIGJ1ZltpKytdID0gMHhFMCB8IChjID4+PiAxMik7XG4gICAgICAgICAgICBidWZbaSsrXSA9IDB4ODAgfCAoYyA+Pj4gNiAmIDB4M2YpO1xuICAgICAgICAgICAgYnVmW2krK10gPSAweDgwIHwgKGMgJiAweDNmKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8qIGZvdXIgYnl0ZXMgKi9cbiAgICAgICAgICAgIGJ1ZltpKytdID0gMHhmMCB8IChjID4+PiAxOCk7XG4gICAgICAgICAgICBidWZbaSsrXSA9IDB4ODAgfCAoYyA+Pj4gMTIgJiAweDNmKTtcbiAgICAgICAgICAgIGJ1ZltpKytdID0gMHg4MCB8IChjID4+PiA2ICYgMHgzZik7XG4gICAgICAgICAgICBidWZbaSsrXSA9IDB4ODAgfCAoYyAmIDB4M2YpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ1Zjtcbn07XG5cbi8vIENhbGN1bGF0ZSBtYXggcG9zc2libGUgcG9zaXRpb24gaW4gdXRmOCBidWZmZXIsXG4vLyB0aGF0IHdpbGwgbm90IGJyZWFrIHNlcXVlbmNlLiBJZiB0aGF0J3Mgbm90IHBvc3NpYmxlXG4vLyAtICh2ZXJ5IHNtYWxsIGxpbWl0cykgcmV0dXJuIG1heCBzaXplIGFzIGlzLlxuLy9cbi8vIGJ1ZltdIC0gdXRmOCBieXRlcyBhcnJheVxuLy8gbWF4ICAgLSBsZW5ndGggbGltaXQgKG1hbmRhdG9yeSk7XG52YXIgdXRmOGJvcmRlciA9IGZ1bmN0aW9uKGJ1ZiwgbWF4KSB7XG4gICAgdmFyIHBvcztcblxuICAgIG1heCA9IG1heCB8fCBidWYubGVuZ3RoO1xuICAgIGlmIChtYXggPiBidWYubGVuZ3RoKSB7IG1heCA9IGJ1Zi5sZW5ndGg7IH1cblxuICAgIC8vIGdvIGJhY2sgZnJvbSBsYXN0IHBvc2l0aW9uLCB1bnRpbCBzdGFydCBvZiBzZXF1ZW5jZSBmb3VuZFxuICAgIHBvcyA9IG1heC0xO1xuICAgIHdoaWxlIChwb3MgPj0gMCAmJiAoYnVmW3Bvc10gJiAweEMwKSA9PT0gMHg4MCkgeyBwb3MtLTsgfVxuXG4gICAgLy8gRnVja3VwIC0gdmVyeSBzbWFsbCBhbmQgYnJva2VuIHNlcXVlbmNlLFxuICAgIC8vIHJldHVybiBtYXgsIGJlY2F1c2Ugd2Ugc2hvdWxkIHJldHVybiBzb21ldGhpbmcgYW55d2F5LlxuICAgIGlmIChwb3MgPCAwKSB7IHJldHVybiBtYXg7IH1cblxuICAgIC8vIElmIHdlIGNhbWUgdG8gc3RhcnQgb2YgYnVmZmVyIC0gdGhhdCBtZWFucyB2dWZmZXIgaXMgdG9vIHNtYWxsLFxuICAgIC8vIHJldHVybiBtYXggdG9vLlxuICAgIGlmIChwb3MgPT09IDApIHsgcmV0dXJuIG1heDsgfVxuXG4gICAgcmV0dXJuIChwb3MgKyBfdXRmOGxlbltidWZbcG9zXV0gPiBtYXgpID8gcG9zIDogbWF4O1xufTtcblxuLy8gY29udmVydCBhcnJheSB0byBzdHJpbmdcbnZhciBidWYyc3RyaW5nID0gZnVuY3Rpb24gKGJ1Zikge1xuICAgIHZhciBzdHIsIGksIG91dCwgYywgY19sZW47XG4gICAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGg7XG5cbiAgICAvLyBSZXNlcnZlIG1heCBwb3NzaWJsZSBsZW5ndGggKDIgd29yZHMgcGVyIGNoYXIpXG4gICAgLy8gTkI6IGJ5IHVua25vd24gcmVhc29ucywgQXJyYXkgaXMgc2lnbmlmaWNhbnRseSBmYXN0ZXIgZm9yXG4gICAgLy8gICAgIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkgdGhhbiBVaW50MTZBcnJheS5cbiAgICB2YXIgdXRmMTZidWYgPSBuZXcgQXJyYXkobGVuKjIpO1xuXG4gICAgZm9yIChvdXQ9MCwgaT0wOyBpPGxlbjspIHtcbiAgICAgICAgYyA9IGJ1ZltpKytdO1xuICAgICAgICAvLyBxdWljayBwcm9jZXNzIGFzY2lpXG4gICAgICAgIGlmIChjIDwgMHg4MCkgeyB1dGYxNmJ1ZltvdXQrK10gPSBjOyBjb250aW51ZTsgfVxuXG4gICAgICAgIGNfbGVuID0gX3V0ZjhsZW5bY107XG4gICAgICAgIC8vIHNraXAgNSAmIDYgYnl0ZSBjb2Rlc1xuICAgICAgICBpZiAoY19sZW4gPiA0KSB7IHV0ZjE2YnVmW291dCsrXSA9IDB4ZmZmZDsgaSArPSBjX2xlbi0xOyBjb250aW51ZTsgfVxuXG4gICAgICAgIC8vIGFwcGx5IG1hc2sgb24gZmlyc3QgYnl0ZVxuICAgICAgICBjICY9IGNfbGVuID09PSAyID8gMHgxZiA6IGNfbGVuID09PSAzID8gMHgwZiA6IDB4MDc7XG4gICAgICAgIC8vIGpvaW4gdGhlIHJlc3RcbiAgICAgICAgd2hpbGUgKGNfbGVuID4gMSAmJiBpIDwgbGVuKSB7XG4gICAgICAgICAgICBjID0gKGMgPDwgNikgfCAoYnVmW2krK10gJiAweDNmKTtcbiAgICAgICAgICAgIGNfbGVuLS07XG4gICAgICAgIH1cblxuICAgICAgICAvLyB0ZXJtaW5hdGVkIGJ5IGVuZCBvZiBzdHJpbmc/XG4gICAgICAgIGlmIChjX2xlbiA+IDEpIHsgdXRmMTZidWZbb3V0KytdID0gMHhmZmZkOyBjb250aW51ZTsgfVxuXG4gICAgICAgIGlmIChjIDwgMHgxMDAwMCkge1xuICAgICAgICAgICAgdXRmMTZidWZbb3V0KytdID0gYztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGMgLT0gMHgxMDAwMDtcbiAgICAgICAgICAgIHV0ZjE2YnVmW291dCsrXSA9IDB4ZDgwMCB8ICgoYyA+PiAxMCkgJiAweDNmZik7XG4gICAgICAgICAgICB1dGYxNmJ1ZltvdXQrK10gPSAweGRjMDAgfCAoYyAmIDB4M2ZmKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNocmlua0J1Zih1dGYxNmJ1Ziwgb3V0KVxuICAgIGlmICh1dGYxNmJ1Zi5sZW5ndGggIT09IG91dCkge1xuICAgICAgICBpZih1dGYxNmJ1Zi5zdWJhcnJheSkge1xuICAgICAgICAgICAgdXRmMTZidWYgPSB1dGYxNmJ1Zi5zdWJhcnJheSgwLCBvdXQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdXRmMTZidWYubGVuZ3RoID0gb3V0O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgdXRmMTZidWYpO1xuICAgIHJldHVybiB1dGlscy5hcHBseUZyb21DaGFyQ29kZSh1dGYxNmJ1Zik7XG59O1xuXG5cbi8vIFRoYXQncyBhbGwgZm9yIHRoZSBwYWtvIGZ1bmN0aW9ucy5cblxuXG4vKipcbiAqIFRyYW5zZm9ybSBhIGphdmFzY3JpcHQgc3RyaW5nIGludG8gYW4gYXJyYXkgKHR5cGVkIGlmIHBvc3NpYmxlKSBvZiBieXRlcyxcbiAqIFVURi04IGVuY29kZWQuXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyIHRoZSBzdHJpbmcgdG8gZW5jb2RlXG4gKiBAcmV0dXJuIHtBcnJheXxVaW50OEFycmF5fEJ1ZmZlcn0gdGhlIFVURi04IGVuY29kZWQgc3RyaW5nLlxuICovXG5leHBvcnRzLnV0ZjhlbmNvZGUgPSBmdW5jdGlvbiB1dGY4ZW5jb2RlKHN0cikge1xuICAgIGlmIChzdXBwb3J0Lm5vZGVidWZmZXIpIHtcbiAgICAgICAgcmV0dXJuIG5vZGVqc1V0aWxzLm5ld0J1ZmZlckZyb20oc3RyLCBcInV0Zi04XCIpO1xuICAgIH1cblxuICAgIHJldHVybiBzdHJpbmcyYnVmKHN0cik7XG59O1xuXG5cbi8qKlxuICogVHJhbnNmb3JtIGEgYnl0ZXMgYXJyYXkgKG9yIGEgcmVwcmVzZW50YXRpb24pIHJlcHJlc2VudGluZyBhbiBVVEYtOCBlbmNvZGVkXG4gKiBzdHJpbmcgaW50byBhIGphdmFzY3JpcHQgc3RyaW5nLlxuICogQHBhcmFtIHtBcnJheXxVaW50OEFycmF5fEJ1ZmZlcn0gYnVmIHRoZSBkYXRhIGRlIGRlY29kZVxuICogQHJldHVybiB7U3RyaW5nfSB0aGUgZGVjb2RlZCBzdHJpbmcuXG4gKi9cbmV4cG9ydHMudXRmOGRlY29kZSA9IGZ1bmN0aW9uIHV0ZjhkZWNvZGUoYnVmKSB7XG4gICAgaWYgKHN1cHBvcnQubm9kZWJ1ZmZlcikge1xuICAgICAgICByZXR1cm4gdXRpbHMudHJhbnNmb3JtVG8oXCJub2RlYnVmZmVyXCIsIGJ1ZikudG9TdHJpbmcoXCJ1dGYtOFwiKTtcbiAgICB9XG5cbiAgICBidWYgPSB1dGlscy50cmFuc2Zvcm1UbyhzdXBwb3J0LnVpbnQ4YXJyYXkgPyBcInVpbnQ4YXJyYXlcIiA6IFwiYXJyYXlcIiwgYnVmKTtcblxuICAgIHJldHVybiBidWYyc3RyaW5nKGJ1Zik7XG59O1xuXG4vKipcbiAqIEEgd29ya2VyIHRvIGRlY29kZSB1dGY4IGVuY29kZWQgYmluYXJ5IGNodW5rcyBpbnRvIHN0cmluZyBjaHVua3MuXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gVXRmOERlY29kZVdvcmtlcigpIHtcbiAgICBHZW5lcmljV29ya2VyLmNhbGwodGhpcywgXCJ1dGYtOCBkZWNvZGVcIik7XG4gICAgLy8gdGhlIGxhc3QgYnl0ZXMgaWYgYSBjaHVuayBkaWRuJ3QgZW5kIHdpdGggYSBjb21wbGV0ZSBjb2RlcG9pbnQuXG4gICAgdGhpcy5sZWZ0T3ZlciA9IG51bGw7XG59XG51dGlscy5pbmhlcml0cyhVdGY4RGVjb2RlV29ya2VyLCBHZW5lcmljV29ya2VyKTtcblxuLyoqXG4gKiBAc2VlIEdlbmVyaWNXb3JrZXIucHJvY2Vzc0NodW5rXG4gKi9cblV0ZjhEZWNvZGVXb3JrZXIucHJvdG90eXBlLnByb2Nlc3NDaHVuayA9IGZ1bmN0aW9uIChjaHVuaykge1xuXG4gICAgdmFyIGRhdGEgPSB1dGlscy50cmFuc2Zvcm1UbyhzdXBwb3J0LnVpbnQ4YXJyYXkgPyBcInVpbnQ4YXJyYXlcIiA6IFwiYXJyYXlcIiwgY2h1bmsuZGF0YSk7XG5cbiAgICAvLyAxc3Qgc3RlcCwgcmUtdXNlIHdoYXQncyBsZWZ0IG9mIHRoZSBwcmV2aW91cyBjaHVua1xuICAgIGlmICh0aGlzLmxlZnRPdmVyICYmIHRoaXMubGVmdE92ZXIubGVuZ3RoKSB7XG4gICAgICAgIGlmKHN1cHBvcnQudWludDhhcnJheSkge1xuICAgICAgICAgICAgdmFyIHByZXZpb3VzRGF0YSA9IGRhdGE7XG4gICAgICAgICAgICBkYXRhID0gbmV3IFVpbnQ4QXJyYXkocHJldmlvdXNEYXRhLmxlbmd0aCArIHRoaXMubGVmdE92ZXIubGVuZ3RoKTtcbiAgICAgICAgICAgIGRhdGEuc2V0KHRoaXMubGVmdE92ZXIsIDApO1xuICAgICAgICAgICAgZGF0YS5zZXQocHJldmlvdXNEYXRhLCB0aGlzLmxlZnRPdmVyLmxlbmd0aCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkYXRhID0gdGhpcy5sZWZ0T3Zlci5jb25jYXQoZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5sZWZ0T3ZlciA9IG51bGw7XG4gICAgfVxuXG4gICAgdmFyIG5leHRCb3VuZGFyeSA9IHV0Zjhib3JkZXIoZGF0YSk7XG4gICAgdmFyIHVzYWJsZURhdGEgPSBkYXRhO1xuICAgIGlmIChuZXh0Qm91bmRhcnkgIT09IGRhdGEubGVuZ3RoKSB7XG4gICAgICAgIGlmIChzdXBwb3J0LnVpbnQ4YXJyYXkpIHtcbiAgICAgICAgICAgIHVzYWJsZURhdGEgPSBkYXRhLnN1YmFycmF5KDAsIG5leHRCb3VuZGFyeSk7XG4gICAgICAgICAgICB0aGlzLmxlZnRPdmVyID0gZGF0YS5zdWJhcnJheShuZXh0Qm91bmRhcnksIGRhdGEubGVuZ3RoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHVzYWJsZURhdGEgPSBkYXRhLnNsaWNlKDAsIG5leHRCb3VuZGFyeSk7XG4gICAgICAgICAgICB0aGlzLmxlZnRPdmVyID0gZGF0YS5zbGljZShuZXh0Qm91bmRhcnksIGRhdGEubGVuZ3RoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMucHVzaCh7XG4gICAgICAgIGRhdGEgOiBleHBvcnRzLnV0ZjhkZWNvZGUodXNhYmxlRGF0YSksXG4gICAgICAgIG1ldGEgOiBjaHVuay5tZXRhXG4gICAgfSk7XG59O1xuXG4vKipcbiAqIEBzZWUgR2VuZXJpY1dvcmtlci5mbHVzaFxuICovXG5VdGY4RGVjb2RlV29ya2VyLnByb3RvdHlwZS5mbHVzaCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZih0aGlzLmxlZnRPdmVyICYmIHRoaXMubGVmdE92ZXIubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMucHVzaCh7XG4gICAgICAgICAgICBkYXRhIDogZXhwb3J0cy51dGY4ZGVjb2RlKHRoaXMubGVmdE92ZXIpLFxuICAgICAgICAgICAgbWV0YSA6IHt9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmxlZnRPdmVyID0gbnVsbDtcbiAgICB9XG59O1xuZXhwb3J0cy5VdGY4RGVjb2RlV29ya2VyID0gVXRmOERlY29kZVdvcmtlcjtcblxuLyoqXG4gKiBBIHdvcmtlciB0byBlbmRjb2RlIHN0cmluZyBjaHVua3MgaW50byB1dGY4IGVuY29kZWQgYmluYXJ5IGNodW5rcy5cbiAqIEBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBVdGY4RW5jb2RlV29ya2VyKCkge1xuICAgIEdlbmVyaWNXb3JrZXIuY2FsbCh0aGlzLCBcInV0Zi04IGVuY29kZVwiKTtcbn1cbnV0aWxzLmluaGVyaXRzKFV0ZjhFbmNvZGVXb3JrZXIsIEdlbmVyaWNXb3JrZXIpO1xuXG4vKipcbiAqIEBzZWUgR2VuZXJpY1dvcmtlci5wcm9jZXNzQ2h1bmtcbiAqL1xuVXRmOEVuY29kZVdvcmtlci5wcm90b3R5cGUucHJvY2Vzc0NodW5rID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgdGhpcy5wdXNoKHtcbiAgICAgICAgZGF0YSA6IGV4cG9ydHMudXRmOGVuY29kZShjaHVuay5kYXRhKSxcbiAgICAgICAgbWV0YSA6IGNodW5rLm1ldGFcbiAgICB9KTtcbn07XG5leHBvcnRzLlV0ZjhFbmNvZGVXb3JrZXIgPSBVdGY4RW5jb2RlV29ya2VyO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgc3VwcG9ydCA9IHJlcXVpcmUoJy4vc3VwcG9ydCcpO1xudmFyIGJhc2U2NCA9IHJlcXVpcmUoJy4vYmFzZTY0Jyk7XG52YXIgbm9kZWpzVXRpbHMgPSByZXF1aXJlKCcuL25vZGVqc1V0aWxzJyk7XG52YXIgc2V0SW1tZWRpYXRlID0gcmVxdWlyZSgnY29yZS1qcy9saWJyYXJ5L2ZuL3NldC1pbW1lZGlhdGUnKTtcbnZhciBleHRlcm5hbCA9IHJlcXVpcmUoXCIuL2V4dGVybmFsXCIpO1xuXG5cbi8qKlxuICogQ29udmVydCBhIHN0cmluZyB0aGF0IHBhc3MgYXMgYSBcImJpbmFyeSBzdHJpbmdcIjogaXQgc2hvdWxkIHJlcHJlc2VudCBhIGJ5dGVcbiAqIGFycmF5IGJ1dCBtYXkgaGF2ZSA+IDI1NSBjaGFyIGNvZGVzLiBCZSBzdXJlIHRvIHRha2Ugb25seSB0aGUgZmlyc3QgYnl0ZVxuICogYW5kIHJldHVybnMgdGhlIGJ5dGUgYXJyYXkuXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyIHRoZSBzdHJpbmcgdG8gdHJhbnNmb3JtLlxuICogQHJldHVybiB7QXJyYXl8VWludDhBcnJheX0gdGhlIHN0cmluZyBpbiBhIGJpbmFyeSBmb3JtYXQuXG4gKi9cbmZ1bmN0aW9uIHN0cmluZzJiaW5hcnkoc3RyKSB7XG4gICAgdmFyIHJlc3VsdCA9IG51bGw7XG4gICAgaWYgKHN1cHBvcnQudWludDhhcnJheSkge1xuICAgICAgcmVzdWx0ID0gbmV3IFVpbnQ4QXJyYXkoc3RyLmxlbmd0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdCA9IG5ldyBBcnJheShzdHIubGVuZ3RoKTtcbiAgICB9XG4gICAgcmV0dXJuIHN0cmluZ1RvQXJyYXlMaWtlKHN0ciwgcmVzdWx0KTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgYmxvYiB3aXRoIHRoZSBnaXZlbiBjb250ZW50IGFuZCB0aGUgZ2l2ZW4gdHlwZS5cbiAqIEBwYXJhbSB7U3RyaW5nfEFycmF5QnVmZmVyfSBwYXJ0IHRoZSBjb250ZW50IHRvIHB1dCBpbiB0aGUgYmxvYi4gRE8gTk9UIHVzZVxuICogYW4gVWludDhBcnJheSBiZWNhdXNlIHRoZSBzdG9jayBicm93c2VyIG9mIGFuZHJvaWQgNCB3b24ndCBhY2NlcHQgaXQgKGl0XG4gKiB3aWxsIGJlIHNpbGVudGx5IGNvbnZlcnRlZCB0byBhIHN0cmluZywgXCJbb2JqZWN0IFVpbnQ4QXJyYXldXCIpLlxuICpcbiAqIFVzZSBvbmx5IE9ORSBwYXJ0IHRvIGJ1aWxkIHRoZSBibG9iIHRvIGF2b2lkIGEgbWVtb3J5IGxlYWsgaW4gSUUxMSAvIEVkZ2U6XG4gKiB3aGVuIGEgbGFyZ2UgYW1vdW50IG9mIEFycmF5IGlzIHVzZWQgdG8gY3JlYXRlIHRoZSBCbG9iLCB0aGUgYW1vdW50IG9mXG4gKiBtZW1vcnkgY29uc3VtZWQgaXMgbmVhcmx5IDEwMCB0aW1lcyB0aGUgb3JpZ2luYWwgZGF0YSBhbW91bnQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgdGhlIG1pbWUgdHlwZSBvZiB0aGUgYmxvYi5cbiAqIEByZXR1cm4ge0Jsb2J9IHRoZSBjcmVhdGVkIGJsb2IuXG4gKi9cbmV4cG9ydHMubmV3QmxvYiA9IGZ1bmN0aW9uKHBhcnQsIHR5cGUpIHtcbiAgICBleHBvcnRzLmNoZWNrU3VwcG9ydChcImJsb2JcIik7XG5cbiAgICB0cnkge1xuICAgICAgICAvLyBCbG9iIGNvbnN0cnVjdG9yXG4gICAgICAgIHJldHVybiBuZXcgQmxvYihbcGFydF0sIHtcbiAgICAgICAgICAgIHR5cGU6IHR5cGVcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGNhdGNoIChlKSB7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIGRlcHJlY2F0ZWQsIGJyb3dzZXIgb25seSwgb2xkIHdheVxuICAgICAgICAgICAgdmFyIEJ1aWxkZXIgPSBzZWxmLkJsb2JCdWlsZGVyIHx8IHNlbGYuV2ViS2l0QmxvYkJ1aWxkZXIgfHwgc2VsZi5Nb3pCbG9iQnVpbGRlciB8fCBzZWxmLk1TQmxvYkJ1aWxkZXI7XG4gICAgICAgICAgICB2YXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKCk7XG4gICAgICAgICAgICBidWlsZGVyLmFwcGVuZChwYXJ0KTtcbiAgICAgICAgICAgIHJldHVybiBidWlsZGVyLmdldEJsb2IodHlwZSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcblxuICAgICAgICAgICAgLy8gd2VsbCwgZnVjayA/IVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQnVnIDogY2FuJ3QgY29uc3RydWN0IHRoZSBCbG9iLlwiKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG59O1xuLyoqXG4gKiBUaGUgaWRlbnRpdHkgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge09iamVjdH0gaW5wdXQgdGhlIGlucHV0LlxuICogQHJldHVybiB7T2JqZWN0fSB0aGUgc2FtZSBpbnB1dC5cbiAqL1xuZnVuY3Rpb24gaWRlbnRpdHkoaW5wdXQpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG59XG5cbi8qKlxuICogRmlsbCBpbiBhbiBhcnJheSB3aXRoIGEgc3RyaW5nLlxuICogQHBhcmFtIHtTdHJpbmd9IHN0ciB0aGUgc3RyaW5nIHRvIHVzZS5cbiAqIEBwYXJhbSB7QXJyYXl8QXJyYXlCdWZmZXJ8VWludDhBcnJheXxCdWZmZXJ9IGFycmF5IHRoZSBhcnJheSB0byBmaWxsIGluICh3aWxsIGJlIG11dGF0ZWQpLlxuICogQHJldHVybiB7QXJyYXl8QXJyYXlCdWZmZXJ8VWludDhBcnJheXxCdWZmZXJ9IHRoZSB1cGRhdGVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBzdHJpbmdUb0FycmF5TGlrZShzdHIsIGFycmF5KSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgYXJyYXlbaV0gPSBzdHIuY2hhckNvZGVBdChpKSAmIDB4RkY7XG4gICAgfVxuICAgIHJldHVybiBhcnJheTtcbn1cblxuLyoqXG4gKiBBbiBoZWxwZXIgZm9yIHRoZSBmdW5jdGlvbiBhcnJheUxpa2VUb1N0cmluZy5cbiAqIFRoaXMgY29udGFpbnMgc3RhdGljIGluZm9ybWF0aW9ucyBhbmQgZnVuY3Rpb25zIHRoYXRcbiAqIGNhbiBiZSBvcHRpbWl6ZWQgYnkgdGhlIGJyb3dzZXIgSklUIGNvbXBpbGVyLlxuICovXG52YXIgYXJyYXlUb1N0cmluZ0hlbHBlciA9IHtcbiAgICAvKipcbiAgICAgKiBUcmFuc2Zvcm0gYW4gYXJyYXkgb2YgaW50IGludG8gYSBzdHJpbmcsIGNodW5rIGJ5IGNodW5rLlxuICAgICAqIFNlZSB0aGUgcGVyZm9ybWFuY2VzIG5vdGVzIG9uIGFycmF5TGlrZVRvU3RyaW5nLlxuICAgICAqIEBwYXJhbSB7QXJyYXl8QXJyYXlCdWZmZXJ8VWludDhBcnJheXxCdWZmZXJ9IGFycmF5IHRoZSBhcnJheSB0byB0cmFuc2Zvcm0uXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgdGhlIHR5cGUgb2YgdGhlIGFycmF5LlxuICAgICAqIEBwYXJhbSB7SW50ZWdlcn0gY2h1bmsgdGhlIGNodW5rIHNpemUuXG4gICAgICogQHJldHVybiB7U3RyaW5nfSB0aGUgcmVzdWx0aW5nIHN0cmluZy5cbiAgICAgKiBAdGhyb3dzIEVycm9yIGlmIHRoZSBjaHVuayBpcyB0b28gYmlnIGZvciB0aGUgc3RhY2suXG4gICAgICovXG4gICAgc3RyaW5naWZ5QnlDaHVuazogZnVuY3Rpb24oYXJyYXksIHR5cGUsIGNodW5rKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBbXSwgayA9IDAsIGxlbiA9IGFycmF5Lmxlbmd0aDtcbiAgICAgICAgLy8gc2hvcnRjdXRcbiAgICAgICAgaWYgKGxlbiA8PSBjaHVuaykge1xuICAgICAgICAgICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgYXJyYXkpO1xuICAgICAgICB9XG4gICAgICAgIHdoaWxlIChrIDwgbGVuKSB7XG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gXCJhcnJheVwiIHx8IHR5cGUgPT09IFwibm9kZWJ1ZmZlclwiKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBhcnJheS5zbGljZShrLCBNYXRoLm1pbihrICsgY2h1bmssIGxlbikpKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGFycmF5LnN1YmFycmF5KGssIE1hdGgubWluKGsgKyBjaHVuaywgbGVuKSkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGsgKz0gY2h1bms7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdC5qb2luKFwiXCIpO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogQ2FsbCBTdHJpbmcuZnJvbUNoYXJDb2RlIG9uIGV2ZXJ5IGl0ZW0gaW4gdGhlIGFycmF5LlxuICAgICAqIFRoaXMgaXMgdGhlIG5haXZlIGltcGxlbWVudGF0aW9uLCB3aGljaCBnZW5lcmF0ZSBBIExPVCBvZiBpbnRlcm1lZGlhdGUgc3RyaW5nLlxuICAgICAqIFRoaXMgc2hvdWxkIGJlIHVzZWQgd2hlbiBldmVyeXRoaW5nIGVsc2UgZmFpbC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fEFycmF5QnVmZmVyfFVpbnQ4QXJyYXl8QnVmZmVyfSBhcnJheSB0aGUgYXJyYXkgdG8gdHJhbnNmb3JtLlxuICAgICAqIEByZXR1cm4ge1N0cmluZ30gdGhlIHJlc3VsdC5cbiAgICAgKi9cbiAgICBzdHJpbmdpZnlCeUNoYXI6IGZ1bmN0aW9uKGFycmF5KXtcbiAgICAgICAgdmFyIHJlc3VsdFN0ciA9IFwiXCI7XG4gICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgcmVzdWx0U3RyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYXJyYXlbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRTdHI7XG4gICAgfSxcbiAgICBhcHBseUNhbkJlVXNlZCA6IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRydWUgaWYgdGhlIGJyb3dzZXIgYWNjZXB0cyB0byB1c2UgU3RyaW5nLmZyb21DaGFyQ29kZSBvbiBVaW50OEFycmF5XG4gICAgICAgICAqL1xuICAgICAgICB1aW50OGFycmF5IDogKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1cHBvcnQudWludDhhcnJheSAmJiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIG5ldyBVaW50OEFycmF5KDEpKS5sZW5ndGggPT09IDE7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KSgpLFxuICAgICAgICAvKipcbiAgICAgICAgICogdHJ1ZSBpZiB0aGUgYnJvd3NlciBhY2NlcHRzIHRvIHVzZSBTdHJpbmcuZnJvbUNoYXJDb2RlIG9uIG5vZGVqcyBCdWZmZXIuXG4gICAgICAgICAqL1xuICAgICAgICBub2RlYnVmZmVyIDogKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN1cHBvcnQubm9kZWJ1ZmZlciAmJiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIG5vZGVqc1V0aWxzLmFsbG9jQnVmZmVyKDEpKS5sZW5ndGggPT09IDE7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KSgpXG4gICAgfVxufTtcblxuLyoqXG4gKiBUcmFuc2Zvcm0gYW4gYXJyYXktbGlrZSBvYmplY3QgdG8gYSBzdHJpbmcuXG4gKiBAcGFyYW0ge0FycmF5fEFycmF5QnVmZmVyfFVpbnQ4QXJyYXl8QnVmZmVyfSBhcnJheSB0aGUgYXJyYXkgdG8gdHJhbnNmb3JtLlxuICogQHJldHVybiB7U3RyaW5nfSB0aGUgcmVzdWx0LlxuICovXG5mdW5jdGlvbiBhcnJheUxpa2VUb1N0cmluZyhhcnJheSkge1xuICAgIC8vIFBlcmZvcm1hbmNlcyBub3RlcyA6XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGFycmF5KSBpcyB0aGUgZmFzdGVzdCwgc2VlXG4gICAgLy8gc2VlIGh0dHA6Ly9qc3BlcmYuY29tL2NvbnZlcnRpbmctYS11aW50OGFycmF5LXRvLWEtc3RyaW5nLzJcbiAgICAvLyBidXQgdGhlIHN0YWNrIGlzIGxpbWl0ZWQgKGFuZCB3ZSBjYW4gZ2V0IGh1Z2UgYXJyYXlzICEpLlxuICAgIC8vXG4gICAgLy8gcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYXJyYXlbaV0pOyBnZW5lcmF0ZSB0b28gbWFueSBzdHJpbmdzICFcbiAgICAvL1xuICAgIC8vIFRoaXMgY29kZSBpcyBpbnNwaXJlZCBieSBodHRwOi8vanNwZXJmLmNvbS9hcnJheWJ1ZmZlci10by1zdHJpbmctYXBwbHktcGVyZm9ybWFuY2UvMlxuICAgIC8vIFRPRE8gOiB3ZSBub3cgaGF2ZSB3b3JrZXJzIHRoYXQgc3BsaXQgdGhlIHdvcmsuIERvIHdlIHN0aWxsIG5lZWQgdGhhdCA/XG4gICAgdmFyIGNodW5rID0gNjU1MzYsXG4gICAgICAgIHR5cGUgPSBleHBvcnRzLmdldFR5cGVPZihhcnJheSksXG4gICAgICAgIGNhblVzZUFwcGx5ID0gdHJ1ZTtcbiAgICBpZiAodHlwZSA9PT0gXCJ1aW50OGFycmF5XCIpIHtcbiAgICAgICAgY2FuVXNlQXBwbHkgPSBhcnJheVRvU3RyaW5nSGVscGVyLmFwcGx5Q2FuQmVVc2VkLnVpbnQ4YXJyYXk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSBcIm5vZGVidWZmZXJcIikge1xuICAgICAgICBjYW5Vc2VBcHBseSA9IGFycmF5VG9TdHJpbmdIZWxwZXIuYXBwbHlDYW5CZVVzZWQubm9kZWJ1ZmZlcjtcbiAgICB9XG5cbiAgICBpZiAoY2FuVXNlQXBwbHkpIHtcbiAgICAgICAgd2hpbGUgKGNodW5rID4gMSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXlUb1N0cmluZ0hlbHBlci5zdHJpbmdpZnlCeUNodW5rKGFycmF5LCB0eXBlLCBjaHVuayk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgY2h1bmsgPSBNYXRoLmZsb29yKGNodW5rIC8gMik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBubyBhcHBseSBvciBjaHVuayBlcnJvciA6IHNsb3cgYW5kIHBhaW5mdWwgYWxnb3JpdGhtXG4gICAgLy8gZGVmYXVsdCBicm93c2VyIG9uIGFuZHJvaWQgNC4qXG4gICAgcmV0dXJuIGFycmF5VG9TdHJpbmdIZWxwZXIuc3RyaW5naWZ5QnlDaGFyKGFycmF5KTtcbn1cblxuZXhwb3J0cy5hcHBseUZyb21DaGFyQ29kZSA9IGFycmF5TGlrZVRvU3RyaW5nO1xuXG5cbi8qKlxuICogQ29weSB0aGUgZGF0YSBmcm9tIGFuIGFycmF5LWxpa2UgdG8gYW4gb3RoZXIgYXJyYXktbGlrZS5cbiAqIEBwYXJhbSB7QXJyYXl8QXJyYXlCdWZmZXJ8VWludDhBcnJheXxCdWZmZXJ9IGFycmF5RnJvbSB0aGUgb3JpZ2luIGFycmF5LlxuICogQHBhcmFtIHtBcnJheXxBcnJheUJ1ZmZlcnxVaW50OEFycmF5fEJ1ZmZlcn0gYXJyYXlUbyB0aGUgZGVzdGluYXRpb24gYXJyYXkgd2hpY2ggd2lsbCBiZSBtdXRhdGVkLlxuICogQHJldHVybiB7QXJyYXl8QXJyYXlCdWZmZXJ8VWludDhBcnJheXxCdWZmZXJ9IHRoZSB1cGRhdGVkIGRlc3RpbmF0aW9uIGFycmF5LlxuICovXG5mdW5jdGlvbiBhcnJheUxpa2VUb0FycmF5TGlrZShhcnJheUZyb20sIGFycmF5VG8pIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5RnJvbS5sZW5ndGg7IGkrKykge1xuICAgICAgICBhcnJheVRvW2ldID0gYXJyYXlGcm9tW2ldO1xuICAgIH1cbiAgICByZXR1cm4gYXJyYXlUbztcbn1cblxuLy8gYSBtYXRyaXggY29udGFpbmluZyBmdW5jdGlvbnMgdG8gdHJhbnNmb3JtIGV2ZXJ5dGhpbmcgaW50byBldmVyeXRoaW5nLlxudmFyIHRyYW5zZm9ybSA9IHt9O1xuXG4vLyBzdHJpbmcgdG8gP1xudHJhbnNmb3JtW1wic3RyaW5nXCJdID0ge1xuICAgIFwic3RyaW5nXCI6IGlkZW50aXR5LFxuICAgIFwiYXJyYXlcIjogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZ1RvQXJyYXlMaWtlKGlucHV0LCBuZXcgQXJyYXkoaW5wdXQubGVuZ3RoKSk7XG4gICAgfSxcbiAgICBcImFycmF5YnVmZmVyXCI6IGZ1bmN0aW9uKGlucHV0KSB7XG4gICAgICAgIHJldHVybiB0cmFuc2Zvcm1bXCJzdHJpbmdcIl1bXCJ1aW50OGFycmF5XCJdKGlucHV0KS5idWZmZXI7XG4gICAgfSxcbiAgICBcInVpbnQ4YXJyYXlcIjogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZ1RvQXJyYXlMaWtlKGlucHV0LCBuZXcgVWludDhBcnJheShpbnB1dC5sZW5ndGgpKTtcbiAgICB9LFxuICAgIFwibm9kZWJ1ZmZlclwiOiBmdW5jdGlvbihpbnB1dCkge1xuICAgICAgICByZXR1cm4gc3RyaW5nVG9BcnJheUxpa2UoaW5wdXQsIG5vZGVqc1V0aWxzLmFsbG9jQnVmZmVyKGlucHV0Lmxlbmd0aCkpO1xuICAgIH1cbn07XG5cbi8vIGFycmF5IHRvID9cbnRyYW5zZm9ybVtcImFycmF5XCJdID0ge1xuICAgIFwic3RyaW5nXCI6IGFycmF5TGlrZVRvU3RyaW5nLFxuICAgIFwiYXJyYXlcIjogaWRlbnRpdHksXG4gICAgXCJhcnJheWJ1ZmZlclwiOiBmdW5jdGlvbihpbnB1dCkge1xuICAgICAgICByZXR1cm4gKG5ldyBVaW50OEFycmF5KGlucHV0KSkuYnVmZmVyO1xuICAgIH0sXG4gICAgXCJ1aW50OGFycmF5XCI6IGZ1bmN0aW9uKGlucHV0KSB7XG4gICAgICAgIHJldHVybiBuZXcgVWludDhBcnJheShpbnB1dCk7XG4gICAgfSxcbiAgICBcIm5vZGVidWZmZXJcIjogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIG5vZGVqc1V0aWxzLm5ld0J1ZmZlckZyb20oaW5wdXQpO1xuICAgIH1cbn07XG5cbi8vIGFycmF5YnVmZmVyIHRvID9cbnRyYW5zZm9ybVtcImFycmF5YnVmZmVyXCJdID0ge1xuICAgIFwic3RyaW5nXCI6IGZ1bmN0aW9uKGlucHV0KSB7XG4gICAgICAgIHJldHVybiBhcnJheUxpa2VUb1N0cmluZyhuZXcgVWludDhBcnJheShpbnB1dCkpO1xuICAgIH0sXG4gICAgXCJhcnJheVwiOiBmdW5jdGlvbihpbnB1dCkge1xuICAgICAgICByZXR1cm4gYXJyYXlMaWtlVG9BcnJheUxpa2UobmV3IFVpbnQ4QXJyYXkoaW5wdXQpLCBuZXcgQXJyYXkoaW5wdXQuYnl0ZUxlbmd0aCkpO1xuICAgIH0sXG4gICAgXCJhcnJheWJ1ZmZlclwiOiBpZGVudGl0eSxcbiAgICBcInVpbnQ4YXJyYXlcIjogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGlucHV0KTtcbiAgICB9LFxuICAgIFwibm9kZWJ1ZmZlclwiOiBmdW5jdGlvbihpbnB1dCkge1xuICAgICAgICByZXR1cm4gbm9kZWpzVXRpbHMubmV3QnVmZmVyRnJvbShuZXcgVWludDhBcnJheShpbnB1dCkpO1xuICAgIH1cbn07XG5cbi8vIHVpbnQ4YXJyYXkgdG8gP1xudHJhbnNmb3JtW1widWludDhhcnJheVwiXSA9IHtcbiAgICBcInN0cmluZ1wiOiBhcnJheUxpa2VUb1N0cmluZyxcbiAgICBcImFycmF5XCI6IGZ1bmN0aW9uKGlucHV0KSB7XG4gICAgICAgIHJldHVybiBhcnJheUxpa2VUb0FycmF5TGlrZShpbnB1dCwgbmV3IEFycmF5KGlucHV0Lmxlbmd0aCkpO1xuICAgIH0sXG4gICAgXCJhcnJheWJ1ZmZlclwiOiBmdW5jdGlvbihpbnB1dCkge1xuICAgICAgICByZXR1cm4gaW5wdXQuYnVmZmVyO1xuICAgIH0sXG4gICAgXCJ1aW50OGFycmF5XCI6IGlkZW50aXR5LFxuICAgIFwibm9kZWJ1ZmZlclwiOiBmdW5jdGlvbihpbnB1dCkge1xuICAgICAgICByZXR1cm4gbm9kZWpzVXRpbHMubmV3QnVmZmVyRnJvbShpbnB1dCk7XG4gICAgfVxufTtcblxuLy8gbm9kZWJ1ZmZlciB0byA/XG50cmFuc2Zvcm1bXCJub2RlYnVmZmVyXCJdID0ge1xuICAgIFwic3RyaW5nXCI6IGFycmF5TGlrZVRvU3RyaW5nLFxuICAgIFwiYXJyYXlcIjogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIGFycmF5TGlrZVRvQXJyYXlMaWtlKGlucHV0LCBuZXcgQXJyYXkoaW5wdXQubGVuZ3RoKSk7XG4gICAgfSxcbiAgICBcImFycmF5YnVmZmVyXCI6IGZ1bmN0aW9uKGlucHV0KSB7XG4gICAgICAgIHJldHVybiB0cmFuc2Zvcm1bXCJub2RlYnVmZmVyXCJdW1widWludDhhcnJheVwiXShpbnB1dCkuYnVmZmVyO1xuICAgIH0sXG4gICAgXCJ1aW50OGFycmF5XCI6IGZ1bmN0aW9uKGlucHV0KSB7XG4gICAgICAgIHJldHVybiBhcnJheUxpa2VUb0FycmF5TGlrZShpbnB1dCwgbmV3IFVpbnQ4QXJyYXkoaW5wdXQubGVuZ3RoKSk7XG4gICAgfSxcbiAgICBcIm5vZGVidWZmZXJcIjogaWRlbnRpdHlcbn07XG5cbi8qKlxuICogVHJhbnNmb3JtIGFuIGlucHV0IGludG8gYW55IHR5cGUuXG4gKiBUaGUgc3VwcG9ydGVkIG91dHB1dCB0eXBlIGFyZSA6IHN0cmluZywgYXJyYXksIHVpbnQ4YXJyYXksIGFycmF5YnVmZmVyLCBub2RlYnVmZmVyLlxuICogSWYgbm8gb3V0cHV0IHR5cGUgaXMgc3BlY2lmaWVkLCB0aGUgdW5tb2RpZmllZCBpbnB1dCB3aWxsIGJlIHJldHVybmVkLlxuICogQHBhcmFtIHtTdHJpbmd9IG91dHB1dFR5cGUgdGhlIG91dHB1dCB0eXBlLlxuICogQHBhcmFtIHtTdHJpbmd8QXJyYXl8QXJyYXlCdWZmZXJ8VWludDhBcnJheXxCdWZmZXJ9IGlucHV0IHRoZSBpbnB1dCB0byBjb252ZXJ0LlxuICogQHRocm93cyB7RXJyb3J9IGFuIEVycm9yIGlmIHRoZSBicm93c2VyIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgcmVxdWVzdGVkIG91dHB1dCB0eXBlLlxuICovXG5leHBvcnRzLnRyYW5zZm9ybVRvID0gZnVuY3Rpb24ob3V0cHV0VHlwZSwgaW5wdXQpIHtcbiAgICBpZiAoIWlucHV0KSB7XG4gICAgICAgIC8vIHVuZGVmaW5lZCwgbnVsbCwgZXRjXG4gICAgICAgIC8vIGFuIGVtcHR5IHN0cmluZyB3b24ndCBoYXJtLlxuICAgICAgICBpbnB1dCA9IFwiXCI7XG4gICAgfVxuICAgIGlmICghb3V0cHV0VHlwZSkge1xuICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgfVxuICAgIGV4cG9ydHMuY2hlY2tTdXBwb3J0KG91dHB1dFR5cGUpO1xuICAgIHZhciBpbnB1dFR5cGUgPSBleHBvcnRzLmdldFR5cGVPZihpbnB1dCk7XG4gICAgdmFyIHJlc3VsdCA9IHRyYW5zZm9ybVtpbnB1dFR5cGVdW291dHB1dFR5cGVdKGlucHV0KTtcbiAgICByZXR1cm4gcmVzdWx0O1xufTtcblxuLyoqXG4gKiBSZXR1cm4gdGhlIHR5cGUgb2YgdGhlIGlucHV0LlxuICogVGhlIHR5cGUgd2lsbCBiZSBpbiBhIGZvcm1hdCB2YWxpZCBmb3IgSlNaaXAudXRpbHMudHJhbnNmb3JtVG8gOiBzdHJpbmcsIGFycmF5LCB1aW50OGFycmF5LCBhcnJheWJ1ZmZlci5cbiAqIEBwYXJhbSB7T2JqZWN0fSBpbnB1dCB0aGUgaW5wdXQgdG8gaWRlbnRpZnkuXG4gKiBAcmV0dXJuIHtTdHJpbmd9IHRoZSAobG93ZXJjYXNlKSB0eXBlIG9mIHRoZSBpbnB1dC5cbiAqL1xuZXhwb3J0cy5nZXRUeXBlT2YgPSBmdW5jdGlvbihpbnB1dCkge1xuICAgIGlmICh0eXBlb2YgaW5wdXQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgcmV0dXJuIFwic3RyaW5nXCI7XG4gICAgfVxuICAgIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoaW5wdXQpID09PSBcIltvYmplY3QgQXJyYXldXCIpIHtcbiAgICAgICAgcmV0dXJuIFwiYXJyYXlcIjtcbiAgICB9XG4gICAgaWYgKHN1cHBvcnQubm9kZWJ1ZmZlciAmJiBub2RlanNVdGlscy5pc0J1ZmZlcihpbnB1dCkpIHtcbiAgICAgICAgcmV0dXJuIFwibm9kZWJ1ZmZlclwiO1xuICAgIH1cbiAgICBpZiAoc3VwcG9ydC51aW50OGFycmF5ICYmIGlucHV0IGluc3RhbmNlb2YgVWludDhBcnJheSkge1xuICAgICAgICByZXR1cm4gXCJ1aW50OGFycmF5XCI7XG4gICAgfVxuICAgIGlmIChzdXBwb3J0LmFycmF5YnVmZmVyICYmIGlucHV0IGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgICAgcmV0dXJuIFwiYXJyYXlidWZmZXJcIjtcbiAgICB9XG59O1xuXG4vKipcbiAqIFRocm93IGFuIGV4Y2VwdGlvbiBpZiB0aGUgdHlwZSBpcyBub3Qgc3VwcG9ydGVkLlxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgdGhlIHR5cGUgdG8gY2hlY2suXG4gKiBAdGhyb3dzIHtFcnJvcn0gYW4gRXJyb3IgaWYgdGhlIGJyb3dzZXIgZG9lc24ndCBzdXBwb3J0IHRoZSByZXF1ZXN0ZWQgdHlwZS5cbiAqL1xuZXhwb3J0cy5jaGVja1N1cHBvcnQgPSBmdW5jdGlvbih0eXBlKSB7XG4gICAgdmFyIHN1cHBvcnRlZCA9IHN1cHBvcnRbdHlwZS50b0xvd2VyQ2FzZSgpXTtcbiAgICBpZiAoIXN1cHBvcnRlZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IodHlwZSArIFwiIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBwbGF0Zm9ybVwiKTtcbiAgICB9XG59O1xuXG5leHBvcnRzLk1BWF9WQUxVRV8xNkJJVFMgPSA2NTUzNTtcbmV4cG9ydHMuTUFYX1ZBTFVFXzMyQklUUyA9IC0xOyAvLyB3ZWxsLCBcIlxceEZGXFx4RkZcXHhGRlxceEZGXFx4RkZcXHhGRlxceEZGXFx4RkZcIiBpcyBwYXJzZWQgYXMgLTFcblxuLyoqXG4gKiBQcmV0dGlmeSBhIHN0cmluZyByZWFkIGFzIGJpbmFyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgdGhlIHN0cmluZyB0byBwcmV0dGlmeS5cbiAqIEByZXR1cm4ge3N0cmluZ30gYSBwcmV0dHkgc3RyaW5nLlxuICovXG5leHBvcnRzLnByZXR0eSA9IGZ1bmN0aW9uKHN0cikge1xuICAgIHZhciByZXMgPSAnJyxcbiAgICAgICAgY29kZSwgaTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgKHN0ciB8fCBcIlwiKS5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb2RlID0gc3RyLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIHJlcyArPSAnXFxcXHgnICsgKGNvZGUgPCAxNiA/IFwiMFwiIDogXCJcIikgKyBjb2RlLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xufTtcblxuLyoqXG4gKiBEZWZlciB0aGUgY2FsbCBvZiBhIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgdGhlIGZ1bmN0aW9uIHRvIGNhbGwgYXN5bmNocm9ub3VzbHkuXG4gKiBAcGFyYW0ge0FycmF5fSBhcmdzIHRoZSBhcmd1bWVudHMgdG8gZ2l2ZSB0byB0aGUgY2FsbGJhY2suXG4gKi9cbmV4cG9ydHMuZGVsYXkgPSBmdW5jdGlvbihjYWxsYmFjaywgYXJncywgc2VsZikge1xuICAgIHNldEltbWVkaWF0ZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNhbGxiYWNrLmFwcGx5KHNlbGYgfHwgbnVsbCwgYXJncyB8fCBbXSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIEV4dGVuZHMgYSBwcm90b3R5cGUgd2l0aCBhbiBvdGhlciwgd2l0aG91dCBjYWxsaW5nIGEgY29uc3RydWN0b3Igd2l0aFxuICogc2lkZSBlZmZlY3RzLiBJbnNwaXJlZCBieSBub2RlanMnIGB1dGlscy5pbmhlcml0c2BcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGN0b3IgdGhlIGNvbnN0cnVjdG9yIHRvIGF1Z21lbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHN1cGVyQ3RvciB0aGUgcGFyZW50IGNvbnN0cnVjdG9yIHRvIHVzZVxuICovXG5leHBvcnRzLmluaGVyaXRzID0gZnVuY3Rpb24gKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIHZhciBPYmogPSBmdW5jdGlvbigpIHt9O1xuICAgIE9iai5wcm90b3R5cGUgPSBzdXBlckN0b3IucHJvdG90eXBlO1xuICAgIGN0b3IucHJvdG90eXBlID0gbmV3IE9iaigpO1xufTtcblxuLyoqXG4gKiBNZXJnZSB0aGUgb2JqZWN0cyBwYXNzZWQgYXMgcGFyYW1ldGVycyBpbnRvIGEgbmV3IG9uZS5cbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gey4uLk9iamVjdH0gdmFyX2FyZ3MgQWxsIG9iamVjdHMgdG8gbWVyZ2UuXG4gKiBAcmV0dXJuIHtPYmplY3R9IGEgbmV3IG9iamVjdCB3aXRoIHRoZSBkYXRhIG9mIHRoZSBvdGhlcnMuXG4gKi9cbmV4cG9ydHMuZXh0ZW5kID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHJlc3VsdCA9IHt9LCBpLCBhdHRyO1xuICAgIGZvciAoaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgLy8gYXJndW1lbnRzIGlzIG5vdCBlbnVtZXJhYmxlIGluIHNvbWUgYnJvd3NlcnNcbiAgICAgICAgZm9yIChhdHRyIGluIGFyZ3VtZW50c1tpXSkge1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50c1tpXS5oYXNPd25Qcm9wZXJ0eShhdHRyKSAmJiB0eXBlb2YgcmVzdWx0W2F0dHJdID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0W2F0dHJdID0gYXJndW1lbnRzW2ldW2F0dHJdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59O1xuXG4vKipcbiAqIFRyYW5zZm9ybSBhcmJpdHJhcnkgY29udGVudCBpbnRvIGEgUHJvbWlzZS5cbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIGEgbmFtZSBmb3IgdGhlIGNvbnRlbnQgYmVpbmcgcHJvY2Vzc2VkLlxuICogQHBhcmFtIHtPYmplY3R9IGlucHV0RGF0YSB0aGUgY29udGVudCB0byBwcm9jZXNzLlxuICogQHBhcmFtIHtCb29sZWFufSBpc0JpbmFyeSB0cnVlIGlmIHRoZSBjb250ZW50IGlzIG5vdCBhbiB1bmljb2RlIHN0cmluZ1xuICogQHBhcmFtIHtCb29sZWFufSBpc09wdGltaXplZEJpbmFyeVN0cmluZyB0cnVlIGlmIHRoZSBzdHJpbmcgY29udGVudCBvbmx5IGhhcyBvbmUgYnl0ZSBwZXIgY2hhcmFjdGVyLlxuICogQHBhcmFtIHtCb29sZWFufSBpc0Jhc2U2NCB0cnVlIGlmIHRoZSBzdHJpbmcgY29udGVudCBpcyBlbmNvZGVkIHdpdGggYmFzZTY0LlxuICogQHJldHVybiB7UHJvbWlzZX0gYSBwcm9taXNlIGluIGEgZm9ybWF0IHVzYWJsZSBieSBKU1ppcC5cbiAqL1xuZXhwb3J0cy5wcmVwYXJlQ29udGVudCA9IGZ1bmN0aW9uKG5hbWUsIGlucHV0RGF0YSwgaXNCaW5hcnksIGlzT3B0aW1pemVkQmluYXJ5U3RyaW5nLCBpc0Jhc2U2NCkge1xuXG4gICAgLy8gaWYgaW5wdXREYXRhIGlzIGFscmVhZHkgYSBwcm9taXNlLCB0aGlzIGZsYXR0ZW4gaXQuXG4gICAgdmFyIHByb21pc2UgPSBleHRlcm5hbC5Qcm9taXNlLnJlc29sdmUoaW5wdXREYXRhKS50aGVuKGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgICAgXG4gICAgICAgIFxuICAgICAgICB2YXIgaXNCbG9iID0gc3VwcG9ydC5ibG9iICYmIChkYXRhIGluc3RhbmNlb2YgQmxvYiB8fCBbJ1tvYmplY3QgRmlsZV0nLCAnW29iamVjdCBCbG9iXSddLmluZGV4T2YoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGRhdGEpKSAhPT0gLTEpO1xuXG4gICAgICAgIGlmIChpc0Jsb2IgJiYgdHlwZW9mIEZpbGVSZWFkZXIgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgZXh0ZXJuYWwuUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG5cbiAgICAgICAgICAgICAgICByZWFkZXIub25sb2FkID0gZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGUudGFyZ2V0LnJlc3VsdCk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZWFkZXIub25lcnJvciA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUudGFyZ2V0LmVycm9yKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcihkYXRhKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBwcm9taXNlLnRoZW4oZnVuY3Rpb24oZGF0YSkge1xuICAgICAgICB2YXIgZGF0YVR5cGUgPSBleHBvcnRzLmdldFR5cGVPZihkYXRhKTtcblxuICAgICAgICBpZiAoIWRhdGFUeXBlKSB7XG4gICAgICAgICAgICByZXR1cm4gZXh0ZXJuYWwuUHJvbWlzZS5yZWplY3QoXG4gICAgICAgICAgICAgICAgbmV3IEVycm9yKFwiQ2FuJ3QgcmVhZCB0aGUgZGF0YSBvZiAnXCIgKyBuYW1lICsgXCInLiBJcyBpdCBcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFwiaW4gYSBzdXBwb3J0ZWQgSmF2YVNjcmlwdCB0eXBlIChTdHJpbmcsIEJsb2IsIEFycmF5QnVmZmVyLCBldGMpID9cIilcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gc3BlY2lhbCBjYXNlIDogaXQncyB3YXkgZWFzaWVyIHRvIHdvcmsgd2l0aCBVaW50OEFycmF5IHRoYW4gd2l0aCBBcnJheUJ1ZmZlclxuICAgICAgICBpZiAoZGF0YVR5cGUgPT09IFwiYXJyYXlidWZmZXJcIikge1xuICAgICAgICAgICAgZGF0YSA9IGV4cG9ydHMudHJhbnNmb3JtVG8oXCJ1aW50OGFycmF5XCIsIGRhdGEpO1xuICAgICAgICB9IGVsc2UgaWYgKGRhdGFUeXBlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICBpZiAoaXNCYXNlNjQpIHtcbiAgICAgICAgICAgICAgICBkYXRhID0gYmFzZTY0LmRlY29kZShkYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGlzQmluYXJ5KSB7XG4gICAgICAgICAgICAgICAgLy8gb3B0aW1pemVkQmluYXJ5U3RyaW5nID09PSB0cnVlIG1lYW5zIHRoYXQgdGhlIGZpbGUgaGFzIGFscmVhZHkgYmVlbiBmaWx0ZXJlZCB3aXRoIGEgMHhGRiBtYXNrXG4gICAgICAgICAgICAgICAgaWYgKGlzT3B0aW1pemVkQmluYXJ5U3RyaW5nICE9PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgaXMgYSBzdHJpbmcsIG5vdCBpbiBhIGJhc2U2NCBmb3JtYXQuXG4gICAgICAgICAgICAgICAgICAgIC8vIEJlIHN1cmUgdGhhdCB0aGlzIGlzIGEgY29ycmVjdCBcImJpbmFyeSBzdHJpbmdcIlxuICAgICAgICAgICAgICAgICAgICBkYXRhID0gc3RyaW5nMmJpbmFyeShkYXRhKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfSk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIHJlYWRlckZvciA9IHJlcXVpcmUoJy4vcmVhZGVyL3JlYWRlckZvcicpO1xudmFyIHV0aWxzID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIHNpZyA9IHJlcXVpcmUoJy4vc2lnbmF0dXJlJyk7XG52YXIgWmlwRW50cnkgPSByZXF1aXJlKCcuL3ppcEVudHJ5Jyk7XG52YXIgdXRmOCA9IHJlcXVpcmUoJy4vdXRmOCcpO1xudmFyIHN1cHBvcnQgPSByZXF1aXJlKCcuL3N1cHBvcnQnKTtcbi8vICBjbGFzcyBaaXBFbnRyaWVzIHt7e1xuLyoqXG4gKiBBbGwgdGhlIGVudHJpZXMgaW4gdGhlIHppcCBmaWxlLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge09iamVjdH0gbG9hZE9wdGlvbnMgT3B0aW9ucyBmb3IgbG9hZGluZyB0aGUgc3RyZWFtLlxuICovXG5mdW5jdGlvbiBaaXBFbnRyaWVzKGxvYWRPcHRpb25zKSB7XG4gICAgdGhpcy5maWxlcyA9IFtdO1xuICAgIHRoaXMubG9hZE9wdGlvbnMgPSBsb2FkT3B0aW9ucztcbn1cblppcEVudHJpZXMucHJvdG90eXBlID0ge1xuICAgIC8qKlxuICAgICAqIENoZWNrIHRoYXQgdGhlIHJlYWRlciBpcyBvbiB0aGUgc3BlY2lmaWVkIHNpZ25hdHVyZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZXhwZWN0ZWRTaWduYXR1cmUgdGhlIGV4cGVjdGVkIHNpZ25hdHVyZS5cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gaWYgaXQgaXMgYW4gb3RoZXIgc2lnbmF0dXJlLlxuICAgICAqL1xuICAgIGNoZWNrU2lnbmF0dXJlOiBmdW5jdGlvbihleHBlY3RlZFNpZ25hdHVyZSkge1xuICAgICAgICBpZiAoIXRoaXMucmVhZGVyLnJlYWRBbmRDaGVja1NpZ25hdHVyZShleHBlY3RlZFNpZ25hdHVyZSkpIHtcbiAgICAgICAgICAgIHRoaXMucmVhZGVyLmluZGV4IC09IDQ7XG4gICAgICAgICAgICB2YXIgc2lnbmF0dXJlID0gdGhpcy5yZWFkZXIucmVhZFN0cmluZyg0KTtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvcnJ1cHRlZCB6aXAgb3IgYnVnOiB1bmV4cGVjdGVkIHNpZ25hdHVyZSBcIiArIFwiKFwiICsgdXRpbHMucHJldHR5KHNpZ25hdHVyZSkgKyBcIiwgZXhwZWN0ZWQgXCIgKyB1dGlscy5wcmV0dHkoZXhwZWN0ZWRTaWduYXR1cmUpICsgXCIpXCIpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBDaGVjayBpZiB0aGUgZ2l2ZW4gc2lnbmF0dXJlIGlzIGF0IHRoZSBnaXZlbiBpbmRleC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYXNrZWRJbmRleCB0aGUgaW5kZXggdG8gY2hlY2suXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGV4cGVjdGVkU2lnbmF0dXJlIHRoZSBzaWduYXR1cmUgdG8gZXhwZWN0LlxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59IHRydWUgaWYgdGhlIHNpZ25hdHVyZSBpcyBoZXJlLCBmYWxzZSBvdGhlcndpc2UuXG4gICAgICovXG4gICAgaXNTaWduYXR1cmU6IGZ1bmN0aW9uKGFza2VkSW5kZXgsIGV4cGVjdGVkU2lnbmF0dXJlKSB7XG4gICAgICAgIHZhciBjdXJyZW50SW5kZXggPSB0aGlzLnJlYWRlci5pbmRleDtcbiAgICAgICAgdGhpcy5yZWFkZXIuc2V0SW5kZXgoYXNrZWRJbmRleCk7XG4gICAgICAgIHZhciBzaWduYXR1cmUgPSB0aGlzLnJlYWRlci5yZWFkU3RyaW5nKDQpO1xuICAgICAgICB2YXIgcmVzdWx0ID0gc2lnbmF0dXJlID09PSBleHBlY3RlZFNpZ25hdHVyZTtcbiAgICAgICAgdGhpcy5yZWFkZXIuc2V0SW5kZXgoY3VycmVudEluZGV4KTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFJlYWQgdGhlIGVuZCBvZiB0aGUgY2VudHJhbCBkaXJlY3RvcnkuXG4gICAgICovXG4gICAgcmVhZEJsb2NrRW5kT2ZDZW50cmFsOiBmdW5jdGlvbigpIHtcbiAgICAgICAgdGhpcy5kaXNrTnVtYmVyID0gdGhpcy5yZWFkZXIucmVhZEludCgyKTtcbiAgICAgICAgdGhpcy5kaXNrV2l0aENlbnRyYWxEaXJTdGFydCA9IHRoaXMucmVhZGVyLnJlYWRJbnQoMik7XG4gICAgICAgIHRoaXMuY2VudHJhbERpclJlY29yZHNPblRoaXNEaXNrID0gdGhpcy5yZWFkZXIucmVhZEludCgyKTtcbiAgICAgICAgdGhpcy5jZW50cmFsRGlyUmVjb3JkcyA9IHRoaXMucmVhZGVyLnJlYWRJbnQoMik7XG4gICAgICAgIHRoaXMuY2VudHJhbERpclNpemUgPSB0aGlzLnJlYWRlci5yZWFkSW50KDQpO1xuICAgICAgICB0aGlzLmNlbnRyYWxEaXJPZmZzZXQgPSB0aGlzLnJlYWRlci5yZWFkSW50KDQpO1xuXG4gICAgICAgIHRoaXMuemlwQ29tbWVudExlbmd0aCA9IHRoaXMucmVhZGVyLnJlYWRJbnQoMik7XG4gICAgICAgIC8vIHdhcm5pbmcgOiB0aGUgZW5jb2RpbmcgZGVwZW5kcyBvZiB0aGUgc3lzdGVtIGxvY2FsZVxuICAgICAgICAvLyBPbiBhIGxpbnV4IG1hY2hpbmUgd2l0aCBMQU5HPWVuX1VTLnV0ZjgsIHRoaXMgZmllbGQgaXMgdXRmOCBlbmNvZGVkLlxuICAgICAgICAvLyBPbiBhIHdpbmRvd3MgbWFjaGluZSwgdGhpcyBmaWVsZCBpcyBlbmNvZGVkIHdpdGggdGhlIGxvY2FsaXplZCB3aW5kb3dzIGNvZGUgcGFnZS5cbiAgICAgICAgdmFyIHppcENvbW1lbnQgPSB0aGlzLnJlYWRlci5yZWFkRGF0YSh0aGlzLnppcENvbW1lbnRMZW5ndGgpO1xuICAgICAgICB2YXIgZGVjb2RlUGFyYW1UeXBlID0gc3VwcG9ydC51aW50OGFycmF5ID8gXCJ1aW50OGFycmF5XCIgOiBcImFycmF5XCI7XG4gICAgICAgIC8vIFRvIGdldCBjb25zaXN0ZW50IGJlaGF2aW9yIHdpdGggdGhlIGdlbmVyYXRpb24gcGFydCwgd2Ugd2lsbCBhc3N1bWUgdGhhdFxuICAgICAgICAvLyB0aGlzIGlzIHV0ZjggZW5jb2RlZCB1bmxlc3Mgc3BlY2lmaWVkIG90aGVyd2lzZS5cbiAgICAgICAgdmFyIGRlY29kZUNvbnRlbnQgPSB1dGlscy50cmFuc2Zvcm1UbyhkZWNvZGVQYXJhbVR5cGUsIHppcENvbW1lbnQpO1xuICAgICAgICB0aGlzLnppcENvbW1lbnQgPSB0aGlzLmxvYWRPcHRpb25zLmRlY29kZUZpbGVOYW1lKGRlY29kZUNvbnRlbnQpO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogUmVhZCB0aGUgZW5kIG9mIHRoZSBaaXAgNjQgY2VudHJhbCBkaXJlY3RvcnkuXG4gICAgICogTm90IG1lcmdlZCB3aXRoIHRoZSBtZXRob2QgcmVhZEVuZE9mQ2VudHJhbCA6XG4gICAgICogVGhlIGVuZCBvZiBjZW50cmFsIGNhbiBjb2V4aXN0IHdpdGggaXRzIFppcDY0IGJyb3RoZXIsXG4gICAgICogSSBkb24ndCB3YW50IHRvIHJlYWQgdGhlIHdyb25nIG51bWJlciBvZiBieXRlcyAhXG4gICAgICovXG4gICAgcmVhZEJsb2NrWmlwNjRFbmRPZkNlbnRyYWw6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLnppcDY0RW5kT2ZDZW50cmFsU2l6ZSA9IHRoaXMucmVhZGVyLnJlYWRJbnQoOCk7XG4gICAgICAgIHRoaXMucmVhZGVyLnNraXAoNCk7XG4gICAgICAgIC8vIHRoaXMudmVyc2lvbk1hZGVCeSA9IHRoaXMucmVhZGVyLnJlYWRTdHJpbmcoMik7XG4gICAgICAgIC8vIHRoaXMudmVyc2lvbk5lZWRlZCA9IHRoaXMucmVhZGVyLnJlYWRJbnQoMik7XG4gICAgICAgIHRoaXMuZGlza051bWJlciA9IHRoaXMucmVhZGVyLnJlYWRJbnQoNCk7XG4gICAgICAgIHRoaXMuZGlza1dpdGhDZW50cmFsRGlyU3RhcnQgPSB0aGlzLnJlYWRlci5yZWFkSW50KDQpO1xuICAgICAgICB0aGlzLmNlbnRyYWxEaXJSZWNvcmRzT25UaGlzRGlzayA9IHRoaXMucmVhZGVyLnJlYWRJbnQoOCk7XG4gICAgICAgIHRoaXMuY2VudHJhbERpclJlY29yZHMgPSB0aGlzLnJlYWRlci5yZWFkSW50KDgpO1xuICAgICAgICB0aGlzLmNlbnRyYWxEaXJTaXplID0gdGhpcy5yZWFkZXIucmVhZEludCg4KTtcbiAgICAgICAgdGhpcy5jZW50cmFsRGlyT2Zmc2V0ID0gdGhpcy5yZWFkZXIucmVhZEludCg4KTtcblxuICAgICAgICB0aGlzLnppcDY0RXh0ZW5zaWJsZURhdGEgPSB7fTtcbiAgICAgICAgdmFyIGV4dHJhRGF0YVNpemUgPSB0aGlzLnppcDY0RW5kT2ZDZW50cmFsU2l6ZSAtIDQ0LFxuICAgICAgICAgICAgaW5kZXggPSAwLFxuICAgICAgICAgICAgZXh0cmFGaWVsZElkLFxuICAgICAgICAgICAgZXh0cmFGaWVsZExlbmd0aCxcbiAgICAgICAgICAgIGV4dHJhRmllbGRWYWx1ZTtcbiAgICAgICAgd2hpbGUgKGluZGV4IDwgZXh0cmFEYXRhU2l6ZSkge1xuICAgICAgICAgICAgZXh0cmFGaWVsZElkID0gdGhpcy5yZWFkZXIucmVhZEludCgyKTtcbiAgICAgICAgICAgIGV4dHJhRmllbGRMZW5ndGggPSB0aGlzLnJlYWRlci5yZWFkSW50KDQpO1xuICAgICAgICAgICAgZXh0cmFGaWVsZFZhbHVlID0gdGhpcy5yZWFkZXIucmVhZERhdGEoZXh0cmFGaWVsZExlbmd0aCk7XG4gICAgICAgICAgICB0aGlzLnppcDY0RXh0ZW5zaWJsZURhdGFbZXh0cmFGaWVsZElkXSA9IHtcbiAgICAgICAgICAgICAgICBpZDogZXh0cmFGaWVsZElkLFxuICAgICAgICAgICAgICAgIGxlbmd0aDogZXh0cmFGaWVsZExlbmd0aCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogZXh0cmFGaWVsZFZhbHVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBSZWFkIHRoZSBlbmQgb2YgdGhlIFppcCA2NCBjZW50cmFsIGRpcmVjdG9yeSBsb2NhdG9yLlxuICAgICAqL1xuICAgIHJlYWRCbG9ja1ppcDY0RW5kT2ZDZW50cmFsTG9jYXRvcjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMuZGlza1dpdGhaaXA2NENlbnRyYWxEaXJTdGFydCA9IHRoaXMucmVhZGVyLnJlYWRJbnQoNCk7XG4gICAgICAgIHRoaXMucmVsYXRpdmVPZmZzZXRFbmRPZlppcDY0Q2VudHJhbERpciA9IHRoaXMucmVhZGVyLnJlYWRJbnQoOCk7XG4gICAgICAgIHRoaXMuZGlza3NDb3VudCA9IHRoaXMucmVhZGVyLnJlYWRJbnQoNCk7XG4gICAgICAgIGlmICh0aGlzLmRpc2tzQ291bnQgPiAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNdWx0aS12b2x1bWVzIHppcCBhcmUgbm90IHN1cHBvcnRlZFwiKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogUmVhZCB0aGUgbG9jYWwgZmlsZXMsIGJhc2VkIG9uIHRoZSBvZmZzZXQgcmVhZCBpbiB0aGUgY2VudHJhbCBwYXJ0LlxuICAgICAqL1xuICAgIHJlYWRMb2NhbEZpbGVzOiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGksIGZpbGU7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCB0aGlzLmZpbGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBmaWxlID0gdGhpcy5maWxlc1tpXTtcbiAgICAgICAgICAgIHRoaXMucmVhZGVyLnNldEluZGV4KGZpbGUubG9jYWxIZWFkZXJPZmZzZXQpO1xuICAgICAgICAgICAgdGhpcy5jaGVja1NpZ25hdHVyZShzaWcuTE9DQUxfRklMRV9IRUFERVIpO1xuICAgICAgICAgICAgZmlsZS5yZWFkTG9jYWxQYXJ0KHRoaXMucmVhZGVyKTtcbiAgICAgICAgICAgIGZpbGUuaGFuZGxlVVRGOCgpO1xuICAgICAgICAgICAgZmlsZS5wcm9jZXNzQXR0cmlidXRlcygpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBSZWFkIHRoZSBjZW50cmFsIGRpcmVjdG9yeS5cbiAgICAgKi9cbiAgICByZWFkQ2VudHJhbERpcjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBmaWxlO1xuXG4gICAgICAgIHRoaXMucmVhZGVyLnNldEluZGV4KHRoaXMuY2VudHJhbERpck9mZnNldCk7XG4gICAgICAgIHdoaWxlICh0aGlzLnJlYWRlci5yZWFkQW5kQ2hlY2tTaWduYXR1cmUoc2lnLkNFTlRSQUxfRklMRV9IRUFERVIpKSB7XG4gICAgICAgICAgICBmaWxlID0gbmV3IFppcEVudHJ5KHtcbiAgICAgICAgICAgICAgICB6aXA2NDogdGhpcy56aXA2NFxuICAgICAgICAgICAgfSwgdGhpcy5sb2FkT3B0aW9ucyk7XG4gICAgICAgICAgICBmaWxlLnJlYWRDZW50cmFsUGFydCh0aGlzLnJlYWRlcik7XG4gICAgICAgICAgICB0aGlzLmZpbGVzLnB1c2goZmlsZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5jZW50cmFsRGlyUmVjb3JkcyAhPT0gdGhpcy5maWxlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmNlbnRyYWxEaXJSZWNvcmRzICE9PSAwICYmIHRoaXMuZmlsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgLy8gV2UgZXhwZWN0ZWQgc29tZSByZWNvcmRzIGJ1dCBjb3VsZG4ndCBmaW5kIEFOWS5cbiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHJlYWxseSBzdXNwaWNpb3VzLCBhcyBpZiBzb21ldGhpbmcgd2VudCB3cm9uZy5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb3JydXB0ZWQgemlwIG9yIGJ1ZzogZXhwZWN0ZWQgXCIgKyB0aGlzLmNlbnRyYWxEaXJSZWNvcmRzICsgXCIgcmVjb3JkcyBpbiBjZW50cmFsIGRpciwgZ290IFwiICsgdGhpcy5maWxlcy5sZW5ndGgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBXZSBmb3VuZCBzb21lIHJlY29yZHMgYnV0IG5vdCBhbGwuXG4gICAgICAgICAgICAgICAgLy8gU29tZXRoaW5nIGlzIHdyb25nIGJ1dCB3ZSBnb3Qgc29tZXRoaW5nIGZvciB0aGUgdXNlcjogbm8gZXJyb3IgaGVyZS5cbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLndhcm4oXCJleHBlY3RlZFwiLCB0aGlzLmNlbnRyYWxEaXJSZWNvcmRzLCBcInJlY29yZHMgaW4gY2VudHJhbCBkaXIsIGdvdFwiLCB0aGlzLmZpbGVzLmxlbmd0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFJlYWQgdGhlIGVuZCBvZiBjZW50cmFsIGRpcmVjdG9yeS5cbiAgICAgKi9cbiAgICByZWFkRW5kT2ZDZW50cmFsOiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIG9mZnNldCA9IHRoaXMucmVhZGVyLmxhc3RJbmRleE9mU2lnbmF0dXJlKHNpZy5DRU5UUkFMX0RJUkVDVE9SWV9FTkQpO1xuICAgICAgICBpZiAob2Zmc2V0IDwgMCkge1xuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIGNvbnRlbnQgaXMgYSB0cnVuY2F0ZWQgemlwIG9yIGNvbXBsZXRlIGdhcmJhZ2UuXG4gICAgICAgICAgICAvLyBBIFwiTE9DQUxfRklMRV9IRUFERVJcIiBpcyBub3QgcmVxdWlyZWQgYXQgdGhlIGJlZ2lubmluZyAoYXV0b1xuICAgICAgICAgICAgLy8gZXh0cmFjdGlibGUgemlwIGZvciBleGFtcGxlKSBidXQgaXQgY2FuIGdpdmUgYSBnb29kIGhpbnQuXG4gICAgICAgICAgICAvLyBJZiBhbiBhamF4IHJlcXVlc3Qgd2FzIHVzZWQgd2l0aG91dCByZXNwb25zZVR5cGUsIHdlIHdpbGwgYWxzb1xuICAgICAgICAgICAgLy8gZ2V0IHVucmVhZGFibGUgZGF0YS5cbiAgICAgICAgICAgIHZhciBpc0dhcmJhZ2UgPSAhdGhpcy5pc1NpZ25hdHVyZSgwLCBzaWcuTE9DQUxfRklMRV9IRUFERVIpO1xuXG4gICAgICAgICAgICBpZiAoaXNHYXJiYWdlKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3QgZmluZCBlbmQgb2YgY2VudHJhbCBkaXJlY3RvcnkgOiBpcyB0aGlzIGEgemlwIGZpbGUgPyBcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiSWYgaXQgaXMsIHNlZSBodHRwczovL3N0dWsuZ2l0aHViLmlvL2pzemlwL2RvY3VtZW50YXRpb24vaG93dG8vcmVhZF96aXAuaHRtbFwiKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ29ycnVwdGVkIHppcDogY2FuJ3QgZmluZCBlbmQgb2YgY2VudHJhbCBkaXJlY3RvcnlcIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlYWRlci5zZXRJbmRleChvZmZzZXQpO1xuICAgICAgICB2YXIgZW5kT2ZDZW50cmFsRGlyT2Zmc2V0ID0gb2Zmc2V0O1xuICAgICAgICB0aGlzLmNoZWNrU2lnbmF0dXJlKHNpZy5DRU5UUkFMX0RJUkVDVE9SWV9FTkQpO1xuICAgICAgICB0aGlzLnJlYWRCbG9ja0VuZE9mQ2VudHJhbCgpO1xuXG5cbiAgICAgICAgLyogZXh0cmFjdCBmcm9tIHRoZSB6aXAgc3BlYyA6XG4gICAgICAgICAgICA0KSAgSWYgb25lIG9mIHRoZSBmaWVsZHMgaW4gdGhlIGVuZCBvZiBjZW50cmFsIGRpcmVjdG9yeVxuICAgICAgICAgICAgICAgIHJlY29yZCBpcyB0b28gc21hbGwgdG8gaG9sZCByZXF1aXJlZCBkYXRhLCB0aGUgZmllbGRcbiAgICAgICAgICAgICAgICBzaG91bGQgYmUgc2V0IHRvIC0xICgweEZGRkYgb3IgMHhGRkZGRkZGRikgYW5kIHRoZVxuICAgICAgICAgICAgICAgIFpJUDY0IGZvcm1hdCByZWNvcmQgc2hvdWxkIGJlIGNyZWF0ZWQuXG4gICAgICAgICAgICA1KSAgVGhlIGVuZCBvZiBjZW50cmFsIGRpcmVjdG9yeSByZWNvcmQgYW5kIHRoZVxuICAgICAgICAgICAgICAgIFppcDY0IGVuZCBvZiBjZW50cmFsIGRpcmVjdG9yeSBsb2NhdG9yIHJlY29yZCBtdXN0XG4gICAgICAgICAgICAgICAgcmVzaWRlIG9uIHRoZSBzYW1lIGRpc2sgd2hlbiBzcGxpdHRpbmcgb3Igc3Bhbm5pbmdcbiAgICAgICAgICAgICAgICBhbiBhcmNoaXZlLlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKHRoaXMuZGlza051bWJlciA9PT0gdXRpbHMuTUFYX1ZBTFVFXzE2QklUUyB8fCB0aGlzLmRpc2tXaXRoQ2VudHJhbERpclN0YXJ0ID09PSB1dGlscy5NQVhfVkFMVUVfMTZCSVRTIHx8IHRoaXMuY2VudHJhbERpclJlY29yZHNPblRoaXNEaXNrID09PSB1dGlscy5NQVhfVkFMVUVfMTZCSVRTIHx8IHRoaXMuY2VudHJhbERpclJlY29yZHMgPT09IHV0aWxzLk1BWF9WQUxVRV8xNkJJVFMgfHwgdGhpcy5jZW50cmFsRGlyU2l6ZSA9PT0gdXRpbHMuTUFYX1ZBTFVFXzMyQklUUyB8fCB0aGlzLmNlbnRyYWxEaXJPZmZzZXQgPT09IHV0aWxzLk1BWF9WQUxVRV8zMkJJVFMpIHtcbiAgICAgICAgICAgIHRoaXMuemlwNjQgPSB0cnVlO1xuXG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgV2FybmluZyA6IHRoZSB6aXA2NCBleHRlbnNpb24gaXMgc3VwcG9ydGVkLCBidXQgT05MWSBpZiB0aGUgNjRiaXRzIGludGVnZXIgcmVhZCBmcm9tXG4gICAgICAgICAgICB0aGUgemlwIGZpbGUgY2FuIGZpdCBpbnRvIGEgMzJiaXRzIGludGVnZXIuIFRoaXMgY2Fubm90IGJlIHNvbHZlZCA6IEphdmFTY3JpcHQgcmVwcmVzZW50c1xuICAgICAgICAgICAgYWxsIG51bWJlcnMgYXMgNjQtYml0IGRvdWJsZSBwcmVjaXNpb24gSUVFRSA3NTQgZmxvYXRpbmcgcG9pbnQgbnVtYmVycy5cbiAgICAgICAgICAgIFNvLCB3ZSBoYXZlIDUzYml0cyBmb3IgaW50ZWdlcnMgYW5kIGJpdHdpc2Ugb3BlcmF0aW9ucyB0cmVhdCBldmVyeXRoaW5nIGFzIDMyYml0cy5cbiAgICAgICAgICAgIHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL0phdmFTY3JpcHQvUmVmZXJlbmNlL09wZXJhdG9ycy9CaXR3aXNlX09wZXJhdG9yc1xuICAgICAgICAgICAgYW5kIGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9wdWJsaWNhdGlvbnMvZmlsZXMvRUNNQS1TVC9FQ01BLTI2Mi5wZGYgc2VjdGlvbiA4LjVcbiAgICAgICAgICAgICovXG5cbiAgICAgICAgICAgIC8vIHNob3VsZCBsb29rIGZvciBhIHppcDY0IEVPQ0QgbG9jYXRvclxuICAgICAgICAgICAgb2Zmc2V0ID0gdGhpcy5yZWFkZXIubGFzdEluZGV4T2ZTaWduYXR1cmUoc2lnLlpJUDY0X0NFTlRSQUxfRElSRUNUT1JZX0xPQ0FUT1IpO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA8IDApIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb3JydXB0ZWQgemlwOiBjYW4ndCBmaW5kIHRoZSBaSVA2NCBlbmQgb2YgY2VudHJhbCBkaXJlY3RvcnkgbG9jYXRvclwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucmVhZGVyLnNldEluZGV4KG9mZnNldCk7XG4gICAgICAgICAgICB0aGlzLmNoZWNrU2lnbmF0dXJlKHNpZy5aSVA2NF9DRU5UUkFMX0RJUkVDVE9SWV9MT0NBVE9SKTtcbiAgICAgICAgICAgIHRoaXMucmVhZEJsb2NrWmlwNjRFbmRPZkNlbnRyYWxMb2NhdG9yKCk7XG5cbiAgICAgICAgICAgIC8vIG5vdyB0aGUgemlwNjQgRU9DRCByZWNvcmRcbiAgICAgICAgICAgIGlmICghdGhpcy5pc1NpZ25hdHVyZSh0aGlzLnJlbGF0aXZlT2Zmc2V0RW5kT2ZaaXA2NENlbnRyYWxEaXIsIHNpZy5aSVA2NF9DRU5UUkFMX0RJUkVDVE9SWV9FTkQpKSB7XG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS53YXJuKFwiWklQNjQgZW5kIG9mIGNlbnRyYWwgZGlyZWN0b3J5IG5vdCB3aGVyZSBleHBlY3RlZC5cIik7XG4gICAgICAgICAgICAgICAgdGhpcy5yZWxhdGl2ZU9mZnNldEVuZE9mWmlwNjRDZW50cmFsRGlyID0gdGhpcy5yZWFkZXIubGFzdEluZGV4T2ZTaWduYXR1cmUoc2lnLlpJUDY0X0NFTlRSQUxfRElSRUNUT1JZX0VORCk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucmVsYXRpdmVPZmZzZXRFbmRPZlppcDY0Q2VudHJhbERpciA8IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ29ycnVwdGVkIHppcDogY2FuJ3QgZmluZCB0aGUgWklQNjQgZW5kIG9mIGNlbnRyYWwgZGlyZWN0b3J5XCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucmVhZGVyLnNldEluZGV4KHRoaXMucmVsYXRpdmVPZmZzZXRFbmRPZlppcDY0Q2VudHJhbERpcik7XG4gICAgICAgICAgICB0aGlzLmNoZWNrU2lnbmF0dXJlKHNpZy5aSVA2NF9DRU5UUkFMX0RJUkVDVE9SWV9FTkQpO1xuICAgICAgICAgICAgdGhpcy5yZWFkQmxvY2taaXA2NEVuZE9mQ2VudHJhbCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGV4cGVjdGVkRW5kT2ZDZW50cmFsRGlyT2Zmc2V0ID0gdGhpcy5jZW50cmFsRGlyT2Zmc2V0ICsgdGhpcy5jZW50cmFsRGlyU2l6ZTtcbiAgICAgICAgaWYgKHRoaXMuemlwNjQpIHtcbiAgICAgICAgICAgIGV4cGVjdGVkRW5kT2ZDZW50cmFsRGlyT2Zmc2V0ICs9IDIwOyAvLyBlbmQgb2YgY2VudHJhbCBkaXIgNjQgbG9jYXRvclxuICAgICAgICAgICAgZXhwZWN0ZWRFbmRPZkNlbnRyYWxEaXJPZmZzZXQgKz0gMTIgLyogc2hvdWxkIG5vdCBpbmNsdWRlIHRoZSBsZWFkaW5nIDEyIGJ5dGVzICovICsgdGhpcy56aXA2NEVuZE9mQ2VudHJhbFNpemU7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgZXh0cmFCeXRlcyA9IGVuZE9mQ2VudHJhbERpck9mZnNldCAtIGV4cGVjdGVkRW5kT2ZDZW50cmFsRGlyT2Zmc2V0O1xuXG4gICAgICAgIGlmIChleHRyYUJ5dGVzID4gMCkge1xuICAgICAgICAgICAgLy8gY29uc29sZS53YXJuKGV4dHJhQnl0ZXMsIFwiZXh0cmEgYnl0ZXMgYXQgYmVnaW5uaW5nIG9yIHdpdGhpbiB6aXBmaWxlXCIpO1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNTaWduYXR1cmUoZW5kT2ZDZW50cmFsRGlyT2Zmc2V0LCBzaWcuQ0VOVFJBTF9GSUxFX0hFQURFUikpIHtcbiAgICAgICAgICAgICAgICAvLyBUaGUgb2Zmc2V0cyBzZWVtIHdyb25nLCBidXQgd2UgaGF2ZSBzb21ldGhpbmcgYXQgdGhlIHNwZWNpZmllZCBvZmZzZXQuXG4gICAgICAgICAgICAgICAgLy8gU2/igKYgd2Uga2VlcCBpdC5cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gdGhlIG9mZnNldCBpcyB3cm9uZywgdXBkYXRlIHRoZSBcInplcm9cIiBvZiB0aGUgcmVhZGVyXG4gICAgICAgICAgICAgICAgLy8gdGhpcyBoYXBwZW5zIGlmIGRhdGEgaGFzIGJlZW4gcHJlcGVuZGVkIChjcnggZmlsZXMgZm9yIGV4YW1wbGUpXG4gICAgICAgICAgICAgICAgdGhpcy5yZWFkZXIuemVybyA9IGV4dHJhQnl0ZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZXh0cmFCeXRlcyA8IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvcnJ1cHRlZCB6aXA6IG1pc3NpbmcgXCIgKyBNYXRoLmFicyhleHRyYUJ5dGVzKSArIFwiIGJ5dGVzLlwiKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgcHJlcGFyZVJlYWRlcjogZnVuY3Rpb24oZGF0YSkge1xuICAgICAgICB0aGlzLnJlYWRlciA9IHJlYWRlckZvcihkYXRhKTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFJlYWQgYSB6aXAgZmlsZSBhbmQgY3JlYXRlIFppcEVudHJpZXMuXG4gICAgICogQHBhcmFtIHtTdHJpbmd8QXJyYXlCdWZmZXJ8VWludDhBcnJheXxCdWZmZXJ9IGRhdGEgdGhlIGJpbmFyeSBzdHJpbmcgcmVwcmVzZW50aW5nIGEgemlwIGZpbGUuXG4gICAgICovXG4gICAgbG9hZDogZnVuY3Rpb24oZGF0YSkge1xuICAgICAgICB0aGlzLnByZXBhcmVSZWFkZXIoZGF0YSk7XG4gICAgICAgIHRoaXMucmVhZEVuZE9mQ2VudHJhbCgpO1xuICAgICAgICB0aGlzLnJlYWRDZW50cmFsRGlyKCk7XG4gICAgICAgIHRoaXMucmVhZExvY2FsRmlsZXMoKTtcbiAgICB9XG59O1xuLy8gfX19IGVuZCBvZiBaaXBFbnRyaWVzXG5tb2R1bGUuZXhwb3J0cyA9IFppcEVudHJpZXM7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgcmVhZGVyRm9yID0gcmVxdWlyZSgnLi9yZWFkZXIvcmVhZGVyRm9yJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzJyk7XG52YXIgQ29tcHJlc3NlZE9iamVjdCA9IHJlcXVpcmUoJy4vY29tcHJlc3NlZE9iamVjdCcpO1xudmFyIGNyYzMyZm4gPSByZXF1aXJlKCcuL2NyYzMyJyk7XG52YXIgdXRmOCA9IHJlcXVpcmUoJy4vdXRmOCcpO1xudmFyIGNvbXByZXNzaW9ucyA9IHJlcXVpcmUoJy4vY29tcHJlc3Npb25zJyk7XG52YXIgc3VwcG9ydCA9IHJlcXVpcmUoJy4vc3VwcG9ydCcpO1xuXG52YXIgTUFERV9CWV9ET1MgPSAweDAwO1xudmFyIE1BREVfQllfVU5JWCA9IDB4MDM7XG5cbi8qKlxuICogRmluZCBhIGNvbXByZXNzaW9uIHJlZ2lzdGVyZWQgaW4gSlNaaXAuXG4gKiBAcGFyYW0ge3N0cmluZ30gY29tcHJlc3Npb25NZXRob2QgdGhlIG1ldGhvZCBtYWdpYyB0byBmaW5kLlxuICogQHJldHVybiB7T2JqZWN0fG51bGx9IHRoZSBKU1ppcCBjb21wcmVzc2lvbiBvYmplY3QsIG51bGwgaWYgbm9uZSBmb3VuZC5cbiAqL1xudmFyIGZpbmRDb21wcmVzc2lvbiA9IGZ1bmN0aW9uKGNvbXByZXNzaW9uTWV0aG9kKSB7XG4gICAgZm9yICh2YXIgbWV0aG9kIGluIGNvbXByZXNzaW9ucykge1xuICAgICAgICBpZiAoIWNvbXByZXNzaW9ucy5oYXNPd25Qcm9wZXJ0eShtZXRob2QpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29tcHJlc3Npb25zW21ldGhvZF0ubWFnaWMgPT09IGNvbXByZXNzaW9uTWV0aG9kKSB7XG4gICAgICAgICAgICByZXR1cm4gY29tcHJlc3Npb25zW21ldGhvZF07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59O1xuXG4vLyBjbGFzcyBaaXBFbnRyeSB7e3tcbi8qKlxuICogQW4gZW50cnkgaW4gdGhlIHppcCBmaWxlLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBPcHRpb25zIG9mIHRoZSBjdXJyZW50IGZpbGUuXG4gKiBAcGFyYW0ge09iamVjdH0gbG9hZE9wdGlvbnMgT3B0aW9ucyBmb3IgbG9hZGluZyB0aGUgc3RyZWFtLlxuICovXG5mdW5jdGlvbiBaaXBFbnRyeShvcHRpb25zLCBsb2FkT3B0aW9ucykge1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgdGhpcy5sb2FkT3B0aW9ucyA9IGxvYWRPcHRpb25zO1xufVxuWmlwRW50cnkucHJvdG90eXBlID0ge1xuICAgIC8qKlxuICAgICAqIHNheSBpZiB0aGUgZmlsZSBpcyBlbmNyeXB0ZWQuXG4gICAgICogQHJldHVybiB7Ym9vbGVhbn0gdHJ1ZSBpZiB0aGUgZmlsZSBpcyBlbmNyeXB0ZWQsIGZhbHNlIG90aGVyd2lzZS5cbiAgICAgKi9cbiAgICBpc0VuY3J5cHRlZDogZnVuY3Rpb24oKSB7XG4gICAgICAgIC8vIGJpdCAxIGlzIHNldFxuICAgICAgICByZXR1cm4gKHRoaXMuYml0RmxhZyAmIDB4MDAwMSkgPT09IDB4MDAwMTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIHNheSBpZiB0aGUgZmlsZSBoYXMgdXRmLTggZmlsZW5hbWUvY29tbWVudC5cbiAgICAgKiBAcmV0dXJuIHtib29sZWFufSB0cnVlIGlmIHRoZSBmaWxlbmFtZS9jb21tZW50IGlzIGluIHV0Zi04LCBmYWxzZSBvdGhlcndpc2UuXG4gICAgICovXG4gICAgdXNlVVRGODogZnVuY3Rpb24oKSB7XG4gICAgICAgIC8vIGJpdCAxMSBpcyBzZXRcbiAgICAgICAgcmV0dXJuICh0aGlzLmJpdEZsYWcgJiAweDA4MDApID09PSAweDA4MDA7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBSZWFkIHRoZSBsb2NhbCBwYXJ0IG9mIGEgemlwIGZpbGUgYW5kIGFkZCB0aGUgaW5mbyBpbiB0aGlzIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge0RhdGFSZWFkZXJ9IHJlYWRlciB0aGUgcmVhZGVyIHRvIHVzZS5cbiAgICAgKi9cbiAgICByZWFkTG9jYWxQYXJ0OiBmdW5jdGlvbihyZWFkZXIpIHtcbiAgICAgICAgdmFyIGNvbXByZXNzaW9uLCBsb2NhbEV4dHJhRmllbGRzTGVuZ3RoO1xuXG4gICAgICAgIC8vIHdlIGFscmVhZHkga25vdyBldmVyeXRoaW5nIGZyb20gdGhlIGNlbnRyYWwgZGlyICFcbiAgICAgICAgLy8gSWYgdGhlIGNlbnRyYWwgZGlyIGRhdGEgYXJlIGZhbHNlLCB3ZSBhcmUgZG9vbWVkLlxuICAgICAgICAvLyBPbiB0aGUgYnJpZ2h0IHNpZGUsIHRoZSBsb2NhbCBwYXJ0IGlzIHNjYXJ5ICA6IHppcDY0LCBkYXRhIGRlc2NyaXB0b3JzLCBib3RoLCBldGMuXG4gICAgICAgIC8vIFRoZSBsZXNzIGRhdGEgd2UgZ2V0IGhlcmUsIHRoZSBtb3JlIHJlbGlhYmxlIHRoaXMgc2hvdWxkIGJlLlxuICAgICAgICAvLyBMZXQncyBza2lwIHRoZSB3aG9sZSBoZWFkZXIgYW5kIGRhc2ggdG8gdGhlIGRhdGEgIVxuICAgICAgICByZWFkZXIuc2tpcCgyMik7XG4gICAgICAgIC8vIGluIHNvbWUgemlwIGNyZWF0ZWQgb24gd2luZG93cywgdGhlIGZpbGVuYW1lIHN0b3JlZCBpbiB0aGUgY2VudHJhbCBkaXIgY29udGFpbnMgXFwgaW5zdGVhZCBvZiAvLlxuICAgICAgICAvLyBTdHJhbmdlbHksIHRoZSBmaWxlbmFtZSBoZXJlIGlzIE9LLlxuICAgICAgICAvLyBJIHdvdWxkIGxvdmUgdG8gdHJlYXQgdGhlc2UgemlwIGZpbGVzIGFzIGNvcnJ1cHRlZCAoc2VlIGh0dHA6Ly93d3cuaW5mby16aXAub3JnL0ZBUS5odG1sI2JhY2tzbGFzaGVzXG4gICAgICAgIC8vIG9yIEFQUE5PVEUjNC40LjE3LjEsIFwiQWxsIHNsYXNoZXMgTVVTVCBiZSBmb3J3YXJkIHNsYXNoZXMgJy8nXCIpIGJ1dCB0aGVyZSBhcmUgYSBsb3Qgb2YgYmFkIHppcCBnZW5lcmF0b3JzLi4uXG4gICAgICAgIC8vIFNlYXJjaCBcInVuemlwIG1pc21hdGNoaW5nIFwibG9jYWxcIiBmaWxlbmFtZSBjb250aW51aW5nIHdpdGggXCJjZW50cmFsXCIgZmlsZW5hbWUgdmVyc2lvblwiIG9uXG4gICAgICAgIC8vIHRoZSBpbnRlcm5ldC5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gSSB0aGluayBJIHNlZSB0aGUgbG9naWMgaGVyZSA6IHRoZSBjZW50cmFsIGRpcmVjdG9yeSBpcyB1c2VkIHRvIGRpc3BsYXlcbiAgICAgICAgLy8gY29udGVudCBhbmQgdGhlIGxvY2FsIGRpcmVjdG9yeSBpcyB1c2VkIHRvIGV4dHJhY3QgdGhlIGZpbGVzLiBNaXhpbmcgLyBhbmQgXFxcbiAgICAgICAgLy8gbWF5IGJlIHVzZWQgdG8gZGlzcGxheSBcXCB0byB3aW5kb3dzIHVzZXJzIGFuZCB1c2UgLyB3aGVuIGV4dHJhY3RpbmcgdGhlIGZpbGVzLlxuICAgICAgICAvLyBVbmZvcnR1bmF0ZWx5LCB0aGlzIGxlYWQgYWxzbyB0byBzb21lIGlzc3VlcyA6IGh0dHA6Ly9zZWNsaXN0cy5vcmcvZnVsbGRpc2Nsb3N1cmUvMjAwOS9TZXAvMzk0XG4gICAgICAgIHRoaXMuZmlsZU5hbWVMZW5ndGggPSByZWFkZXIucmVhZEludCgyKTtcbiAgICAgICAgbG9jYWxFeHRyYUZpZWxkc0xlbmd0aCA9IHJlYWRlci5yZWFkSW50KDIpOyAvLyBjYW4ndCBiZSBzdXJlIHRoaXMgd2lsbCBiZSB0aGUgc2FtZSBhcyB0aGUgY2VudHJhbCBkaXJcbiAgICAgICAgLy8gdGhlIGZpbGVOYW1lIGlzIHN0b3JlZCBhcyBiaW5hcnkgZGF0YSwgdGhlIGhhbmRsZVVURjggbWV0aG9kIHdpbGwgdGFrZSBjYXJlIG9mIHRoZSBlbmNvZGluZy5cbiAgICAgICAgdGhpcy5maWxlTmFtZSA9IHJlYWRlci5yZWFkRGF0YSh0aGlzLmZpbGVOYW1lTGVuZ3RoKTtcbiAgICAgICAgcmVhZGVyLnNraXAobG9jYWxFeHRyYUZpZWxkc0xlbmd0aCk7XG5cbiAgICAgICAgaWYgKHRoaXMuY29tcHJlc3NlZFNpemUgPT09IC0xIHx8IHRoaXMudW5jb21wcmVzc2VkU2l6ZSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkJ1ZyBvciBjb3JydXB0ZWQgemlwIDogZGlkbid0IGdldCBlbm91Z2ggaW5mb3JtYXRpb25zIGZyb20gdGhlIGNlbnRyYWwgZGlyZWN0b3J5IFwiICsgXCIoY29tcHJlc3NlZFNpemUgPT09IC0xIHx8IHVuY29tcHJlc3NlZFNpemUgPT09IC0xKVwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbXByZXNzaW9uID0gZmluZENvbXByZXNzaW9uKHRoaXMuY29tcHJlc3Npb25NZXRob2QpO1xuICAgICAgICBpZiAoY29tcHJlc3Npb24gPT09IG51bGwpIHsgLy8gbm8gY29tcHJlc3Npb24gZm91bmRcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvcnJ1cHRlZCB6aXAgOiBjb21wcmVzc2lvbiBcIiArIHV0aWxzLnByZXR0eSh0aGlzLmNvbXByZXNzaW9uTWV0aG9kKSArIFwiIHVua25vd24gKGlubmVyIGZpbGUgOiBcIiArIHV0aWxzLnRyYW5zZm9ybVRvKFwic3RyaW5nXCIsIHRoaXMuZmlsZU5hbWUpICsgXCIpXCIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZGVjb21wcmVzc2VkID0gbmV3IENvbXByZXNzZWRPYmplY3QodGhpcy5jb21wcmVzc2VkU2l6ZSwgdGhpcy51bmNvbXByZXNzZWRTaXplLCB0aGlzLmNyYzMyLCBjb21wcmVzc2lvbiwgcmVhZGVyLnJlYWREYXRhKHRoaXMuY29tcHJlc3NlZFNpemUpKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmVhZCB0aGUgY2VudHJhbCBwYXJ0IG9mIGEgemlwIGZpbGUgYW5kIGFkZCB0aGUgaW5mbyBpbiB0aGlzIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge0RhdGFSZWFkZXJ9IHJlYWRlciB0aGUgcmVhZGVyIHRvIHVzZS5cbiAgICAgKi9cbiAgICByZWFkQ2VudHJhbFBhcnQ6IGZ1bmN0aW9uKHJlYWRlcikge1xuICAgICAgICB0aGlzLnZlcnNpb25NYWRlQnkgPSByZWFkZXIucmVhZEludCgyKTtcbiAgICAgICAgcmVhZGVyLnNraXAoMik7XG4gICAgICAgIC8vIHRoaXMudmVyc2lvbk5lZWRlZCA9IHJlYWRlci5yZWFkSW50KDIpO1xuICAgICAgICB0aGlzLmJpdEZsYWcgPSByZWFkZXIucmVhZEludCgyKTtcbiAgICAgICAgdGhpcy5jb21wcmVzc2lvbk1ldGhvZCA9IHJlYWRlci5yZWFkU3RyaW5nKDIpO1xuICAgICAgICB0aGlzLmRhdGUgPSByZWFkZXIucmVhZERhdGUoKTtcbiAgICAgICAgdGhpcy5jcmMzMiA9IHJlYWRlci5yZWFkSW50KDQpO1xuICAgICAgICB0aGlzLmNvbXByZXNzZWRTaXplID0gcmVhZGVyLnJlYWRJbnQoNCk7XG4gICAgICAgIHRoaXMudW5jb21wcmVzc2VkU2l6ZSA9IHJlYWRlci5yZWFkSW50KDQpO1xuICAgICAgICB2YXIgZmlsZU5hbWVMZW5ndGggPSByZWFkZXIucmVhZEludCgyKTtcbiAgICAgICAgdGhpcy5leHRyYUZpZWxkc0xlbmd0aCA9IHJlYWRlci5yZWFkSW50KDIpO1xuICAgICAgICB0aGlzLmZpbGVDb21tZW50TGVuZ3RoID0gcmVhZGVyLnJlYWRJbnQoMik7XG4gICAgICAgIHRoaXMuZGlza051bWJlclN0YXJ0ID0gcmVhZGVyLnJlYWRJbnQoMik7XG4gICAgICAgIHRoaXMuaW50ZXJuYWxGaWxlQXR0cmlidXRlcyA9IHJlYWRlci5yZWFkSW50KDIpO1xuICAgICAgICB0aGlzLmV4dGVybmFsRmlsZUF0dHJpYnV0ZXMgPSByZWFkZXIucmVhZEludCg0KTtcbiAgICAgICAgdGhpcy5sb2NhbEhlYWRlck9mZnNldCA9IHJlYWRlci5yZWFkSW50KDQpO1xuXG4gICAgICAgIGlmICh0aGlzLmlzRW5jcnlwdGVkKCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkVuY3J5cHRlZCB6aXAgYXJlIG5vdCBzdXBwb3J0ZWRcIik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB3aWxsIGJlIHJlYWQgaW4gdGhlIGxvY2FsIHBhcnQsIHNlZSB0aGUgY29tbWVudHMgdGhlcmVcbiAgICAgICAgcmVhZGVyLnNraXAoZmlsZU5hbWVMZW5ndGgpO1xuICAgICAgICB0aGlzLnJlYWRFeHRyYUZpZWxkcyhyZWFkZXIpO1xuICAgICAgICB0aGlzLnBhcnNlWklQNjRFeHRyYUZpZWxkKHJlYWRlcik7XG4gICAgICAgIHRoaXMuZmlsZUNvbW1lbnQgPSByZWFkZXIucmVhZERhdGEodGhpcy5maWxlQ29tbWVudExlbmd0aCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFBhcnNlIHRoZSBleHRlcm5hbCBmaWxlIGF0dHJpYnV0ZXMgYW5kIGdldCB0aGUgdW5peC9kb3MgcGVybWlzc2lvbnMuXG4gICAgICovXG4gICAgcHJvY2Vzc0F0dHJpYnV0ZXM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy51bml4UGVybWlzc2lvbnMgPSBudWxsO1xuICAgICAgICB0aGlzLmRvc1Blcm1pc3Npb25zID0gbnVsbDtcbiAgICAgICAgdmFyIG1hZGVCeSA9IHRoaXMudmVyc2lvbk1hZGVCeSA+PiA4O1xuXG4gICAgICAgIC8vIENoZWNrIGlmIHdlIGhhdmUgdGhlIERPUyBkaXJlY3RvcnkgZmxhZyBzZXQuXG4gICAgICAgIC8vIFdlIGxvb2sgZm9yIGl0IGluIHRoZSBET1MgYW5kIFVOSVggcGVybWlzc2lvbnNcbiAgICAgICAgLy8gYnV0IHNvbWUgdW5rbm93biBwbGF0Zm9ybSBjb3VsZCBzZXQgaXQgYXMgYSBjb21wYXRpYmlsaXR5IGZsYWcuXG4gICAgICAgIHRoaXMuZGlyID0gdGhpcy5leHRlcm5hbEZpbGVBdHRyaWJ1dGVzICYgMHgwMDEwID8gdHJ1ZSA6IGZhbHNlO1xuXG4gICAgICAgIGlmKG1hZGVCeSA9PT0gTUFERV9CWV9ET1MpIHtcbiAgICAgICAgICAgIC8vIGZpcnN0IDYgYml0cyAoMCB0byA1KVxuICAgICAgICAgICAgdGhpcy5kb3NQZXJtaXNzaW9ucyA9IHRoaXMuZXh0ZXJuYWxGaWxlQXR0cmlidXRlcyAmIDB4M0Y7XG4gICAgICAgIH1cblxuICAgICAgICBpZihtYWRlQnkgPT09IE1BREVfQllfVU5JWCkge1xuICAgICAgICAgICAgdGhpcy51bml4UGVybWlzc2lvbnMgPSAodGhpcy5leHRlcm5hbEZpbGVBdHRyaWJ1dGVzID4+IDE2KSAmIDB4RkZGRjtcbiAgICAgICAgICAgIC8vIHRoZSBvY3RhbCBwZXJtaXNzaW9ucyBhcmUgaW4gKHRoaXMudW5peFBlcm1pc3Npb25zICYgMHgwMUZGKS50b1N0cmluZyg4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGZhaWwgc2FmZSA6IGlmIHRoZSBuYW1lIGVuZHMgd2l0aCBhIC8gaXQgcHJvYmFibHkgbWVhbnMgYSBmb2xkZXJcbiAgICAgICAgaWYgKCF0aGlzLmRpciAmJiB0aGlzLmZpbGVOYW1lU3RyLnNsaWNlKC0xKSA9PT0gJy8nKSB7XG4gICAgICAgICAgICB0aGlzLmRpciA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUGFyc2UgdGhlIFpJUDY0IGV4dHJhIGZpZWxkIGFuZCBtZXJnZSB0aGUgaW5mbyBpbiB0aGUgY3VycmVudCBaaXBFbnRyeS5cbiAgICAgKiBAcGFyYW0ge0RhdGFSZWFkZXJ9IHJlYWRlciB0aGUgcmVhZGVyIHRvIHVzZS5cbiAgICAgKi9cbiAgICBwYXJzZVpJUDY0RXh0cmFGaWVsZDogZnVuY3Rpb24ocmVhZGVyKSB7XG5cbiAgICAgICAgaWYgKCF0aGlzLmV4dHJhRmllbGRzWzB4MDAwMV0pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHNob3VsZCBiZSBzb21ldGhpbmcsIHByZXBhcmluZyB0aGUgZXh0cmEgcmVhZGVyXG4gICAgICAgIHZhciBleHRyYVJlYWRlciA9IHJlYWRlckZvcih0aGlzLmV4dHJhRmllbGRzWzB4MDAwMV0udmFsdWUpO1xuXG4gICAgICAgIC8vIEkgcmVhbGx5IGhvcGUgdGhhdCB0aGVzZSA2NGJpdHMgaW50ZWdlciBjYW4gZml0IGluIDMyIGJpdHMgaW50ZWdlciwgYmVjYXVzZSBqc1xuICAgICAgICAvLyB3b24ndCBsZXQgdXMgaGF2ZSBtb3JlLlxuICAgICAgICBpZiAodGhpcy51bmNvbXByZXNzZWRTaXplID09PSB1dGlscy5NQVhfVkFMVUVfMzJCSVRTKSB7XG4gICAgICAgICAgICB0aGlzLnVuY29tcHJlc3NlZFNpemUgPSBleHRyYVJlYWRlci5yZWFkSW50KDgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmNvbXByZXNzZWRTaXplID09PSB1dGlscy5NQVhfVkFMVUVfMzJCSVRTKSB7XG4gICAgICAgICAgICB0aGlzLmNvbXByZXNzZWRTaXplID0gZXh0cmFSZWFkZXIucmVhZEludCg4KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5sb2NhbEhlYWRlck9mZnNldCA9PT0gdXRpbHMuTUFYX1ZBTFVFXzMyQklUUykge1xuICAgICAgICAgICAgdGhpcy5sb2NhbEhlYWRlck9mZnNldCA9IGV4dHJhUmVhZGVyLnJlYWRJbnQoOCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZGlza051bWJlclN0YXJ0ID09PSB1dGlscy5NQVhfVkFMVUVfMzJCSVRTKSB7XG4gICAgICAgICAgICB0aGlzLmRpc2tOdW1iZXJTdGFydCA9IGV4dHJhUmVhZGVyLnJlYWRJbnQoNCk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFJlYWQgdGhlIGNlbnRyYWwgcGFydCBvZiBhIHppcCBmaWxlIGFuZCBhZGQgdGhlIGluZm8gaW4gdGhpcyBvYmplY3QuXG4gICAgICogQHBhcmFtIHtEYXRhUmVhZGVyfSByZWFkZXIgdGhlIHJlYWRlciB0byB1c2UuXG4gICAgICovXG4gICAgcmVhZEV4dHJhRmllbGRzOiBmdW5jdGlvbihyZWFkZXIpIHtcbiAgICAgICAgdmFyIGVuZCA9IHJlYWRlci5pbmRleCArIHRoaXMuZXh0cmFGaWVsZHNMZW5ndGgsXG4gICAgICAgICAgICBleHRyYUZpZWxkSWQsXG4gICAgICAgICAgICBleHRyYUZpZWxkTGVuZ3RoLFxuICAgICAgICAgICAgZXh0cmFGaWVsZFZhbHVlO1xuXG4gICAgICAgIGlmICghdGhpcy5leHRyYUZpZWxkcykge1xuICAgICAgICAgICAgdGhpcy5leHRyYUZpZWxkcyA9IHt9O1xuICAgICAgICB9XG5cbiAgICAgICAgd2hpbGUgKHJlYWRlci5pbmRleCA8IGVuZCkge1xuICAgICAgICAgICAgZXh0cmFGaWVsZElkID0gcmVhZGVyLnJlYWRJbnQoMik7XG4gICAgICAgICAgICBleHRyYUZpZWxkTGVuZ3RoID0gcmVhZGVyLnJlYWRJbnQoMik7XG4gICAgICAgICAgICBleHRyYUZpZWxkVmFsdWUgPSByZWFkZXIucmVhZERhdGEoZXh0cmFGaWVsZExlbmd0aCk7XG5cbiAgICAgICAgICAgIHRoaXMuZXh0cmFGaWVsZHNbZXh0cmFGaWVsZElkXSA9IHtcbiAgICAgICAgICAgICAgICBpZDogZXh0cmFGaWVsZElkLFxuICAgICAgICAgICAgICAgIGxlbmd0aDogZXh0cmFGaWVsZExlbmd0aCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogZXh0cmFGaWVsZFZhbHVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiBBcHBseSBhbiBVVEY4IHRyYW5zZm9ybWF0aW9uIGlmIG5lZWRlZC5cbiAgICAgKi9cbiAgICBoYW5kbGVVVEY4OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGRlY29kZVBhcmFtVHlwZSA9IHN1cHBvcnQudWludDhhcnJheSA/IFwidWludDhhcnJheVwiIDogXCJhcnJheVwiO1xuICAgICAgICBpZiAodGhpcy51c2VVVEY4KCkpIHtcbiAgICAgICAgICAgIHRoaXMuZmlsZU5hbWVTdHIgPSB1dGY4LnV0ZjhkZWNvZGUodGhpcy5maWxlTmFtZSk7XG4gICAgICAgICAgICB0aGlzLmZpbGVDb21tZW50U3RyID0gdXRmOC51dGY4ZGVjb2RlKHRoaXMuZmlsZUNvbW1lbnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIHVwYXRoID0gdGhpcy5maW5kRXh0cmFGaWVsZFVuaWNvZGVQYXRoKCk7XG4gICAgICAgICAgICBpZiAodXBhdGggIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpbGVOYW1lU3RyID0gdXBhdGg7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEFTQ0lJIHRleHQgb3IgdW5zdXBwb3J0ZWQgY29kZSBwYWdlXG4gICAgICAgICAgICAgICAgdmFyIGZpbGVOYW1lQnl0ZUFycmF5ID0gIHV0aWxzLnRyYW5zZm9ybVRvKGRlY29kZVBhcmFtVHlwZSwgdGhpcy5maWxlTmFtZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5maWxlTmFtZVN0ciA9IHRoaXMubG9hZE9wdGlvbnMuZGVjb2RlRmlsZU5hbWUoZmlsZU5hbWVCeXRlQXJyYXkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgdWNvbW1lbnQgPSB0aGlzLmZpbmRFeHRyYUZpZWxkVW5pY29kZUNvbW1lbnQoKTtcbiAgICAgICAgICAgIGlmICh1Y29tbWVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZmlsZUNvbW1lbnRTdHIgPSB1Y29tbWVudDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gQVNDSUkgdGV4dCBvciB1bnN1cHBvcnRlZCBjb2RlIHBhZ2VcbiAgICAgICAgICAgICAgICB2YXIgY29tbWVudEJ5dGVBcnJheSA9ICB1dGlscy50cmFuc2Zvcm1UbyhkZWNvZGVQYXJhbVR5cGUsIHRoaXMuZmlsZUNvbW1lbnQpO1xuICAgICAgICAgICAgICAgIHRoaXMuZmlsZUNvbW1lbnRTdHIgPSB0aGlzLmxvYWRPcHRpb25zLmRlY29kZUZpbGVOYW1lKGNvbW1lbnRCeXRlQXJyYXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEZpbmQgdGhlIHVuaWNvZGUgcGF0aCBkZWNsYXJlZCBpbiB0aGUgZXh0cmEgZmllbGQsIGlmIGFueS5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9IHRoZSB1bmljb2RlIHBhdGgsIG51bGwgb3RoZXJ3aXNlLlxuICAgICAqL1xuICAgIGZpbmRFeHRyYUZpZWxkVW5pY29kZVBhdGg6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgdXBhdGhGaWVsZCA9IHRoaXMuZXh0cmFGaWVsZHNbMHg3MDc1XTtcbiAgICAgICAgaWYgKHVwYXRoRmllbGQpIHtcbiAgICAgICAgICAgIHZhciBleHRyYVJlYWRlciA9IHJlYWRlckZvcih1cGF0aEZpZWxkLnZhbHVlKTtcblxuICAgICAgICAgICAgLy8gd3JvbmcgdmVyc2lvblxuICAgICAgICAgICAgaWYgKGV4dHJhUmVhZGVyLnJlYWRJbnQoMSkgIT09IDEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gdGhlIGNyYyBvZiB0aGUgZmlsZW5hbWUgY2hhbmdlZCwgdGhpcyBmaWVsZCBpcyBvdXQgb2YgZGF0ZS5cbiAgICAgICAgICAgIGlmIChjcmMzMmZuKHRoaXMuZmlsZU5hbWUpICE9PSBleHRyYVJlYWRlci5yZWFkSW50KDQpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB1dGY4LnV0ZjhkZWNvZGUoZXh0cmFSZWFkZXIucmVhZERhdGEodXBhdGhGaWVsZC5sZW5ndGggLSA1KSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEZpbmQgdGhlIHVuaWNvZGUgY29tbWVudCBkZWNsYXJlZCBpbiB0aGUgZXh0cmEgZmllbGQsIGlmIGFueS5cbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9IHRoZSB1bmljb2RlIGNvbW1lbnQsIG51bGwgb3RoZXJ3aXNlLlxuICAgICAqL1xuICAgIGZpbmRFeHRyYUZpZWxkVW5pY29kZUNvbW1lbnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgdWNvbW1lbnRGaWVsZCA9IHRoaXMuZXh0cmFGaWVsZHNbMHg2Mzc1XTtcbiAgICAgICAgaWYgKHVjb21tZW50RmllbGQpIHtcbiAgICAgICAgICAgIHZhciBleHRyYVJlYWRlciA9IHJlYWRlckZvcih1Y29tbWVudEZpZWxkLnZhbHVlKTtcblxuICAgICAgICAgICAgLy8gd3JvbmcgdmVyc2lvblxuICAgICAgICAgICAgaWYgKGV4dHJhUmVhZGVyLnJlYWRJbnQoMSkgIT09IDEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gdGhlIGNyYyBvZiB0aGUgY29tbWVudCBjaGFuZ2VkLCB0aGlzIGZpZWxkIGlzIG91dCBvZiBkYXRlLlxuICAgICAgICAgICAgaWYgKGNyYzMyZm4odGhpcy5maWxlQ29tbWVudCkgIT09IGV4dHJhUmVhZGVyLnJlYWRJbnQoNCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHV0ZjgudXRmOGRlY29kZShleHRyYVJlYWRlci5yZWFkRGF0YSh1Y29tbWVudEZpZWxkLmxlbmd0aCAtIDUpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG59O1xubW9kdWxlLmV4cG9ydHMgPSBaaXBFbnRyeTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFN0cmVhbUhlbHBlciA9IHJlcXVpcmUoJy4vc3RyZWFtL1N0cmVhbUhlbHBlcicpO1xudmFyIERhdGFXb3JrZXIgPSByZXF1aXJlKCcuL3N0cmVhbS9EYXRhV29ya2VyJyk7XG52YXIgdXRmOCA9IHJlcXVpcmUoJy4vdXRmOCcpO1xudmFyIENvbXByZXNzZWRPYmplY3QgPSByZXF1aXJlKCcuL2NvbXByZXNzZWRPYmplY3QnKTtcbnZhciBHZW5lcmljV29ya2VyID0gcmVxdWlyZSgnLi9zdHJlYW0vR2VuZXJpY1dvcmtlcicpO1xuXG4vKipcbiAqIEEgc2ltcGxlIG9iamVjdCByZXByZXNlbnRpbmcgYSBmaWxlIGluIHRoZSB6aXAgZmlsZS5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgdGhlIG5hbWUgb2YgdGhlIGZpbGVcbiAqIEBwYXJhbSB7U3RyaW5nfEFycmF5QnVmZmVyfFVpbnQ4QXJyYXl8QnVmZmVyfSBkYXRhIHRoZSBkYXRhXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyB0aGUgb3B0aW9ucyBvZiB0aGUgZmlsZVxuICovXG52YXIgWmlwT2JqZWN0ID0gZnVuY3Rpb24obmFtZSwgZGF0YSwgb3B0aW9ucykge1xuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgdGhpcy5kaXIgPSBvcHRpb25zLmRpcjtcbiAgICB0aGlzLmRhdGUgPSBvcHRpb25zLmRhdGU7XG4gICAgdGhpcy5jb21tZW50ID0gb3B0aW9ucy5jb21tZW50O1xuICAgIHRoaXMudW5peFBlcm1pc3Npb25zID0gb3B0aW9ucy51bml4UGVybWlzc2lvbnM7XG4gICAgdGhpcy5kb3NQZXJtaXNzaW9ucyA9IG9wdGlvbnMuZG9zUGVybWlzc2lvbnM7XG5cbiAgICB0aGlzLl9kYXRhID0gZGF0YTtcbiAgICB0aGlzLl9kYXRhQmluYXJ5ID0gb3B0aW9ucy5iaW5hcnk7XG4gICAgLy8ga2VlcCBvbmx5IHRoZSBjb21wcmVzc2lvblxuICAgIHRoaXMub3B0aW9ucyA9IHtcbiAgICAgICAgY29tcHJlc3Npb24gOiBvcHRpb25zLmNvbXByZXNzaW9uLFxuICAgICAgICBjb21wcmVzc2lvbk9wdGlvbnMgOiBvcHRpb25zLmNvbXByZXNzaW9uT3B0aW9uc1xuICAgIH07XG59O1xuXG5aaXBPYmplY3QucHJvdG90eXBlID0ge1xuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhbiBpbnRlcm5hbCBzdHJlYW0gZm9yIHRoZSBjb250ZW50IG9mIHRoaXMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIHRoZSB0eXBlIG9mIGVhY2ggY2h1bmsuXG4gICAgICogQHJldHVybiBTdHJlYW1IZWxwZXIgdGhlIHN0cmVhbS5cbiAgICAgKi9cbiAgICBpbnRlcm5hbFN0cmVhbTogZnVuY3Rpb24gKHR5cGUpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IG51bGwsIG91dHB1dFR5cGUgPSBcInN0cmluZ1wiO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKCF0eXBlKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gb3V0cHV0IHR5cGUgc3BlY2lmaWVkLlwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG91dHB1dFR5cGUgPSB0eXBlLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICB2YXIgYXNrVW5pY29kZVN0cmluZyA9IG91dHB1dFR5cGUgPT09IFwic3RyaW5nXCIgfHwgb3V0cHV0VHlwZSA9PT0gXCJ0ZXh0XCI7XG4gICAgICAgICAgICBpZiAob3V0cHV0VHlwZSA9PT0gXCJiaW5hcnlzdHJpbmdcIiB8fCBvdXRwdXRUeXBlID09PSBcInRleHRcIikge1xuICAgICAgICAgICAgICAgIG91dHB1dFR5cGUgPSBcInN0cmluZ1wiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzdWx0ID0gdGhpcy5fZGVjb21wcmVzc1dvcmtlcigpO1xuXG4gICAgICAgICAgICB2YXIgaXNVbmljb2RlU3RyaW5nID0gIXRoaXMuX2RhdGFCaW5hcnk7XG5cbiAgICAgICAgICAgIGlmIChpc1VuaWNvZGVTdHJpbmcgJiYgIWFza1VuaWNvZGVTdHJpbmcpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQucGlwZShuZXcgdXRmOC5VdGY4RW5jb2RlV29ya2VyKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFpc1VuaWNvZGVTdHJpbmcgJiYgYXNrVW5pY29kZVN0cmluZykge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5waXBlKG5ldyB1dGY4LlV0ZjhEZWNvZGVXb3JrZXIoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBHZW5lcmljV29ya2VyKFwiZXJyb3JcIik7XG4gICAgICAgICAgICByZXN1bHQuZXJyb3IoZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IFN0cmVhbUhlbHBlcihyZXN1bHQsIG91dHB1dFR5cGUsIFwiXCIpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBQcmVwYXJlIHRoZSBjb250ZW50IGluIHRoZSBhc2tlZCB0eXBlLlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIHRoZSB0eXBlIG9mIHRoZSByZXN1bHQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gb25VcGRhdGUgYSBmdW5jdGlvbiB0byBjYWxsIG9uIGVhY2ggaW50ZXJuYWwgdXBkYXRlLlxuICAgICAqIEByZXR1cm4gUHJvbWlzZSB0aGUgcHJvbWlzZSBvZiB0aGUgcmVzdWx0LlxuICAgICAqL1xuICAgIGFzeW5jOiBmdW5jdGlvbiAodHlwZSwgb25VcGRhdGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW50ZXJuYWxTdHJlYW0odHlwZSkuYWNjdW11bGF0ZShvblVwZGF0ZSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFByZXBhcmUgdGhlIGNvbnRlbnQgYXMgYSBub2RlanMgc3RyZWFtLlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlIHRoZSB0eXBlIG9mIGVhY2ggY2h1bmsuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gb25VcGRhdGUgYSBmdW5jdGlvbiB0byBjYWxsIG9uIGVhY2ggaW50ZXJuYWwgdXBkYXRlLlxuICAgICAqIEByZXR1cm4gU3RyZWFtIHRoZSBzdHJlYW0uXG4gICAgICovXG4gICAgbm9kZVN0cmVhbTogZnVuY3Rpb24gKHR5cGUsIG9uVXBkYXRlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmludGVybmFsU3RyZWFtKHR5cGUgfHwgXCJub2RlYnVmZmVyXCIpLnRvTm9kZWpzU3RyZWFtKG9uVXBkYXRlKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmV0dXJuIGEgd29ya2VyIGZvciB0aGUgY29tcHJlc3NlZCBjb250ZW50LlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGNvbXByZXNzaW9uIHRoZSBjb21wcmVzc2lvbiBvYmplY3QgdG8gdXNlLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb21wcmVzc2lvbk9wdGlvbnMgdGhlIG9wdGlvbnMgdG8gdXNlIHdoZW4gY29tcHJlc3NpbmcuXG4gICAgICogQHJldHVybiBXb3JrZXIgdGhlIHdvcmtlci5cbiAgICAgKi9cbiAgICBfY29tcHJlc3NXb3JrZXI6IGZ1bmN0aW9uIChjb21wcmVzc2lvbiwgY29tcHJlc3Npb25PcHRpb25zKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMuX2RhdGEgaW5zdGFuY2VvZiBDb21wcmVzc2VkT2JqZWN0ICYmXG4gICAgICAgICAgICB0aGlzLl9kYXRhLmNvbXByZXNzaW9uLm1hZ2ljID09PSBjb21wcmVzc2lvbi5tYWdpY1xuICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kYXRhLmdldENvbXByZXNzZWRXb3JrZXIoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSB0aGlzLl9kZWNvbXByZXNzV29ya2VyKCk7XG4gICAgICAgICAgICBpZighdGhpcy5fZGF0YUJpbmFyeSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5waXBlKG5ldyB1dGY4LlV0ZjhFbmNvZGVXb3JrZXIoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gQ29tcHJlc3NlZE9iamVjdC5jcmVhdGVXb3JrZXJGcm9tKHJlc3VsdCwgY29tcHJlc3Npb24sIGNvbXByZXNzaW9uT3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIFJldHVybiBhIHdvcmtlciBmb3IgdGhlIGRlY29tcHJlc3NlZCBjb250ZW50LlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHJldHVybiBXb3JrZXIgdGhlIHdvcmtlci5cbiAgICAgKi9cbiAgICBfZGVjb21wcmVzc1dvcmtlciA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2RhdGEgaW5zdGFuY2VvZiBDb21wcmVzc2VkT2JqZWN0KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGF0YS5nZXRDb250ZW50V29ya2VyKCk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5fZGF0YSBpbnN0YW5jZW9mIEdlbmVyaWNXb3JrZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kYXRhO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBEYXRhV29ya2VyKHRoaXMuX2RhdGEpO1xuICAgICAgICB9XG4gICAgfVxufTtcblxudmFyIHJlbW92ZWRNZXRob2RzID0gW1wiYXNUZXh0XCIsIFwiYXNCaW5hcnlcIiwgXCJhc05vZGVCdWZmZXJcIiwgXCJhc1VpbnQ4QXJyYXlcIiwgXCJhc0FycmF5QnVmZmVyXCJdO1xudmFyIHJlbW92ZWRGbiA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIG1ldGhvZCBoYXMgYmVlbiByZW1vdmVkIGluIEpTWmlwIDMuMCwgcGxlYXNlIGNoZWNrIHRoZSB1cGdyYWRlIGd1aWRlLlwiKTtcbn07XG5cbmZvcih2YXIgaSA9IDA7IGkgPCByZW1vdmVkTWV0aG9kcy5sZW5ndGg7IGkrKykge1xuICAgIFppcE9iamVjdC5wcm90b3R5cGVbcmVtb3ZlZE1ldGhvZHNbaV1dID0gcmVtb3ZlZEZuO1xufVxubW9kdWxlLmV4cG9ydHMgPSBaaXBPYmplY3Q7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgaW1tZWRpYXRlID0gcmVxdWlyZSgnaW1tZWRpYXRlJyk7XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5mdW5jdGlvbiBJTlRFUk5BTCgpIHt9XG5cbnZhciBoYW5kbGVycyA9IHt9O1xuXG52YXIgUkVKRUNURUQgPSBbJ1JFSkVDVEVEJ107XG52YXIgRlVMRklMTEVEID0gWydGVUxGSUxMRUQnXTtcbnZhciBQRU5ESU5HID0gWydQRU5ESU5HJ107XG5cbm1vZHVsZS5leHBvcnRzID0gUHJvbWlzZTtcblxuZnVuY3Rpb24gUHJvbWlzZShyZXNvbHZlcikge1xuICBpZiAodHlwZW9mIHJlc29sdmVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcigncmVzb2x2ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIH1cbiAgdGhpcy5zdGF0ZSA9IFBFTkRJTkc7XG4gIHRoaXMucXVldWUgPSBbXTtcbiAgdGhpcy5vdXRjb21lID0gdm9pZCAwO1xuICBpZiAocmVzb2x2ZXIgIT09IElOVEVSTkFMKSB7XG4gICAgc2FmZWx5UmVzb2x2ZVRoZW5hYmxlKHRoaXMsIHJlc29sdmVyKTtcbiAgfVxufVxuXG5Qcm9taXNlLnByb3RvdHlwZVtcImNhdGNoXCJdID0gZnVuY3Rpb24gKG9uUmVqZWN0ZWQpIHtcbiAgcmV0dXJuIHRoaXMudGhlbihudWxsLCBvblJlamVjdGVkKTtcbn07XG5Qcm9taXNlLnByb3RvdHlwZS50aGVuID0gZnVuY3Rpb24gKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKSB7XG4gIGlmICh0eXBlb2Ygb25GdWxmaWxsZWQgIT09ICdmdW5jdGlvbicgJiYgdGhpcy5zdGF0ZSA9PT0gRlVMRklMTEVEIHx8XG4gICAgdHlwZW9mIG9uUmVqZWN0ZWQgIT09ICdmdW5jdGlvbicgJiYgdGhpcy5zdGF0ZSA9PT0gUkVKRUNURUQpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICB2YXIgcHJvbWlzZSA9IG5ldyB0aGlzLmNvbnN0cnVjdG9yKElOVEVSTkFMKTtcbiAgaWYgKHRoaXMuc3RhdGUgIT09IFBFTkRJTkcpIHtcbiAgICB2YXIgcmVzb2x2ZXIgPSB0aGlzLnN0YXRlID09PSBGVUxGSUxMRUQgPyBvbkZ1bGZpbGxlZCA6IG9uUmVqZWN0ZWQ7XG4gICAgdW53cmFwKHByb21pc2UsIHJlc29sdmVyLCB0aGlzLm91dGNvbWUpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMucXVldWUucHVzaChuZXcgUXVldWVJdGVtKHByb21pc2UsIG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKSk7XG4gIH1cblxuICByZXR1cm4gcHJvbWlzZTtcbn07XG5mdW5jdGlvbiBRdWV1ZUl0ZW0ocHJvbWlzZSwgb25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpIHtcbiAgdGhpcy5wcm9taXNlID0gcHJvbWlzZTtcbiAgaWYgKHR5cGVvZiBvbkZ1bGZpbGxlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRoaXMub25GdWxmaWxsZWQgPSBvbkZ1bGZpbGxlZDtcbiAgICB0aGlzLmNhbGxGdWxmaWxsZWQgPSB0aGlzLm90aGVyQ2FsbEZ1bGZpbGxlZDtcbiAgfVxuICBpZiAodHlwZW9mIG9uUmVqZWN0ZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICB0aGlzLm9uUmVqZWN0ZWQgPSBvblJlamVjdGVkO1xuICAgIHRoaXMuY2FsbFJlamVjdGVkID0gdGhpcy5vdGhlckNhbGxSZWplY3RlZDtcbiAgfVxufVxuUXVldWVJdGVtLnByb3RvdHlwZS5jYWxsRnVsZmlsbGVkID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gIGhhbmRsZXJzLnJlc29sdmUodGhpcy5wcm9taXNlLCB2YWx1ZSk7XG59O1xuUXVldWVJdGVtLnByb3RvdHlwZS5vdGhlckNhbGxGdWxmaWxsZWQgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgdW53cmFwKHRoaXMucHJvbWlzZSwgdGhpcy5vbkZ1bGZpbGxlZCwgdmFsdWUpO1xufTtcblF1ZXVlSXRlbS5wcm90b3R5cGUuY2FsbFJlamVjdGVkID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gIGhhbmRsZXJzLnJlamVjdCh0aGlzLnByb21pc2UsIHZhbHVlKTtcbn07XG5RdWV1ZUl0ZW0ucHJvdG90eXBlLm90aGVyQ2FsbFJlamVjdGVkID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gIHVud3JhcCh0aGlzLnByb21pc2UsIHRoaXMub25SZWplY3RlZCwgdmFsdWUpO1xufTtcblxuZnVuY3Rpb24gdW53cmFwKHByb21pc2UsIGZ1bmMsIHZhbHVlKSB7XG4gIGltbWVkaWF0ZShmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHJldHVyblZhbHVlO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm5WYWx1ZSA9IGZ1bmModmFsdWUpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBoYW5kbGVycy5yZWplY3QocHJvbWlzZSwgZSk7XG4gICAgfVxuICAgIGlmIChyZXR1cm5WYWx1ZSA9PT0gcHJvbWlzZSkge1xuICAgICAgaGFuZGxlcnMucmVqZWN0KHByb21pc2UsIG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCByZXNvbHZlIHByb21pc2Ugd2l0aCBpdHNlbGYnKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGhhbmRsZXJzLnJlc29sdmUocHJvbWlzZSwgcmV0dXJuVmFsdWUpO1xuICAgIH1cbiAgfSk7XG59XG5cbmhhbmRsZXJzLnJlc29sdmUgPSBmdW5jdGlvbiAoc2VsZiwgdmFsdWUpIHtcbiAgdmFyIHJlc3VsdCA9IHRyeUNhdGNoKGdldFRoZW4sIHZhbHVlKTtcbiAgaWYgKHJlc3VsdC5zdGF0dXMgPT09ICdlcnJvcicpIHtcbiAgICByZXR1cm4gaGFuZGxlcnMucmVqZWN0KHNlbGYsIHJlc3VsdC52YWx1ZSk7XG4gIH1cbiAgdmFyIHRoZW5hYmxlID0gcmVzdWx0LnZhbHVlO1xuXG4gIGlmICh0aGVuYWJsZSkge1xuICAgIHNhZmVseVJlc29sdmVUaGVuYWJsZShzZWxmLCB0aGVuYWJsZSk7XG4gIH0gZWxzZSB7XG4gICAgc2VsZi5zdGF0ZSA9IEZVTEZJTExFRDtcbiAgICBzZWxmLm91dGNvbWUgPSB2YWx1ZTtcbiAgICB2YXIgaSA9IC0xO1xuICAgIHZhciBsZW4gPSBzZWxmLnF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgICBzZWxmLnF1ZXVlW2ldLmNhbGxGdWxmaWxsZWQodmFsdWUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gc2VsZjtcbn07XG5oYW5kbGVycy5yZWplY3QgPSBmdW5jdGlvbiAoc2VsZiwgZXJyb3IpIHtcbiAgc2VsZi5zdGF0ZSA9IFJFSkVDVEVEO1xuICBzZWxmLm91dGNvbWUgPSBlcnJvcjtcbiAgdmFyIGkgPSAtMTtcbiAgdmFyIGxlbiA9IHNlbGYucXVldWUubGVuZ3RoO1xuICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgc2VsZi5xdWV1ZVtpXS5jYWxsUmVqZWN0ZWQoZXJyb3IpO1xuICB9XG4gIHJldHVybiBzZWxmO1xufTtcblxuZnVuY3Rpb24gZ2V0VGhlbihvYmopIHtcbiAgLy8gTWFrZSBzdXJlIHdlIG9ubHkgYWNjZXNzIHRoZSBhY2Nlc3NvciBvbmNlIGFzIHJlcXVpcmVkIGJ5IHRoZSBzcGVjXG4gIHZhciB0aGVuID0gb2JqICYmIG9iai50aGVuO1xuICBpZiAob2JqICYmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyB8fCB0eXBlb2Ygb2JqID09PSAnZnVuY3Rpb24nKSAmJiB0eXBlb2YgdGhlbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBmdW5jdGlvbiBhcHB5VGhlbigpIHtcbiAgICAgIHRoZW4uYXBwbHkob2JqLCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH1cbn1cblxuZnVuY3Rpb24gc2FmZWx5UmVzb2x2ZVRoZW5hYmxlKHNlbGYsIHRoZW5hYmxlKSB7XG4gIC8vIEVpdGhlciBmdWxmaWxsLCByZWplY3Qgb3IgcmVqZWN0IHdpdGggZXJyb3JcbiAgdmFyIGNhbGxlZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBvbkVycm9yKHZhbHVlKSB7XG4gICAgaWYgKGNhbGxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjYWxsZWQgPSB0cnVlO1xuICAgIGhhbmRsZXJzLnJlamVjdChzZWxmLCB2YWx1ZSk7XG4gIH1cblxuICBmdW5jdGlvbiBvblN1Y2Nlc3ModmFsdWUpIHtcbiAgICBpZiAoY2FsbGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNhbGxlZCA9IHRydWU7XG4gICAgaGFuZGxlcnMucmVzb2x2ZShzZWxmLCB2YWx1ZSk7XG4gIH1cblxuICBmdW5jdGlvbiB0cnlUb1Vud3JhcCgpIHtcbiAgICB0aGVuYWJsZShvblN1Y2Nlc3MsIG9uRXJyb3IpO1xuICB9XG5cbiAgdmFyIHJlc3VsdCA9IHRyeUNhdGNoKHRyeVRvVW53cmFwKTtcbiAgaWYgKHJlc3VsdC5zdGF0dXMgPT09ICdlcnJvcicpIHtcbiAgICBvbkVycm9yKHJlc3VsdC52YWx1ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gdHJ5Q2F0Y2goZnVuYywgdmFsdWUpIHtcbiAgdmFyIG91dCA9IHt9O1xuICB0cnkge1xuICAgIG91dC52YWx1ZSA9IGZ1bmModmFsdWUpO1xuICAgIG91dC5zdGF0dXMgPSAnc3VjY2Vzcyc7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBvdXQuc3RhdHVzID0gJ2Vycm9yJztcbiAgICBvdXQudmFsdWUgPSBlO1xuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cblByb21pc2UucmVzb2x2ZSA9IHJlc29sdmU7XG5mdW5jdGlvbiByZXNvbHZlKHZhbHVlKSB7XG4gIGlmICh2YWx1ZSBpbnN0YW5jZW9mIHRoaXMpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgcmV0dXJuIGhhbmRsZXJzLnJlc29sdmUobmV3IHRoaXMoSU5URVJOQUwpLCB2YWx1ZSk7XG59XG5cblByb21pc2UucmVqZWN0ID0gcmVqZWN0O1xuZnVuY3Rpb24gcmVqZWN0KHJlYXNvbikge1xuICB2YXIgcHJvbWlzZSA9IG5ldyB0aGlzKElOVEVSTkFMKTtcbiAgcmV0dXJuIGhhbmRsZXJzLnJlamVjdChwcm9taXNlLCByZWFzb24pO1xufVxuXG5Qcm9taXNlLmFsbCA9IGFsbDtcbmZ1bmN0aW9uIGFsbChpdGVyYWJsZSkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoaXRlcmFibGUpICE9PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgcmV0dXJuIHRoaXMucmVqZWN0KG5ldyBUeXBlRXJyb3IoJ211c3QgYmUgYW4gYXJyYXknKSk7XG4gIH1cblxuICB2YXIgbGVuID0gaXRlcmFibGUubGVuZ3RoO1xuICB2YXIgY2FsbGVkID0gZmFsc2U7XG4gIGlmICghbGVuKSB7XG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZShbXSk7XG4gIH1cblxuICB2YXIgdmFsdWVzID0gbmV3IEFycmF5KGxlbik7XG4gIHZhciByZXNvbHZlZCA9IDA7XG4gIHZhciBpID0gLTE7XG4gIHZhciBwcm9taXNlID0gbmV3IHRoaXMoSU5URVJOQUwpO1xuXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBhbGxSZXNvbHZlcihpdGVyYWJsZVtpXSwgaSk7XG4gIH1cbiAgcmV0dXJuIHByb21pc2U7XG4gIGZ1bmN0aW9uIGFsbFJlc29sdmVyKHZhbHVlLCBpKSB7XG4gICAgc2VsZi5yZXNvbHZlKHZhbHVlKS50aGVuKHJlc29sdmVGcm9tQWxsLCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIGlmICghY2FsbGVkKSB7XG4gICAgICAgIGNhbGxlZCA9IHRydWU7XG4gICAgICAgIGhhbmRsZXJzLnJlamVjdChwcm9taXNlLCBlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG4gICAgZnVuY3Rpb24gcmVzb2x2ZUZyb21BbGwob3V0VmFsdWUpIHtcbiAgICAgIHZhbHVlc1tpXSA9IG91dFZhbHVlO1xuICAgICAgaWYgKCsrcmVzb2x2ZWQgPT09IGxlbiAmJiAhY2FsbGVkKSB7XG4gICAgICAgIGNhbGxlZCA9IHRydWU7XG4gICAgICAgIGhhbmRsZXJzLnJlc29sdmUocHJvbWlzZSwgdmFsdWVzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuUHJvbWlzZS5yYWNlID0gcmFjZTtcbmZ1bmN0aW9uIHJhY2UoaXRlcmFibGUpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGl0ZXJhYmxlKSAhPT0gJ1tvYmplY3QgQXJyYXldJykge1xuICAgIHJldHVybiB0aGlzLnJlamVjdChuZXcgVHlwZUVycm9yKCdtdXN0IGJlIGFuIGFycmF5JykpO1xuICB9XG5cbiAgdmFyIGxlbiA9IGl0ZXJhYmxlLmxlbmd0aDtcbiAgdmFyIGNhbGxlZCA9IGZhbHNlO1xuICBpZiAoIWxlbikge1xuICAgIHJldHVybiB0aGlzLnJlc29sdmUoW10pO1xuICB9XG5cbiAgdmFyIGkgPSAtMTtcbiAgdmFyIHByb21pc2UgPSBuZXcgdGhpcyhJTlRFUk5BTCk7XG5cbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIHJlc29sdmVyKGl0ZXJhYmxlW2ldKTtcbiAgfVxuICByZXR1cm4gcHJvbWlzZTtcbiAgZnVuY3Rpb24gcmVzb2x2ZXIodmFsdWUpIHtcbiAgICBzZWxmLnJlc29sdmUodmFsdWUpLnRoZW4oZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICBpZiAoIWNhbGxlZCkge1xuICAgICAgICBjYWxsZWQgPSB0cnVlO1xuICAgICAgICBoYW5kbGVycy5yZXNvbHZlKHByb21pc2UsIHJlc3BvbnNlKTtcbiAgICAgIH1cbiAgICB9LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIGlmICghY2FsbGVkKSB7XG4gICAgICAgIGNhbGxlZCA9IHRydWU7XG4gICAgICAgIGhhbmRsZXJzLnJlamVjdChwcm9taXNlLCBlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cbiIsIi8qKlxuICogQGxpY2Vuc2VcbiAqIExvZGFzaCA8aHR0cHM6Ly9sb2Rhc2guY29tLz5cbiAqIENvcHlyaWdodCBKUyBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnMgPGh0dHBzOi8vanMuZm91bmRhdGlvbi8+XG4gKiBSZWxlYXNlZCB1bmRlciBNSVQgbGljZW5zZSA8aHR0cHM6Ly9sb2Rhc2guY29tL2xpY2Vuc2U+XG4gKiBCYXNlZCBvbiBVbmRlcnNjb3JlLmpzIDEuOC4zIDxodHRwOi8vdW5kZXJzY29yZWpzLm9yZy9MSUNFTlNFPlxuICogQ29weXJpZ2h0IEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzXG4gKi9cbjsoZnVuY3Rpb24oKSB7XG5cbiAgLyoqIFVzZWQgYXMgYSBzYWZlIHJlZmVyZW5jZSBmb3IgYHVuZGVmaW5lZGAgaW4gcHJlLUVTNSBlbnZpcm9ubWVudHMuICovXG4gIHZhciB1bmRlZmluZWQ7XG5cbiAgLyoqIFVzZWQgYXMgdGhlIHNlbWFudGljIHZlcnNpb24gbnVtYmVyLiAqL1xuICB2YXIgVkVSU0lPTiA9ICc0LjE3LjExJztcblxuICAvKiogVXNlZCBhcyB0aGUgc2l6ZSB0byBlbmFibGUgbGFyZ2UgYXJyYXkgb3B0aW1pemF0aW9ucy4gKi9cbiAgdmFyIExBUkdFX0FSUkFZX1NJWkUgPSAyMDA7XG5cbiAgLyoqIEVycm9yIG1lc3NhZ2UgY29uc3RhbnRzLiAqL1xuICB2YXIgQ09SRV9FUlJPUl9URVhUID0gJ1Vuc3VwcG9ydGVkIGNvcmUtanMgdXNlLiBUcnkgaHR0cHM6Ly9ucG1zLmlvL3NlYXJjaD9xPXBvbnlmaWxsLicsXG4gICAgICBGVU5DX0VSUk9SX1RFWFQgPSAnRXhwZWN0ZWQgYSBmdW5jdGlvbic7XG5cbiAgLyoqIFVzZWQgdG8gc3RhbmQtaW4gZm9yIGB1bmRlZmluZWRgIGhhc2ggdmFsdWVzLiAqL1xuICB2YXIgSEFTSF9VTkRFRklORUQgPSAnX19sb2Rhc2hfaGFzaF91bmRlZmluZWRfXyc7XG5cbiAgLyoqIFVzZWQgYXMgdGhlIG1heGltdW0gbWVtb2l6ZSBjYWNoZSBzaXplLiAqL1xuICB2YXIgTUFYX01FTU9JWkVfU0laRSA9IDUwMDtcblxuICAvKiogVXNlZCBhcyB0aGUgaW50ZXJuYWwgYXJndW1lbnQgcGxhY2Vob2xkZXIuICovXG4gIHZhciBQTEFDRUhPTERFUiA9ICdfX2xvZGFzaF9wbGFjZWhvbGRlcl9fJztcblxuICAvKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciBjbG9uaW5nLiAqL1xuICB2YXIgQ0xPTkVfREVFUF9GTEFHID0gMSxcbiAgICAgIENMT05FX0ZMQVRfRkxBRyA9IDIsXG4gICAgICBDTE9ORV9TWU1CT0xTX0ZMQUcgPSA0O1xuXG4gIC8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHZhbHVlIGNvbXBhcmlzb25zLiAqL1xuICB2YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgPSAxLFxuICAgICAgQ09NUEFSRV9VTk9SREVSRURfRkxBRyA9IDI7XG5cbiAgLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgZnVuY3Rpb24gbWV0YWRhdGEuICovXG4gIHZhciBXUkFQX0JJTkRfRkxBRyA9IDEsXG4gICAgICBXUkFQX0JJTkRfS0VZX0ZMQUcgPSAyLFxuICAgICAgV1JBUF9DVVJSWV9CT1VORF9GTEFHID0gNCxcbiAgICAgIFdSQVBfQ1VSUllfRkxBRyA9IDgsXG4gICAgICBXUkFQX0NVUlJZX1JJR0hUX0ZMQUcgPSAxNixcbiAgICAgIFdSQVBfUEFSVElBTF9GTEFHID0gMzIsXG4gICAgICBXUkFQX1BBUlRJQUxfUklHSFRfRkxBRyA9IDY0LFxuICAgICAgV1JBUF9BUllfRkxBRyA9IDEyOCxcbiAgICAgIFdSQVBfUkVBUkdfRkxBRyA9IDI1NixcbiAgICAgIFdSQVBfRkxJUF9GTEFHID0gNTEyO1xuXG4gIC8qKiBVc2VkIGFzIGRlZmF1bHQgb3B0aW9ucyBmb3IgYF8udHJ1bmNhdGVgLiAqL1xuICB2YXIgREVGQVVMVF9UUlVOQ19MRU5HVEggPSAzMCxcbiAgICAgIERFRkFVTFRfVFJVTkNfT01JU1NJT04gPSAnLi4uJztcblxuICAvKiogVXNlZCB0byBkZXRlY3QgaG90IGZ1bmN0aW9ucyBieSBudW1iZXIgb2YgY2FsbHMgd2l0aGluIGEgc3BhbiBvZiBtaWxsaXNlY29uZHMuICovXG4gIHZhciBIT1RfQ09VTlQgPSA4MDAsXG4gICAgICBIT1RfU1BBTiA9IDE2O1xuXG4gIC8qKiBVc2VkIHRvIGluZGljYXRlIHRoZSB0eXBlIG9mIGxhenkgaXRlcmF0ZWVzLiAqL1xuICB2YXIgTEFaWV9GSUxURVJfRkxBRyA9IDEsXG4gICAgICBMQVpZX01BUF9GTEFHID0gMixcbiAgICAgIExBWllfV0hJTEVfRkxBRyA9IDM7XG5cbiAgLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovXG4gIHZhciBJTkZJTklUWSA9IDEgLyAwLFxuICAgICAgTUFYX1NBRkVfSU5URUdFUiA9IDkwMDcxOTkyNTQ3NDA5OTEsXG4gICAgICBNQVhfSU5URUdFUiA9IDEuNzk3NjkzMTM0ODYyMzE1N2UrMzA4LFxuICAgICAgTkFOID0gMCAvIDA7XG5cbiAgLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdGhlIG1heGltdW0gbGVuZ3RoIGFuZCBpbmRleCBvZiBhbiBhcnJheS4gKi9cbiAgdmFyIE1BWF9BUlJBWV9MRU5HVEggPSA0Mjk0OTY3Mjk1LFxuICAgICAgTUFYX0FSUkFZX0lOREVYID0gTUFYX0FSUkFZX0xFTkdUSCAtIDEsXG4gICAgICBIQUxGX01BWF9BUlJBWV9MRU5HVEggPSBNQVhfQVJSQVlfTEVOR1RIID4+PiAxO1xuXG4gIC8qKiBVc2VkIHRvIGFzc29jaWF0ZSB3cmFwIG1ldGhvZHMgd2l0aCB0aGVpciBiaXQgZmxhZ3MuICovXG4gIHZhciB3cmFwRmxhZ3MgPSBbXG4gICAgWydhcnknLCBXUkFQX0FSWV9GTEFHXSxcbiAgICBbJ2JpbmQnLCBXUkFQX0JJTkRfRkxBR10sXG4gICAgWydiaW5kS2V5JywgV1JBUF9CSU5EX0tFWV9GTEFHXSxcbiAgICBbJ2N1cnJ5JywgV1JBUF9DVVJSWV9GTEFHXSxcbiAgICBbJ2N1cnJ5UmlnaHQnLCBXUkFQX0NVUlJZX1JJR0hUX0ZMQUddLFxuICAgIFsnZmxpcCcsIFdSQVBfRkxJUF9GTEFHXSxcbiAgICBbJ3BhcnRpYWwnLCBXUkFQX1BBUlRJQUxfRkxBR10sXG4gICAgWydwYXJ0aWFsUmlnaHQnLCBXUkFQX1BBUlRJQUxfUklHSFRfRkxBR10sXG4gICAgWydyZWFyZycsIFdSQVBfUkVBUkdfRkxBR11cbiAgXTtcblxuICAvKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG4gIHZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsXG4gICAgICBhcnJheVRhZyA9ICdbb2JqZWN0IEFycmF5XScsXG4gICAgICBhc3luY1RhZyA9ICdbb2JqZWN0IEFzeW5jRnVuY3Rpb25dJyxcbiAgICAgIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgICBkYXRlVGFnID0gJ1tvYmplY3QgRGF0ZV0nLFxuICAgICAgZG9tRXhjVGFnID0gJ1tvYmplY3QgRE9NRXhjZXB0aW9uXScsXG4gICAgICBlcnJvclRhZyA9ICdbb2JqZWN0IEVycm9yXScsXG4gICAgICBmdW5jVGFnID0gJ1tvYmplY3QgRnVuY3Rpb25dJyxcbiAgICAgIGdlblRhZyA9ICdbb2JqZWN0IEdlbmVyYXRvckZ1bmN0aW9uXScsXG4gICAgICBtYXBUYWcgPSAnW29iamVjdCBNYXBdJyxcbiAgICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgICAgbnVsbFRhZyA9ICdbb2JqZWN0IE51bGxdJyxcbiAgICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgICAgcHJvbWlzZVRhZyA9ICdbb2JqZWN0IFByb21pc2VdJyxcbiAgICAgIHByb3h5VGFnID0gJ1tvYmplY3QgUHJveHldJyxcbiAgICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgICAgc2V0VGFnID0gJ1tvYmplY3QgU2V0XScsXG4gICAgICBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJyxcbiAgICAgIHN5bWJvbFRhZyA9ICdbb2JqZWN0IFN5bWJvbF0nLFxuICAgICAgdW5kZWZpbmVkVGFnID0gJ1tvYmplY3QgVW5kZWZpbmVkXScsXG4gICAgICB3ZWFrTWFwVGFnID0gJ1tvYmplY3QgV2Vha01hcF0nLFxuICAgICAgd2Vha1NldFRhZyA9ICdbb2JqZWN0IFdlYWtTZXRdJztcblxuICB2YXIgYXJyYXlCdWZmZXJUYWcgPSAnW29iamVjdCBBcnJheUJ1ZmZlcl0nLFxuICAgICAgZGF0YVZpZXdUYWcgPSAnW29iamVjdCBEYXRhVmlld10nLFxuICAgICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgICAgZmxvYXQ2NFRhZyA9ICdbb2JqZWN0IEZsb2F0NjRBcnJheV0nLFxuICAgICAgaW50OFRhZyA9ICdbb2JqZWN0IEludDhBcnJheV0nLFxuICAgICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgICBpbnQzMlRhZyA9ICdbb2JqZWN0IEludDMyQXJyYXldJyxcbiAgICAgIHVpbnQ4VGFnID0gJ1tvYmplY3QgVWludDhBcnJheV0nLFxuICAgICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICAgIHVpbnQxNlRhZyA9ICdbb2JqZWN0IFVpbnQxNkFycmF5XScsXG4gICAgICB1aW50MzJUYWcgPSAnW29iamVjdCBVaW50MzJBcnJheV0nO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIGVtcHR5IHN0cmluZyBsaXRlcmFscyBpbiBjb21waWxlZCB0ZW1wbGF0ZSBzb3VyY2UuICovXG4gIHZhciByZUVtcHR5U3RyaW5nTGVhZGluZyA9IC9cXGJfX3AgXFwrPSAnJzsvZyxcbiAgICAgIHJlRW1wdHlTdHJpbmdNaWRkbGUgPSAvXFxiKF9fcCBcXCs9KSAnJyBcXCsvZyxcbiAgICAgIHJlRW1wdHlTdHJpbmdUcmFpbGluZyA9IC8oX19lXFwoLio/XFwpfFxcYl9fdFxcKSkgXFwrXFxuJyc7L2c7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggSFRNTCBlbnRpdGllcyBhbmQgSFRNTCBjaGFyYWN0ZXJzLiAqL1xuICB2YXIgcmVFc2NhcGVkSHRtbCA9IC8mKD86YW1wfGx0fGd0fHF1b3R8IzM5KTsvZyxcbiAgICAgIHJlVW5lc2NhcGVkSHRtbCA9IC9bJjw+XCInXS9nLFxuICAgICAgcmVIYXNFc2NhcGVkSHRtbCA9IFJlZ0V4cChyZUVzY2FwZWRIdG1sLnNvdXJjZSksXG4gICAgICByZUhhc1VuZXNjYXBlZEh0bWwgPSBSZWdFeHAocmVVbmVzY2FwZWRIdG1sLnNvdXJjZSk7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggdGVtcGxhdGUgZGVsaW1pdGVycy4gKi9cbiAgdmFyIHJlRXNjYXBlID0gLzwlLShbXFxzXFxTXSs/KSU+L2csXG4gICAgICByZUV2YWx1YXRlID0gLzwlKFtcXHNcXFNdKz8pJT4vZyxcbiAgICAgIHJlSW50ZXJwb2xhdGUgPSAvPCU9KFtcXHNcXFNdKz8pJT4vZztcblxuICAvKiogVXNlZCB0byBtYXRjaCBwcm9wZXJ0eSBuYW1lcyB3aXRoaW4gcHJvcGVydHkgcGF0aHMuICovXG4gIHZhciByZUlzRGVlcFByb3AgPSAvXFwufFxcWyg/OlteW1xcXV0qfChbXCInXSkoPzooPyFcXDEpW15cXFxcXXxcXFxcLikqP1xcMSlcXF0vLFxuICAgICAgcmVJc1BsYWluUHJvcCA9IC9eXFx3KiQvLFxuICAgICAgcmVQcm9wTmFtZSA9IC9bXi5bXFxdXSt8XFxbKD86KC0/XFxkKyg/OlxcLlxcZCspPyl8KFtcIiddKSgoPzooPyFcXDIpW15cXFxcXXxcXFxcLikqPylcXDIpXFxdfCg/PSg/OlxcLnxcXFtcXF0pKD86XFwufFxcW1xcXXwkKSkvZztcblxuICAvKipcbiAgICogVXNlZCB0byBtYXRjaCBgUmVnRXhwYFxuICAgKiBbc3ludGF4IGNoYXJhY3RlcnNdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXBhdHRlcm5zKS5cbiAgICovXG4gIHZhciByZVJlZ0V4cENoYXIgPSAvW1xcXFxeJC4qKz8oKVtcXF17fXxdL2csXG4gICAgICByZUhhc1JlZ0V4cENoYXIgPSBSZWdFeHAocmVSZWdFeHBDaGFyLnNvdXJjZSk7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZS4gKi9cbiAgdmFyIHJlVHJpbSA9IC9eXFxzK3xcXHMrJC9nLFxuICAgICAgcmVUcmltU3RhcnQgPSAvXlxccysvLFxuICAgICAgcmVUcmltRW5kID0gL1xccyskLztcblxuICAvKiogVXNlZCB0byBtYXRjaCB3cmFwIGRldGFpbCBjb21tZW50cy4gKi9cbiAgdmFyIHJlV3JhcENvbW1lbnQgPSAvXFx7KD86XFxuXFwvXFwqIFxcW3dyYXBwZWQgd2l0aCAuK1xcXSBcXCpcXC8pP1xcbj8vLFxuICAgICAgcmVXcmFwRGV0YWlscyA9IC9cXHtcXG5cXC9cXCogXFxbd3JhcHBlZCB3aXRoICguKylcXF0gXFwqLyxcbiAgICAgIHJlU3BsaXREZXRhaWxzID0gLyw/ICYgLztcblxuICAvKiogVXNlZCB0byBtYXRjaCB3b3JkcyBjb21wb3NlZCBvZiBhbHBoYW51bWVyaWMgY2hhcmFjdGVycy4gKi9cbiAgdmFyIHJlQXNjaWlXb3JkID0gL1teXFx4MDAtXFx4MmZcXHgzYS1cXHg0MFxceDViLVxceDYwXFx4N2ItXFx4N2ZdKy9nO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIGJhY2tzbGFzaGVzIGluIHByb3BlcnR5IHBhdGhzLiAqL1xuICB2YXIgcmVFc2NhcGVDaGFyID0gL1xcXFwoXFxcXCk/L2c7XG5cbiAgLyoqXG4gICAqIFVzZWQgdG8gbWF0Y2hcbiAgICogW0VTIHRlbXBsYXRlIGRlbGltaXRlcnNdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXRlbXBsYXRlLWxpdGVyYWwtbGV4aWNhbC1jb21wb25lbnRzKS5cbiAgICovXG4gIHZhciByZUVzVGVtcGxhdGUgPSAvXFwkXFx7KFteXFxcXH1dKig/OlxcXFwuW15cXFxcfV0qKSopXFx9L2c7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggYFJlZ0V4cGAgZmxhZ3MgZnJvbSB0aGVpciBjb2VyY2VkIHN0cmluZyB2YWx1ZXMuICovXG4gIHZhciByZUZsYWdzID0gL1xcdyokLztcblxuICAvKiogVXNlZCB0byBkZXRlY3QgYmFkIHNpZ25lZCBoZXhhZGVjaW1hbCBzdHJpbmcgdmFsdWVzLiAqL1xuICB2YXIgcmVJc0JhZEhleCA9IC9eWy0rXTB4WzAtOWEtZl0rJC9pO1xuXG4gIC8qKiBVc2VkIHRvIGRldGVjdCBiaW5hcnkgc3RyaW5nIHZhbHVlcy4gKi9cbiAgdmFyIHJlSXNCaW5hcnkgPSAvXjBiWzAxXSskL2k7XG5cbiAgLyoqIFVzZWQgdG8gZGV0ZWN0IGhvc3QgY29uc3RydWN0b3JzIChTYWZhcmkpLiAqL1xuICB2YXIgcmVJc0hvc3RDdG9yID0gL15cXFtvYmplY3QgLis/Q29uc3RydWN0b3JcXF0kLztcblxuICAvKiogVXNlZCB0byBkZXRlY3Qgb2N0YWwgc3RyaW5nIHZhbHVlcy4gKi9cbiAgdmFyIHJlSXNPY3RhbCA9IC9eMG9bMC03XSskL2k7XG5cbiAgLyoqIFVzZWQgdG8gZGV0ZWN0IHVuc2lnbmVkIGludGVnZXIgdmFsdWVzLiAqL1xuICB2YXIgcmVJc1VpbnQgPSAvXig/OjB8WzEtOV1cXGQqKSQvO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIExhdGluIFVuaWNvZGUgbGV0dGVycyAoZXhjbHVkaW5nIG1hdGhlbWF0aWNhbCBvcGVyYXRvcnMpLiAqL1xuICB2YXIgcmVMYXRpbiA9IC9bXFx4YzAtXFx4ZDZcXHhkOC1cXHhmNlxceGY4LVxceGZmXFx1MDEwMC1cXHUwMTdmXS9nO1xuXG4gIC8qKiBVc2VkIHRvIGVuc3VyZSBjYXB0dXJpbmcgb3JkZXIgb2YgdGVtcGxhdGUgZGVsaW1pdGVycy4gKi9cbiAgdmFyIHJlTm9NYXRjaCA9IC8oJF4pLztcblxuICAvKiogVXNlZCB0byBtYXRjaCB1bmVzY2FwZWQgY2hhcmFjdGVycyBpbiBjb21waWxlZCBzdHJpbmcgbGl0ZXJhbHMuICovXG4gIHZhciByZVVuZXNjYXBlZFN0cmluZyA9IC9bJ1xcblxcclxcdTIwMjhcXHUyMDI5XFxcXF0vZztcblxuICAvKiogVXNlZCB0byBjb21wb3NlIHVuaWNvZGUgY2hhcmFjdGVyIGNsYXNzZXMuICovXG4gIHZhciByc0FzdHJhbFJhbmdlID0gJ1xcXFx1ZDgwMC1cXFxcdWRmZmYnLFxuICAgICAgcnNDb21ib01hcmtzUmFuZ2UgPSAnXFxcXHUwMzAwLVxcXFx1MDM2ZicsXG4gICAgICByZUNvbWJvSGFsZk1hcmtzUmFuZ2UgPSAnXFxcXHVmZTIwLVxcXFx1ZmUyZicsXG4gICAgICByc0NvbWJvU3ltYm9sc1JhbmdlID0gJ1xcXFx1MjBkMC1cXFxcdTIwZmYnLFxuICAgICAgcnNDb21ib1JhbmdlID0gcnNDb21ib01hcmtzUmFuZ2UgKyByZUNvbWJvSGFsZk1hcmtzUmFuZ2UgKyByc0NvbWJvU3ltYm9sc1JhbmdlLFxuICAgICAgcnNEaW5nYmF0UmFuZ2UgPSAnXFxcXHUyNzAwLVxcXFx1MjdiZicsXG4gICAgICByc0xvd2VyUmFuZ2UgPSAnYS16XFxcXHhkZi1cXFxceGY2XFxcXHhmOC1cXFxceGZmJyxcbiAgICAgIHJzTWF0aE9wUmFuZ2UgPSAnXFxcXHhhY1xcXFx4YjFcXFxceGQ3XFxcXHhmNycsXG4gICAgICByc05vbkNoYXJSYW5nZSA9ICdcXFxceDAwLVxcXFx4MmZcXFxceDNhLVxcXFx4NDBcXFxceDViLVxcXFx4NjBcXFxceDdiLVxcXFx4YmYnLFxuICAgICAgcnNQdW5jdHVhdGlvblJhbmdlID0gJ1xcXFx1MjAwMC1cXFxcdTIwNmYnLFxuICAgICAgcnNTcGFjZVJhbmdlID0gJyBcXFxcdFxcXFx4MGJcXFxcZlxcXFx4YTBcXFxcdWZlZmZcXFxcblxcXFxyXFxcXHUyMDI4XFxcXHUyMDI5XFxcXHUxNjgwXFxcXHUxODBlXFxcXHUyMDAwXFxcXHUyMDAxXFxcXHUyMDAyXFxcXHUyMDAzXFxcXHUyMDA0XFxcXHUyMDA1XFxcXHUyMDA2XFxcXHUyMDA3XFxcXHUyMDA4XFxcXHUyMDA5XFxcXHUyMDBhXFxcXHUyMDJmXFxcXHUyMDVmXFxcXHUzMDAwJyxcbiAgICAgIHJzVXBwZXJSYW5nZSA9ICdBLVpcXFxceGMwLVxcXFx4ZDZcXFxceGQ4LVxcXFx4ZGUnLFxuICAgICAgcnNWYXJSYW5nZSA9ICdcXFxcdWZlMGVcXFxcdWZlMGYnLFxuICAgICAgcnNCcmVha1JhbmdlID0gcnNNYXRoT3BSYW5nZSArIHJzTm9uQ2hhclJhbmdlICsgcnNQdW5jdHVhdGlvblJhbmdlICsgcnNTcGFjZVJhbmdlO1xuXG4gIC8qKiBVc2VkIHRvIGNvbXBvc2UgdW5pY29kZSBjYXB0dXJlIGdyb3Vwcy4gKi9cbiAgdmFyIHJzQXBvcyA9IFwiWydcXHUyMDE5XVwiLFxuICAgICAgcnNBc3RyYWwgPSAnWycgKyByc0FzdHJhbFJhbmdlICsgJ10nLFxuICAgICAgcnNCcmVhayA9ICdbJyArIHJzQnJlYWtSYW5nZSArICddJyxcbiAgICAgIHJzQ29tYm8gPSAnWycgKyByc0NvbWJvUmFuZ2UgKyAnXScsXG4gICAgICByc0RpZ2l0cyA9ICdcXFxcZCsnLFxuICAgICAgcnNEaW5nYmF0ID0gJ1snICsgcnNEaW5nYmF0UmFuZ2UgKyAnXScsXG4gICAgICByc0xvd2VyID0gJ1snICsgcnNMb3dlclJhbmdlICsgJ10nLFxuICAgICAgcnNNaXNjID0gJ1teJyArIHJzQXN0cmFsUmFuZ2UgKyByc0JyZWFrUmFuZ2UgKyByc0RpZ2l0cyArIHJzRGluZ2JhdFJhbmdlICsgcnNMb3dlclJhbmdlICsgcnNVcHBlclJhbmdlICsgJ10nLFxuICAgICAgcnNGaXR6ID0gJ1xcXFx1ZDgzY1tcXFxcdWRmZmItXFxcXHVkZmZmXScsXG4gICAgICByc01vZGlmaWVyID0gJyg/OicgKyByc0NvbWJvICsgJ3wnICsgcnNGaXR6ICsgJyknLFxuICAgICAgcnNOb25Bc3RyYWwgPSAnW14nICsgcnNBc3RyYWxSYW5nZSArICddJyxcbiAgICAgIHJzUmVnaW9uYWwgPSAnKD86XFxcXHVkODNjW1xcXFx1ZGRlNi1cXFxcdWRkZmZdKXsyfScsXG4gICAgICByc1N1cnJQYWlyID0gJ1tcXFxcdWQ4MDAtXFxcXHVkYmZmXVtcXFxcdWRjMDAtXFxcXHVkZmZmXScsXG4gICAgICByc1VwcGVyID0gJ1snICsgcnNVcHBlclJhbmdlICsgJ10nLFxuICAgICAgcnNaV0ogPSAnXFxcXHUyMDBkJztcblxuICAvKiogVXNlZCB0byBjb21wb3NlIHVuaWNvZGUgcmVnZXhlcy4gKi9cbiAgdmFyIHJzTWlzY0xvd2VyID0gJyg/OicgKyByc0xvd2VyICsgJ3wnICsgcnNNaXNjICsgJyknLFxuICAgICAgcnNNaXNjVXBwZXIgPSAnKD86JyArIHJzVXBwZXIgKyAnfCcgKyByc01pc2MgKyAnKScsXG4gICAgICByc09wdENvbnRyTG93ZXIgPSAnKD86JyArIHJzQXBvcyArICcoPzpkfGxsfG18cmV8c3x0fHZlKSk/JyxcbiAgICAgIHJzT3B0Q29udHJVcHBlciA9ICcoPzonICsgcnNBcG9zICsgJyg/OkR8TEx8TXxSRXxTfFR8VkUpKT8nLFxuICAgICAgcmVPcHRNb2QgPSByc01vZGlmaWVyICsgJz8nLFxuICAgICAgcnNPcHRWYXIgPSAnWycgKyByc1ZhclJhbmdlICsgJ10/JyxcbiAgICAgIHJzT3B0Sm9pbiA9ICcoPzonICsgcnNaV0ogKyAnKD86JyArIFtyc05vbkFzdHJhbCwgcnNSZWdpb25hbCwgcnNTdXJyUGFpcl0uam9pbignfCcpICsgJyknICsgcnNPcHRWYXIgKyByZU9wdE1vZCArICcpKicsXG4gICAgICByc09yZExvd2VyID0gJ1xcXFxkKig/OjFzdHwybmR8M3JkfCg/IVsxMjNdKVxcXFxkdGgpKD89XFxcXGJ8W0EtWl9dKScsXG4gICAgICByc09yZFVwcGVyID0gJ1xcXFxkKig/OjFTVHwyTkR8M1JEfCg/IVsxMjNdKVxcXFxkVEgpKD89XFxcXGJ8W2Etel9dKScsXG4gICAgICByc1NlcSA9IHJzT3B0VmFyICsgcmVPcHRNb2QgKyByc09wdEpvaW4sXG4gICAgICByc0Vtb2ppID0gJyg/OicgKyBbcnNEaW5nYmF0LCByc1JlZ2lvbmFsLCByc1N1cnJQYWlyXS5qb2luKCd8JykgKyAnKScgKyByc1NlcSxcbiAgICAgIHJzU3ltYm9sID0gJyg/OicgKyBbcnNOb25Bc3RyYWwgKyByc0NvbWJvICsgJz8nLCByc0NvbWJvLCByc1JlZ2lvbmFsLCByc1N1cnJQYWlyLCByc0FzdHJhbF0uam9pbignfCcpICsgJyknO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIGFwb3N0cm9waGVzLiAqL1xuICB2YXIgcmVBcG9zID0gUmVnRXhwKHJzQXBvcywgJ2cnKTtcblxuICAvKipcbiAgICogVXNlZCB0byBtYXRjaCBbY29tYmluaW5nIGRpYWNyaXRpY2FsIG1hcmtzXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db21iaW5pbmdfRGlhY3JpdGljYWxfTWFya3MpIGFuZFxuICAgKiBbY29tYmluaW5nIGRpYWNyaXRpY2FsIG1hcmtzIGZvciBzeW1ib2xzXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db21iaW5pbmdfRGlhY3JpdGljYWxfTWFya3NfZm9yX1N5bWJvbHMpLlxuICAgKi9cbiAgdmFyIHJlQ29tYm9NYXJrID0gUmVnRXhwKHJzQ29tYm8sICdnJyk7XG5cbiAgLyoqIFVzZWQgdG8gbWF0Y2ggW3N0cmluZyBzeW1ib2xzXShodHRwczovL21hdGhpYXNieW5lbnMuYmUvbm90ZXMvamF2YXNjcmlwdC11bmljb2RlKS4gKi9cbiAgdmFyIHJlVW5pY29kZSA9IFJlZ0V4cChyc0ZpdHogKyAnKD89JyArIHJzRml0eiArICcpfCcgKyByc1N5bWJvbCArIHJzU2VxLCAnZycpO1xuXG4gIC8qKiBVc2VkIHRvIG1hdGNoIGNvbXBsZXggb3IgY29tcG91bmQgd29yZHMuICovXG4gIHZhciByZVVuaWNvZGVXb3JkID0gUmVnRXhwKFtcbiAgICByc1VwcGVyICsgJz8nICsgcnNMb3dlciArICcrJyArIHJzT3B0Q29udHJMb3dlciArICcoPz0nICsgW3JzQnJlYWssIHJzVXBwZXIsICckJ10uam9pbignfCcpICsgJyknLFxuICAgIHJzTWlzY1VwcGVyICsgJysnICsgcnNPcHRDb250clVwcGVyICsgJyg/PScgKyBbcnNCcmVhaywgcnNVcHBlciArIHJzTWlzY0xvd2VyLCAnJCddLmpvaW4oJ3wnKSArICcpJyxcbiAgICByc1VwcGVyICsgJz8nICsgcnNNaXNjTG93ZXIgKyAnKycgKyByc09wdENvbnRyTG93ZXIsXG4gICAgcnNVcHBlciArICcrJyArIHJzT3B0Q29udHJVcHBlcixcbiAgICByc09yZFVwcGVyLFxuICAgIHJzT3JkTG93ZXIsXG4gICAgcnNEaWdpdHMsXG4gICAgcnNFbW9qaVxuICBdLmpvaW4oJ3wnKSwgJ2cnKTtcblxuICAvKiogVXNlZCB0byBkZXRlY3Qgc3RyaW5ncyB3aXRoIFt6ZXJvLXdpZHRoIGpvaW5lcnMgb3IgY29kZSBwb2ludHMgZnJvbSB0aGUgYXN0cmFsIHBsYW5lc10oaHR0cDovL2Vldi5lZS9ibG9nLzIwMTUvMDkvMTIvZGFyay1jb3JuZXJzLW9mLXVuaWNvZGUvKS4gKi9cbiAgdmFyIHJlSGFzVW5pY29kZSA9IFJlZ0V4cCgnWycgKyByc1pXSiArIHJzQXN0cmFsUmFuZ2UgICsgcnNDb21ib1JhbmdlICsgcnNWYXJSYW5nZSArICddJyk7XG5cbiAgLyoqIFVzZWQgdG8gZGV0ZWN0IHN0cmluZ3MgdGhhdCBuZWVkIGEgbW9yZSByb2J1c3QgcmVnZXhwIHRvIG1hdGNoIHdvcmRzLiAqL1xuICB2YXIgcmVIYXNVbmljb2RlV29yZCA9IC9bYS16XVtBLVpdfFtBLVpdezJ9W2Etel18WzAtOV1bYS16QS1aXXxbYS16QS1aXVswLTldfFteYS16QS1aMC05IF0vO1xuXG4gIC8qKiBVc2VkIHRvIGFzc2lnbiBkZWZhdWx0IGBjb250ZXh0YCBvYmplY3QgcHJvcGVydGllcy4gKi9cbiAgdmFyIGNvbnRleHRQcm9wcyA9IFtcbiAgICAnQXJyYXknLCAnQnVmZmVyJywgJ0RhdGFWaWV3JywgJ0RhdGUnLCAnRXJyb3InLCAnRmxvYXQzMkFycmF5JywgJ0Zsb2F0NjRBcnJheScsXG4gICAgJ0Z1bmN0aW9uJywgJ0ludDhBcnJheScsICdJbnQxNkFycmF5JywgJ0ludDMyQXJyYXknLCAnTWFwJywgJ01hdGgnLCAnT2JqZWN0JyxcbiAgICAnUHJvbWlzZScsICdSZWdFeHAnLCAnU2V0JywgJ1N0cmluZycsICdTeW1ib2wnLCAnVHlwZUVycm9yJywgJ1VpbnQ4QXJyYXknLFxuICAgICdVaW50OENsYW1wZWRBcnJheScsICdVaW50MTZBcnJheScsICdVaW50MzJBcnJheScsICdXZWFrTWFwJyxcbiAgICAnXycsICdjbGVhclRpbWVvdXQnLCAnaXNGaW5pdGUnLCAncGFyc2VJbnQnLCAnc2V0VGltZW91dCdcbiAgXTtcblxuICAvKiogVXNlZCB0byBtYWtlIHRlbXBsYXRlIHNvdXJjZVVSTHMgZWFzaWVyIHRvIGlkZW50aWZ5LiAqL1xuICB2YXIgdGVtcGxhdGVDb3VudGVyID0gLTE7XG5cbiAgLyoqIFVzZWQgdG8gaWRlbnRpZnkgYHRvU3RyaW5nVGFnYCB2YWx1ZXMgb2YgdHlwZWQgYXJyYXlzLiAqL1xuICB2YXIgdHlwZWRBcnJheVRhZ3MgPSB7fTtcbiAgdHlwZWRBcnJheVRhZ3NbZmxvYXQzMlRhZ10gPSB0eXBlZEFycmF5VGFnc1tmbG9hdDY0VGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW2ludDhUYWddID0gdHlwZWRBcnJheVRhZ3NbaW50MTZUYWddID1cbiAgdHlwZWRBcnJheVRhZ3NbaW50MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDhUYWddID1cbiAgdHlwZWRBcnJheVRhZ3NbdWludDhDbGFtcGVkVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3VpbnQxNlRhZ10gPVxuICB0eXBlZEFycmF5VGFnc1t1aW50MzJUYWddID0gdHJ1ZTtcbiAgdHlwZWRBcnJheVRhZ3NbYXJnc1RhZ10gPSB0eXBlZEFycmF5VGFnc1thcnJheVRhZ10gPVxuICB0eXBlZEFycmF5VGFnc1thcnJheUJ1ZmZlclRhZ10gPSB0eXBlZEFycmF5VGFnc1tib29sVGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW2RhdGFWaWV3VGFnXSA9IHR5cGVkQXJyYXlUYWdzW2RhdGVUYWddID1cbiAgdHlwZWRBcnJheVRhZ3NbZXJyb3JUYWddID0gdHlwZWRBcnJheVRhZ3NbZnVuY1RhZ10gPVxuICB0eXBlZEFycmF5VGFnc1ttYXBUYWddID0gdHlwZWRBcnJheVRhZ3NbbnVtYmVyVGFnXSA9XG4gIHR5cGVkQXJyYXlUYWdzW29iamVjdFRhZ10gPSB0eXBlZEFycmF5VGFnc1tyZWdleHBUYWddID1cbiAgdHlwZWRBcnJheVRhZ3Nbc2V0VGFnXSA9IHR5cGVkQXJyYXlUYWdzW3N0cmluZ1RhZ10gPVxuICB0eXBlZEFycmF5VGFnc1t3ZWFrTWFwVGFnXSA9IGZhbHNlO1xuXG4gIC8qKiBVc2VkIHRvIGlkZW50aWZ5IGB0b1N0cmluZ1RhZ2AgdmFsdWVzIHN1cHBvcnRlZCBieSBgXy5jbG9uZWAuICovXG4gIHZhciBjbG9uZWFibGVUYWdzID0ge307XG4gIGNsb25lYWJsZVRhZ3NbYXJnc1RhZ10gPSBjbG9uZWFibGVUYWdzW2FycmF5VGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbYXJyYXlCdWZmZXJUYWddID0gY2xvbmVhYmxlVGFnc1tkYXRhVmlld1RhZ10gPVxuICBjbG9uZWFibGVUYWdzW2Jvb2xUYWddID0gY2xvbmVhYmxlVGFnc1tkYXRlVGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbZmxvYXQzMlRhZ10gPSBjbG9uZWFibGVUYWdzW2Zsb2F0NjRUYWddID1cbiAgY2xvbmVhYmxlVGFnc1tpbnQ4VGFnXSA9IGNsb25lYWJsZVRhZ3NbaW50MTZUYWddID1cbiAgY2xvbmVhYmxlVGFnc1tpbnQzMlRhZ10gPSBjbG9uZWFibGVUYWdzW21hcFRhZ10gPVxuICBjbG9uZWFibGVUYWdzW251bWJlclRhZ10gPSBjbG9uZWFibGVUYWdzW29iamVjdFRhZ10gPVxuICBjbG9uZWFibGVUYWdzW3JlZ2V4cFRhZ10gPSBjbG9uZWFibGVUYWdzW3NldFRhZ10gPVxuICBjbG9uZWFibGVUYWdzW3N0cmluZ1RhZ10gPSBjbG9uZWFibGVUYWdzW3N5bWJvbFRhZ10gPVxuICBjbG9uZWFibGVUYWdzW3VpbnQ4VGFnXSA9IGNsb25lYWJsZVRhZ3NbdWludDhDbGFtcGVkVGFnXSA9XG4gIGNsb25lYWJsZVRhZ3NbdWludDE2VGFnXSA9IGNsb25lYWJsZVRhZ3NbdWludDMyVGFnXSA9IHRydWU7XG4gIGNsb25lYWJsZVRhZ3NbZXJyb3JUYWddID0gY2xvbmVhYmxlVGFnc1tmdW5jVGFnXSA9XG4gIGNsb25lYWJsZVRhZ3Nbd2Vha01hcFRhZ10gPSBmYWxzZTtcblxuICAvKiogVXNlZCB0byBtYXAgTGF0aW4gVW5pY29kZSBsZXR0ZXJzIHRvIGJhc2ljIExhdGluIGxldHRlcnMuICovXG4gIHZhciBkZWJ1cnJlZExldHRlcnMgPSB7XG4gICAgLy8gTGF0aW4tMSBTdXBwbGVtZW50IGJsb2NrLlxuICAgICdcXHhjMCc6ICdBJywgICdcXHhjMSc6ICdBJywgJ1xceGMyJzogJ0EnLCAnXFx4YzMnOiAnQScsICdcXHhjNCc6ICdBJywgJ1xceGM1JzogJ0EnLFxuICAgICdcXHhlMCc6ICdhJywgICdcXHhlMSc6ICdhJywgJ1xceGUyJzogJ2EnLCAnXFx4ZTMnOiAnYScsICdcXHhlNCc6ICdhJywgJ1xceGU1JzogJ2EnLFxuICAgICdcXHhjNyc6ICdDJywgICdcXHhlNyc6ICdjJyxcbiAgICAnXFx4ZDAnOiAnRCcsICAnXFx4ZjAnOiAnZCcsXG4gICAgJ1xceGM4JzogJ0UnLCAgJ1xceGM5JzogJ0UnLCAnXFx4Y2EnOiAnRScsICdcXHhjYic6ICdFJyxcbiAgICAnXFx4ZTgnOiAnZScsICAnXFx4ZTknOiAnZScsICdcXHhlYSc6ICdlJywgJ1xceGViJzogJ2UnLFxuICAgICdcXHhjYyc6ICdJJywgICdcXHhjZCc6ICdJJywgJ1xceGNlJzogJ0knLCAnXFx4Y2YnOiAnSScsXG4gICAgJ1xceGVjJzogJ2knLCAgJ1xceGVkJzogJ2knLCAnXFx4ZWUnOiAnaScsICdcXHhlZic6ICdpJyxcbiAgICAnXFx4ZDEnOiAnTicsICAnXFx4ZjEnOiAnbicsXG4gICAgJ1xceGQyJzogJ08nLCAgJ1xceGQzJzogJ08nLCAnXFx4ZDQnOiAnTycsICdcXHhkNSc6ICdPJywgJ1xceGQ2JzogJ08nLCAnXFx4ZDgnOiAnTycsXG4gICAgJ1xceGYyJzogJ28nLCAgJ1xceGYzJzogJ28nLCAnXFx4ZjQnOiAnbycsICdcXHhmNSc6ICdvJywgJ1xceGY2JzogJ28nLCAnXFx4ZjgnOiAnbycsXG4gICAgJ1xceGQ5JzogJ1UnLCAgJ1xceGRhJzogJ1UnLCAnXFx4ZGInOiAnVScsICdcXHhkYyc6ICdVJyxcbiAgICAnXFx4ZjknOiAndScsICAnXFx4ZmEnOiAndScsICdcXHhmYic6ICd1JywgJ1xceGZjJzogJ3UnLFxuICAgICdcXHhkZCc6ICdZJywgICdcXHhmZCc6ICd5JywgJ1xceGZmJzogJ3knLFxuICAgICdcXHhjNic6ICdBZScsICdcXHhlNic6ICdhZScsXG4gICAgJ1xceGRlJzogJ1RoJywgJ1xceGZlJzogJ3RoJyxcbiAgICAnXFx4ZGYnOiAnc3MnLFxuICAgIC8vIExhdGluIEV4dGVuZGVkLUEgYmxvY2suXG4gICAgJ1xcdTAxMDAnOiAnQScsICAnXFx1MDEwMic6ICdBJywgJ1xcdTAxMDQnOiAnQScsXG4gICAgJ1xcdTAxMDEnOiAnYScsICAnXFx1MDEwMyc6ICdhJywgJ1xcdTAxMDUnOiAnYScsXG4gICAgJ1xcdTAxMDYnOiAnQycsICAnXFx1MDEwOCc6ICdDJywgJ1xcdTAxMGEnOiAnQycsICdcXHUwMTBjJzogJ0MnLFxuICAgICdcXHUwMTA3JzogJ2MnLCAgJ1xcdTAxMDknOiAnYycsICdcXHUwMTBiJzogJ2MnLCAnXFx1MDEwZCc6ICdjJyxcbiAgICAnXFx1MDEwZSc6ICdEJywgICdcXHUwMTEwJzogJ0QnLCAnXFx1MDEwZic6ICdkJywgJ1xcdTAxMTEnOiAnZCcsXG4gICAgJ1xcdTAxMTInOiAnRScsICAnXFx1MDExNCc6ICdFJywgJ1xcdTAxMTYnOiAnRScsICdcXHUwMTE4JzogJ0UnLCAnXFx1MDExYSc6ICdFJyxcbiAgICAnXFx1MDExMyc6ICdlJywgICdcXHUwMTE1JzogJ2UnLCAnXFx1MDExNyc6ICdlJywgJ1xcdTAxMTknOiAnZScsICdcXHUwMTFiJzogJ2UnLFxuICAgICdcXHUwMTFjJzogJ0cnLCAgJ1xcdTAxMWUnOiAnRycsICdcXHUwMTIwJzogJ0cnLCAnXFx1MDEyMic6ICdHJyxcbiAgICAnXFx1MDExZCc6ICdnJywgICdcXHUwMTFmJzogJ2cnLCAnXFx1MDEyMSc6ICdnJywgJ1xcdTAxMjMnOiAnZycsXG4gICAgJ1xcdTAxMjQnOiAnSCcsICAnXFx1MDEyNic6ICdIJywgJ1xcdTAxMjUnOiAnaCcsICdcXHUwMTI3JzogJ2gnLFxuICAgICdcXHUwMTI4JzogJ0knLCAgJ1xcdTAxMmEnOiAnSScsICdcXHUwMTJjJzogJ0knLCAnXFx1MDEyZSc6ICdJJywgJ1xcdTAxMzAnOiAnSScsXG4gICAgJ1xcdTAxMjknOiAnaScsICAnXFx1MDEyYic6ICdpJywgJ1xcdTAxMmQnOiAnaScsICdcXHUwMTJmJzogJ2knLCAnXFx1MDEzMSc6ICdpJyxcbiAgICAnXFx1MDEzNCc6ICdKJywgICdcXHUwMTM1JzogJ2onLFxuICAgICdcXHUwMTM2JzogJ0snLCAgJ1xcdTAxMzcnOiAnaycsICdcXHUwMTM4JzogJ2snLFxuICAgICdcXHUwMTM5JzogJ0wnLCAgJ1xcdTAxM2InOiAnTCcsICdcXHUwMTNkJzogJ0wnLCAnXFx1MDEzZic6ICdMJywgJ1xcdTAxNDEnOiAnTCcsXG4gICAgJ1xcdTAxM2EnOiAnbCcsICAnXFx1MDEzYyc6ICdsJywgJ1xcdTAxM2UnOiAnbCcsICdcXHUwMTQwJzogJ2wnLCAnXFx1MDE0Mic6ICdsJyxcbiAgICAnXFx1MDE0Myc6ICdOJywgICdcXHUwMTQ1JzogJ04nLCAnXFx1MDE0Nyc6ICdOJywgJ1xcdTAxNGEnOiAnTicsXG4gICAgJ1xcdTAxNDQnOiAnbicsICAnXFx1MDE0Nic6ICduJywgJ1xcdTAxNDgnOiAnbicsICdcXHUwMTRiJzogJ24nLFxuICAgICdcXHUwMTRjJzogJ08nLCAgJ1xcdTAxNGUnOiAnTycsICdcXHUwMTUwJzogJ08nLFxuICAgICdcXHUwMTRkJzogJ28nLCAgJ1xcdTAxNGYnOiAnbycsICdcXHUwMTUxJzogJ28nLFxuICAgICdcXHUwMTU0JzogJ1InLCAgJ1xcdTAxNTYnOiAnUicsICdcXHUwMTU4JzogJ1InLFxuICAgICdcXHUwMTU1JzogJ3InLCAgJ1xcdTAxNTcnOiAncicsICdcXHUwMTU5JzogJ3InLFxuICAgICdcXHUwMTVhJzogJ1MnLCAgJ1xcdTAxNWMnOiAnUycsICdcXHUwMTVlJzogJ1MnLCAnXFx1MDE2MCc6ICdTJyxcbiAgICAnXFx1MDE1Yic6ICdzJywgICdcXHUwMTVkJzogJ3MnLCAnXFx1MDE1Zic6ICdzJywgJ1xcdTAxNjEnOiAncycsXG4gICAgJ1xcdTAxNjInOiAnVCcsICAnXFx1MDE2NCc6ICdUJywgJ1xcdTAxNjYnOiAnVCcsXG4gICAgJ1xcdTAxNjMnOiAndCcsICAnXFx1MDE2NSc6ICd0JywgJ1xcdTAxNjcnOiAndCcsXG4gICAgJ1xcdTAxNjgnOiAnVScsICAnXFx1MDE2YSc6ICdVJywgJ1xcdTAxNmMnOiAnVScsICdcXHUwMTZlJzogJ1UnLCAnXFx1MDE3MCc6ICdVJywgJ1xcdTAxNzInOiAnVScsXG4gICAgJ1xcdTAxNjknOiAndScsICAnXFx1MDE2Yic6ICd1JywgJ1xcdTAxNmQnOiAndScsICdcXHUwMTZmJzogJ3UnLCAnXFx1MDE3MSc6ICd1JywgJ1xcdTAxNzMnOiAndScsXG4gICAgJ1xcdTAxNzQnOiAnVycsICAnXFx1MDE3NSc6ICd3JyxcbiAgICAnXFx1MDE3Nic6ICdZJywgICdcXHUwMTc3JzogJ3knLCAnXFx1MDE3OCc6ICdZJyxcbiAgICAnXFx1MDE3OSc6ICdaJywgICdcXHUwMTdiJzogJ1onLCAnXFx1MDE3ZCc6ICdaJyxcbiAgICAnXFx1MDE3YSc6ICd6JywgICdcXHUwMTdjJzogJ3onLCAnXFx1MDE3ZSc6ICd6JyxcbiAgICAnXFx1MDEzMic6ICdJSicsICdcXHUwMTMzJzogJ2lqJyxcbiAgICAnXFx1MDE1Mic6ICdPZScsICdcXHUwMTUzJzogJ29lJyxcbiAgICAnXFx1MDE0OSc6IFwiJ25cIiwgJ1xcdTAxN2YnOiAncydcbiAgfTtcblxuICAvKiogVXNlZCB0byBtYXAgY2hhcmFjdGVycyB0byBIVE1MIGVudGl0aWVzLiAqL1xuICB2YXIgaHRtbEVzY2FwZXMgPSB7XG4gICAgJyYnOiAnJmFtcDsnLFxuICAgICc8JzogJyZsdDsnLFxuICAgICc+JzogJyZndDsnLFxuICAgICdcIic6ICcmcXVvdDsnLFxuICAgIFwiJ1wiOiAnJiMzOTsnXG4gIH07XG5cbiAgLyoqIFVzZWQgdG8gbWFwIEhUTUwgZW50aXRpZXMgdG8gY2hhcmFjdGVycy4gKi9cbiAgdmFyIGh0bWxVbmVzY2FwZXMgPSB7XG4gICAgJyZhbXA7JzogJyYnLFxuICAgICcmbHQ7JzogJzwnLFxuICAgICcmZ3Q7JzogJz4nLFxuICAgICcmcXVvdDsnOiAnXCInLFxuICAgICcmIzM5Oyc6IFwiJ1wiXG4gIH07XG5cbiAgLyoqIFVzZWQgdG8gZXNjYXBlIGNoYXJhY3RlcnMgZm9yIGluY2x1c2lvbiBpbiBjb21waWxlZCBzdHJpbmcgbGl0ZXJhbHMuICovXG4gIHZhciBzdHJpbmdFc2NhcGVzID0ge1xuICAgICdcXFxcJzogJ1xcXFwnLFxuICAgIFwiJ1wiOiBcIidcIixcbiAgICAnXFxuJzogJ24nLFxuICAgICdcXHInOiAncicsXG4gICAgJ1xcdTIwMjgnOiAndTIwMjgnLFxuICAgICdcXHUyMDI5JzogJ3UyMDI5J1xuICB9O1xuXG4gIC8qKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB3aXRob3V0IGEgZGVwZW5kZW5jeSBvbiBgcm9vdGAuICovXG4gIHZhciBmcmVlUGFyc2VGbG9hdCA9IHBhcnNlRmxvYXQsXG4gICAgICBmcmVlUGFyc2VJbnQgPSBwYXJzZUludDtcblxuICAvKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGdsb2JhbGAgZnJvbSBOb2RlLmpzLiAqL1xuICB2YXIgZnJlZUdsb2JhbCA9IHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsICYmIGdsb2JhbC5PYmplY3QgPT09IE9iamVjdCAmJiBnbG9iYWw7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBzZWxmYC4gKi9cbiAgdmFyIGZyZWVTZWxmID0gdHlwZW9mIHNlbGYgPT0gJ29iamVjdCcgJiYgc2VsZiAmJiBzZWxmLk9iamVjdCA9PT0gT2JqZWN0ICYmIHNlbGY7XG5cbiAgLyoqIFVzZWQgYXMgYSByZWZlcmVuY2UgdG8gdGhlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciByb290ID0gZnJlZUdsb2JhbCB8fCBmcmVlU2VsZiB8fCBGdW5jdGlvbigncmV0dXJuIHRoaXMnKSgpO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG4gIHZhciBmcmVlRXhwb3J0cyA9IHR5cGVvZiBleHBvcnRzID09ICdvYmplY3QnICYmIGV4cG9ydHMgJiYgIWV4cG9ydHMubm9kZVR5cGUgJiYgZXhwb3J0cztcblxuICAvKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYG1vZHVsZWAuICovXG4gIHZhciBmcmVlTW9kdWxlID0gZnJlZUV4cG9ydHMgJiYgdHlwZW9mIG1vZHVsZSA9PSAnb2JqZWN0JyAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbiAgLyoqIERldGVjdCB0aGUgcG9wdWxhciBDb21tb25KUyBleHRlbnNpb24gYG1vZHVsZS5leHBvcnRzYC4gKi9cbiAgdmFyIG1vZHVsZUV4cG9ydHMgPSBmcmVlTW9kdWxlICYmIGZyZWVNb2R1bGUuZXhwb3J0cyA9PT0gZnJlZUV4cG9ydHM7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBwcm9jZXNzYCBmcm9tIE5vZGUuanMuICovXG4gIHZhciBmcmVlUHJvY2VzcyA9IG1vZHVsZUV4cG9ydHMgJiYgZnJlZUdsb2JhbC5wcm9jZXNzO1xuXG4gIC8qKiBVc2VkIHRvIGFjY2VzcyBmYXN0ZXIgTm9kZS5qcyBoZWxwZXJzLiAqL1xuICB2YXIgbm9kZVV0aWwgPSAoZnVuY3Rpb24oKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFVzZSBgdXRpbC50eXBlc2AgZm9yIE5vZGUuanMgMTArLlxuICAgICAgdmFyIHR5cGVzID0gZnJlZU1vZHVsZSAmJiBmcmVlTW9kdWxlLnJlcXVpcmUgJiYgZnJlZU1vZHVsZS5yZXF1aXJlKCd1dGlsJykudHlwZXM7XG5cbiAgICAgIGlmICh0eXBlcykge1xuICAgICAgICByZXR1cm4gdHlwZXM7XG4gICAgICB9XG5cbiAgICAgIC8vIExlZ2FjeSBgcHJvY2Vzcy5iaW5kaW5nKCd1dGlsJylgIGZvciBOb2RlLmpzIDwgMTAuXG4gICAgICByZXR1cm4gZnJlZVByb2Nlc3MgJiYgZnJlZVByb2Nlc3MuYmluZGluZyAmJiBmcmVlUHJvY2Vzcy5iaW5kaW5nKCd1dGlsJyk7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgfSgpKTtcblxuICAvKiBOb2RlLmpzIGhlbHBlciByZWZlcmVuY2VzLiAqL1xuICB2YXIgbm9kZUlzQXJyYXlCdWZmZXIgPSBub2RlVXRpbCAmJiBub2RlVXRpbC5pc0FycmF5QnVmZmVyLFxuICAgICAgbm9kZUlzRGF0ZSA9IG5vZGVVdGlsICYmIG5vZGVVdGlsLmlzRGF0ZSxcbiAgICAgIG5vZGVJc01hcCA9IG5vZGVVdGlsICYmIG5vZGVVdGlsLmlzTWFwLFxuICAgICAgbm9kZUlzUmVnRXhwID0gbm9kZVV0aWwgJiYgbm9kZVV0aWwuaXNSZWdFeHAsXG4gICAgICBub2RlSXNTZXQgPSBub2RlVXRpbCAmJiBub2RlVXRpbC5pc1NldCxcbiAgICAgIG5vZGVJc1R5cGVkQXJyYXkgPSBub2RlVXRpbCAmJiBub2RlVXRpbC5pc1R5cGVkQXJyYXk7XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLyoqXG4gICAqIEEgZmFzdGVyIGFsdGVybmF0aXZlIHRvIGBGdW5jdGlvbiNhcHBseWAsIHRoaXMgZnVuY3Rpb24gaW52b2tlcyBgZnVuY2BcbiAgICogd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgYHRoaXNBcmdgIGFuZCB0aGUgYXJndW1lbnRzIG9mIGBhcmdzYC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gaW52b2tlLlxuICAgKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAgICogQHBhcmFtIHtBcnJheX0gYXJncyBUaGUgYXJndW1lbnRzIHRvIGludm9rZSBgZnVuY2Agd2l0aC5cbiAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc3VsdCBvZiBgZnVuY2AuXG4gICAqL1xuICBmdW5jdGlvbiBhcHBseShmdW5jLCB0aGlzQXJnLCBhcmdzKSB7XG4gICAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOiByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcpO1xuICAgICAgY2FzZSAxOiByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIGFyZ3NbMF0pO1xuICAgICAgY2FzZSAyOiByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgICAgY2FzZSAzOiByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgIH1cbiAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzQXJnLCBhcmdzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VBZ2dyZWdhdG9yYCBmb3IgYXJyYXlzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHNldHRlciBUaGUgZnVuY3Rpb24gdG8gc2V0IGBhY2N1bXVsYXRvcmAgdmFsdWVzLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgaXRlcmF0ZWUgdG8gdHJhbnNmb3JtIGtleXMuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBhY2N1bXVsYXRvciBUaGUgaW5pdGlhbCBhZ2dyZWdhdGVkIG9iamVjdC5cbiAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBhY2N1bXVsYXRvcmAuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheUFnZ3JlZ2F0b3IoYXJyYXksIHNldHRlciwgaXRlcmF0ZWUsIGFjY3VtdWxhdG9yKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICAgIHNldHRlcihhY2N1bXVsYXRvciwgdmFsdWUsIGl0ZXJhdGVlKHZhbHVlKSwgYXJyYXkpO1xuICAgIH1cbiAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmZvckVhY2hgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvclxuICAgKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlFYWNoKGFycmF5LCBpdGVyYXRlZSkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICBpZiAoaXRlcmF0ZWUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpID09PSBmYWxzZSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFycmF5O1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5mb3JFYWNoUmlnaHRgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvclxuICAgKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlFYWNoUmlnaHQoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICBpZiAoaXRlcmF0ZWUoYXJyYXlbbGVuZ3RoXSwgbGVuZ3RoLCBhcnJheSkgPT09IGZhbHNlKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXk7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmV2ZXJ5YCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAgICogaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFsbCBlbGVtZW50cyBwYXNzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gICAqICBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheUV2ZXJ5KGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgaWYgKCFwcmVkaWNhdGUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmZpbHRlcmAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gICAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlGaWx0ZXIoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgcmVzSW5kZXggPSAwLFxuICAgICAgICByZXN1bHQgPSBbXTtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF07XG4gICAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBpbmRleCwgYXJyYXkpKSB7XG4gICAgICAgIHJlc3VsdFtyZXNJbmRleCsrXSA9IHZhbHVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5pbmNsdWRlc2AgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gICAqIHNwZWNpZnlpbmcgYW4gaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7Kn0gdGFyZ2V0IFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHRhcmdldGAgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAgICovXG4gIGZ1bmN0aW9uIGFycmF5SW5jbHVkZXMoYXJyYXksIHZhbHVlKSB7XG4gICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgIHJldHVybiAhIWxlbmd0aCAmJiBiYXNlSW5kZXhPZihhcnJheSwgdmFsdWUsIDApID4gLTE7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBmdW5jdGlvbiBpcyBsaWtlIGBhcnJheUluY2x1ZGVzYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGEgY29tcGFyYXRvci5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHsqfSB0YXJnZXQgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNvbXBhcmF0b3IgVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB0YXJnZXRgIGlzIGZvdW5kLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheUluY2x1ZGVzV2l0aChhcnJheSwgdmFsdWUsIGNvbXBhcmF0b3IpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgaWYgKGNvbXBhcmF0b3IodmFsdWUsIGFycmF5W2luZGV4XSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8ubWFwYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWVcbiAgICogc2hvcnRoYW5kcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgYXJyYXkuXG4gICAqL1xuICBmdW5jdGlvbiBhcnJheU1hcChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGgsXG4gICAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgcmVzdWx0W2luZGV4XSA9IGl0ZXJhdGVlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBlbmRzIHRoZSBlbGVtZW50cyBvZiBgdmFsdWVzYCB0byBgYXJyYXlgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICAgKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byBhcHBlbmQuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlQdXNoKGFycmF5LCB2YWx1ZXMpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gdmFsdWVzLmxlbmd0aCxcbiAgICAgICAgb2Zmc2V0ID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIGFycmF5W29mZnNldCArIGluZGV4XSA9IHZhbHVlc1tpbmRleF07XG4gICAgfVxuICAgIHJldHVybiBhcnJheTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8ucmVkdWNlYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAgICogaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcGFyYW0geyp9IFthY2N1bXVsYXRvcl0gVGhlIGluaXRpYWwgdmFsdWUuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2luaXRBY2N1bV0gU3BlY2lmeSB1c2luZyB0aGUgZmlyc3QgZWxlbWVudCBvZiBgYXJyYXlgIGFzXG4gICAqICB0aGUgaW5pdGlhbCB2YWx1ZS5cbiAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHZhbHVlLlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlSZWR1Y2UoYXJyYXksIGl0ZXJhdGVlLCBhY2N1bXVsYXRvciwgaW5pdEFjY3VtKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuXG4gICAgaWYgKGluaXRBY2N1bSAmJiBsZW5ndGgpIHtcbiAgICAgIGFjY3VtdWxhdG9yID0gYXJyYXlbKytpbmRleF07XG4gICAgfVxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICBhY2N1bXVsYXRvciA9IGl0ZXJhdGVlKGFjY3VtdWxhdG9yLCBhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSk7XG4gICAgfVxuICAgIHJldHVybiBhY2N1bXVsYXRvcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8ucmVkdWNlUmlnaHRgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvclxuICAgKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEBwYXJhbSB7Kn0gW2FjY3VtdWxhdG9yXSBUaGUgaW5pdGlhbCB2YWx1ZS5cbiAgICogQHBhcmFtIHtib29sZWFufSBbaW5pdEFjY3VtXSBTcGVjaWZ5IHVzaW5nIHRoZSBsYXN0IGVsZW1lbnQgb2YgYGFycmF5YCBhc1xuICAgKiAgdGhlIGluaXRpYWwgdmFsdWUuXG4gICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBhY2N1bXVsYXRlZCB2YWx1ZS5cbiAgICovXG4gIGZ1bmN0aW9uIGFycmF5UmVkdWNlUmlnaHQoYXJyYXksIGl0ZXJhdGVlLCBhY2N1bXVsYXRvciwgaW5pdEFjY3VtKSB7XG4gICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgIGlmIChpbml0QWNjdW0gJiYgbGVuZ3RoKSB7XG4gICAgICBhY2N1bXVsYXRvciA9IGFycmF5Wy0tbGVuZ3RoXTtcbiAgICB9XG4gICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICBhY2N1bXVsYXRvciA9IGl0ZXJhdGVlKGFjY3VtdWxhdG9yLCBhcnJheVtsZW5ndGhdLCBsZW5ndGgsIGFycmF5KTtcbiAgICB9XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5zb21lYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWVcbiAgICogc2hvcnRoYW5kcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFueSBlbGVtZW50IHBhc3NlcyB0aGUgcHJlZGljYXRlIGNoZWNrLFxuICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgKi9cbiAgZnVuY3Rpb24gYXJyYXlTb21lKGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgaWYgKHByZWRpY2F0ZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBzaXplIG9mIGFuIEFTQ0lJIGBzdHJpbmdgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgaW5zcGVjdC5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3RyaW5nIHNpemUuXG4gICAqL1xuICB2YXIgYXNjaWlTaXplID0gYmFzZVByb3BlcnR5KCdsZW5ndGgnKTtcblxuICAvKipcbiAgICogQ29udmVydHMgYW4gQVNDSUkgYHN0cmluZ2AgdG8gYW4gYXJyYXkuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBhcnJheS5cbiAgICovXG4gIGZ1bmN0aW9uIGFzY2lpVG9BcnJheShzdHJpbmcpIHtcbiAgICByZXR1cm4gc3RyaW5nLnNwbGl0KCcnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTcGxpdHMgYW4gQVNDSUkgYHN0cmluZ2AgaW50byBhbiBhcnJheSBvZiBpdHMgd29yZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgd29yZHMgb2YgYHN0cmluZ2AuXG4gICAqL1xuICBmdW5jdGlvbiBhc2NpaVdvcmRzKHN0cmluZykge1xuICAgIHJldHVybiBzdHJpbmcubWF0Y2gocmVBc2NpaVdvcmQpIHx8IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIG1ldGhvZHMgbGlrZSBgXy5maW5kS2V5YCBhbmQgYF8uZmluZExhc3RLZXlgLFxuICAgKiB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMsIHdoaWNoIGl0ZXJhdGVzIG92ZXIgYGNvbGxlY3Rpb25gXG4gICAqIHVzaW5nIGBlYWNoRnVuY2AuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGBjb2xsZWN0aW9uYC5cbiAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGZvdW5kIGVsZW1lbnQgb3IgaXRzIGtleSwgZWxzZSBgdW5kZWZpbmVkYC5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VGaW5kS2V5KGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZWFjaEZ1bmMpIHtcbiAgICB2YXIgcmVzdWx0O1xuICAgIGVhY2hGdW5jKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pIHtcbiAgICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGtleSwgY29sbGVjdGlvbikpIHtcbiAgICAgICAgcmVzdWx0ID0ga2V5O1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5maW5kSW5kZXhgIGFuZCBgXy5maW5kTGFzdEluZGV4YCB3aXRob3V0XG4gICAqIHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZUZpbmRJbmRleChhcnJheSwgcHJlZGljYXRlLCBmcm9tSW5kZXgsIGZyb21SaWdodCkge1xuICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgIGluZGV4ID0gZnJvbUluZGV4ICsgKGZyb21SaWdodCA/IDEgOiAtMSk7XG5cbiAgICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgICAgaWYgKHByZWRpY2F0ZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkpIHtcbiAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaW5kZXhPZmAgd2l0aG91dCBgZnJvbUluZGV4YCBib3VuZHMgY2hlY2tzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlSW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICAgIHJldHVybiB2YWx1ZSA9PT0gdmFsdWVcbiAgICAgID8gc3RyaWN0SW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleClcbiAgICAgIDogYmFzZUZpbmRJbmRleChhcnJheSwgYmFzZUlzTmFOLCBmcm9tSW5kZXgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgZnVuY3Rpb24gaXMgbGlrZSBgYmFzZUluZGV4T2ZgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYSBjb21wYXJhdG9yLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNvbXBhcmF0b3IgVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VJbmRleE9mV2l0aChhcnJheSwgdmFsdWUsIGZyb21JbmRleCwgY29tcGFyYXRvcikge1xuICAgIHZhciBpbmRleCA9IGZyb21JbmRleCAtIDEsXG4gICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICBpZiAoY29tcGFyYXRvcihhcnJheVtpbmRleF0sIHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAtMTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc05hTmAgd2l0aG91dCBzdXBwb3J0IGZvciBudW1iZXIgb2JqZWN0cy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGBOYU5gLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBiYXNlSXNOYU4odmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgIT09IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1lYW5gIGFuZCBgXy5tZWFuQnlgIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAgICogaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgbWVhbi5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VNZWFuKGFycmF5LCBpdGVyYXRlZSkge1xuICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICByZXR1cm4gbGVuZ3RoID8gKGJhc2VTdW0oYXJyYXksIGl0ZXJhdGVlKSAvIGxlbmd0aCkgOiBOQU47XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucHJvcGVydHlgIHdpdGhvdXQgc3VwcG9ydCBmb3IgZGVlcCBwYXRocy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGFjY2Vzc29yIGZ1bmN0aW9uLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVByb3BlcnR5KGtleSkge1xuICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFtrZXldO1xuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucHJvcGVydHlPZmAgd2l0aG91dCBzdXBwb3J0IGZvciBkZWVwIHBhdGhzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGFjY2Vzc29yIGZ1bmN0aW9uLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVByb3BlcnR5T2Yob2JqZWN0KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGtleSkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0W2tleV07XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5yZWR1Y2VgIGFuZCBgXy5yZWR1Y2VSaWdodGAsIHdpdGhvdXQgc3VwcG9ydFxuICAgKiBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcywgd2hpY2ggaXRlcmF0ZXMgb3ZlciBgY29sbGVjdGlvbmAgdXNpbmcgYGVhY2hGdW5jYC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcGFyYW0geyp9IGFjY3VtdWxhdG9yIFRoZSBpbml0aWFsIHZhbHVlLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGluaXRBY2N1bSBTcGVjaWZ5IHVzaW5nIHRoZSBmaXJzdCBvciBsYXN0IGVsZW1lbnQgb2ZcbiAgICogIGBjb2xsZWN0aW9uYCBhcyB0aGUgaW5pdGlhbCB2YWx1ZS5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBgY29sbGVjdGlvbmAuXG4gICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBhY2N1bXVsYXRlZCB2YWx1ZS5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VSZWR1Y2UoY29sbGVjdGlvbiwgaXRlcmF0ZWUsIGFjY3VtdWxhdG9yLCBpbml0QWNjdW0sIGVhY2hGdW5jKSB7XG4gICAgZWFjaEZ1bmMoY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB7XG4gICAgICBhY2N1bXVsYXRvciA9IGluaXRBY2N1bVxuICAgICAgICA/IChpbml0QWNjdW0gPSBmYWxzZSwgdmFsdWUpXG4gICAgICAgIDogaXRlcmF0ZWUoYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbik7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnNvcnRCeWAgd2hpY2ggdXNlcyBgY29tcGFyZXJgIHRvIGRlZmluZSB0aGVcbiAgICogc29ydCBvcmRlciBvZiBgYXJyYXlgIGFuZCByZXBsYWNlcyBjcml0ZXJpYSBvYmplY3RzIHdpdGggdGhlaXIgY29ycmVzcG9uZGluZ1xuICAgKiB2YWx1ZXMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzb3J0LlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjb21wYXJlciBUaGUgZnVuY3Rpb24gdG8gZGVmaW5lIHNvcnQgb3JkZXIuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVNvcnRCeShhcnJheSwgY29tcGFyZXIpIHtcbiAgICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgYXJyYXkuc29ydChjb21wYXJlcik7XG4gICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICBhcnJheVtsZW5ndGhdID0gYXJyYXlbbGVuZ3RoXS52YWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnN1bWAgYW5kIGBfLnN1bUJ5YCB3aXRob3V0IHN1cHBvcnQgZm9yXG4gICAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHN1bS5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VTdW0oYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgdmFyIHJlc3VsdCxcbiAgICAgICAgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIHZhciBjdXJyZW50ID0gaXRlcmF0ZWUoYXJyYXlbaW5kZXhdKTtcbiAgICAgIGlmIChjdXJyZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmVzdWx0ID0gcmVzdWx0ID09PSB1bmRlZmluZWQgPyBjdXJyZW50IDogKHJlc3VsdCArIGN1cnJlbnQpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnRpbWVzYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHNcbiAgICogb3IgbWF4IGFycmF5IGxlbmd0aCBjaGVja3MuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgdGltZXMgdG8gaW52b2tlIGBpdGVyYXRlZWAuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcmVzdWx0cy5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VUaW1lcyhuLCBpdGVyYXRlZSkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICByZXN1bHQgPSBBcnJheShuKTtcblxuICAgIHdoaWxlICgrK2luZGV4IDwgbikge1xuICAgICAgcmVzdWx0W2luZGV4XSA9IGl0ZXJhdGVlKGluZGV4KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy50b1BhaXJzYCBhbmQgYF8udG9QYWlyc0luYCB3aGljaCBjcmVhdGVzIGFuIGFycmF5XG4gICAqIG9mIGtleS12YWx1ZSBwYWlycyBmb3IgYG9iamVjdGAgY29ycmVzcG9uZGluZyB0byB0aGUgcHJvcGVydHkgbmFtZXMgb2YgYHByb3BzYC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgbmFtZXMgdG8gZ2V0IHZhbHVlcyBmb3IuXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGtleS12YWx1ZSBwYWlycy5cbiAgICovXG4gIGZ1bmN0aW9uIGJhc2VUb1BhaXJzKG9iamVjdCwgcHJvcHMpIHtcbiAgICByZXR1cm4gYXJyYXlNYXAocHJvcHMsIGZ1bmN0aW9uKGtleSkge1xuICAgICAgcmV0dXJuIFtrZXksIG9iamVjdFtrZXldXTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy51bmFyeWAgd2l0aG91dCBzdXBwb3J0IGZvciBzdG9yaW5nIG1ldGFkYXRhLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjYXAgYXJndW1lbnRzIGZvci5cbiAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY2FwcGVkIGZ1bmN0aW9uLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVVuYXJ5KGZ1bmMpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiBmdW5jKHZhbHVlKTtcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnZhbHVlc2AgYW5kIGBfLnZhbHVlc0luYCB3aGljaCBjcmVhdGVzIGFuXG4gICAqIGFycmF5IG9mIGBvYmplY3RgIHByb3BlcnR5IHZhbHVlcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBwcm9wZXJ0eSBuYW1lc1xuICAgKiBvZiBgcHJvcHNgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAqIEBwYXJhbSB7QXJyYXl9IHByb3BzIFRoZSBwcm9wZXJ0eSBuYW1lcyB0byBnZXQgdmFsdWVzIGZvci5cbiAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgdmFsdWVzLlxuICAgKi9cbiAgZnVuY3Rpb24gYmFzZVZhbHVlcyhvYmplY3QsIHByb3BzKSB7XG4gICAgcmV0dXJuIGFycmF5TWFwKHByb3BzLCBmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBvYmplY3Rba2V5XTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgYSBgY2FjaGVgIHZhbHVlIGZvciBga2V5YCBleGlzdHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjYWNoZSBUaGUgY2FjaGUgdG8gcXVlcnkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBjYWNoZUhhcyhjYWNoZSwga2V5KSB7XG4gICAgcmV0dXJuIGNhY2hlLmhhcyhrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYnkgYF8udHJpbWAgYW5kIGBfLnRyaW1TdGFydGAgdG8gZ2V0IHRoZSBpbmRleCBvZiB0aGUgZmlyc3Qgc3RyaW5nIHN5bWJvbFxuICAgKiB0aGF0IGlzIG5vdCBmb3VuZCBpbiB0aGUgY2hhcmFjdGVyIHN5bWJvbHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IHN0clN5bWJvbHMgVGhlIHN0cmluZyBzeW1ib2xzIHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7QXJyYXl9IGNoclN5bWJvbHMgVGhlIGNoYXJhY3RlciBzeW1ib2xzIHRvIGZpbmQuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmaXJzdCB1bm1hdGNoZWQgc3RyaW5nIHN5bWJvbC5cbiAgICovXG4gIGZ1bmN0aW9uIGNoYXJzU3RhcnRJbmRleChzdHJTeW1ib2xzLCBjaHJTeW1ib2xzKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IHN0clN5bWJvbHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGggJiYgYmFzZUluZGV4T2YoY2hyU3ltYm9scywgc3RyU3ltYm9sc1tpbmRleF0sIDApID4gLTEpIHt9XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYnkgYF8udHJpbWAgYW5kIGBfLnRyaW1FbmRgIHRvIGdldCB0aGUgaW5kZXggb2YgdGhlIGxhc3Qgc3RyaW5nIHN5bWJvbFxuICAgKiB0aGF0IGlzIG5vdCBmb3VuZCBpbiB0aGUgY2hhcmFjdGVyIHN5bWJvbHMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IHN0clN5bWJvbHMgVGhlIHN0cmluZyBzeW1ib2xzIHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7QXJyYXl9IGNoclN5bWJvbHMgVGhlIGNoYXJhY3RlciBzeW1ib2xzIHRvIGZpbmQuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBsYXN0IHVubWF0Y2hlZCBzdHJpbmcgc3ltYm9sLlxuICAgKi9cbiAgZnVuY3Rpb24gY2hhcnNFbmRJbmRleChzdHJTeW1ib2xzLCBjaHJTeW1ib2xzKSB7XG4gICAgdmFyIGluZGV4ID0gc3RyU3ltYm9scy5sZW5ndGg7XG5cbiAgICB3aGlsZSAoaW5kZXgtLSAmJiBiYXNlSW5kZXhPZihjaHJTeW1ib2xzLCBzdHJTeW1ib2xzW2luZGV4XSwgMCkgPiAtMSkge31cbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGBwbGFjZWhvbGRlcmAgb2NjdXJyZW5jZXMgaW4gYGFycmF5YC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAqIEBwYXJhbSB7Kn0gcGxhY2Vob2xkZXIgVGhlIHBsYWNlaG9sZGVyIHRvIHNlYXJjaCBmb3IuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHBsYWNlaG9sZGVyIGNvdW50LlxuICAgKi9cbiAgZnVuY3Rpb24gY291bnRIb2xkZXJzKGFycmF5LCBwbGFjZWhvbGRlcikge1xuICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgIHJlc3VsdCA9IDA7XG5cbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIGlmIChhcnJheVtsZW5ndGhdID09PSBwbGFjZWhvbGRlcikge1xuICAgICAgICArK3Jlc3VsdDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2VkIGJ5IGBfLmRlYnVycmAgdG8gY29udmVydCBMYXRpbi0xIFN1cHBsZW1lbnQgYW5kIExhdGluIEV4dGVuZGVkLUFcbiAgICogbGV0dGVycyB0byBiYXNpYyBMYXRpbiBsZXR0ZXJzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gbGV0dGVyIFRoZSBtYXRjaGVkIGxldHRlciB0byBkZWJ1cnIuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGRlYnVycmVkIGxldHRlci5cbiAgICovXG4gIHZhciBkZWJ1cnJMZXR0ZXIgPSBiYXNlUHJvcGVydHlPZihkZWJ1cnJlZExldHRlcnMpO1xuXG4gIC8qKlxuICAgKiBVc2VkIGJ5IGBfLmVzY2FwZWAgdG8gY29udmVydCBjaGFyYWN0ZXJzIHRvIEhUTUwgZW50aXRpZXMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjaHIgVGhlIG1hdGNoZWQgY2hhcmFjdGVyIHRvIGVzY2FwZS5cbiAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgZXNjYXBlZCBjaGFyYWN0ZXIuXG4gICAqL1xuICB2YXIgZXNjYXBlSHRtbENoYXIgPSBiYXNlUHJvcGVydHlPZihodG1sRXNjYXBlcyk7XG5cbiAgLyoqXG4gICAqIFVzZWQgYnkgYF8udGVtcGxhdGVgIHRvIGVzY2FwZSBjaGFyYWN0ZXJzIGZvciBpbmNsdXNpb24gaW4gY29tcGlsZWQgc3RyaW5nIGxpdGVyYWxzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gY2hyIFRoZSBtYXRjaGVkIGNoYXJhY3RlciB0byBlc2NhcGUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGVzY2FwZWQgY2hhcmFjdGVyLlxuICAgKi9cbiAgZnVuY3Rpb24gZXNjYXBlU3RyaW5nQ2hhcihjaHIpIHtcbiAgICByZXR1cm4gJ1xcXFwnICsgc3RyaW5nRXNjYXBlc1tjaHJdO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIHZhbHVlIGF0IGBrZXlgIG9mIGBvYmplY3RgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZS5cbiAgICovXG4gIGZ1bmN0aW9uIGdldFZhbHVlKG9iamVjdCwga2V5KSB7XG4gICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0W2tleV07XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGBzdHJpbmdgIGNvbnRhaW5zIFVuaWNvZGUgc3ltYm9scy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhIHN5bWJvbCBpcyBmb3VuZCwgZWxzZSBgZmFsc2VgLlxuICAgKi9cbiAgZnVuY3Rpb24gaGFzVW5pY29kZShzdHJpbmcpIHtcbiAgICByZXR1cm4gcmVIYXNVbmljb2RlLnRlc3Qoc3RyaW5nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgYHN0cmluZ2AgY29udGFpbnMgYSB3b3JkIGNvbXBvc2VkIG9mIFVuaWNvZGUgc3ltYm9scy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhIHdvcmQgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAgICovXG4gIGZ1bmN0aW9uIGhhc1VuaWNvZGVXb3JkKHN0cmluZykge1xuICAgIHJldHVybiByZUhhc1VuaWNvZGVXb3JkLnRlc3Qoc3RyaW5nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBgaXRlcmF0b3JgIHRvIGFuIGFycmF5LlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gaXRlcmF0b3IgVGhlIGl0ZXJhdG9yIHRvIGNvbnZlcnQuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY29udmVydGVkIGFycmF5LlxuICAgKi9cbiAgZnVuY3Rpb24gaXRlcmF0b3JUb0FycmF5KGl0ZXJhdG9yKSB7XG4gICAgdmFyIGRhdGEsXG4gICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgd2hpbGUgKCEoZGF0YSA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZSkge1xuICAgICAgcmVzdWx0LnB1c2goZGF0YS52YWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYG1hcGAgdG8gaXRzIGtleS12YWx1ZSBwYWlycy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtPYmplY3R9IG1hcCBUaGUgbWFwIHRvIGNvbnZlcnQuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUga2V5LXZhbHVlIHBhaXJzLlxuICAgKi9cbiAgZnVuY3Rpb24gbWFwVG9BcnJheShtYXApIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgcmVzdWx0ID0gQXJyYXkobWFwLnNpemUpO1xuXG4gICAgbWFwLmZvckVhY2goZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgcmVzdWx0WysraW5kZXhdID0gW2tleSwgdmFsdWVdO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHVuYXJ5IGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCBpdHMgYXJndW1lbnQgdHJhbnNmb3JtZWQuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHRyYW5zZm9ybSBUaGUgYXJndW1lbnQgdHJhbnNmb3JtLlxuICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICovXG4gIGZ1bmN0aW9uIG92ZXJBcmcoZnVuYywgdHJhbnNmb3JtKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGFyZykge1xuICAgICAgcmV0dXJuIGZ1bmModHJhbnNmb3JtKGFyZykpO1xuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmVwbGFjZXMgYWxsIGBwbGFjZWhvbGRlcmAgZWxlbWVudHMgaW4gYGFycmF5YCB3aXRoIGFuIGludGVybmFsIHBsYWNlaG9sZGVyXG4gICAqIGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIHRoZWlyIGluZGV4ZXMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAqIEBwYXJhbSB7Kn0gcGxhY2Vob2xkZXIgVGhlIHBsYWNlaG9sZGVyIHRvIHJlcGxhY2UuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAqL1xuICBmdW5jdGlvbiByZXBsYWNlSG9sZGVycyhhcnJheSwgcGxhY2Vob2xkZXIpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICByZXNJbmRleCA9IDAsXG4gICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICAgIGlmICh2YWx1ZSA9PT0gcGxhY2Vob2xkZXIgfHwgdmFsdWUgPT09IFBMQUNFSE9MREVSKSB7XG4gICAgICAgIGFycmF5W2luZGV4XSA9IFBMQUNFSE9MREVSO1xuICAgICAgICByZXN1bHRbcmVzSW5kZXgrK10gPSBpbmRleDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBgc2V0YCB0byBhbiBhcnJheSBvZiBpdHMgdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gc2V0IFRoZSBzZXQgdG8gY29udmVydC5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSB2YWx1ZXMuXG4gICAqL1xuICBmdW5jdGlvbiBzZXRUb0FycmF5KHNldCkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICByZXN1bHQgPSBBcnJheShzZXQuc2l6ZSk7XG5cbiAgICBzZXQuZm9yRWFjaChmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmVzdWx0WysraW5kZXhdID0gdmFsdWU7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBgc2V0YCB0byBpdHMgdmFsdWUtdmFsdWUgcGFpcnMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBzZXQgVGhlIHNldCB0byBjb252ZXJ0LlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHZhbHVlLXZhbHVlIHBhaXJzLlxuICAgKi9cbiAgZnVuY3Rpb24gc2V0VG9QYWlycyhzZXQpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgcmVzdWx0ID0gQXJyYXkoc2V0LnNpemUpO1xuXG4gICAgc2V0LmZvckVhY2goZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJlc3VsdFsrK2luZGV4XSA9IFt2YWx1ZSwgdmFsdWVdO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmluZGV4T2ZgIHdoaWNoIHBlcmZvcm1zIHN0cmljdCBlcXVhbGl0eVxuICAgKiBjb21wYXJpc29ucyBvZiB2YWx1ZXMsIGkuZS4gYD09PWAuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICAgKiBAcGFyYW0ge251bWJlcn0gZnJvbUluZGV4IFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAgICovXG4gIGZ1bmN0aW9uIHN0cmljdEluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXgpIHtcbiAgICB2YXIgaW5kZXggPSBmcm9tSW5kZXggLSAxLFxuICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgaWYgKGFycmF5W2luZGV4XSA9PT0gdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICAvKipcbiAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmxhc3RJbmRleE9mYCB3aGljaCBwZXJmb3JtcyBzdHJpY3QgZXF1YWxpdHlcbiAgICogY29tcGFyaXNvbnMgb2YgdmFsdWVzLCBpLmUuIGA9PT1gLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAqL1xuICBmdW5jdGlvbiBzdHJpY3RMYXN0SW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICAgIHZhciBpbmRleCA9IGZyb21JbmRleCArIDE7XG4gICAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICAgIGlmIChhcnJheVtpbmRleF0gPT09IHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBpbmRleDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIG51bWJlciBvZiBzeW1ib2xzIGluIGBzdHJpbmdgLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gaW5zcGVjdC5cbiAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc3RyaW5nIHNpemUuXG4gICAqL1xuICBmdW5jdGlvbiBzdHJpbmdTaXplKHN0cmluZykge1xuICAgIHJldHVybiBoYXNVbmljb2RlKHN0cmluZylcbiAgICAgID8gdW5pY29kZVNpemUoc3RyaW5nKVxuICAgICAgOiBhc2NpaVNpemUoc3RyaW5nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBgc3RyaW5nYCB0byBhbiBhcnJheS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY29udmVydGVkIGFycmF5LlxuICAgKi9cbiAgZnVuY3Rpb24gc3RyaW5nVG9BcnJheShzdHJpbmcpIHtcbiAgICByZXR1cm4gaGFzVW5pY29kZShzdHJpbmcpXG4gICAgICA/IHVuaWNvZGVUb0FycmF5KHN0cmluZylcbiAgICAgIDogYXNjaWlUb0FycmF5KHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogVXNlZCBieSBgXy51bmVzY2FwZWAgdG8gY29udmVydCBIVE1MIGVudGl0aWVzIHRvIGNoYXJhY3RlcnMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjaHIgVGhlIG1hdGNoZWQgY2hhcmFjdGVyIHRvIHVuZXNjYXBlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSB1bmVzY2FwZWQgY2hhcmFjdGVyLlxuICAgKi9cbiAgdmFyIHVuZXNjYXBlSHRtbENoYXIgPSBiYXNlUHJvcGVydHlPZihodG1sVW5lc2NhcGVzKTtcblxuICAvKipcbiAgICogR2V0cyB0aGUgc2l6ZSBvZiBhIFVuaWNvZGUgYHN0cmluZ2AuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyBpbnNwZWN0LlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzdHJpbmcgc2l6ZS5cbiAgICovXG4gIGZ1bmN0aW9uIHVuaWNvZGVTaXplKHN0cmluZykge1xuICAgIHZhciByZXN1bHQgPSByZVVuaWNvZGUubGFzdEluZGV4ID0gMDtcbiAgICB3aGlsZSAocmVVbmljb2RlLnRlc3Qoc3RyaW5nKSkge1xuICAgICAgKytyZXN1bHQ7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYSBVbmljb2RlIGBzdHJpbmdgIHRvIGFuIGFycmF5LlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgYXJyYXkuXG4gICAqL1xuICBmdW5jdGlvbiB1bmljb2RlVG9BcnJheShzdHJpbmcpIHtcbiAgICByZXR1cm4gc3RyaW5nLm1hdGNoKHJlVW5pY29kZSkgfHwgW107XG4gIH1cblxuICAvKipcbiAgICogU3BsaXRzIGEgVW5pY29kZSBgc3RyaW5nYCBpbnRvIGFuIGFycmF5IG9mIGl0cyB3b3Jkcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IFRoZSBzdHJpbmcgdG8gaW5zcGVjdC5cbiAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSB3b3JkcyBvZiBgc3RyaW5nYC5cbiAgICovXG4gIGZ1bmN0aW9uIHVuaWNvZGVXb3JkcyhzdHJpbmcpIHtcbiAgICByZXR1cm4gc3RyaW5nLm1hdGNoKHJlVW5pY29kZVdvcmQpIHx8IFtdO1xuICB9XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBwcmlzdGluZSBgbG9kYXNoYCBmdW5jdGlvbiB1c2luZyB0aGUgYGNvbnRleHRgIG9iamVjdC5cbiAgICpcbiAgICogQHN0YXRpY1xuICAgKiBAbWVtYmVyT2YgX1xuICAgKiBAc2luY2UgMS4xLjBcbiAgICogQGNhdGVnb3J5IFV0aWxcbiAgICogQHBhcmFtIHtPYmplY3R9IFtjb250ZXh0PXJvb3RdIFRoZSBjb250ZXh0IG9iamVjdC5cbiAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGEgbmV3IGBsb2Rhc2hgIGZ1bmN0aW9uLlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiBfLm1peGluKHsgJ2Zvbyc6IF8uY29uc3RhbnQoJ2ZvbycpIH0pO1xuICAgKlxuICAgKiB2YXIgbG9kYXNoID0gXy5ydW5JbkNvbnRleHQoKTtcbiAgICogbG9kYXNoLm1peGluKHsgJ2Jhcic6IGxvZGFzaC5jb25zdGFudCgnYmFyJykgfSk7XG4gICAqXG4gICAqIF8uaXNGdW5jdGlvbihfLmZvbyk7XG4gICAqIC8vID0+IHRydWVcbiAgICogXy5pc0Z1bmN0aW9uKF8uYmFyKTtcbiAgICogLy8gPT4gZmFsc2VcbiAgICpcbiAgICogbG9kYXNoLmlzRnVuY3Rpb24obG9kYXNoLmZvbyk7XG4gICAqIC8vID0+IGZhbHNlXG4gICAqIGxvZGFzaC5pc0Z1bmN0aW9uKGxvZGFzaC5iYXIpO1xuICAgKiAvLyA9PiB0cnVlXG4gICAqXG4gICAqIC8vIENyZWF0ZSBhIHN1cGVkLXVwIGBkZWZlcmAgaW4gTm9kZS5qcy5cbiAgICogdmFyIGRlZmVyID0gXy5ydW5JbkNvbnRleHQoeyAnc2V0VGltZW91dCc6IHNldEltbWVkaWF0ZSB9KS5kZWZlcjtcbiAgICovXG4gIHZhciBydW5JbkNvbnRleHQgPSAoZnVuY3Rpb24gcnVuSW5Db250ZXh0KGNvbnRleHQpIHtcbiAgICBjb250ZXh0ID0gY29udGV4dCA9PSBudWxsID8gcm9vdCA6IF8uZGVmYXVsdHMocm9vdC5PYmplY3QoKSwgY29udGV4dCwgXy5waWNrKHJvb3QsIGNvbnRleHRQcm9wcykpO1xuXG4gICAgLyoqIEJ1aWx0LWluIGNvbnN0cnVjdG9yIHJlZmVyZW5jZXMuICovXG4gICAgdmFyIEFycmF5ID0gY29udGV4dC5BcnJheSxcbiAgICAgICAgRGF0ZSA9IGNvbnRleHQuRGF0ZSxcbiAgICAgICAgRXJyb3IgPSBjb250ZXh0LkVycm9yLFxuICAgICAgICBGdW5jdGlvbiA9IGNvbnRleHQuRnVuY3Rpb24sXG4gICAgICAgIE1hdGggPSBjb250ZXh0Lk1hdGgsXG4gICAgICAgIE9iamVjdCA9IGNvbnRleHQuT2JqZWN0LFxuICAgICAgICBSZWdFeHAgPSBjb250ZXh0LlJlZ0V4cCxcbiAgICAgICAgU3RyaW5nID0gY29udGV4dC5TdHJpbmcsXG4gICAgICAgIFR5cGVFcnJvciA9IGNvbnRleHQuVHlwZUVycm9yO1xuXG4gICAgLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xuICAgIHZhciBhcnJheVByb3RvID0gQXJyYXkucHJvdG90eXBlLFxuICAgICAgICBmdW5jUHJvdG8gPSBGdW5jdGlvbi5wcm90b3R5cGUsXG4gICAgICAgIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuICAgIC8qKiBVc2VkIHRvIGRldGVjdCBvdmVycmVhY2hpbmcgY29yZS1qcyBzaGltcy4gKi9cbiAgICB2YXIgY29yZUpzRGF0YSA9IGNvbnRleHRbJ19fY29yZS1qc19zaGFyZWRfXyddO1xuXG4gICAgLyoqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgZGVjb21waWxlZCBzb3VyY2Ugb2YgZnVuY3Rpb25zLiAqL1xuICAgIHZhciBmdW5jVG9TdHJpbmcgPSBmdW5jUHJvdG8udG9TdHJpbmc7XG5cbiAgICAvKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbiAgICB2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuICAgIC8qKiBVc2VkIHRvIGdlbmVyYXRlIHVuaXF1ZSBJRHMuICovXG4gICAgdmFyIGlkQ291bnRlciA9IDA7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3QgbWV0aG9kcyBtYXNxdWVyYWRpbmcgYXMgbmF0aXZlLiAqL1xuICAgIHZhciBtYXNrU3JjS2V5ID0gKGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHVpZCA9IC9bXi5dKyQvLmV4ZWMoY29yZUpzRGF0YSAmJiBjb3JlSnNEYXRhLmtleXMgJiYgY29yZUpzRGF0YS5rZXlzLklFX1BST1RPIHx8ICcnKTtcbiAgICAgIHJldHVybiB1aWQgPyAoJ1N5bWJvbChzcmMpXzEuJyArIHVpZCkgOiAnJztcbiAgICB9KCkpO1xuXG4gICAgLyoqXG4gICAgICogVXNlZCB0byByZXNvbHZlIHRoZVxuICAgICAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICAgICAqIG9mIHZhbHVlcy5cbiAgICAgKi9cbiAgICB2YXIgbmF0aXZlT2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuICAgIC8qKiBVc2VkIHRvIGluZmVyIHRoZSBgT2JqZWN0YCBjb25zdHJ1Y3Rvci4gKi9cbiAgICB2YXIgb2JqZWN0Q3RvclN0cmluZyA9IGZ1bmNUb1N0cmluZy5jYWxsKE9iamVjdCk7XG5cbiAgICAvKiogVXNlZCB0byByZXN0b3JlIHRoZSBvcmlnaW5hbCBgX2AgcmVmZXJlbmNlIGluIGBfLm5vQ29uZmxpY3RgLiAqL1xuICAgIHZhciBvbGREYXNoID0gcm9vdC5fO1xuXG4gICAgLyoqIFVzZWQgdG8gZGV0ZWN0IGlmIGEgbWV0aG9kIGlzIG5hdGl2ZS4gKi9cbiAgICB2YXIgcmVJc05hdGl2ZSA9IFJlZ0V4cCgnXicgK1xuICAgICAgZnVuY1RvU3RyaW5nLmNhbGwoaGFzT3duUHJvcGVydHkpLnJlcGxhY2UocmVSZWdFeHBDaGFyLCAnXFxcXCQmJylcbiAgICAgIC5yZXBsYWNlKC9oYXNPd25Qcm9wZXJ0eXwoZnVuY3Rpb24pLio/KD89XFxcXFxcKCl8IGZvciAuKz8oPz1cXFxcXFxdKS9nLCAnJDEuKj8nKSArICckJ1xuICAgICk7XG5cbiAgICAvKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbiAgICB2YXIgQnVmZmVyID0gbW9kdWxlRXhwb3J0cyA/IGNvbnRleHQuQnVmZmVyIDogdW5kZWZpbmVkLFxuICAgICAgICBTeW1ib2wgPSBjb250ZXh0LlN5bWJvbCxcbiAgICAgICAgVWludDhBcnJheSA9IGNvbnRleHQuVWludDhBcnJheSxcbiAgICAgICAgYWxsb2NVbnNhZmUgPSBCdWZmZXIgPyBCdWZmZXIuYWxsb2NVbnNhZmUgOiB1bmRlZmluZWQsXG4gICAgICAgIGdldFByb3RvdHlwZSA9IG92ZXJBcmcoT2JqZWN0LmdldFByb3RvdHlwZU9mLCBPYmplY3QpLFxuICAgICAgICBvYmplY3RDcmVhdGUgPSBPYmplY3QuY3JlYXRlLFxuICAgICAgICBwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IG9iamVjdFByb3RvLnByb3BlcnR5SXNFbnVtZXJhYmxlLFxuICAgICAgICBzcGxpY2UgPSBhcnJheVByb3RvLnNwbGljZSxcbiAgICAgICAgc3ByZWFkYWJsZVN5bWJvbCA9IFN5bWJvbCA/IFN5bWJvbC5pc0NvbmNhdFNwcmVhZGFibGUgOiB1bmRlZmluZWQsXG4gICAgICAgIHN5bUl0ZXJhdG9yID0gU3ltYm9sID8gU3ltYm9sLml0ZXJhdG9yIDogdW5kZWZpbmVkLFxuICAgICAgICBzeW1Ub1N0cmluZ1RhZyA9IFN5bWJvbCA/IFN5bWJvbC50b1N0cmluZ1RhZyA6IHVuZGVmaW5lZDtcblxuICAgIHZhciBkZWZpbmVQcm9wZXJ0eSA9IChmdW5jdGlvbigpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHZhciBmdW5jID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2RlZmluZVByb3BlcnR5Jyk7XG4gICAgICAgIGZ1bmMoe30sICcnLCB7fSk7XG4gICAgICAgIHJldHVybiBmdW5jO1xuICAgICAgfSBjYXRjaCAoZSkge31cbiAgICB9KCkpO1xuXG4gICAgLyoqIE1vY2tlZCBidWlsdC1pbnMuICovXG4gICAgdmFyIGN0eENsZWFyVGltZW91dCA9IGNvbnRleHQuY2xlYXJUaW1lb3V0ICE9PSByb290LmNsZWFyVGltZW91dCAmJiBjb250ZXh0LmNsZWFyVGltZW91dCxcbiAgICAgICAgY3R4Tm93ID0gRGF0ZSAmJiBEYXRlLm5vdyAhPT0gcm9vdC5EYXRlLm5vdyAmJiBEYXRlLm5vdyxcbiAgICAgICAgY3R4U2V0VGltZW91dCA9IGNvbnRleHQuc2V0VGltZW91dCAhPT0gcm9vdC5zZXRUaW1lb3V0ICYmIGNvbnRleHQuc2V0VGltZW91dDtcblxuICAgIC8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbiAgICB2YXIgbmF0aXZlQ2VpbCA9IE1hdGguY2VpbCxcbiAgICAgICAgbmF0aXZlRmxvb3IgPSBNYXRoLmZsb29yLFxuICAgICAgICBuYXRpdmVHZXRTeW1ib2xzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyxcbiAgICAgICAgbmF0aXZlSXNCdWZmZXIgPSBCdWZmZXIgPyBCdWZmZXIuaXNCdWZmZXIgOiB1bmRlZmluZWQsXG4gICAgICAgIG5hdGl2ZUlzRmluaXRlID0gY29udGV4dC5pc0Zpbml0ZSxcbiAgICAgICAgbmF0aXZlSm9pbiA9IGFycmF5UHJvdG8uam9pbixcbiAgICAgICAgbmF0aXZlS2V5cyA9IG92ZXJBcmcoT2JqZWN0LmtleXMsIE9iamVjdCksXG4gICAgICAgIG5hdGl2ZU1heCA9IE1hdGgubWF4LFxuICAgICAgICBuYXRpdmVNaW4gPSBNYXRoLm1pbixcbiAgICAgICAgbmF0aXZlTm93ID0gRGF0ZS5ub3csXG4gICAgICAgIG5hdGl2ZVBhcnNlSW50ID0gY29udGV4dC5wYXJzZUludCxcbiAgICAgICAgbmF0aXZlUmFuZG9tID0gTWF0aC5yYW5kb20sXG4gICAgICAgIG5hdGl2ZVJldmVyc2UgPSBhcnJheVByb3RvLnJldmVyc2U7XG5cbiAgICAvKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovXG4gICAgdmFyIERhdGFWaWV3ID0gZ2V0TmF0aXZlKGNvbnRleHQsICdEYXRhVmlldycpLFxuICAgICAgICBNYXAgPSBnZXROYXRpdmUoY29udGV4dCwgJ01hcCcpLFxuICAgICAgICBQcm9taXNlID0gZ2V0TmF0aXZlKGNvbnRleHQsICdQcm9taXNlJyksXG4gICAgICAgIFNldCA9IGdldE5hdGl2ZShjb250ZXh0LCAnU2V0JyksXG4gICAgICAgIFdlYWtNYXAgPSBnZXROYXRpdmUoY29udGV4dCwgJ1dlYWtNYXAnKSxcbiAgICAgICAgbmF0aXZlQ3JlYXRlID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2NyZWF0ZScpO1xuXG4gICAgLyoqIFVzZWQgdG8gc3RvcmUgZnVuY3Rpb24gbWV0YWRhdGEuICovXG4gICAgdmFyIG1ldGFNYXAgPSBXZWFrTWFwICYmIG5ldyBXZWFrTWFwO1xuXG4gICAgLyoqIFVzZWQgdG8gbG9va3VwIHVubWluaWZpZWQgZnVuY3Rpb24gbmFtZXMuICovXG4gICAgdmFyIHJlYWxOYW1lcyA9IHt9O1xuXG4gICAgLyoqIFVzZWQgdG8gZGV0ZWN0IG1hcHMsIHNldHMsIGFuZCB3ZWFrbWFwcy4gKi9cbiAgICB2YXIgZGF0YVZpZXdDdG9yU3RyaW5nID0gdG9Tb3VyY2UoRGF0YVZpZXcpLFxuICAgICAgICBtYXBDdG9yU3RyaW5nID0gdG9Tb3VyY2UoTWFwKSxcbiAgICAgICAgcHJvbWlzZUN0b3JTdHJpbmcgPSB0b1NvdXJjZShQcm9taXNlKSxcbiAgICAgICAgc2V0Q3RvclN0cmluZyA9IHRvU291cmNlKFNldCksXG4gICAgICAgIHdlYWtNYXBDdG9yU3RyaW5nID0gdG9Tb3VyY2UoV2Vha01hcCk7XG5cbiAgICAvKiogVXNlZCB0byBjb252ZXJ0IHN5bWJvbHMgdG8gcHJpbWl0aXZlcyBhbmQgc3RyaW5ncy4gKi9cbiAgICB2YXIgc3ltYm9sUHJvdG8gPSBTeW1ib2wgPyBTeW1ib2wucHJvdG90eXBlIDogdW5kZWZpbmVkLFxuICAgICAgICBzeW1ib2xWYWx1ZU9mID0gc3ltYm9sUHJvdG8gPyBzeW1ib2xQcm90by52YWx1ZU9mIDogdW5kZWZpbmVkLFxuICAgICAgICBzeW1ib2xUb1N0cmluZyA9IHN5bWJvbFByb3RvID8gc3ltYm9sUHJvdG8udG9TdHJpbmcgOiB1bmRlZmluZWQ7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYGxvZGFzaGAgb2JqZWN0IHdoaWNoIHdyYXBzIGB2YWx1ZWAgdG8gZW5hYmxlIGltcGxpY2l0IG1ldGhvZFxuICAgICAqIGNoYWluIHNlcXVlbmNlcy4gTWV0aG9kcyB0aGF0IG9wZXJhdGUgb24gYW5kIHJldHVybiBhcnJheXMsIGNvbGxlY3Rpb25zLFxuICAgICAqIGFuZCBmdW5jdGlvbnMgY2FuIGJlIGNoYWluZWQgdG9nZXRoZXIuIE1ldGhvZHMgdGhhdCByZXRyaWV2ZSBhIHNpbmdsZSB2YWx1ZVxuICAgICAqIG9yIG1heSByZXR1cm4gYSBwcmltaXRpdmUgdmFsdWUgd2lsbCBhdXRvbWF0aWNhbGx5IGVuZCB0aGUgY2hhaW4gc2VxdWVuY2VcbiAgICAgKiBhbmQgcmV0dXJuIHRoZSB1bndyYXBwZWQgdmFsdWUuIE90aGVyd2lzZSwgdGhlIHZhbHVlIG11c3QgYmUgdW53cmFwcGVkXG4gICAgICogd2l0aCBgXyN2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBFeHBsaWNpdCBjaGFpbiBzZXF1ZW5jZXMsIHdoaWNoIG11c3QgYmUgdW53cmFwcGVkIHdpdGggYF8jdmFsdWVgLCBtYXkgYmVcbiAgICAgKiBlbmFibGVkIHVzaW5nIGBfLmNoYWluYC5cbiAgICAgKlxuICAgICAqIFRoZSBleGVjdXRpb24gb2YgY2hhaW5lZCBtZXRob2RzIGlzIGxhenksIHRoYXQgaXMsIGl0J3MgZGVmZXJyZWQgdW50aWxcbiAgICAgKiBgXyN2YWx1ZWAgaXMgaW1wbGljaXRseSBvciBleHBsaWNpdGx5IGNhbGxlZC5cbiAgICAgKlxuICAgICAqIExhenkgZXZhbHVhdGlvbiBhbGxvd3Mgc2V2ZXJhbCBtZXRob2RzIHRvIHN1cHBvcnQgc2hvcnRjdXQgZnVzaW9uLlxuICAgICAqIFNob3J0Y3V0IGZ1c2lvbiBpcyBhbiBvcHRpbWl6YXRpb24gdG8gbWVyZ2UgaXRlcmF0ZWUgY2FsbHM7IHRoaXMgYXZvaWRzXG4gICAgICogdGhlIGNyZWF0aW9uIG9mIGludGVybWVkaWF0ZSBhcnJheXMgYW5kIGNhbiBncmVhdGx5IHJlZHVjZSB0aGUgbnVtYmVyIG9mXG4gICAgICogaXRlcmF0ZWUgZXhlY3V0aW9ucy4gU2VjdGlvbnMgb2YgYSBjaGFpbiBzZXF1ZW5jZSBxdWFsaWZ5IGZvciBzaG9ydGN1dFxuICAgICAqIGZ1c2lvbiBpZiB0aGUgc2VjdGlvbiBpcyBhcHBsaWVkIHRvIGFuIGFycmF5IGFuZCBpdGVyYXRlZXMgYWNjZXB0IG9ubHlcbiAgICAgKiBvbmUgYXJndW1lbnQuIFRoZSBoZXVyaXN0aWMgZm9yIHdoZXRoZXIgYSBzZWN0aW9uIHF1YWxpZmllcyBmb3Igc2hvcnRjdXRcbiAgICAgKiBmdXNpb24gaXMgc3ViamVjdCB0byBjaGFuZ2UuXG4gICAgICpcbiAgICAgKiBDaGFpbmluZyBpcyBzdXBwb3J0ZWQgaW4gY3VzdG9tIGJ1aWxkcyBhcyBsb25nIGFzIHRoZSBgXyN2YWx1ZWAgbWV0aG9kIGlzXG4gICAgICogZGlyZWN0bHkgb3IgaW5kaXJlY3RseSBpbmNsdWRlZCBpbiB0aGUgYnVpbGQuXG4gICAgICpcbiAgICAgKiBJbiBhZGRpdGlvbiB0byBsb2Rhc2ggbWV0aG9kcywgd3JhcHBlcnMgaGF2ZSBgQXJyYXlgIGFuZCBgU3RyaW5nYCBtZXRob2RzLlxuICAgICAqXG4gICAgICogVGhlIHdyYXBwZXIgYEFycmF5YCBtZXRob2RzIGFyZTpcbiAgICAgKiBgY29uY2F0YCwgYGpvaW5gLCBgcG9wYCwgYHB1c2hgLCBgc2hpZnRgLCBgc29ydGAsIGBzcGxpY2VgLCBhbmQgYHVuc2hpZnRgXG4gICAgICpcbiAgICAgKiBUaGUgd3JhcHBlciBgU3RyaW5nYCBtZXRob2RzIGFyZTpcbiAgICAgKiBgcmVwbGFjZWAgYW5kIGBzcGxpdGBcbiAgICAgKlxuICAgICAqIFRoZSB3cmFwcGVyIG1ldGhvZHMgdGhhdCBzdXBwb3J0IHNob3J0Y3V0IGZ1c2lvbiBhcmU6XG4gICAgICogYGF0YCwgYGNvbXBhY3RgLCBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZHJvcFdoaWxlYCwgYGZpbHRlcmAsIGBmaW5kYCxcbiAgICAgKiBgZmluZExhc3RgLCBgaGVhZGAsIGBpbml0aWFsYCwgYGxhc3RgLCBgbWFwYCwgYHJlamVjdGAsIGByZXZlcnNlYCwgYHNsaWNlYCxcbiAgICAgKiBgdGFpbGAsIGB0YWtlYCwgYHRha2VSaWdodGAsIGB0YWtlUmlnaHRXaGlsZWAsIGB0YWtlV2hpbGVgLCBhbmQgYHRvQXJyYXlgXG4gICAgICpcbiAgICAgKiBUaGUgY2hhaW5hYmxlIHdyYXBwZXIgbWV0aG9kcyBhcmU6XG4gICAgICogYGFmdGVyYCwgYGFyeWAsIGBhc3NpZ25gLCBgYXNzaWduSW5gLCBgYXNzaWduSW5XaXRoYCwgYGFzc2lnbldpdGhgLCBgYXRgLFxuICAgICAqIGBiZWZvcmVgLCBgYmluZGAsIGBiaW5kQWxsYCwgYGJpbmRLZXlgLCBgY2FzdEFycmF5YCwgYGNoYWluYCwgYGNodW5rYCxcbiAgICAgKiBgY29tbWl0YCwgYGNvbXBhY3RgLCBgY29uY2F0YCwgYGNvbmZvcm1zYCwgYGNvbnN0YW50YCwgYGNvdW50QnlgLCBgY3JlYXRlYCxcbiAgICAgKiBgY3VycnlgLCBgZGVib3VuY2VgLCBgZGVmYXVsdHNgLCBgZGVmYXVsdHNEZWVwYCwgYGRlZmVyYCwgYGRlbGF5YCxcbiAgICAgKiBgZGlmZmVyZW5jZWAsIGBkaWZmZXJlbmNlQnlgLCBgZGlmZmVyZW5jZVdpdGhgLCBgZHJvcGAsIGBkcm9wUmlnaHRgLFxuICAgICAqIGBkcm9wUmlnaHRXaGlsZWAsIGBkcm9wV2hpbGVgLCBgZXh0ZW5kYCwgYGV4dGVuZFdpdGhgLCBgZmlsbGAsIGBmaWx0ZXJgLFxuICAgICAqIGBmbGF0TWFwYCwgYGZsYXRNYXBEZWVwYCwgYGZsYXRNYXBEZXB0aGAsIGBmbGF0dGVuYCwgYGZsYXR0ZW5EZWVwYCxcbiAgICAgKiBgZmxhdHRlbkRlcHRoYCwgYGZsaXBgLCBgZmxvd2AsIGBmbG93UmlnaHRgLCBgZnJvbVBhaXJzYCwgYGZ1bmN0aW9uc2AsXG4gICAgICogYGZ1bmN0aW9uc0luYCwgYGdyb3VwQnlgLCBgaW5pdGlhbGAsIGBpbnRlcnNlY3Rpb25gLCBgaW50ZXJzZWN0aW9uQnlgLFxuICAgICAqIGBpbnRlcnNlY3Rpb25XaXRoYCwgYGludmVydGAsIGBpbnZlcnRCeWAsIGBpbnZva2VNYXBgLCBgaXRlcmF0ZWVgLCBga2V5QnlgLFxuICAgICAqIGBrZXlzYCwgYGtleXNJbmAsIGBtYXBgLCBgbWFwS2V5c2AsIGBtYXBWYWx1ZXNgLCBgbWF0Y2hlc2AsIGBtYXRjaGVzUHJvcGVydHlgLFxuICAgICAqIGBtZW1vaXplYCwgYG1lcmdlYCwgYG1lcmdlV2l0aGAsIGBtZXRob2RgLCBgbWV0aG9kT2ZgLCBgbWl4aW5gLCBgbmVnYXRlYCxcbiAgICAgKiBgbnRoQXJnYCwgYG9taXRgLCBgb21pdEJ5YCwgYG9uY2VgLCBgb3JkZXJCeWAsIGBvdmVyYCwgYG92ZXJBcmdzYCxcbiAgICAgKiBgb3ZlckV2ZXJ5YCwgYG92ZXJTb21lYCwgYHBhcnRpYWxgLCBgcGFydGlhbFJpZ2h0YCwgYHBhcnRpdGlvbmAsIGBwaWNrYCxcbiAgICAgKiBgcGlja0J5YCwgYHBsYW50YCwgYHByb3BlcnR5YCwgYHByb3BlcnR5T2ZgLCBgcHVsbGAsIGBwdWxsQWxsYCwgYHB1bGxBbGxCeWAsXG4gICAgICogYHB1bGxBbGxXaXRoYCwgYHB1bGxBdGAsIGBwdXNoYCwgYHJhbmdlYCwgYHJhbmdlUmlnaHRgLCBgcmVhcmdgLCBgcmVqZWN0YCxcbiAgICAgKiBgcmVtb3ZlYCwgYHJlc3RgLCBgcmV2ZXJzZWAsIGBzYW1wbGVTaXplYCwgYHNldGAsIGBzZXRXaXRoYCwgYHNodWZmbGVgLFxuICAgICAqIGBzbGljZWAsIGBzb3J0YCwgYHNvcnRCeWAsIGBzcGxpY2VgLCBgc3ByZWFkYCwgYHRhaWxgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLFxuICAgICAqIGB0YWtlUmlnaHRXaGlsZWAsIGB0YWtlV2hpbGVgLCBgdGFwYCwgYHRocm90dGxlYCwgYHRocnVgLCBgdG9BcnJheWAsXG4gICAgICogYHRvUGFpcnNgLCBgdG9QYWlyc0luYCwgYHRvUGF0aGAsIGB0b1BsYWluT2JqZWN0YCwgYHRyYW5zZm9ybWAsIGB1bmFyeWAsXG4gICAgICogYHVuaW9uYCwgYHVuaW9uQnlgLCBgdW5pb25XaXRoYCwgYHVuaXFgLCBgdW5pcUJ5YCwgYHVuaXFXaXRoYCwgYHVuc2V0YCxcbiAgICAgKiBgdW5zaGlmdGAsIGB1bnppcGAsIGB1bnppcFdpdGhgLCBgdXBkYXRlYCwgYHVwZGF0ZVdpdGhgLCBgdmFsdWVzYCxcbiAgICAgKiBgdmFsdWVzSW5gLCBgd2l0aG91dGAsIGB3cmFwYCwgYHhvcmAsIGB4b3JCeWAsIGB4b3JXaXRoYCwgYHppcGAsXG4gICAgICogYHppcE9iamVjdGAsIGB6aXBPYmplY3REZWVwYCwgYW5kIGB6aXBXaXRoYFxuICAgICAqXG4gICAgICogVGhlIHdyYXBwZXIgbWV0aG9kcyB0aGF0IGFyZSAqKm5vdCoqIGNoYWluYWJsZSBieSBkZWZhdWx0IGFyZTpcbiAgICAgKiBgYWRkYCwgYGF0dGVtcHRgLCBgY2FtZWxDYXNlYCwgYGNhcGl0YWxpemVgLCBgY2VpbGAsIGBjbGFtcGAsIGBjbG9uZWAsXG4gICAgICogYGNsb25lRGVlcGAsIGBjbG9uZURlZXBXaXRoYCwgYGNsb25lV2l0aGAsIGBjb25mb3Jtc1RvYCwgYGRlYnVycmAsXG4gICAgICogYGRlZmF1bHRUb2AsIGBkaXZpZGVgLCBgZWFjaGAsIGBlYWNoUmlnaHRgLCBgZW5kc1dpdGhgLCBgZXFgLCBgZXNjYXBlYCxcbiAgICAgKiBgZXNjYXBlUmVnRXhwYCwgYGV2ZXJ5YCwgYGZpbmRgLCBgZmluZEluZGV4YCwgYGZpbmRLZXlgLCBgZmluZExhc3RgLFxuICAgICAqIGBmaW5kTGFzdEluZGV4YCwgYGZpbmRMYXN0S2V5YCwgYGZpcnN0YCwgYGZsb29yYCwgYGZvckVhY2hgLCBgZm9yRWFjaFJpZ2h0YCxcbiAgICAgKiBgZm9ySW5gLCBgZm9ySW5SaWdodGAsIGBmb3JPd25gLCBgZm9yT3duUmlnaHRgLCBgZ2V0YCwgYGd0YCwgYGd0ZWAsIGBoYXNgLFxuICAgICAqIGBoYXNJbmAsIGBoZWFkYCwgYGlkZW50aXR5YCwgYGluY2x1ZGVzYCwgYGluZGV4T2ZgLCBgaW5SYW5nZWAsIGBpbnZva2VgLFxuICAgICAqIGBpc0FyZ3VtZW50c2AsIGBpc0FycmF5YCwgYGlzQXJyYXlCdWZmZXJgLCBgaXNBcnJheUxpa2VgLCBgaXNBcnJheUxpa2VPYmplY3RgLFxuICAgICAqIGBpc0Jvb2xlYW5gLCBgaXNCdWZmZXJgLCBgaXNEYXRlYCwgYGlzRWxlbWVudGAsIGBpc0VtcHR5YCwgYGlzRXF1YWxgLFxuICAgICAqIGBpc0VxdWFsV2l0aGAsIGBpc0Vycm9yYCwgYGlzRmluaXRlYCwgYGlzRnVuY3Rpb25gLCBgaXNJbnRlZ2VyYCwgYGlzTGVuZ3RoYCxcbiAgICAgKiBgaXNNYXBgLCBgaXNNYXRjaGAsIGBpc01hdGNoV2l0aGAsIGBpc05hTmAsIGBpc05hdGl2ZWAsIGBpc05pbGAsIGBpc051bGxgLFxuICAgICAqIGBpc051bWJlcmAsIGBpc09iamVjdGAsIGBpc09iamVjdExpa2VgLCBgaXNQbGFpbk9iamVjdGAsIGBpc1JlZ0V4cGAsXG4gICAgICogYGlzU2FmZUludGVnZXJgLCBgaXNTZXRgLCBgaXNTdHJpbmdgLCBgaXNVbmRlZmluZWRgLCBgaXNUeXBlZEFycmF5YCxcbiAgICAgKiBgaXNXZWFrTWFwYCwgYGlzV2Vha1NldGAsIGBqb2luYCwgYGtlYmFiQ2FzZWAsIGBsYXN0YCwgYGxhc3RJbmRleE9mYCxcbiAgICAgKiBgbG93ZXJDYXNlYCwgYGxvd2VyRmlyc3RgLCBgbHRgLCBgbHRlYCwgYG1heGAsIGBtYXhCeWAsIGBtZWFuYCwgYG1lYW5CeWAsXG4gICAgICogYG1pbmAsIGBtaW5CeWAsIGBtdWx0aXBseWAsIGBub0NvbmZsaWN0YCwgYG5vb3BgLCBgbm93YCwgYG50aGAsIGBwYWRgLFxuICAgICAqIGBwYWRFbmRgLCBgcGFkU3RhcnRgLCBgcGFyc2VJbnRgLCBgcG9wYCwgYHJhbmRvbWAsIGByZWR1Y2VgLCBgcmVkdWNlUmlnaHRgLFxuICAgICAqIGByZXBlYXRgLCBgcmVzdWx0YCwgYHJvdW5kYCwgYHJ1bkluQ29udGV4dGAsIGBzYW1wbGVgLCBgc2hpZnRgLCBgc2l6ZWAsXG4gICAgICogYHNuYWtlQ2FzZWAsIGBzb21lYCwgYHNvcnRlZEluZGV4YCwgYHNvcnRlZEluZGV4QnlgLCBgc29ydGVkTGFzdEluZGV4YCxcbiAgICAgKiBgc29ydGVkTGFzdEluZGV4QnlgLCBgc3RhcnRDYXNlYCwgYHN0YXJ0c1dpdGhgLCBgc3R1YkFycmF5YCwgYHN0dWJGYWxzZWAsXG4gICAgICogYHN0dWJPYmplY3RgLCBgc3R1YlN0cmluZ2AsIGBzdHViVHJ1ZWAsIGBzdWJ0cmFjdGAsIGBzdW1gLCBgc3VtQnlgLFxuICAgICAqIGB0ZW1wbGF0ZWAsIGB0aW1lc2AsIGB0b0Zpbml0ZWAsIGB0b0ludGVnZXJgLCBgdG9KU09OYCwgYHRvTGVuZ3RoYCxcbiAgICAgKiBgdG9Mb3dlcmAsIGB0b051bWJlcmAsIGB0b1NhZmVJbnRlZ2VyYCwgYHRvU3RyaW5nYCwgYHRvVXBwZXJgLCBgdHJpbWAsXG4gICAgICogYHRyaW1FbmRgLCBgdHJpbVN0YXJ0YCwgYHRydW5jYXRlYCwgYHVuZXNjYXBlYCwgYHVuaXF1ZUlkYCwgYHVwcGVyQ2FzZWAsXG4gICAgICogYHVwcGVyRmlyc3RgLCBgdmFsdWVgLCBhbmQgYHdvcmRzYFxuICAgICAqXG4gICAgICogQG5hbWUgX1xuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwIGluIGEgYGxvZGFzaGAgaW5zdGFuY2UuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIHNxdWFyZShuKSB7XG4gICAgICogICByZXR1cm4gbiAqIG47XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIHdyYXBwZWQgPSBfKFsxLCAyLCAzXSk7XG4gICAgICpcbiAgICAgKiAvLyBSZXR1cm5zIGFuIHVud3JhcHBlZCB2YWx1ZS5cbiAgICAgKiB3cmFwcGVkLnJlZHVjZShfLmFkZCk7XG4gICAgICogLy8gPT4gNlxuICAgICAqXG4gICAgICogLy8gUmV0dXJucyBhIHdyYXBwZWQgdmFsdWUuXG4gICAgICogdmFyIHNxdWFyZXMgPSB3cmFwcGVkLm1hcChzcXVhcmUpO1xuICAgICAqXG4gICAgICogXy5pc0FycmF5KHNxdWFyZXMpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXkoc3F1YXJlcy52YWx1ZSgpKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gbG9kYXNoKHZhbHVlKSB7XG4gICAgICBpZiAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiAhaXNBcnJheSh2YWx1ZSkgJiYgISh2YWx1ZSBpbnN0YW5jZW9mIExhenlXcmFwcGVyKSkge1xuICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBMb2Rhc2hXcmFwcGVyKSB7XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCAnX193cmFwcGVkX18nKSkge1xuICAgICAgICAgIHJldHVybiB3cmFwcGVyQ2xvbmUodmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3IExvZGFzaFdyYXBwZXIodmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNyZWF0ZWAgd2l0aG91dCBzdXBwb3J0IGZvciBhc3NpZ25pbmdcbiAgICAgKiBwcm9wZXJ0aWVzIHRvIHRoZSBjcmVhdGVkIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHByb3RvIFRoZSBvYmplY3QgdG8gaW5oZXJpdCBmcm9tLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICovXG4gICAgdmFyIGJhc2VDcmVhdGUgPSAoZnVuY3Rpb24oKSB7XG4gICAgICBmdW5jdGlvbiBvYmplY3QoKSB7fVxuICAgICAgcmV0dXJuIGZ1bmN0aW9uKHByb3RvKSB7XG4gICAgICAgIGlmICghaXNPYmplY3QocHJvdG8pKSB7XG4gICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChvYmplY3RDcmVhdGUpIHtcbiAgICAgICAgICByZXR1cm4gb2JqZWN0Q3JlYXRlKHByb3RvKTtcbiAgICAgICAgfVxuICAgICAgICBvYmplY3QucHJvdG90eXBlID0gcHJvdG87XG4gICAgICAgIHZhciByZXN1bHQgPSBuZXcgb2JqZWN0O1xuICAgICAgICBvYmplY3QucHJvdG90eXBlID0gdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfTtcbiAgICB9KCkpO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGZ1bmN0aW9uIHdob3NlIHByb3RvdHlwZSBjaGFpbiBzZXF1ZW5jZSB3cmFwcGVycyBpbmhlcml0IGZyb20uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VMb2Rhc2goKSB7XG4gICAgICAvLyBObyBvcGVyYXRpb24gcGVyZm9ybWVkLlxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGNvbnN0cnVjdG9yIGZvciBjcmVhdGluZyBgbG9kYXNoYCB3cmFwcGVyIG9iamVjdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbY2hhaW5BbGxdIEVuYWJsZSBleHBsaWNpdCBtZXRob2QgY2hhaW4gc2VxdWVuY2VzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIExvZGFzaFdyYXBwZXIodmFsdWUsIGNoYWluQWxsKSB7XG4gICAgICB0aGlzLl9fd3JhcHBlZF9fID0gdmFsdWU7XG4gICAgICB0aGlzLl9fYWN0aW9uc19fID0gW107XG4gICAgICB0aGlzLl9fY2hhaW5fXyA9ICEhY2hhaW5BbGw7XG4gICAgICB0aGlzLl9faW5kZXhfXyA9IDA7XG4gICAgICB0aGlzLl9fdmFsdWVzX18gPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQnkgZGVmYXVsdCwgdGhlIHRlbXBsYXRlIGRlbGltaXRlcnMgdXNlZCBieSBsb2Rhc2ggYXJlIGxpa2UgdGhvc2UgaW5cbiAgICAgKiBlbWJlZGRlZCBSdWJ5IChFUkIpIGFzIHdlbGwgYXMgRVMyMDE1IHRlbXBsYXRlIHN0cmluZ3MuIENoYW5nZSB0aGVcbiAgICAgKiBmb2xsb3dpbmcgdGVtcGxhdGUgc2V0dGluZ3MgdG8gdXNlIGFsdGVybmF0aXZlIGRlbGltaXRlcnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAqL1xuICAgIGxvZGFzaC50ZW1wbGF0ZVNldHRpbmdzID0ge1xuXG4gICAgICAvKipcbiAgICAgICAqIFVzZWQgdG8gZGV0ZWN0IGBkYXRhYCBwcm9wZXJ0eSB2YWx1ZXMgdG8gYmUgSFRNTC1lc2NhcGVkLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBfLnRlbXBsYXRlU2V0dGluZ3NcbiAgICAgICAqIEB0eXBlIHtSZWdFeHB9XG4gICAgICAgKi9cbiAgICAgICdlc2NhcGUnOiByZUVzY2FwZSxcblxuICAgICAgLyoqXG4gICAgICAgKiBVc2VkIHRvIGRldGVjdCBjb2RlIHRvIGJlIGV2YWx1YXRlZC5cbiAgICAgICAqXG4gICAgICAgKiBAbWVtYmVyT2YgXy50ZW1wbGF0ZVNldHRpbmdzXG4gICAgICAgKiBAdHlwZSB7UmVnRXhwfVxuICAgICAgICovXG4gICAgICAnZXZhbHVhdGUnOiByZUV2YWx1YXRlLFxuXG4gICAgICAvKipcbiAgICAgICAqIFVzZWQgdG8gZGV0ZWN0IGBkYXRhYCBwcm9wZXJ0eSB2YWx1ZXMgdG8gaW5qZWN0LlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBfLnRlbXBsYXRlU2V0dGluZ3NcbiAgICAgICAqIEB0eXBlIHtSZWdFeHB9XG4gICAgICAgKi9cbiAgICAgICdpbnRlcnBvbGF0ZSc6IHJlSW50ZXJwb2xhdGUsXG5cbiAgICAgIC8qKlxuICAgICAgICogVXNlZCB0byByZWZlcmVuY2UgdGhlIGRhdGEgb2JqZWN0IGluIHRoZSB0ZW1wbGF0ZSB0ZXh0LlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBfLnRlbXBsYXRlU2V0dGluZ3NcbiAgICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICAgKi9cbiAgICAgICd2YXJpYWJsZSc6ICcnLFxuXG4gICAgICAvKipcbiAgICAgICAqIFVzZWQgdG8gaW1wb3J0IHZhcmlhYmxlcyBpbnRvIHRoZSBjb21waWxlZCB0ZW1wbGF0ZS5cbiAgICAgICAqXG4gICAgICAgKiBAbWVtYmVyT2YgXy50ZW1wbGF0ZVNldHRpbmdzXG4gICAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAgICovXG4gICAgICAnaW1wb3J0cyc6IHtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQSByZWZlcmVuY2UgdG8gdGhlIGBsb2Rhc2hgIGZ1bmN0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAbWVtYmVyT2YgXy50ZW1wbGF0ZVNldHRpbmdzLmltcG9ydHNcbiAgICAgICAgICogQHR5cGUge0Z1bmN0aW9ufVxuICAgICAgICAgKi9cbiAgICAgICAgJ18nOiBsb2Rhc2hcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgLy8gRW5zdXJlIHdyYXBwZXJzIGFyZSBpbnN0YW5jZXMgb2YgYGJhc2VMb2Rhc2hgLlxuICAgIGxvZGFzaC5wcm90b3R5cGUgPSBiYXNlTG9kYXNoLnByb3RvdHlwZTtcbiAgICBsb2Rhc2gucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gbG9kYXNoO1xuXG4gICAgTG9kYXNoV3JhcHBlci5wcm90b3R5cGUgPSBiYXNlQ3JlYXRlKGJhc2VMb2Rhc2gucHJvdG90eXBlKTtcbiAgICBMb2Rhc2hXcmFwcGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IExvZGFzaFdyYXBwZXI7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbGF6eSB3cmFwcGVyIG9iamVjdCB3aGljaCB3cmFwcyBgdmFsdWVgIHRvIGVuYWJsZSBsYXp5IGV2YWx1YXRpb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyYXAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gTGF6eVdyYXBwZXIodmFsdWUpIHtcbiAgICAgIHRoaXMuX193cmFwcGVkX18gPSB2YWx1ZTtcbiAgICAgIHRoaXMuX19hY3Rpb25zX18gPSBbXTtcbiAgICAgIHRoaXMuX19kaXJfXyA9IDE7XG4gICAgICB0aGlzLl9fZmlsdGVyZWRfXyA9IGZhbHNlO1xuICAgICAgdGhpcy5fX2l0ZXJhdGVlc19fID0gW107XG4gICAgICB0aGlzLl9fdGFrZUNvdW50X18gPSBNQVhfQVJSQVlfTEVOR1RIO1xuICAgICAgdGhpcy5fX3ZpZXdzX18gPSBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY2xvbmUgb2YgdGhlIGxhenkgd3JhcHBlciBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGNsb25lXG4gICAgICogQG1lbWJlck9mIExhenlXcmFwcGVyXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIGBMYXp5V3JhcHBlcmAgb2JqZWN0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxhenlDbG9uZSgpIHtcbiAgICAgIHZhciByZXN1bHQgPSBuZXcgTGF6eVdyYXBwZXIodGhpcy5fX3dyYXBwZWRfXyk7XG4gICAgICByZXN1bHQuX19hY3Rpb25zX18gPSBjb3B5QXJyYXkodGhpcy5fX2FjdGlvbnNfXyk7XG4gICAgICByZXN1bHQuX19kaXJfXyA9IHRoaXMuX19kaXJfXztcbiAgICAgIHJlc3VsdC5fX2ZpbHRlcmVkX18gPSB0aGlzLl9fZmlsdGVyZWRfXztcbiAgICAgIHJlc3VsdC5fX2l0ZXJhdGVlc19fID0gY29weUFycmF5KHRoaXMuX19pdGVyYXRlZXNfXyk7XG4gICAgICByZXN1bHQuX190YWtlQ291bnRfXyA9IHRoaXMuX190YWtlQ291bnRfXztcbiAgICAgIHJlc3VsdC5fX3ZpZXdzX18gPSBjb3B5QXJyYXkodGhpcy5fX3ZpZXdzX18pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXZlcnNlcyB0aGUgZGlyZWN0aW9uIG9mIGxhenkgaXRlcmF0aW9uLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSByZXZlcnNlXG4gICAgICogQG1lbWJlck9mIExhenlXcmFwcGVyXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IHJldmVyc2VkIGBMYXp5V3JhcHBlcmAgb2JqZWN0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxhenlSZXZlcnNlKCkge1xuICAgICAgaWYgKHRoaXMuX19maWx0ZXJlZF9fKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBuZXcgTGF6eVdyYXBwZXIodGhpcyk7XG4gICAgICAgIHJlc3VsdC5fX2Rpcl9fID0gLTE7XG4gICAgICAgIHJlc3VsdC5fX2ZpbHRlcmVkX18gPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0ID0gdGhpcy5jbG9uZSgpO1xuICAgICAgICByZXN1bHQuX19kaXJfXyAqPSAtMTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdHMgdGhlIHVud3JhcHBlZCB2YWx1ZSBmcm9tIGl0cyBsYXp5IHdyYXBwZXIuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIHZhbHVlXG4gICAgICogQG1lbWJlck9mIExhenlXcmFwcGVyXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHVud3JhcHBlZCB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsYXp5VmFsdWUoKSB7XG4gICAgICB2YXIgYXJyYXkgPSB0aGlzLl9fd3JhcHBlZF9fLnZhbHVlKCksXG4gICAgICAgICAgZGlyID0gdGhpcy5fX2Rpcl9fLFxuICAgICAgICAgIGlzQXJyID0gaXNBcnJheShhcnJheSksXG4gICAgICAgICAgaXNSaWdodCA9IGRpciA8IDAsXG4gICAgICAgICAgYXJyTGVuZ3RoID0gaXNBcnIgPyBhcnJheS5sZW5ndGggOiAwLFxuICAgICAgICAgIHZpZXcgPSBnZXRWaWV3KDAsIGFyckxlbmd0aCwgdGhpcy5fX3ZpZXdzX18pLFxuICAgICAgICAgIHN0YXJ0ID0gdmlldy5zdGFydCxcbiAgICAgICAgICBlbmQgPSB2aWV3LmVuZCxcbiAgICAgICAgICBsZW5ndGggPSBlbmQgLSBzdGFydCxcbiAgICAgICAgICBpbmRleCA9IGlzUmlnaHQgPyBlbmQgOiAoc3RhcnQgLSAxKSxcbiAgICAgICAgICBpdGVyYXRlZXMgPSB0aGlzLl9faXRlcmF0ZWVzX18sXG4gICAgICAgICAgaXRlckxlbmd0aCA9IGl0ZXJhdGVlcy5sZW5ndGgsXG4gICAgICAgICAgcmVzSW5kZXggPSAwLFxuICAgICAgICAgIHRha2VDb3VudCA9IG5hdGl2ZU1pbihsZW5ndGgsIHRoaXMuX190YWtlQ291bnRfXyk7XG5cbiAgICAgIGlmICghaXNBcnIgfHwgKCFpc1JpZ2h0ICYmIGFyckxlbmd0aCA9PSBsZW5ndGggJiYgdGFrZUNvdW50ID09IGxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIGJhc2VXcmFwcGVyVmFsdWUoYXJyYXksIHRoaXMuX19hY3Rpb25zX18pO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuXG4gICAgICBvdXRlcjpcbiAgICAgIHdoaWxlIChsZW5ndGgtLSAmJiByZXNJbmRleCA8IHRha2VDb3VudCkge1xuICAgICAgICBpbmRleCArPSBkaXI7XG5cbiAgICAgICAgdmFyIGl0ZXJJbmRleCA9IC0xLFxuICAgICAgICAgICAgdmFsdWUgPSBhcnJheVtpbmRleF07XG5cbiAgICAgICAgd2hpbGUgKCsraXRlckluZGV4IDwgaXRlckxlbmd0aCkge1xuICAgICAgICAgIHZhciBkYXRhID0gaXRlcmF0ZWVzW2l0ZXJJbmRleF0sXG4gICAgICAgICAgICAgIGl0ZXJhdGVlID0gZGF0YS5pdGVyYXRlZSxcbiAgICAgICAgICAgICAgdHlwZSA9IGRhdGEudHlwZSxcbiAgICAgICAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZSh2YWx1ZSk7XG5cbiAgICAgICAgICBpZiAodHlwZSA9PSBMQVpZX01BUF9GTEFHKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IGNvbXB1dGVkO1xuICAgICAgICAgIH0gZWxzZSBpZiAoIWNvbXB1dGVkKSB7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSBMQVpZX0ZJTFRFUl9GTEFHKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgYnJlYWsgb3V0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJlc3VsdFtyZXNJbmRleCsrXSA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvLyBFbnN1cmUgYExhenlXcmFwcGVyYCBpcyBhbiBpbnN0YW5jZSBvZiBgYmFzZUxvZGFzaGAuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlID0gYmFzZUNyZWF0ZShiYXNlTG9kYXNoLnByb3RvdHlwZSk7XG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gTGF6eVdyYXBwZXI7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgaGFzaCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtlbnRyaWVzXSBUaGUga2V5LXZhbHVlIHBhaXJzIHRvIGNhY2hlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIEhhc2goZW50cmllcykge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gZW50cmllcyA9PSBudWxsID8gMCA6IGVudHJpZXMubGVuZ3RoO1xuXG4gICAgICB0aGlzLmNsZWFyKCk7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgZW50cnkgPSBlbnRyaWVzW2luZGV4XTtcbiAgICAgICAgdGhpcy5zZXQoZW50cnlbMF0sIGVudHJ5WzFdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFsbCBrZXktdmFsdWUgZW50cmllcyBmcm9tIHRoZSBoYXNoLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBjbGVhclxuICAgICAqIEBtZW1iZXJPZiBIYXNoXG4gICAgICovXG4gICAgZnVuY3Rpb24gaGFzaENsZWFyKCkge1xuICAgICAgdGhpcy5fX2RhdGFfXyA9IG5hdGl2ZUNyZWF0ZSA/IG5hdGl2ZUNyZWF0ZShudWxsKSA6IHt9O1xuICAgICAgdGhpcy5zaXplID0gMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGBrZXlgIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGUgaGFzaC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgZGVsZXRlXG4gICAgICogQG1lbWJlck9mIEhhc2hcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gaGFzaCBUaGUgaGFzaCB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGhhc2hEZWxldGUoa2V5KSB7XG4gICAgICB2YXIgcmVzdWx0ID0gdGhpcy5oYXMoa2V5KSAmJiBkZWxldGUgdGhpcy5fX2RhdGFfX1trZXldO1xuICAgICAgdGhpcy5zaXplIC09IHJlc3VsdCA/IDEgOiAwO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBoYXNoIHZhbHVlIGZvciBga2V5YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgZ2V0XG4gICAgICogQG1lbWJlck9mIEhhc2hcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZW50cnkgdmFsdWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaGFzaEdldChrZXkpIHtcbiAgICAgIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXztcbiAgICAgIGlmIChuYXRpdmVDcmVhdGUpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGRhdGFba2V5XTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gSEFTSF9VTkRFRklORUQgPyB1bmRlZmluZWQgOiByZXN1bHQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gaGFzT3duUHJvcGVydHkuY2FsbChkYXRhLCBrZXkpID8gZGF0YVtrZXldIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBhIGhhc2ggdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgaGFzXG4gICAgICogQG1lbWJlck9mIEhhc2hcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVudHJ5IHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaGFzaEhhcyhrZXkpIHtcbiAgICAgIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXztcbiAgICAgIHJldHVybiBuYXRpdmVDcmVhdGUgPyAoZGF0YVtrZXldICE9PSB1bmRlZmluZWQpIDogaGFzT3duUHJvcGVydHkuY2FsbChkYXRhLCBrZXkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGhhc2ggYGtleWAgdG8gYHZhbHVlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgc2V0XG4gICAgICogQG1lbWJlck9mIEhhc2hcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgaGFzaCBpbnN0YW5jZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBoYXNoU2V0KGtleSwgdmFsdWUpIHtcbiAgICAgIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXztcbiAgICAgIHRoaXMuc2l6ZSArPSB0aGlzLmhhcyhrZXkpID8gMCA6IDE7XG4gICAgICBkYXRhW2tleV0gPSAobmF0aXZlQ3JlYXRlICYmIHZhbHVlID09PSB1bmRlZmluZWQpID8gSEFTSF9VTkRFRklORUQgOiB2YWx1ZTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEFkZCBtZXRob2RzIHRvIGBIYXNoYC5cbiAgICBIYXNoLnByb3RvdHlwZS5jbGVhciA9IGhhc2hDbGVhcjtcbiAgICBIYXNoLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBoYXNoRGVsZXRlO1xuICAgIEhhc2gucHJvdG90eXBlLmdldCA9IGhhc2hHZXQ7XG4gICAgSGFzaC5wcm90b3R5cGUuaGFzID0gaGFzaEhhcztcbiAgICBIYXNoLnByb3RvdHlwZS5zZXQgPSBoYXNoU2V0O1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBsaXN0IGNhY2hlIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2VudHJpZXNdIFRoZSBrZXktdmFsdWUgcGFpcnMgdG8gY2FjaGUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gTGlzdENhY2hlKGVudHJpZXMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IGVudHJpZXMgPT0gbnVsbCA/IDAgOiBlbnRyaWVzLmxlbmd0aDtcblxuICAgICAgdGhpcy5jbGVhcigpO1xuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gZW50cmllc1tpbmRleF07XG4gICAgICAgIHRoaXMuc2V0KGVudHJ5WzBdLCBlbnRyeVsxXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgbGlzdCBjYWNoZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgY2xlYXJcbiAgICAgKiBAbWVtYmVyT2YgTGlzdENhY2hlXG4gICAgICovXG4gICAgZnVuY3Rpb24gbGlzdENhY2hlQ2xlYXIoKSB7XG4gICAgICB0aGlzLl9fZGF0YV9fID0gW107XG4gICAgICB0aGlzLnNpemUgPSAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBsaXN0IGNhY2hlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBkZWxldGVcbiAgICAgKiBAbWVtYmVyT2YgTGlzdENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxpc3RDYWNoZURlbGV0ZShrZXkpIHtcbiAgICAgIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyxcbiAgICAgICAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpO1xuXG4gICAgICBpZiAoaW5kZXggPCAwKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHZhciBsYXN0SW5kZXggPSBkYXRhLmxlbmd0aCAtIDE7XG4gICAgICBpZiAoaW5kZXggPT0gbGFzdEluZGV4KSB7XG4gICAgICAgIGRhdGEucG9wKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzcGxpY2UuY2FsbChkYXRhLCBpbmRleCwgMSk7XG4gICAgICB9XG4gICAgICAtLXRoaXMuc2l6ZTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGxpc3QgY2FjaGUgdmFsdWUgZm9yIGBrZXlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBnZXRcbiAgICAgKiBAbWVtYmVyT2YgTGlzdENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBnZXQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGVudHJ5IHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxpc3RDYWNoZUdldChrZXkpIHtcbiAgICAgIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyxcbiAgICAgICAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpO1xuXG4gICAgICByZXR1cm4gaW5kZXggPCAwID8gdW5kZWZpbmVkIDogZGF0YVtpbmRleF1bMV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGEgbGlzdCBjYWNoZSB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBoYXNcbiAgICAgKiBAbWVtYmVyT2YgTGlzdENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxpc3RDYWNoZUhhcyhrZXkpIHtcbiAgICAgIHJldHVybiBhc3NvY0luZGV4T2YodGhpcy5fX2RhdGFfXywga2V5KSA+IC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIGxpc3QgY2FjaGUgYGtleWAgdG8gYHZhbHVlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgc2V0XG4gICAgICogQG1lbWJlck9mIExpc3RDYWNoZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBsaXN0IGNhY2hlIGluc3RhbmNlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGxpc3RDYWNoZVNldChrZXksIHZhbHVlKSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICAgICAgaW5kZXggPSBhc3NvY0luZGV4T2YoZGF0YSwga2V5KTtcblxuICAgICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgICArK3RoaXMuc2l6ZTtcbiAgICAgICAgZGF0YS5wdXNoKFtrZXksIHZhbHVlXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkYXRhW2luZGV4XVsxXSA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLy8gQWRkIG1ldGhvZHMgdG8gYExpc3RDYWNoZWAuXG4gICAgTGlzdENhY2hlLnByb3RvdHlwZS5jbGVhciA9IGxpc3RDYWNoZUNsZWFyO1xuICAgIExpc3RDYWNoZS5wcm90b3R5cGVbJ2RlbGV0ZSddID0gbGlzdENhY2hlRGVsZXRlO1xuICAgIExpc3RDYWNoZS5wcm90b3R5cGUuZ2V0ID0gbGlzdENhY2hlR2V0O1xuICAgIExpc3RDYWNoZS5wcm90b3R5cGUuaGFzID0gbGlzdENhY2hlSGFzO1xuICAgIExpc3RDYWNoZS5wcm90b3R5cGUuc2V0ID0gbGlzdENhY2hlU2V0O1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG1hcCBjYWNoZSBvYmplY3QgdG8gc3RvcmUga2V5LXZhbHVlIHBhaXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBNYXBDYWNoZShlbnRyaWVzKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBlbnRyaWVzID09IG51bGwgPyAwIDogZW50cmllcy5sZW5ndGg7XG5cbiAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBlbnRyeSA9IGVudHJpZXNbaW5kZXhdO1xuICAgICAgICB0aGlzLnNldChlbnRyeVswXSwgZW50cnlbMV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGtleS12YWx1ZSBlbnRyaWVzIGZyb20gdGhlIG1hcC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgY2xlYXJcbiAgICAgKiBAbWVtYmVyT2YgTWFwQ2FjaGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXBDYWNoZUNsZWFyKCkge1xuICAgICAgdGhpcy5zaXplID0gMDtcbiAgICAgIHRoaXMuX19kYXRhX18gPSB7XG4gICAgICAgICdoYXNoJzogbmV3IEhhc2gsXG4gICAgICAgICdtYXAnOiBuZXcgKE1hcCB8fCBMaXN0Q2FjaGUpLFxuICAgICAgICAnc3RyaW5nJzogbmV3IEhhc2hcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBga2V5YCBhbmQgaXRzIHZhbHVlIGZyb20gdGhlIG1hcC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgZGVsZXRlXG4gICAgICogQG1lbWJlck9mIE1hcENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hcENhY2hlRGVsZXRlKGtleSkge1xuICAgICAgdmFyIHJlc3VsdCA9IGdldE1hcERhdGEodGhpcywga2V5KVsnZGVsZXRlJ10oa2V5KTtcbiAgICAgIHRoaXMuc2l6ZSAtPSByZXN1bHQgPyAxIDogMDtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgbWFwIHZhbHVlIGZvciBga2V5YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgZ2V0XG4gICAgICogQG1lbWJlck9mIE1hcENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBnZXQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGVudHJ5IHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hcENhY2hlR2V0KGtleSkge1xuICAgICAgcmV0dXJuIGdldE1hcERhdGEodGhpcywga2V5KS5nZXQoa2V5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYSBtYXAgdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgaGFzXG4gICAgICogQG1lbWJlck9mIE1hcENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hcENhY2hlSGFzKGtleSkge1xuICAgICAgcmV0dXJuIGdldE1hcERhdGEodGhpcywga2V5KS5oYXMoa2V5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBtYXAgYGtleWAgdG8gYHZhbHVlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQG5hbWUgc2V0XG4gICAgICogQG1lbWJlck9mIE1hcENhY2hlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBzZXQuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG1hcCBjYWNoZSBpbnN0YW5jZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXBDYWNoZVNldChrZXksIHZhbHVlKSB7XG4gICAgICB2YXIgZGF0YSA9IGdldE1hcERhdGEodGhpcywga2V5KSxcbiAgICAgICAgICBzaXplID0gZGF0YS5zaXplO1xuXG4gICAgICBkYXRhLnNldChrZXksIHZhbHVlKTtcbiAgICAgIHRoaXMuc2l6ZSArPSBkYXRhLnNpemUgPT0gc2l6ZSA/IDAgOiAxO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLy8gQWRkIG1ldGhvZHMgdG8gYE1hcENhY2hlYC5cbiAgICBNYXBDYWNoZS5wcm90b3R5cGUuY2xlYXIgPSBtYXBDYWNoZUNsZWFyO1xuICAgIE1hcENhY2hlLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBtYXBDYWNoZURlbGV0ZTtcbiAgICBNYXBDYWNoZS5wcm90b3R5cGUuZ2V0ID0gbWFwQ2FjaGVHZXQ7XG4gICAgTWFwQ2FjaGUucHJvdG90eXBlLmhhcyA9IG1hcENhY2hlSGFzO1xuICAgIE1hcENhY2hlLnByb3RvdHlwZS5zZXQgPSBtYXBDYWNoZVNldDtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBjYWNoZSBvYmplY3QgdG8gc3RvcmUgdW5pcXVlIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3ZhbHVlc10gVGhlIHZhbHVlcyB0byBjYWNoZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBTZXRDYWNoZSh2YWx1ZXMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHZhbHVlcyA9PSBudWxsID8gMCA6IHZhbHVlcy5sZW5ndGg7XG5cbiAgICAgIHRoaXMuX19kYXRhX18gPSBuZXcgTWFwQ2FjaGU7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB0aGlzLmFkZCh2YWx1ZXNbaW5kZXhdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGB2YWx1ZWAgdG8gdGhlIGFycmF5IGNhY2hlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBhZGRcbiAgICAgKiBAbWVtYmVyT2YgU2V0Q2FjaGVcbiAgICAgKiBAYWxpYXMgcHVzaFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNhY2hlLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNhY2hlIGluc3RhbmNlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNldENhY2hlQWRkKHZhbHVlKSB7XG4gICAgICB0aGlzLl9fZGF0YV9fLnNldCh2YWx1ZSwgSEFTSF9VTkRFRklORUQpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgaW4gdGhlIGFycmF5IGNhY2hlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBoYXNcbiAgICAgKiBAbWVtYmVyT2YgU2V0Q2FjaGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzZXRDYWNoZUhhcyh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX19kYXRhX18uaGFzKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvLyBBZGQgbWV0aG9kcyB0byBgU2V0Q2FjaGVgLlxuICAgIFNldENhY2hlLnByb3RvdHlwZS5hZGQgPSBTZXRDYWNoZS5wcm90b3R5cGUucHVzaCA9IHNldENhY2hlQWRkO1xuICAgIFNldENhY2hlLnByb3RvdHlwZS5oYXMgPSBzZXRDYWNoZUhhcztcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzdGFjayBjYWNoZSBvYmplY3QgdG8gc3RvcmUga2V5LXZhbHVlIHBhaXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBTdGFjayhlbnRyaWVzKSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18gPSBuZXcgTGlzdENhY2hlKGVudHJpZXMpO1xuICAgICAgdGhpcy5zaXplID0gZGF0YS5zaXplO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGtleS12YWx1ZSBlbnRyaWVzIGZyb20gdGhlIHN0YWNrLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBjbGVhclxuICAgICAqIEBtZW1iZXJPZiBTdGFja1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN0YWNrQ2xlYXIoKSB7XG4gICAgICB0aGlzLl9fZGF0YV9fID0gbmV3IExpc3RDYWNoZTtcbiAgICAgIHRoaXMuc2l6ZSA9IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBga2V5YCBhbmQgaXRzIHZhbHVlIGZyb20gdGhlIHN0YWNrLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAbmFtZSBkZWxldGVcbiAgICAgKiBAbWVtYmVyT2YgU3RhY2tcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJlbW92ZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGVudHJ5IHdhcyByZW1vdmVkLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3RhY2tEZWxldGUoa2V5KSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICAgICAgcmVzdWx0ID0gZGF0YVsnZGVsZXRlJ10oa2V5KTtcblxuICAgICAgdGhpcy5zaXplID0gZGF0YS5zaXplO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBzdGFjayB2YWx1ZSBmb3IgYGtleWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGdldFxuICAgICAqIEBtZW1iZXJPZiBTdGFja1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdGFja0dldChrZXkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fZGF0YV9fLmdldChrZXkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBhIHN0YWNrIHZhbHVlIGZvciBga2V5YCBleGlzdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIGhhc1xuICAgICAqIEBtZW1iZXJPZiBTdGFja1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFuIGVudHJ5IGZvciBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdGFja0hhcyhrZXkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9fZGF0YV9fLmhhcyhrZXkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHN0YWNrIGBrZXlgIHRvIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBuYW1lIHNldFxuICAgICAqIEBtZW1iZXJPZiBTdGFja1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBzdGFjayBjYWNoZSBpbnN0YW5jZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdGFja1NldChrZXksIHZhbHVlKSB7XG4gICAgICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187XG4gICAgICBpZiAoZGF0YSBpbnN0YW5jZW9mIExpc3RDYWNoZSkge1xuICAgICAgICB2YXIgcGFpcnMgPSBkYXRhLl9fZGF0YV9fO1xuICAgICAgICBpZiAoIU1hcCB8fCAocGFpcnMubGVuZ3RoIDwgTEFSR0VfQVJSQVlfU0laRSAtIDEpKSB7XG4gICAgICAgICAgcGFpcnMucHVzaChba2V5LCB2YWx1ZV0pO1xuICAgICAgICAgIHRoaXMuc2l6ZSA9ICsrZGF0YS5zaXplO1xuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIGRhdGEgPSB0aGlzLl9fZGF0YV9fID0gbmV3IE1hcENhY2hlKHBhaXJzKTtcbiAgICAgIH1cbiAgICAgIGRhdGEuc2V0KGtleSwgdmFsdWUpO1xuICAgICAgdGhpcy5zaXplID0gZGF0YS5zaXplO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLy8gQWRkIG1ldGhvZHMgdG8gYFN0YWNrYC5cbiAgICBTdGFjay5wcm90b3R5cGUuY2xlYXIgPSBzdGFja0NsZWFyO1xuICAgIFN0YWNrLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBzdGFja0RlbGV0ZTtcbiAgICBTdGFjay5wcm90b3R5cGUuZ2V0ID0gc3RhY2tHZXQ7XG4gICAgU3RhY2sucHJvdG90eXBlLmhhcyA9IHN0YWNrSGFzO1xuICAgIFN0YWNrLnByb3RvdHlwZS5zZXQgPSBzdGFja1NldDtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgdGhlIGFycmF5LWxpa2UgYHZhbHVlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBpbmhlcml0ZWQgU3BlY2lmeSByZXR1cm5pbmcgaW5oZXJpdGVkIHByb3BlcnR5IG5hbWVzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXJyYXlMaWtlS2V5cyh2YWx1ZSwgaW5oZXJpdGVkKSB7XG4gICAgICB2YXIgaXNBcnIgPSBpc0FycmF5KHZhbHVlKSxcbiAgICAgICAgICBpc0FyZyA9ICFpc0FyciAmJiBpc0FyZ3VtZW50cyh2YWx1ZSksXG4gICAgICAgICAgaXNCdWZmID0gIWlzQXJyICYmICFpc0FyZyAmJiBpc0J1ZmZlcih2YWx1ZSksXG4gICAgICAgICAgaXNUeXBlID0gIWlzQXJyICYmICFpc0FyZyAmJiAhaXNCdWZmICYmIGlzVHlwZWRBcnJheSh2YWx1ZSksXG4gICAgICAgICAgc2tpcEluZGV4ZXMgPSBpc0FyciB8fCBpc0FyZyB8fCBpc0J1ZmYgfHwgaXNUeXBlLFxuICAgICAgICAgIHJlc3VsdCA9IHNraXBJbmRleGVzID8gYmFzZVRpbWVzKHZhbHVlLmxlbmd0aCwgU3RyaW5nKSA6IFtdLFxuICAgICAgICAgIGxlbmd0aCA9IHJlc3VsdC5sZW5ndGg7XG5cbiAgICAgIGZvciAodmFyIGtleSBpbiB2YWx1ZSkge1xuICAgICAgICBpZiAoKGluaGVyaXRlZCB8fCBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCBrZXkpKSAmJlxuICAgICAgICAgICAgIShza2lwSW5kZXhlcyAmJiAoXG4gICAgICAgICAgICAgICAvLyBTYWZhcmkgOSBoYXMgZW51bWVyYWJsZSBgYXJndW1lbnRzLmxlbmd0aGAgaW4gc3RyaWN0IG1vZGUuXG4gICAgICAgICAgICAgICBrZXkgPT0gJ2xlbmd0aCcgfHxcbiAgICAgICAgICAgICAgIC8vIE5vZGUuanMgMC4xMCBoYXMgZW51bWVyYWJsZSBub24taW5kZXggcHJvcGVydGllcyBvbiBidWZmZXJzLlxuICAgICAgICAgICAgICAgKGlzQnVmZiAmJiAoa2V5ID09ICdvZmZzZXQnIHx8IGtleSA9PSAncGFyZW50JykpIHx8XG4gICAgICAgICAgICAgICAvLyBQaGFudG9tSlMgMiBoYXMgZW51bWVyYWJsZSBub24taW5kZXggcHJvcGVydGllcyBvbiB0eXBlZCBhcnJheXMuXG4gICAgICAgICAgICAgICAoaXNUeXBlICYmIChrZXkgPT0gJ2J1ZmZlcicgfHwga2V5ID09ICdieXRlTGVuZ3RoJyB8fCBrZXkgPT0gJ2J5dGVPZmZzZXQnKSkgfHxcbiAgICAgICAgICAgICAgIC8vIFNraXAgaW5kZXggcHJvcGVydGllcy5cbiAgICAgICAgICAgICAgIGlzSW5kZXgoa2V5LCBsZW5ndGgpXG4gICAgICAgICAgICApKSkge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLnNhbXBsZWAgZm9yIGFycmF5cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNhbXBsZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmFuZG9tIGVsZW1lbnQuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXJyYXlTYW1wbGUoYXJyYXkpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gICAgICByZXR1cm4gbGVuZ3RoID8gYXJyYXlbYmFzZVJhbmRvbSgwLCBsZW5ndGggLSAxKV0gOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLnNhbXBsZVNpemVgIGZvciBhcnJheXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzYW1wbGUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byBzYW1wbGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSByYW5kb20gZWxlbWVudHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXJyYXlTYW1wbGVTaXplKGFycmF5LCBuKSB7XG4gICAgICByZXR1cm4gc2h1ZmZsZVNlbGYoY29weUFycmF5KGFycmF5KSwgYmFzZUNsYW1wKG4sIDAsIGFycmF5Lmxlbmd0aCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5zaHVmZmxlYCBmb3IgYXJyYXlzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2h1ZmZsZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBzaHVmZmxlZCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhcnJheVNodWZmbGUoYXJyYXkpIHtcbiAgICAgIHJldHVybiBzaHVmZmxlU2VsZihjb3B5QXJyYXkoYXJyYXkpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGFzc2lnblZhbHVlYCBleGNlcHQgdGhhdCBpdCBkb2Vzbid0IGFzc2lnblxuICAgICAqIGB1bmRlZmluZWRgIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGFzc2lnbi5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBhc3NpZ24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXNzaWduTWVyZ2VWYWx1ZShvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgICAgIGlmICgodmFsdWUgIT09IHVuZGVmaW5lZCAmJiAhZXEob2JqZWN0W2tleV0sIHZhbHVlKSkgfHxcbiAgICAgICAgICAodmFsdWUgPT09IHVuZGVmaW5lZCAmJiAhKGtleSBpbiBvYmplY3QpKSkge1xuICAgICAgICBiYXNlQXNzaWduVmFsdWUob2JqZWN0LCBrZXksIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBc3NpZ25zIGB2YWx1ZWAgdG8gYGtleWAgb2YgYG9iamVjdGAgaWYgdGhlIGV4aXN0aW5nIHZhbHVlIGlzIG5vdCBlcXVpdmFsZW50XG4gICAgICogdXNpbmcgW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBhc3NpZ24uXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gYXNzaWduLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFzc2lnblZhbHVlKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICAgICAgdmFyIG9ialZhbHVlID0gb2JqZWN0W2tleV07XG4gICAgICBpZiAoIShoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSAmJiBlcShvYmpWYWx1ZSwgdmFsdWUpKSB8fFxuICAgICAgICAgICh2YWx1ZSA9PT0gdW5kZWZpbmVkICYmICEoa2V5IGluIG9iamVjdCkpKSB7XG4gICAgICAgIGJhc2VBc3NpZ25WYWx1ZShvYmplY3QsIGtleSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGluZGV4IGF0IHdoaWNoIHRoZSBga2V5YCBpcyBmb3VuZCBpbiBgYXJyYXlgIG9mIGtleS12YWx1ZSBwYWlycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSBrZXkgVGhlIGtleSB0byBzZWFyY2ggZm9yLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXNzb2NJbmRleE9mKGFycmF5LCBrZXkpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgaWYgKGVxKGFycmF5W2xlbmd0aF1bMF0sIGtleSkpIHtcbiAgICAgICAgICByZXR1cm4gbGVuZ3RoO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gLTE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWdncmVnYXRlcyBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAgb24gYGFjY3VtdWxhdG9yYCB3aXRoIGtleXMgdHJhbnNmb3JtZWRcbiAgICAgKiBieSBgaXRlcmF0ZWVgIGFuZCB2YWx1ZXMgc2V0IGJ5IGBzZXR0ZXJgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gc2V0dGVyIFRoZSBmdW5jdGlvbiB0byBzZXQgYGFjY3VtdWxhdG9yYCB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGl0ZXJhdGVlIHRvIHRyYW5zZm9ybSBrZXlzLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBhY2N1bXVsYXRvciBUaGUgaW5pdGlhbCBhZ2dyZWdhdGVkIG9iamVjdC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGFjY3VtdWxhdG9yYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQWdncmVnYXRvcihjb2xsZWN0aW9uLCBzZXR0ZXIsIGl0ZXJhdGVlLCBhY2N1bXVsYXRvcikge1xuICAgICAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGtleSwgY29sbGVjdGlvbikge1xuICAgICAgICBzZXR0ZXIoYWNjdW11bGF0b3IsIHZhbHVlLCBpdGVyYXRlZSh2YWx1ZSksIGNvbGxlY3Rpb24pO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uYXNzaWduYCB3aXRob3V0IHN1cHBvcnQgZm9yIG11bHRpcGxlIHNvdXJjZXNcbiAgICAgKiBvciBgY3VzdG9taXplcmAgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgc291cmNlIG9iamVjdC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VBc3NpZ24ob2JqZWN0LCBzb3VyY2UpIHtcbiAgICAgIHJldHVybiBvYmplY3QgJiYgY29weU9iamVjdChzb3VyY2UsIGtleXMoc291cmNlKSwgb2JqZWN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5hc3NpZ25JbmAgd2l0aG91dCBzdXBwb3J0IGZvciBtdWx0aXBsZSBzb3VyY2VzXG4gICAgICogb3IgYGN1c3RvbWl6ZXJgIGZ1bmN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQXNzaWduSW4ob2JqZWN0LCBzb3VyY2UpIHtcbiAgICAgIHJldHVybiBvYmplY3QgJiYgY29weU9iamVjdChzb3VyY2UsIGtleXNJbihzb3VyY2UpLCBvYmplY3QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBhc3NpZ25WYWx1ZWAgYW5kIGBhc3NpZ25NZXJnZVZhbHVlYCB3aXRob3V0XG4gICAgICogdmFsdWUgY2hlY2tzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gYXNzaWduLlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGFzc2lnbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQXNzaWduVmFsdWUob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgICBpZiAoa2V5ID09ICdfX3Byb3RvX18nICYmIGRlZmluZVByb3BlcnR5KSB7XG4gICAgICAgIGRlZmluZVByb3BlcnR5KG9iamVjdCwga2V5LCB7XG4gICAgICAgICAgJ2NvbmZpZ3VyYWJsZSc6IHRydWUsXG4gICAgICAgICAgJ2VudW1lcmFibGUnOiB0cnVlLFxuICAgICAgICAgICd2YWx1ZSc6IHZhbHVlLFxuICAgICAgICAgICd3cml0YWJsZSc6IHRydWVcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvYmplY3Rba2V5XSA9IHZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmF0YCB3aXRob3V0IHN1cHBvcnQgZm9yIGluZGl2aWR1YWwgcGF0aHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtzdHJpbmdbXX0gcGF0aHMgVGhlIHByb3BlcnR5IHBhdGhzIHRvIHBpY2suXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBwaWNrZWQgZWxlbWVudHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUF0KG9iamVjdCwgcGF0aHMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHBhdGhzLmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpLFxuICAgICAgICAgIHNraXAgPSBvYmplY3QgPT0gbnVsbDtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0W2luZGV4XSA9IHNraXAgPyB1bmRlZmluZWQgOiBnZXQob2JqZWN0LCBwYXRoc1tpbmRleF0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jbGFtcGAgd2hpY2ggZG9lc24ndCBjb2VyY2UgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbnVtYmVyIFRoZSBudW1iZXIgdG8gY2xhbXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsb3dlcl0gVGhlIGxvd2VyIGJvdW5kLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSB1cHBlciBUaGUgdXBwZXIgYm91bmQuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY2xhbXBlZCBudW1iZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUNsYW1wKG51bWJlciwgbG93ZXIsIHVwcGVyKSB7XG4gICAgICBpZiAobnVtYmVyID09PSBudW1iZXIpIHtcbiAgICAgICAgaWYgKHVwcGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBudW1iZXIgPSBudW1iZXIgPD0gdXBwZXIgPyBudW1iZXIgOiB1cHBlcjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobG93ZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIG51bWJlciA9IG51bWJlciA+PSBsb3dlciA/IG51bWJlciA6IGxvd2VyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVtYmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNsb25lYCBhbmQgYF8uY2xvbmVEZWVwYCB3aGljaCB0cmFja3NcbiAgICAgKiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2xvbmUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLlxuICAgICAqICAxIC0gRGVlcCBjbG9uZVxuICAgICAqICAyIC0gRmxhdHRlbiBpbmhlcml0ZWQgcHJvcGVydGllc1xuICAgICAqICA0IC0gQ2xvbmUgc3ltYm9sc1xuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNsb25pbmcuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIFRoZSBrZXkgb2YgYHZhbHVlYC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIHBhcmVudCBvYmplY3Qgb2YgYHZhbHVlYC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW3N0YWNrXSBUcmFja3MgdHJhdmVyc2VkIG9iamVjdHMgYW5kIHRoZWlyIGNsb25lIGNvdW50ZXJwYXJ0cy5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgY2xvbmVkIHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VDbG9uZSh2YWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwga2V5LCBvYmplY3QsIHN0YWNrKSB7XG4gICAgICB2YXIgcmVzdWx0LFxuICAgICAgICAgIGlzRGVlcCA9IGJpdG1hc2sgJiBDTE9ORV9ERUVQX0ZMQUcsXG4gICAgICAgICAgaXNGbGF0ID0gYml0bWFzayAmIENMT05FX0ZMQVRfRkxBRyxcbiAgICAgICAgICBpc0Z1bGwgPSBiaXRtYXNrICYgQ0xPTkVfU1lNQk9MU19GTEFHO1xuXG4gICAgICBpZiAoY3VzdG9taXplcikge1xuICAgICAgICByZXN1bHQgPSBvYmplY3QgPyBjdXN0b21pemVyKHZhbHVlLCBrZXksIG9iamVjdCwgc3RhY2spIDogY3VzdG9taXplcih2YWx1ZSk7XG4gICAgICB9XG4gICAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIGlmICghaXNPYmplY3QodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHZhciBpc0FyciA9IGlzQXJyYXkodmFsdWUpO1xuICAgICAgaWYgKGlzQXJyKSB7XG4gICAgICAgIHJlc3VsdCA9IGluaXRDbG9uZUFycmF5KHZhbHVlKTtcbiAgICAgICAgaWYgKCFpc0RlZXApIHtcbiAgICAgICAgICByZXR1cm4gY29weUFycmF5KHZhbHVlLCByZXN1bHQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgdGFnID0gZ2V0VGFnKHZhbHVlKSxcbiAgICAgICAgICAgIGlzRnVuYyA9IHRhZyA9PSBmdW5jVGFnIHx8IHRhZyA9PSBnZW5UYWc7XG5cbiAgICAgICAgaWYgKGlzQnVmZmVyKHZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiBjbG9uZUJ1ZmZlcih2YWx1ZSwgaXNEZWVwKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGFnID09IG9iamVjdFRhZyB8fCB0YWcgPT0gYXJnc1RhZyB8fCAoaXNGdW5jICYmICFvYmplY3QpKSB7XG4gICAgICAgICAgcmVzdWx0ID0gKGlzRmxhdCB8fCBpc0Z1bmMpID8ge30gOiBpbml0Q2xvbmVPYmplY3QodmFsdWUpO1xuICAgICAgICAgIGlmICghaXNEZWVwKSB7XG4gICAgICAgICAgICByZXR1cm4gaXNGbGF0XG4gICAgICAgICAgICAgID8gY29weVN5bWJvbHNJbih2YWx1ZSwgYmFzZUFzc2lnbkluKHJlc3VsdCwgdmFsdWUpKVxuICAgICAgICAgICAgICA6IGNvcHlTeW1ib2xzKHZhbHVlLCBiYXNlQXNzaWduKHJlc3VsdCwgdmFsdWUpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKCFjbG9uZWFibGVUYWdzW3RhZ10pIHtcbiAgICAgICAgICAgIHJldHVybiBvYmplY3QgPyB2YWx1ZSA6IHt9O1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXN1bHQgPSBpbml0Q2xvbmVCeVRhZyh2YWx1ZSwgdGFnLCBpc0RlZXApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBDaGVjayBmb3IgY2lyY3VsYXIgcmVmZXJlbmNlcyBhbmQgcmV0dXJuIGl0cyBjb3JyZXNwb25kaW5nIGNsb25lLlxuICAgICAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgICAgIHZhciBzdGFja2VkID0gc3RhY2suZ2V0KHZhbHVlKTtcbiAgICAgIGlmIChzdGFja2VkKSB7XG4gICAgICAgIHJldHVybiBzdGFja2VkO1xuICAgICAgfVxuICAgICAgc3RhY2suc2V0KHZhbHVlLCByZXN1bHQpO1xuXG4gICAgICBpZiAoaXNTZXQodmFsdWUpKSB7XG4gICAgICAgIHZhbHVlLmZvckVhY2goZnVuY3Rpb24oc3ViVmFsdWUpIHtcbiAgICAgICAgICByZXN1bHQuYWRkKGJhc2VDbG9uZShzdWJWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwgc3ViVmFsdWUsIHZhbHVlLCBzdGFjaykpO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNNYXAodmFsdWUpKSB7XG4gICAgICAgIHZhbHVlLmZvckVhY2goZnVuY3Rpb24oc3ViVmFsdWUsIGtleSkge1xuICAgICAgICAgIHJlc3VsdC5zZXQoa2V5LCBiYXNlQ2xvbmUoc3ViVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGtleSwgdmFsdWUsIHN0YWNrKSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIHZhciBrZXlzRnVuYyA9IGlzRnVsbFxuICAgICAgICA/IChpc0ZsYXQgPyBnZXRBbGxLZXlzSW4gOiBnZXRBbGxLZXlzKVxuICAgICAgICA6IChpc0ZsYXQgPyBrZXlzSW4gOiBrZXlzKTtcblxuICAgICAgdmFyIHByb3BzID0gaXNBcnIgPyB1bmRlZmluZWQgOiBrZXlzRnVuYyh2YWx1ZSk7XG4gICAgICBhcnJheUVhY2gocHJvcHMgfHwgdmFsdWUsIGZ1bmN0aW9uKHN1YlZhbHVlLCBrZXkpIHtcbiAgICAgICAgaWYgKHByb3BzKSB7XG4gICAgICAgICAga2V5ID0gc3ViVmFsdWU7XG4gICAgICAgICAgc3ViVmFsdWUgPSB2YWx1ZVtrZXldO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJlY3Vyc2l2ZWx5IHBvcHVsYXRlIGNsb25lIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICAgIGFzc2lnblZhbHVlKHJlc3VsdCwga2V5LCBiYXNlQ2xvbmUoc3ViVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGtleSwgdmFsdWUsIHN0YWNrKSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uY29uZm9ybXNgIHdoaWNoIGRvZXNuJ3QgY2xvbmUgYHNvdXJjZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSBwcmVkaWNhdGVzIHRvIGNvbmZvcm0gdG8uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgc3BlYyBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlQ29uZm9ybXMoc291cmNlKSB7XG4gICAgICB2YXIgcHJvcHMgPSBrZXlzKHNvdXJjZSk7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICAgIHJldHVybiBiYXNlQ29uZm9ybXNUbyhvYmplY3QsIHNvdXJjZSwgcHJvcHMpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jb25mb3Jtc1RvYCB3aGljaCBhY2NlcHRzIGBwcm9wc2AgdG8gY2hlY2suXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSBwcmVkaWNhdGVzIHRvIGNvbmZvcm0gdG8uXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBvYmplY3RgIGNvbmZvcm1zLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUNvbmZvcm1zVG8ob2JqZWN0LCBzb3VyY2UsIHByb3BzKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gcHJvcHMubGVuZ3RoO1xuICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiAhbGVuZ3RoO1xuICAgICAgfVxuICAgICAgb2JqZWN0ID0gT2JqZWN0KG9iamVjdCk7XG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgdmFyIGtleSA9IHByb3BzW2xlbmd0aF0sXG4gICAgICAgICAgICBwcmVkaWNhdGUgPSBzb3VyY2Vba2V5XSxcbiAgICAgICAgICAgIHZhbHVlID0gb2JqZWN0W2tleV07XG5cbiAgICAgICAgaWYgKCh2YWx1ZSA9PT0gdW5kZWZpbmVkICYmICEoa2V5IGluIG9iamVjdCkpIHx8ICFwcmVkaWNhdGUodmFsdWUpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5kZWxheWAgYW5kIGBfLmRlZmVyYCB3aGljaCBhY2NlcHRzIGBhcmdzYFxuICAgICAqIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBkZWxheS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gd2FpdCBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byBkZWxheSBpbnZvY2F0aW9uLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgVGhlIGFyZ3VtZW50cyB0byBwcm92aWRlIHRvIGBmdW5jYC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfE9iamVjdH0gUmV0dXJucyB0aGUgdGltZXIgaWQgb3IgdGltZW91dCBvYmplY3QuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZURlbGF5KGZ1bmMsIHdhaXQsIGFyZ3MpIHtcbiAgICAgIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyBmdW5jLmFwcGx5KHVuZGVmaW5lZCwgYXJncyk7IH0sIHdhaXQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIG1ldGhvZHMgbGlrZSBgXy5kaWZmZXJlbmNlYCB3aXRob3V0IHN1cHBvcnRcbiAgICAgKiBmb3IgZXhjbHVkaW5nIG11bHRpcGxlIGFycmF5cyBvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byBleGNsdWRlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZmlsdGVyZWQgdmFsdWVzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VEaWZmZXJlbmNlKGFycmF5LCB2YWx1ZXMsIGl0ZXJhdGVlLCBjb21wYXJhdG9yKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBpbmNsdWRlcyA9IGFycmF5SW5jbHVkZXMsXG4gICAgICAgICAgaXNDb21tb24gPSB0cnVlLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSBbXSxcbiAgICAgICAgICB2YWx1ZXNMZW5ndGggPSB2YWx1ZXMubGVuZ3RoO1xuXG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuICAgICAgaWYgKGl0ZXJhdGVlKSB7XG4gICAgICAgIHZhbHVlcyA9IGFycmF5TWFwKHZhbHVlcywgYmFzZVVuYXJ5KGl0ZXJhdGVlKSk7XG4gICAgICB9XG4gICAgICBpZiAoY29tcGFyYXRvcikge1xuICAgICAgICBpbmNsdWRlcyA9IGFycmF5SW5jbHVkZXNXaXRoO1xuICAgICAgICBpc0NvbW1vbiA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAodmFsdWVzLmxlbmd0aCA+PSBMQVJHRV9BUlJBWV9TSVpFKSB7XG4gICAgICAgIGluY2x1ZGVzID0gY2FjaGVIYXM7XG4gICAgICAgIGlzQ29tbW9uID0gZmFsc2U7XG4gICAgICAgIHZhbHVlcyA9IG5ldyBTZXRDYWNoZSh2YWx1ZXMpO1xuICAgICAgfVxuICAgICAgb3V0ZXI6XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgICAgICBjb21wdXRlZCA9IGl0ZXJhdGVlID09IG51bGwgPyB2YWx1ZSA6IGl0ZXJhdGVlKHZhbHVlKTtcblxuICAgICAgICB2YWx1ZSA9IChjb21wYXJhdG9yIHx8IHZhbHVlICE9PSAwKSA/IHZhbHVlIDogMDtcbiAgICAgICAgaWYgKGlzQ29tbW9uICYmIGNvbXB1dGVkID09PSBjb21wdXRlZCkge1xuICAgICAgICAgIHZhciB2YWx1ZXNJbmRleCA9IHZhbHVlc0xlbmd0aDtcbiAgICAgICAgICB3aGlsZSAodmFsdWVzSW5kZXgtLSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlc1t2YWx1ZXNJbmRleF0gPT09IGNvbXB1dGVkKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXN1bHQucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIWluY2x1ZGVzKHZhbHVlcywgY29tcHV0ZWQsIGNvbXBhcmF0b3IpKSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvckVhY2hgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fE9iamVjdH0gUmV0dXJucyBgY29sbGVjdGlvbmAuXG4gICAgICovXG4gICAgdmFyIGJhc2VFYWNoID0gY3JlYXRlQmFzZUVhY2goYmFzZUZvck93bik7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JFYWNoUmlnaHRgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fE9iamVjdH0gUmV0dXJucyBgY29sbGVjdGlvbmAuXG4gICAgICovXG4gICAgdmFyIGJhc2VFYWNoUmlnaHQgPSBjcmVhdGVCYXNlRWFjaChiYXNlRm9yT3duUmlnaHQsIHRydWUpO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZXZlcnlgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbGwgZWxlbWVudHMgcGFzcyB0aGUgcHJlZGljYXRlIGNoZWNrLFxuICAgICAqICBlbHNlIGBmYWxzZWBcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRXZlcnkoY29sbGVjdGlvbiwgcHJlZGljYXRlKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gdHJ1ZTtcbiAgICAgIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgICByZXN1bHQgPSAhIXByZWRpY2F0ZSh2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIG1ldGhvZHMgbGlrZSBgXy5tYXhgIGFuZCBgXy5taW5gIHdoaWNoIGFjY2VwdHMgYVxuICAgICAqIGBjb21wYXJhdG9yYCB0byBkZXRlcm1pbmUgdGhlIGV4dHJlbXVtIHZhbHVlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY29tcGFyYXRvciBUaGUgY29tcGFyYXRvciB1c2VkIHRvIGNvbXBhcmUgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBleHRyZW11bSB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRXh0cmVtdW0oYXJyYXksIGl0ZXJhdGVlLCBjb21wYXJhdG9yKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XSxcbiAgICAgICAgICAgIGN1cnJlbnQgPSBpdGVyYXRlZSh2YWx1ZSk7XG5cbiAgICAgICAgaWYgKGN1cnJlbnQgIT0gbnVsbCAmJiAoY29tcHV0ZWQgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICA/IChjdXJyZW50ID09PSBjdXJyZW50ICYmICFpc1N5bWJvbChjdXJyZW50KSlcbiAgICAgICAgICAgICAgOiBjb21wYXJhdG9yKGN1cnJlbnQsIGNvbXB1dGVkKVxuICAgICAgICAgICAgKSkge1xuICAgICAgICAgIHZhciBjb21wdXRlZCA9IGN1cnJlbnQsXG4gICAgICAgICAgICAgIHJlc3VsdCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZpbGxgIHdpdGhvdXQgYW4gaXRlcmF0ZWUgY2FsbCBndWFyZC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGZpbGwuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZmlsbCBgYXJyYXlgIHdpdGguXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtlbmQ9YXJyYXkubGVuZ3RoXSBUaGUgZW5kIHBvc2l0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VGaWxsKGFycmF5LCB2YWx1ZSwgc3RhcnQsIGVuZCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICAgICAgc3RhcnQgPSB0b0ludGVnZXIoc3RhcnQpO1xuICAgICAgaWYgKHN0YXJ0IDwgMCkge1xuICAgICAgICBzdGFydCA9IC1zdGFydCA+IGxlbmd0aCA/IDAgOiAobGVuZ3RoICsgc3RhcnQpO1xuICAgICAgfVxuICAgICAgZW5kID0gKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IGxlbmd0aCkgPyBsZW5ndGggOiB0b0ludGVnZXIoZW5kKTtcbiAgICAgIGlmIChlbmQgPCAwKSB7XG4gICAgICAgIGVuZCArPSBsZW5ndGg7XG4gICAgICB9XG4gICAgICBlbmQgPSBzdGFydCA+IGVuZCA/IDAgOiB0b0xlbmd0aChlbmQpO1xuICAgICAgd2hpbGUgKHN0YXJ0IDwgZW5kKSB7XG4gICAgICAgIGFycmF5W3N0YXJ0KytdID0gdmFsdWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZmlsdGVyYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmaWx0ZXJlZCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRmlsdGVyKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSkge1xuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB7XG4gICAgICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSkge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZsYXR0ZW5gIHdpdGggc3VwcG9ydCBmb3IgcmVzdHJpY3RpbmcgZmxhdHRlbmluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGZsYXR0ZW4uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGRlcHRoIFRoZSBtYXhpbXVtIHJlY3Vyc2lvbiBkZXB0aC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtwcmVkaWNhdGU9aXNGbGF0dGVuYWJsZV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtpc1N0cmljdF0gUmVzdHJpY3QgdG8gdmFsdWVzIHRoYXQgcGFzcyBgcHJlZGljYXRlYCBjaGVja3MuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3Jlc3VsdD1bXV0gVGhlIGluaXRpYWwgcmVzdWx0IHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRmxhdHRlbihhcnJheSwgZGVwdGgsIHByZWRpY2F0ZSwgaXNTdHJpY3QsIHJlc3VsdCkge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgICBwcmVkaWNhdGUgfHwgKHByZWRpY2F0ZSA9IGlzRmxhdHRlbmFibGUpO1xuICAgICAgcmVzdWx0IHx8IChyZXN1bHQgPSBbXSk7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICAgICAgaWYgKGRlcHRoID4gMCAmJiBwcmVkaWNhdGUodmFsdWUpKSB7XG4gICAgICAgICAgaWYgKGRlcHRoID4gMSkge1xuICAgICAgICAgICAgLy8gUmVjdXJzaXZlbHkgZmxhdHRlbiBhcnJheXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICAgICAgICAgIGJhc2VGbGF0dGVuKHZhbHVlLCBkZXB0aCAtIDEsIHByZWRpY2F0ZSwgaXNTdHJpY3QsIHJlc3VsdCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFycmF5UHVzaChyZXN1bHQsIHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoIWlzU3RyaWN0KSB7XG4gICAgICAgICAgcmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGJhc2VGb3JPd25gIHdoaWNoIGl0ZXJhdGVzIG92ZXIgYG9iamVjdGBcbiAgICAgKiBwcm9wZXJ0aWVzIHJldHVybmVkIGJ5IGBrZXlzRnVuY2AgYW5kIGludm9rZXMgYGl0ZXJhdGVlYCBmb3IgZWFjaCBwcm9wZXJ0eS5cbiAgICAgKiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXQgaXRlcmF0aW9uIGVhcmx5IGJ5IGV4cGxpY2l0bHkgcmV0dXJuaW5nIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBrZXlzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBrZXlzIG9mIGBvYmplY3RgLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICovXG4gICAgdmFyIGJhc2VGb3IgPSBjcmVhdGVCYXNlRm9yKCk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGJhc2VGb3JgIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgcHJvcGVydGllc1xuICAgICAqIGluIHRoZSBvcHBvc2l0ZSBvcmRlci5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGtleXNGdW5jIFRoZSBmdW5jdGlvbiB0byBnZXQgdGhlIGtleXMgb2YgYG9iamVjdGAuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICB2YXIgYmFzZUZvclJpZ2h0ID0gY3JlYXRlQmFzZUZvcih0cnVlKTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvck93bmAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRm9yT3duKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiBvYmplY3QgJiYgYmFzZUZvcihvYmplY3QsIGl0ZXJhdGVlLCBrZXlzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JPd25SaWdodGAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlRm9yT3duUmlnaHQob2JqZWN0LCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIG9iamVjdCAmJiBiYXNlRm9yUmlnaHQob2JqZWN0LCBpdGVyYXRlZSwga2V5cyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZnVuY3Rpb25zYCB3aGljaCBjcmVhdGVzIGFuIGFycmF5IG9mXG4gICAgICogYG9iamVjdGAgZnVuY3Rpb24gcHJvcGVydHkgbmFtZXMgZmlsdGVyZWQgZnJvbSBgcHJvcHNgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgbmFtZXMgdG8gZmlsdGVyLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgZnVuY3Rpb24gbmFtZXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUZ1bmN0aW9ucyhvYmplY3QsIHByb3BzKSB7XG4gICAgICByZXR1cm4gYXJyYXlGaWx0ZXIocHJvcHMsIGZ1bmN0aW9uKGtleSkge1xuICAgICAgICByZXR1cm4gaXNGdW5jdGlvbihvYmplY3Rba2V5XSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5nZXRgIHdpdGhvdXQgc3VwcG9ydCBmb3IgZGVmYXVsdCB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlR2V0KG9iamVjdCwgcGF0aCkge1xuICAgICAgcGF0aCA9IGNhc3RQYXRoKHBhdGgsIG9iamVjdCk7XG5cbiAgICAgIHZhciBpbmRleCA9IDAsXG4gICAgICAgICAgbGVuZ3RoID0gcGF0aC5sZW5ndGg7XG5cbiAgICAgIHdoaWxlIChvYmplY3QgIT0gbnVsbCAmJiBpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICBvYmplY3QgPSBvYmplY3RbdG9LZXkocGF0aFtpbmRleCsrXSldO1xuICAgICAgfVxuICAgICAgcmV0dXJuIChpbmRleCAmJiBpbmRleCA9PSBsZW5ndGgpID8gb2JqZWN0IDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBnZXRBbGxLZXlzYCBhbmQgYGdldEFsbEtleXNJbmAgd2hpY2ggdXNlc1xuICAgICAqIGBrZXlzRnVuY2AgYW5kIGBzeW1ib2xzRnVuY2AgdG8gZ2V0IHRoZSBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIGFuZFxuICAgICAqIHN5bWJvbHMgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBrZXlzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBrZXlzIG9mIGBvYmplY3RgLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHN5bWJvbHNGdW5jIFRoZSBmdW5jdGlvbiB0byBnZXQgdGhlIHN5bWJvbHMgb2YgYG9iamVjdGAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlR2V0QWxsS2V5cyhvYmplY3QsIGtleXNGdW5jLCBzeW1ib2xzRnVuYykge1xuICAgICAgdmFyIHJlc3VsdCA9IGtleXNGdW5jKG9iamVjdCk7XG4gICAgICByZXR1cm4gaXNBcnJheShvYmplY3QpID8gcmVzdWx0IDogYXJyYXlQdXNoKHJlc3VsdCwgc3ltYm9sc0Z1bmMob2JqZWN0KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldFRhZ2Agd2l0aG91dCBmYWxsYmFja3MgZm9yIGJ1Z2d5IGVudmlyb25tZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgYHRvU3RyaW5nVGFnYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlR2V0VGFnKHZhbHVlKSB7XG4gICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZFRhZyA6IG51bGxUYWc7XG4gICAgICB9XG4gICAgICByZXR1cm4gKHN5bVRvU3RyaW5nVGFnICYmIHN5bVRvU3RyaW5nVGFnIGluIE9iamVjdCh2YWx1ZSkpXG4gICAgICAgID8gZ2V0UmF3VGFnKHZhbHVlKVxuICAgICAgICA6IG9iamVjdFRvU3RyaW5nKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5ndGAgd2hpY2ggZG9lc24ndCBjb2VyY2UgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZ3JlYXRlciB0aGFuIGBvdGhlcmAsXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlR3QodmFsdWUsIG90aGVyKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPiBvdGhlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5oYXNgIHdpdGhvdXQgc3VwcG9ydCBmb3IgZGVlcCBwYXRocy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IGtleSBUaGUga2V5IHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSGFzKG9iamVjdCwga2V5KSB7XG4gICAgICByZXR1cm4gb2JqZWN0ICE9IG51bGwgJiYgaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaGFzSW5gIHdpdGhvdXQgc3VwcG9ydCBmb3IgZGVlcCBwYXRocy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IGtleSBUaGUga2V5IHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBga2V5YCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSGFzSW4ob2JqZWN0LCBrZXkpIHtcbiAgICAgIHJldHVybiBvYmplY3QgIT0gbnVsbCAmJiBrZXkgaW4gT2JqZWN0KG9iamVjdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaW5SYW5nZWAgd2hpY2ggZG9lc24ndCBjb2VyY2UgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbnVtYmVyIFRoZSBudW1iZXIgdG8gY2hlY2suXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IFRoZSBzdGFydCBvZiB0aGUgcmFuZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGVuZCBUaGUgZW5kIG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG51bWJlcmAgaXMgaW4gdGhlIHJhbmdlLCBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUluUmFuZ2UobnVtYmVyLCBzdGFydCwgZW5kKSB7XG4gICAgICByZXR1cm4gbnVtYmVyID49IG5hdGl2ZU1pbihzdGFydCwgZW5kKSAmJiBudW1iZXIgPCBuYXRpdmVNYXgoc3RhcnQsIGVuZCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgbWV0aG9kcyBsaWtlIGBfLmludGVyc2VjdGlvbmAsIHdpdGhvdXQgc3VwcG9ydFxuICAgICAqIGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLCB0aGF0IGFjY2VwdHMgYW4gYXJyYXkgb2YgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5cyBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlXSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBzaGFyZWQgdmFsdWVzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJbnRlcnNlY3Rpb24oYXJyYXlzLCBpdGVyYXRlZSwgY29tcGFyYXRvcikge1xuICAgICAgdmFyIGluY2x1ZGVzID0gY29tcGFyYXRvciA/IGFycmF5SW5jbHVkZXNXaXRoIDogYXJyYXlJbmNsdWRlcyxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheXNbMF0ubGVuZ3RoLFxuICAgICAgICAgIG90aExlbmd0aCA9IGFycmF5cy5sZW5ndGgsXG4gICAgICAgICAgb3RoSW5kZXggPSBvdGhMZW5ndGgsXG4gICAgICAgICAgY2FjaGVzID0gQXJyYXkob3RoTGVuZ3RoKSxcbiAgICAgICAgICBtYXhMZW5ndGggPSBJbmZpbml0eSxcbiAgICAgICAgICByZXN1bHQgPSBbXTtcblxuICAgICAgd2hpbGUgKG90aEluZGV4LS0pIHtcbiAgICAgICAgdmFyIGFycmF5ID0gYXJyYXlzW290aEluZGV4XTtcbiAgICAgICAgaWYgKG90aEluZGV4ICYmIGl0ZXJhdGVlKSB7XG4gICAgICAgICAgYXJyYXkgPSBhcnJheU1hcChhcnJheSwgYmFzZVVuYXJ5KGl0ZXJhdGVlKSk7XG4gICAgICAgIH1cbiAgICAgICAgbWF4TGVuZ3RoID0gbmF0aXZlTWluKGFycmF5Lmxlbmd0aCwgbWF4TGVuZ3RoKTtcbiAgICAgICAgY2FjaGVzW290aEluZGV4XSA9ICFjb21wYXJhdG9yICYmIChpdGVyYXRlZSB8fCAobGVuZ3RoID49IDEyMCAmJiBhcnJheS5sZW5ndGggPj0gMTIwKSlcbiAgICAgICAgICA/IG5ldyBTZXRDYWNoZShvdGhJbmRleCAmJiBhcnJheSlcbiAgICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGFycmF5ID0gYXJyYXlzWzBdO1xuXG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBzZWVuID0gY2FjaGVzWzBdO1xuXG4gICAgICBvdXRlcjpcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoICYmIHJlc3VsdC5sZW5ndGggPCBtYXhMZW5ndGgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdLFxuICAgICAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZSA/IGl0ZXJhdGVlKHZhbHVlKSA6IHZhbHVlO1xuXG4gICAgICAgIHZhbHVlID0gKGNvbXBhcmF0b3IgfHwgdmFsdWUgIT09IDApID8gdmFsdWUgOiAwO1xuICAgICAgICBpZiAoIShzZWVuXG4gICAgICAgICAgICAgID8gY2FjaGVIYXMoc2VlbiwgY29tcHV0ZWQpXG4gICAgICAgICAgICAgIDogaW5jbHVkZXMocmVzdWx0LCBjb21wdXRlZCwgY29tcGFyYXRvcilcbiAgICAgICAgICAgICkpIHtcbiAgICAgICAgICBvdGhJbmRleCA9IG90aExlbmd0aDtcbiAgICAgICAgICB3aGlsZSAoLS1vdGhJbmRleCkge1xuICAgICAgICAgICAgdmFyIGNhY2hlID0gY2FjaGVzW290aEluZGV4XTtcbiAgICAgICAgICAgIGlmICghKGNhY2hlXG4gICAgICAgICAgICAgICAgICA/IGNhY2hlSGFzKGNhY2hlLCBjb21wdXRlZClcbiAgICAgICAgICAgICAgICAgIDogaW5jbHVkZXMoYXJyYXlzW290aEluZGV4XSwgY29tcHV0ZWQsIGNvbXBhcmF0b3IpKVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICBjb250aW51ZSBvdXRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHNlZW4pIHtcbiAgICAgICAgICAgIHNlZW4ucHVzaChjb21wdXRlZCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pbnZlcnRgIGFuZCBgXy5pbnZlcnRCeWAgd2hpY2ggaW52ZXJ0c1xuICAgICAqIGBvYmplY3RgIHdpdGggdmFsdWVzIHRyYW5zZm9ybWVkIGJ5IGBpdGVyYXRlZWAgYW5kIHNldCBieSBgc2V0dGVyYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZXR0ZXIgVGhlIGZ1bmN0aW9uIHRvIHNldCBgYWNjdW11bGF0b3JgIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgaXRlcmF0ZWUgdG8gdHJhbnNmb3JtIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gYWNjdW11bGF0b3IgVGhlIGluaXRpYWwgaW52ZXJ0ZWQgb2JqZWN0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgYWNjdW11bGF0b3JgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJbnZlcnRlcihvYmplY3QsIHNldHRlciwgaXRlcmF0ZWUsIGFjY3VtdWxhdG9yKSB7XG4gICAgICBiYXNlRm9yT3duKG9iamVjdCwgZnVuY3Rpb24odmFsdWUsIGtleSwgb2JqZWN0KSB7XG4gICAgICAgIHNldHRlcihhY2N1bXVsYXRvciwgaXRlcmF0ZWUodmFsdWUpLCBrZXksIG9iamVjdCk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBhY2N1bXVsYXRvcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pbnZva2VgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaW5kaXZpZHVhbFxuICAgICAqIG1ldGhvZCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgbWV0aG9kIHRvIGludm9rZS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcmdzIFRoZSBhcmd1bWVudHMgdG8gaW52b2tlIHRoZSBtZXRob2Qgd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSBpbnZva2VkIG1ldGhvZC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSW52b2tlKG9iamVjdCwgcGF0aCwgYXJncykge1xuICAgICAgcGF0aCA9IGNhc3RQYXRoKHBhdGgsIG9iamVjdCk7XG4gICAgICBvYmplY3QgPSBwYXJlbnQob2JqZWN0LCBwYXRoKTtcbiAgICAgIHZhciBmdW5jID0gb2JqZWN0ID09IG51bGwgPyBvYmplY3QgOiBvYmplY3RbdG9LZXkobGFzdChwYXRoKSldO1xuICAgICAgcmV0dXJuIGZ1bmMgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IGFwcGx5KGZ1bmMsIG9iamVjdCwgYXJncyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNBcmd1bWVudHNgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBgYXJndW1lbnRzYCBvYmplY3QsXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUlzQXJndW1lbnRzKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBiYXNlR2V0VGFnKHZhbHVlKSA9PSBhcmdzVGFnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzQXJyYXlCdWZmZXJgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBhcnJheSBidWZmZXIsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXNBcnJheUJ1ZmZlcih2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gYXJyYXlCdWZmZXJUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNEYXRlYCB3aXRob3V0IE5vZGUuanMgb3B0aW1pemF0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBkYXRlIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc0RhdGUodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IGRhdGVUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNFcXVhbGAgd2hpY2ggc3VwcG9ydHMgcGFydGlhbCBjb21wYXJpc29uc1xuICAgICAqIGFuZCB0cmFja3MgdHJhdmVyc2VkIG9iamVjdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuXG4gICAgICogIDEgLSBVbm9yZGVyZWQgY29tcGFyaXNvblxuICAgICAqICAyIC0gUGFydGlhbCBjb21wYXJpc29uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBgdmFsdWVgIGFuZCBgb3RoZXJgIG9iamVjdHMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXNFcXVhbCh2YWx1ZSwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSB7XG4gICAgICBpZiAodmFsdWUgPT09IG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKHZhbHVlID09IG51bGwgfHwgb3RoZXIgPT0gbnVsbCB8fCAoIWlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgIWlzT2JqZWN0TGlrZShvdGhlcikpKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZSAhPT0gdmFsdWUgJiYgb3RoZXIgIT09IG90aGVyO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VJc0VxdWFsRGVlcCh2YWx1ZSwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGJhc2VJc0VxdWFsLCBzdGFjayk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbGAgZm9yIGFycmF5cyBhbmQgb2JqZWN0cyB3aGljaCBwZXJmb3Jtc1xuICAgICAqIGRlZXAgY29tcGFyaXNvbnMgYW5kIHRyYWNrcyB0cmF2ZXJzZWQgb2JqZWN0cyBlbmFibGluZyBvYmplY3RzIHdpdGggY2lyY3VsYXJcbiAgICAgKiByZWZlcmVuY2VzIHRvIGJlIGNvbXBhcmVkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBgb2JqZWN0YCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc0VxdWFsRGVlcChvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7XG4gICAgICB2YXIgb2JqSXNBcnIgPSBpc0FycmF5KG9iamVjdCksXG4gICAgICAgICAgb3RoSXNBcnIgPSBpc0FycmF5KG90aGVyKSxcbiAgICAgICAgICBvYmpUYWcgPSBvYmpJc0FyciA/IGFycmF5VGFnIDogZ2V0VGFnKG9iamVjdCksXG4gICAgICAgICAgb3RoVGFnID0gb3RoSXNBcnIgPyBhcnJheVRhZyA6IGdldFRhZyhvdGhlcik7XG5cbiAgICAgIG9ialRhZyA9IG9ialRhZyA9PSBhcmdzVGFnID8gb2JqZWN0VGFnIDogb2JqVGFnO1xuICAgICAgb3RoVGFnID0gb3RoVGFnID09IGFyZ3NUYWcgPyBvYmplY3RUYWcgOiBvdGhUYWc7XG5cbiAgICAgIHZhciBvYmpJc09iaiA9IG9ialRhZyA9PSBvYmplY3RUYWcsXG4gICAgICAgICAgb3RoSXNPYmogPSBvdGhUYWcgPT0gb2JqZWN0VGFnLFxuICAgICAgICAgIGlzU2FtZVRhZyA9IG9ialRhZyA9PSBvdGhUYWc7XG5cbiAgICAgIGlmIChpc1NhbWVUYWcgJiYgaXNCdWZmZXIob2JqZWN0KSkge1xuICAgICAgICBpZiAoIWlzQnVmZmVyKG90aGVyKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBvYmpJc0FyciA9IHRydWU7XG4gICAgICAgIG9iaklzT2JqID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoaXNTYW1lVGFnICYmICFvYmpJc09iaikge1xuICAgICAgICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2spO1xuICAgICAgICByZXR1cm4gKG9iaklzQXJyIHx8IGlzVHlwZWRBcnJheShvYmplY3QpKVxuICAgICAgICAgID8gZXF1YWxBcnJheXMob2JqZWN0LCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaylcbiAgICAgICAgICA6IGVxdWFsQnlUYWcob2JqZWN0LCBvdGhlciwgb2JqVGFnLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTtcbiAgICAgIH1cbiAgICAgIGlmICghKGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRykpIHtcbiAgICAgICAgdmFyIG9iaklzV3JhcHBlZCA9IG9iaklzT2JqICYmIGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCAnX193cmFwcGVkX18nKSxcbiAgICAgICAgICAgIG90aElzV3JhcHBlZCA9IG90aElzT2JqICYmIGhhc093blByb3BlcnR5LmNhbGwob3RoZXIsICdfX3dyYXBwZWRfXycpO1xuXG4gICAgICAgIGlmIChvYmpJc1dyYXBwZWQgfHwgb3RoSXNXcmFwcGVkKSB7XG4gICAgICAgICAgdmFyIG9ialVud3JhcHBlZCA9IG9iaklzV3JhcHBlZCA/IG9iamVjdC52YWx1ZSgpIDogb2JqZWN0LFxuICAgICAgICAgICAgICBvdGhVbndyYXBwZWQgPSBvdGhJc1dyYXBwZWQgPyBvdGhlci52YWx1ZSgpIDogb3RoZXI7XG5cbiAgICAgICAgICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2spO1xuICAgICAgICAgIHJldHVybiBlcXVhbEZ1bmMob2JqVW53cmFwcGVkLCBvdGhVbndyYXBwZWQsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCFpc1NhbWVUYWcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgICAgIHJldHVybiBlcXVhbE9iamVjdHMob2JqZWN0LCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjayk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNNYXBgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG1hcCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc01hcCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgZ2V0VGFnKHZhbHVlKSA9PSBtYXBUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNNYXRjaGAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgdmFsdWVzIHRvIG1hdGNoLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IG1hdGNoRGF0YSBUaGUgcHJvcGVydHkgbmFtZXMsIHZhbHVlcywgYW5kIGNvbXBhcmUgZmxhZ3MgdG8gbWF0Y2guXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBvYmplY3RgIGlzIGEgbWF0Y2gsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXNNYXRjaChvYmplY3QsIHNvdXJjZSwgbWF0Y2hEYXRhLCBjdXN0b21pemVyKSB7XG4gICAgICB2YXIgaW5kZXggPSBtYXRjaERhdGEubGVuZ3RoLFxuICAgICAgICAgIGxlbmd0aCA9IGluZGV4LFxuICAgICAgICAgIG5vQ3VzdG9taXplciA9ICFjdXN0b21pemVyO1xuXG4gICAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuICFsZW5ndGg7XG4gICAgICB9XG4gICAgICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTtcbiAgICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICAgIHZhciBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTtcbiAgICAgICAgaWYgKChub0N1c3RvbWl6ZXIgJiYgZGF0YVsyXSlcbiAgICAgICAgICAgICAgPyBkYXRhWzFdICE9PSBvYmplY3RbZGF0YVswXV1cbiAgICAgICAgICAgICAgOiAhKGRhdGFbMF0gaW4gb2JqZWN0KVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTtcbiAgICAgICAgdmFyIGtleSA9IGRhdGFbMF0sXG4gICAgICAgICAgICBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgICAgICAgc3JjVmFsdWUgPSBkYXRhWzFdO1xuXG4gICAgICAgIGlmIChub0N1c3RvbWl6ZXIgJiYgZGF0YVsyXSkge1xuICAgICAgICAgIGlmIChvYmpWYWx1ZSA9PT0gdW5kZWZpbmVkICYmICEoa2V5IGluIG9iamVjdCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIHN0YWNrID0gbmV3IFN0YWNrO1xuICAgICAgICAgIGlmIChjdXN0b21pemVyKSB7XG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gY3VzdG9taXplcihvYmpWYWx1ZSwgc3JjVmFsdWUsIGtleSwgb2JqZWN0LCBzb3VyY2UsIHN0YWNrKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCEocmVzdWx0ID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICA/IGJhc2VJc0VxdWFsKHNyY1ZhbHVlLCBvYmpWYWx1ZSwgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgfCBDT01QQVJFX1VOT1JERVJFRF9GTEFHLCBjdXN0b21pemVyLCBzdGFjaylcbiAgICAgICAgICAgICAgICA6IHJlc3VsdFxuICAgICAgICAgICAgICApKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc05hdGl2ZWAgd2l0aG91dCBiYWQgc2hpbSBjaGVja3MuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgbmF0aXZlIGZ1bmN0aW9uLFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZUlzTmF0aXZlKHZhbHVlKSB7XG4gICAgICBpZiAoIWlzT2JqZWN0KHZhbHVlKSB8fCBpc01hc2tlZCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIHBhdHRlcm4gPSBpc0Z1bmN0aW9uKHZhbHVlKSA/IHJlSXNOYXRpdmUgOiByZUlzSG9zdEN0b3I7XG4gICAgICByZXR1cm4gcGF0dGVybi50ZXN0KHRvU291cmNlKHZhbHVlKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNSZWdFeHBgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHJlZ2V4cCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VJc1JlZ0V4cCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gcmVnZXhwVGFnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzU2V0YCB3aXRob3V0IE5vZGUuanMgb3B0aW1pemF0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBzZXQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXNTZXQodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGdldFRhZyh2YWx1ZSkgPT0gc2V0VGFnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzVHlwZWRBcnJheWAgd2l0aG91dCBOb2RlLmpzIG9wdGltaXphdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdHlwZWQgYXJyYXksIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXNUeXBlZEFycmF5KHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJlxuICAgICAgICBpc0xlbmd0aCh2YWx1ZS5sZW5ndGgpICYmICEhdHlwZWRBcnJheVRhZ3NbYmFzZUdldFRhZyh2YWx1ZSldO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLml0ZXJhdGVlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSBbdmFsdWU9Xy5pZGVudGl0eV0gVGhlIHZhbHVlIHRvIGNvbnZlcnQgdG8gYW4gaXRlcmF0ZWUuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBpdGVyYXRlZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlSXRlcmF0ZWUodmFsdWUpIHtcbiAgICAgIC8vIERvbid0IHN0b3JlIHRoZSBgdHlwZW9mYCByZXN1bHQgaW4gYSB2YXJpYWJsZSB0byBhdm9pZCBhIEpJVCBidWcgaW4gU2FmYXJpIDkuXG4gICAgICAvLyBTZWUgaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE1NjAzNCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBpZGVudGl0eTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgcmV0dXJuIGlzQXJyYXkodmFsdWUpXG4gICAgICAgICAgPyBiYXNlTWF0Y2hlc1Byb3BlcnR5KHZhbHVlWzBdLCB2YWx1ZVsxXSlcbiAgICAgICAgICA6IGJhc2VNYXRjaGVzKHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBwcm9wZXJ0eSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ua2V5c2Agd2hpY2ggZG9lc24ndCB0cmVhdCBzcGFyc2UgYXJyYXlzIGFzIGRlbnNlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlS2V5cyhvYmplY3QpIHtcbiAgICAgIGlmICghaXNQcm90b3R5cGUob2JqZWN0KSkge1xuICAgICAgICByZXR1cm4gbmF0aXZlS2V5cyhvYmplY3QpO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgZm9yICh2YXIga2V5IGluIE9iamVjdChvYmplY3QpKSB7XG4gICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSAmJiBrZXkgIT0gJ2NvbnN0cnVjdG9yJykge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ua2V5c0luYCB3aGljaCBkb2Vzbid0IHRyZWF0IHNwYXJzZSBhcnJheXMgYXMgZGVuc2UuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VLZXlzSW4ob2JqZWN0KSB7XG4gICAgICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUtleXNJbihvYmplY3QpO1xuICAgICAgfVxuICAgICAgdmFyIGlzUHJvdG8gPSBpc1Byb3RvdHlwZShvYmplY3QpLFxuICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICBmb3IgKHZhciBrZXkgaW4gb2JqZWN0KSB7XG4gICAgICAgIGlmICghKGtleSA9PSAnY29uc3RydWN0b3InICYmIChpc1Byb3RvIHx8ICFoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkpKSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2goa2V5KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5sdGAgd2hpY2ggZG9lc24ndCBjb2VyY2UgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgbGVzcyB0aGFuIGBvdGhlcmAsXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlTHQodmFsdWUsIG90aGVyKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPCBvdGhlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXBgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VNYXAoY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIHJlc3VsdCA9IGlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pID8gQXJyYXkoY29sbGVjdGlvbi5sZW5ndGgpIDogW107XG5cbiAgICAgIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pIHtcbiAgICAgICAgcmVzdWx0WysraW5kZXhdID0gaXRlcmF0ZWUodmFsdWUsIGtleSwgY29sbGVjdGlvbik7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWF0Y2hlc2Agd2hpY2ggZG9lc24ndCBjbG9uZSBgc291cmNlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHZhbHVlcyB0byBtYXRjaC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VNYXRjaGVzKHNvdXJjZSkge1xuICAgICAgdmFyIG1hdGNoRGF0YSA9IGdldE1hdGNoRGF0YShzb3VyY2UpO1xuICAgICAgaWYgKG1hdGNoRGF0YS5sZW5ndGggPT0gMSAmJiBtYXRjaERhdGFbMF1bMl0pIHtcbiAgICAgICAgcmV0dXJuIG1hdGNoZXNTdHJpY3RDb21wYXJhYmxlKG1hdGNoRGF0YVswXVswXSwgbWF0Y2hEYXRhWzBdWzFdKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdCA9PT0gc291cmNlIHx8IGJhc2VJc01hdGNoKG9iamVjdCwgc291cmNlLCBtYXRjaERhdGEpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXRjaGVzUHJvcGVydHlgIHdoaWNoIGRvZXNuJ3QgY2xvbmUgYHNyY1ZhbHVlYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAgICAgKiBAcGFyYW0geyp9IHNyY1ZhbHVlIFRoZSB2YWx1ZSB0byBtYXRjaC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VNYXRjaGVzUHJvcGVydHkocGF0aCwgc3JjVmFsdWUpIHtcbiAgICAgIGlmIChpc0tleShwYXRoKSAmJiBpc1N0cmljdENvbXBhcmFibGUoc3JjVmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBtYXRjaGVzU3RyaWN0Q29tcGFyYWJsZSh0b0tleShwYXRoKSwgc3JjVmFsdWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgICB2YXIgb2JqVmFsdWUgPSBnZXQob2JqZWN0LCBwYXRoKTtcbiAgICAgICAgcmV0dXJuIChvYmpWYWx1ZSA9PT0gdW5kZWZpbmVkICYmIG9ialZhbHVlID09PSBzcmNWYWx1ZSlcbiAgICAgICAgICA/IGhhc0luKG9iamVjdCwgcGF0aClcbiAgICAgICAgICA6IGJhc2VJc0VxdWFsKHNyY1ZhbHVlLCBvYmpWYWx1ZSwgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgfCBDT01QQVJFX1VOT1JERVJFRF9GTEFHKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWVyZ2VgIHdpdGhvdXQgc3VwcG9ydCBmb3IgbXVsdGlwbGUgc291cmNlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHNyY0luZGV4IFRoZSBpbmRleCBvZiBgc291cmNlYC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBtZXJnZWQgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbc3RhY2tdIFRyYWNrcyB0cmF2ZXJzZWQgc291cmNlIHZhbHVlcyBhbmQgdGhlaXIgbWVyZ2VkXG4gICAgICogIGNvdW50ZXJwYXJ0cy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlTWVyZ2Uob2JqZWN0LCBzb3VyY2UsIHNyY0luZGV4LCBjdXN0b21pemVyLCBzdGFjaykge1xuICAgICAgaWYgKG9iamVjdCA9PT0gc291cmNlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGJhc2VGb3Ioc291cmNlLCBmdW5jdGlvbihzcmNWYWx1ZSwga2V5KSB7XG4gICAgICAgIGlmIChpc09iamVjdChzcmNWYWx1ZSkpIHtcbiAgICAgICAgICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2spO1xuICAgICAgICAgIGJhc2VNZXJnZURlZXAob2JqZWN0LCBzb3VyY2UsIGtleSwgc3JjSW5kZXgsIGJhc2VNZXJnZSwgY3VzdG9taXplciwgc3RhY2spO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHZhciBuZXdWYWx1ZSA9IGN1c3RvbWl6ZXJcbiAgICAgICAgICAgID8gY3VzdG9taXplcihzYWZlR2V0KG9iamVjdCwga2V5KSwgc3JjVmFsdWUsIChrZXkgKyAnJyksIG9iamVjdCwgc291cmNlLCBzdGFjaylcbiAgICAgICAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgaWYgKG5ld1ZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gc3JjVmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGFzc2lnbk1lcmdlVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSwga2V5c0luKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VNZXJnZWAgZm9yIGFycmF5cyBhbmQgb2JqZWN0cyB3aGljaCBwZXJmb3Jtc1xuICAgICAqIGRlZXAgbWVyZ2VzIGFuZCB0cmFja3MgdHJhdmVyc2VkIG9iamVjdHMgZW5hYmxpbmcgb2JqZWN0cyB3aXRoIGNpcmN1bGFyXG4gICAgICogcmVmZXJlbmNlcyB0byBiZSBtZXJnZWQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBzb3VyY2Ugb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gbWVyZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHNyY0luZGV4IFRoZSBpbmRleCBvZiBgc291cmNlYC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBtZXJnZUZ1bmMgVGhlIGZ1bmN0aW9uIHRvIG1lcmdlIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBhc3NpZ25lZCB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBzb3VyY2UgdmFsdWVzIGFuZCB0aGVpciBtZXJnZWRcbiAgICAgKiAgY291bnRlcnBhcnRzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VNZXJnZURlZXAob2JqZWN0LCBzb3VyY2UsIGtleSwgc3JjSW5kZXgsIG1lcmdlRnVuYywgY3VzdG9taXplciwgc3RhY2spIHtcbiAgICAgIHZhciBvYmpWYWx1ZSA9IHNhZmVHZXQob2JqZWN0LCBrZXkpLFxuICAgICAgICAgIHNyY1ZhbHVlID0gc2FmZUdldChzb3VyY2UsIGtleSksXG4gICAgICAgICAgc3RhY2tlZCA9IHN0YWNrLmdldChzcmNWYWx1ZSk7XG5cbiAgICAgIGlmIChzdGFja2VkKSB7XG4gICAgICAgIGFzc2lnbk1lcmdlVmFsdWUob2JqZWN0LCBrZXksIHN0YWNrZWQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2YXIgbmV3VmFsdWUgPSBjdXN0b21pemVyXG4gICAgICAgID8gY3VzdG9taXplcihvYmpWYWx1ZSwgc3JjVmFsdWUsIChrZXkgKyAnJyksIG9iamVjdCwgc291cmNlLCBzdGFjaylcbiAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgIHZhciBpc0NvbW1vbiA9IG5ld1ZhbHVlID09PSB1bmRlZmluZWQ7XG5cbiAgICAgIGlmIChpc0NvbW1vbikge1xuICAgICAgICB2YXIgaXNBcnIgPSBpc0FycmF5KHNyY1ZhbHVlKSxcbiAgICAgICAgICAgIGlzQnVmZiA9ICFpc0FyciAmJiBpc0J1ZmZlcihzcmNWYWx1ZSksXG4gICAgICAgICAgICBpc1R5cGVkID0gIWlzQXJyICYmICFpc0J1ZmYgJiYgaXNUeXBlZEFycmF5KHNyY1ZhbHVlKTtcblxuICAgICAgICBuZXdWYWx1ZSA9IHNyY1ZhbHVlO1xuICAgICAgICBpZiAoaXNBcnIgfHwgaXNCdWZmIHx8IGlzVHlwZWQpIHtcbiAgICAgICAgICBpZiAoaXNBcnJheShvYmpWYWx1ZSkpIHtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gb2JqVmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYgKGlzQXJyYXlMaWtlT2JqZWN0KG9ialZhbHVlKSkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBjb3B5QXJyYXkob2JqVmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmIChpc0J1ZmYpIHtcbiAgICAgICAgICAgIGlzQ29tbW9uID0gZmFsc2U7XG4gICAgICAgICAgICBuZXdWYWx1ZSA9IGNsb25lQnVmZmVyKHNyY1ZhbHVlLCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSBpZiAoaXNUeXBlZCkge1xuICAgICAgICAgICAgaXNDb21tb24gPSBmYWxzZTtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gY2xvbmVUeXBlZEFycmF5KHNyY1ZhbHVlLCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBuZXdWYWx1ZSA9IFtdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc1BsYWluT2JqZWN0KHNyY1ZhbHVlKSB8fCBpc0FyZ3VtZW50cyhzcmNWYWx1ZSkpIHtcbiAgICAgICAgICBuZXdWYWx1ZSA9IG9ialZhbHVlO1xuICAgICAgICAgIGlmIChpc0FyZ3VtZW50cyhvYmpWYWx1ZSkpIHtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gdG9QbGFpbk9iamVjdChvYmpWYWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYgKCFpc09iamVjdChvYmpWYWx1ZSkgfHwgaXNGdW5jdGlvbihvYmpWYWx1ZSkpIHtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gaW5pdENsb25lT2JqZWN0KHNyY1ZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgaXNDb21tb24gPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGlzQ29tbW9uKSB7XG4gICAgICAgIC8vIFJlY3Vyc2l2ZWx5IG1lcmdlIG9iamVjdHMgYW5kIGFycmF5cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgICBzdGFjay5zZXQoc3JjVmFsdWUsIG5ld1ZhbHVlKTtcbiAgICAgICAgbWVyZ2VGdW5jKG5ld1ZhbHVlLCBzcmNWYWx1ZSwgc3JjSW5kZXgsIGN1c3RvbWl6ZXIsIHN0YWNrKTtcbiAgICAgICAgc3RhY2tbJ2RlbGV0ZSddKHNyY1ZhbHVlKTtcbiAgICAgIH1cbiAgICAgIGFzc2lnbk1lcmdlVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5udGhgIHdoaWNoIGRvZXNuJ3QgY29lcmNlIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG50aCBlbGVtZW50IG9mIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZU50aChhcnJheSwgbikge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIG4gKz0gbiA8IDAgPyBsZW5ndGggOiAwO1xuICAgICAgcmV0dXJuIGlzSW5kZXgobiwgbGVuZ3RoKSA/IGFycmF5W25dIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm9yZGVyQnlgIHdpdGhvdXQgcGFyYW0gZ3VhcmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfE9iamVjdFtdfHN0cmluZ1tdfSBpdGVyYXRlZXMgVGhlIGl0ZXJhdGVlcyB0byBzb3J0IGJ5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nW119IG9yZGVycyBUaGUgc29ydCBvcmRlcnMgb2YgYGl0ZXJhdGVlc2AuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgc29ydGVkIGFycmF5LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VPcmRlckJ5KGNvbGxlY3Rpb24sIGl0ZXJhdGVlcywgb3JkZXJzKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMTtcbiAgICAgIGl0ZXJhdGVlcyA9IGFycmF5TWFwKGl0ZXJhdGVlcy5sZW5ndGggPyBpdGVyYXRlZXMgOiBbaWRlbnRpdHldLCBiYXNlVW5hcnkoZ2V0SXRlcmF0ZWUoKSkpO1xuXG4gICAgICB2YXIgcmVzdWx0ID0gYmFzZU1hcChjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSB7XG4gICAgICAgIHZhciBjcml0ZXJpYSA9IGFycmF5TWFwKGl0ZXJhdGVlcywgZnVuY3Rpb24oaXRlcmF0ZWUpIHtcbiAgICAgICAgICByZXR1cm4gaXRlcmF0ZWUodmFsdWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHsgJ2NyaXRlcmlhJzogY3JpdGVyaWEsICdpbmRleCc6ICsraW5kZXgsICd2YWx1ZSc6IHZhbHVlIH07XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGJhc2VTb3J0QnkocmVzdWx0LCBmdW5jdGlvbihvYmplY3QsIG90aGVyKSB7XG4gICAgICAgIHJldHVybiBjb21wYXJlTXVsdGlwbGUob2JqZWN0LCBvdGhlciwgb3JkZXJzKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnBpY2tgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaW5kaXZpZHVhbFxuICAgICAqIHByb3BlcnR5IGlkZW50aWZpZXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBzb3VyY2Ugb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nW119IHBhdGhzIFRoZSBwcm9wZXJ0eSBwYXRocyB0byBwaWNrLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVBpY2sob2JqZWN0LCBwYXRocykge1xuICAgICAgcmV0dXJuIGJhc2VQaWNrQnkob2JqZWN0LCBwYXRocywgZnVuY3Rpb24odmFsdWUsIHBhdGgpIHtcbiAgICAgICAgcmV0dXJuIGhhc0luKG9iamVjdCwgcGF0aCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiAgYF8ucGlja0J5YCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHtzdHJpbmdbXX0gcGF0aHMgVGhlIHByb3BlcnR5IHBhdGhzIHRvIHBpY2suXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBwcm9wZXJ0eS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VQaWNrQnkob2JqZWN0LCBwYXRocywgcHJlZGljYXRlKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBwYXRocy5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0ge307XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBwYXRoID0gcGF0aHNbaW5kZXhdLFxuICAgICAgICAgICAgdmFsdWUgPSBiYXNlR2V0KG9iamVjdCwgcGF0aCk7XG5cbiAgICAgICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwgcGF0aCkpIHtcbiAgICAgICAgICBiYXNlU2V0KHJlc3VsdCwgY2FzdFBhdGgocGF0aCwgb2JqZWN0KSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZVByb3BlcnR5YCB3aGljaCBzdXBwb3J0cyBkZWVwIHBhdGhzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGFjY2Vzc29yIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VQcm9wZXJ0eURlZXAocGF0aCkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgICByZXR1cm4gYmFzZUdldChvYmplY3QsIHBhdGgpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5wdWxsQWxsQnlgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWVcbiAgICAgKiBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIHJlbW92ZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWVdIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjb21wYXJhdG9yXSBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VQdWxsQWxsKGFycmF5LCB2YWx1ZXMsIGl0ZXJhdGVlLCBjb21wYXJhdG9yKSB7XG4gICAgICB2YXIgaW5kZXhPZiA9IGNvbXBhcmF0b3IgPyBiYXNlSW5kZXhPZldpdGggOiBiYXNlSW5kZXhPZixcbiAgICAgICAgICBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHZhbHVlcy5sZW5ndGgsXG4gICAgICAgICAgc2VlbiA9IGFycmF5O1xuXG4gICAgICBpZiAoYXJyYXkgPT09IHZhbHVlcykge1xuICAgICAgICB2YWx1ZXMgPSBjb3B5QXJyYXkodmFsdWVzKTtcbiAgICAgIH1cbiAgICAgIGlmIChpdGVyYXRlZSkge1xuICAgICAgICBzZWVuID0gYXJyYXlNYXAoYXJyYXksIGJhc2VVbmFyeShpdGVyYXRlZSkpO1xuICAgICAgfVxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGZyb21JbmRleCA9IDAsXG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlc1tpbmRleF0sXG4gICAgICAgICAgICBjb21wdXRlZCA9IGl0ZXJhdGVlID8gaXRlcmF0ZWUodmFsdWUpIDogdmFsdWU7XG5cbiAgICAgICAgd2hpbGUgKChmcm9tSW5kZXggPSBpbmRleE9mKHNlZW4sIGNvbXB1dGVkLCBmcm9tSW5kZXgsIGNvbXBhcmF0b3IpKSA+IC0xKSB7XG4gICAgICAgICAgaWYgKHNlZW4gIT09IGFycmF5KSB7XG4gICAgICAgICAgICBzcGxpY2UuY2FsbChzZWVuLCBmcm9tSW5kZXgsIDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBzcGxpY2UuY2FsbChhcnJheSwgZnJvbUluZGV4LCAxKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnB1bGxBdGAgd2l0aG91dCBzdXBwb3J0IGZvciBpbmRpdmlkdWFsXG4gICAgICogaW5kZXhlcyBvciBjYXB0dXJpbmcgdGhlIHJlbW92ZWQgZWxlbWVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtudW1iZXJbXX0gaW5kZXhlcyBUaGUgaW5kZXhlcyBvZiBlbGVtZW50cyB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVB1bGxBdChhcnJheSwgaW5kZXhlcykge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID8gaW5kZXhlcy5sZW5ndGggOiAwLFxuICAgICAgICAgIGxhc3RJbmRleCA9IGxlbmd0aCAtIDE7XG5cbiAgICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgICB2YXIgaW5kZXggPSBpbmRleGVzW2xlbmd0aF07XG4gICAgICAgIGlmIChsZW5ndGggPT0gbGFzdEluZGV4IHx8IGluZGV4ICE9PSBwcmV2aW91cykge1xuICAgICAgICAgIHZhciBwcmV2aW91cyA9IGluZGV4O1xuICAgICAgICAgIGlmIChpc0luZGV4KGluZGV4KSkge1xuICAgICAgICAgICAgc3BsaWNlLmNhbGwoYXJyYXksIGluZGV4LCAxKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYmFzZVVuc2V0KGFycmF5LCBpbmRleCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucmFuZG9tYCB3aXRob3V0IHN1cHBvcnQgZm9yIHJldHVybmluZ1xuICAgICAqIGZsb2F0aW5nLXBvaW50IG51bWJlcnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBsb3dlciBUaGUgbG93ZXIgYm91bmQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHVwcGVyIFRoZSB1cHBlciBib3VuZC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSByYW5kb20gbnVtYmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VSYW5kb20obG93ZXIsIHVwcGVyKSB7XG4gICAgICByZXR1cm4gbG93ZXIgKyBuYXRpdmVGbG9vcihuYXRpdmVSYW5kb20oKSAqICh1cHBlciAtIGxvd2VyICsgMSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnJhbmdlYCBhbmQgYF8ucmFuZ2VSaWdodGAgd2hpY2ggZG9lc24ndFxuICAgICAqIGNvZXJjZSBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydCBUaGUgc3RhcnQgb2YgdGhlIHJhbmdlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgVGhlIGVuZCBvZiB0aGUgcmFuZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHN0ZXAgVGhlIHZhbHVlIHRvIGluY3JlbWVudCBvciBkZWNyZW1lbnQgYnkuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSByYW5nZSBvZiBudW1iZXJzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VSYW5nZShzdGFydCwgZW5kLCBzdGVwLCBmcm9tUmlnaHQpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IG5hdGl2ZU1heChuYXRpdmVDZWlsKChlbmQgLSBzdGFydCkgLyAoc3RlcCB8fCAxKSksIDApLFxuICAgICAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgICByZXN1bHRbZnJvbVJpZ2h0ID8gbGVuZ3RoIDogKytpbmRleF0gPSBzdGFydDtcbiAgICAgICAgc3RhcnQgKz0gc3RlcDtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucmVwZWF0YCB3aGljaCBkb2Vzbid0IGNvZXJjZSBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byByZXBlYXQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiB0aW1lcyB0byByZXBlYXQgdGhlIHN0cmluZy5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSByZXBlYXRlZCBzdHJpbmcuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVJlcGVhdChzdHJpbmcsIG4pIHtcbiAgICAgIHZhciByZXN1bHQgPSAnJztcbiAgICAgIGlmICghc3RyaW5nIHx8IG4gPCAxIHx8IG4gPiBNQVhfU0FGRV9JTlRFR0VSKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICAvLyBMZXZlcmFnZSB0aGUgZXhwb25lbnRpYXRpb24gYnkgc3F1YXJpbmcgYWxnb3JpdGhtIGZvciBhIGZhc3RlciByZXBlYXQuXG4gICAgICAvLyBTZWUgaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRXhwb25lbnRpYXRpb25fYnlfc3F1YXJpbmcgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgIGRvIHtcbiAgICAgICAgaWYgKG4gJSAyKSB7XG4gICAgICAgICAgcmVzdWx0ICs9IHN0cmluZztcbiAgICAgICAgfVxuICAgICAgICBuID0gbmF0aXZlRmxvb3IobiAvIDIpO1xuICAgICAgICBpZiAobikge1xuICAgICAgICAgIHN0cmluZyArPSBzdHJpbmc7XG4gICAgICAgIH1cbiAgICAgIH0gd2hpbGUgKG4pO1xuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnJlc3RgIHdoaWNoIGRvZXNuJ3QgdmFsaWRhdGUgb3IgY29lcmNlIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXBwbHkgYSByZXN0IHBhcmFtZXRlciB0by5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PWZ1bmMubGVuZ3RoLTFdIFRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgcmVzdCBwYXJhbWV0ZXIuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVJlc3QoZnVuYywgc3RhcnQpIHtcbiAgICAgIHJldHVybiBzZXRUb1N0cmluZyhvdmVyUmVzdChmdW5jLCBzdGFydCwgaWRlbnRpdHkpLCBmdW5jICsgJycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnNhbXBsZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNhbXBsZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmFuZG9tIGVsZW1lbnQuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNhbXBsZShjb2xsZWN0aW9uKSB7XG4gICAgICByZXR1cm4gYXJyYXlTYW1wbGUodmFsdWVzKGNvbGxlY3Rpb24pKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5zYW1wbGVTaXplYCB3aXRob3V0IHBhcmFtIGd1YXJkcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2FtcGxlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgdG8gc2FtcGxlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcmFuZG9tIGVsZW1lbnRzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VTYW1wbGVTaXplKGNvbGxlY3Rpb24sIG4pIHtcbiAgICAgIHZhciBhcnJheSA9IHZhbHVlcyhjb2xsZWN0aW9uKTtcbiAgICAgIHJldHVybiBzaHVmZmxlU2VsZihhcnJheSwgYmFzZUNsYW1wKG4sIDAsIGFycmF5Lmxlbmd0aCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnNldGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIHNldC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgcGF0aCBjcmVhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VTZXQob2JqZWN0LCBwYXRoLCB2YWx1ZSwgY3VzdG9taXplcikge1xuICAgICAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7XG4gICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICB9XG4gICAgICBwYXRoID0gY2FzdFBhdGgocGF0aCwgb2JqZWN0KTtcblxuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gcGF0aC5sZW5ndGgsXG4gICAgICAgICAgbGFzdEluZGV4ID0gbGVuZ3RoIC0gMSxcbiAgICAgICAgICBuZXN0ZWQgPSBvYmplY3Q7XG5cbiAgICAgIHdoaWxlIChuZXN0ZWQgIT0gbnVsbCAmJiArK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBrZXkgPSB0b0tleShwYXRoW2luZGV4XSksXG4gICAgICAgICAgICBuZXdWYWx1ZSA9IHZhbHVlO1xuXG4gICAgICAgIGlmIChpbmRleCAhPSBsYXN0SW5kZXgpIHtcbiAgICAgICAgICB2YXIgb2JqVmFsdWUgPSBuZXN0ZWRba2V5XTtcbiAgICAgICAgICBuZXdWYWx1ZSA9IGN1c3RvbWl6ZXIgPyBjdXN0b21pemVyKG9ialZhbHVlLCBrZXksIG5lc3RlZCkgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgaWYgKG5ld1ZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gaXNPYmplY3Qob2JqVmFsdWUpXG4gICAgICAgICAgICAgID8gb2JqVmFsdWVcbiAgICAgICAgICAgICAgOiAoaXNJbmRleChwYXRoW2luZGV4ICsgMV0pID8gW10gOiB7fSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGFzc2lnblZhbHVlKG5lc3RlZCwga2V5LCBuZXdWYWx1ZSk7XG4gICAgICAgIG5lc3RlZCA9IG5lc3RlZFtrZXldO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgc2V0RGF0YWAgd2l0aG91dCBzdXBwb3J0IGZvciBob3QgbG9vcCBzaG9ydGluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXNzb2NpYXRlIG1ldGFkYXRhIHdpdGguXG4gICAgICogQHBhcmFtIHsqfSBkYXRhIFRoZSBtZXRhZGF0YS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGZ1bmNgLlxuICAgICAqL1xuICAgIHZhciBiYXNlU2V0RGF0YSA9ICFtZXRhTWFwID8gaWRlbnRpdHkgOiBmdW5jdGlvbihmdW5jLCBkYXRhKSB7XG4gICAgICBtZXRhTWFwLnNldChmdW5jLCBkYXRhKTtcbiAgICAgIHJldHVybiBmdW5jO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgc2V0VG9TdHJpbmdgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaG90IGxvb3Agc2hvcnRpbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzdHJpbmcgVGhlIGB0b1N0cmluZ2AgcmVzdWx0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gICAgICovXG4gICAgdmFyIGJhc2VTZXRUb1N0cmluZyA9ICFkZWZpbmVQcm9wZXJ0eSA/IGlkZW50aXR5IDogZnVuY3Rpb24oZnVuYywgc3RyaW5nKSB7XG4gICAgICByZXR1cm4gZGVmaW5lUHJvcGVydHkoZnVuYywgJ3RvU3RyaW5nJywge1xuICAgICAgICAnY29uZmlndXJhYmxlJzogdHJ1ZSxcbiAgICAgICAgJ2VudW1lcmFibGUnOiBmYWxzZSxcbiAgICAgICAgJ3ZhbHVlJzogY29uc3RhbnQoc3RyaW5nKSxcbiAgICAgICAgJ3dyaXRhYmxlJzogdHJ1ZVxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnNodWZmbGVgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBzaHVmZmxlLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IHNodWZmbGVkIGFycmF5LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VTaHVmZmxlKGNvbGxlY3Rpb24pIHtcbiAgICAgIHJldHVybiBzaHVmZmxlU2VsZih2YWx1ZXMoY29sbGVjdGlvbikpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnNsaWNlYCB3aXRob3V0IGFuIGl0ZXJhdGVlIGNhbGwgZ3VhcmQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzbGljZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PTBdIFRoZSBzdGFydCBwb3NpdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2VuZD1hcnJheS5sZW5ndGhdIFRoZSBlbmQgcG9zaXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VTbGljZShhcnJheSwgc3RhcnQsIGVuZCkge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gICAgICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgICAgIHN0YXJ0ID0gLXN0YXJ0ID4gbGVuZ3RoID8gMCA6IChsZW5ndGggKyBzdGFydCk7XG4gICAgICB9XG4gICAgICBlbmQgPSBlbmQgPiBsZW5ndGggPyBsZW5ndGggOiBlbmQ7XG4gICAgICBpZiAoZW5kIDwgMCkge1xuICAgICAgICBlbmQgKz0gbGVuZ3RoO1xuICAgICAgfVxuICAgICAgbGVuZ3RoID0gc3RhcnQgPiBlbmQgPyAwIDogKChlbmQgLSBzdGFydCkgPj4+IDApO1xuICAgICAgc3RhcnQgPj4+PSAwO1xuXG4gICAgICB2YXIgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHJlc3VsdFtpbmRleF0gPSBhcnJheVtpbmRleCArIHN0YXJ0XTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc29tZWAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFueSBlbGVtZW50IHBhc3NlcyB0aGUgcHJlZGljYXRlIGNoZWNrLFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNvbWUoY29sbGVjdGlvbiwgcHJlZGljYXRlKSB7XG4gICAgICB2YXIgcmVzdWx0O1xuXG4gICAgICBiYXNlRWFjaChjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pIHtcbiAgICAgICAgcmVzdWx0ID0gcHJlZGljYXRlKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbik7XG4gICAgICAgIHJldHVybiAhcmVzdWx0O1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gISFyZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc29ydGVkSW5kZXhgIGFuZCBgXy5zb3J0ZWRMYXN0SW5kZXhgIHdoaWNoXG4gICAgICogcGVyZm9ybXMgYSBiaW5hcnkgc2VhcmNoIG9mIGBhcnJheWAgdG8gZGV0ZXJtaW5lIHRoZSBpbmRleCBhdCB3aGljaCBgdmFsdWVgXG4gICAgICogc2hvdWxkIGJlIGluc2VydGVkIGludG8gYGFycmF5YCBpbiBvcmRlciB0byBtYWludGFpbiBpdHMgc29ydCBvcmRlci5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIHNvcnRlZCBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGV2YWx1YXRlLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JldEhpZ2hlc3RdIFNwZWNpZnkgcmV0dXJuaW5nIHRoZSBoaWdoZXN0IHF1YWxpZmllZCBpbmRleC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZFxuICAgICAqICBpbnRvIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNvcnRlZEluZGV4KGFycmF5LCB2YWx1ZSwgcmV0SGlnaGVzdCkge1xuICAgICAgdmFyIGxvdyA9IDAsXG4gICAgICAgICAgaGlnaCA9IGFycmF5ID09IG51bGwgPyBsb3cgOiBhcnJheS5sZW5ndGg7XG5cbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgJiYgdmFsdWUgPT09IHZhbHVlICYmIGhpZ2ggPD0gSEFMRl9NQVhfQVJSQVlfTEVOR1RIKSB7XG4gICAgICAgIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgICAgICAgdmFyIG1pZCA9IChsb3cgKyBoaWdoKSA+Pj4gMSxcbiAgICAgICAgICAgICAgY29tcHV0ZWQgPSBhcnJheVttaWRdO1xuXG4gICAgICAgICAgaWYgKGNvbXB1dGVkICE9PSBudWxsICYmICFpc1N5bWJvbChjb21wdXRlZCkgJiZcbiAgICAgICAgICAgICAgKHJldEhpZ2hlc3QgPyAoY29tcHV0ZWQgPD0gdmFsdWUpIDogKGNvbXB1dGVkIDwgdmFsdWUpKSkge1xuICAgICAgICAgICAgbG93ID0gbWlkICsgMTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaGlnaCA9IG1pZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGhpZ2g7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZVNvcnRlZEluZGV4QnkoYXJyYXksIHZhbHVlLCBpZGVudGl0eSwgcmV0SGlnaGVzdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc29ydGVkSW5kZXhCeWAgYW5kIGBfLnNvcnRlZExhc3RJbmRleEJ5YFxuICAgICAqIHdoaWNoIGludm9rZXMgYGl0ZXJhdGVlYCBmb3IgYHZhbHVlYCBhbmQgZWFjaCBlbGVtZW50IG9mIGBhcnJheWAgdG8gY29tcHV0ZVxuICAgICAqIHRoZWlyIHNvcnQgcmFua2luZy4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ7ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBzb3J0ZWQgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBldmFsdWF0ZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXRIaWdoZXN0XSBTcGVjaWZ5IHJldHVybmluZyB0aGUgaGlnaGVzdCBxdWFsaWZpZWQgaW5kZXguXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAgICAgKiAgaW50byBgYXJyYXlgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VTb3J0ZWRJbmRleEJ5KGFycmF5LCB2YWx1ZSwgaXRlcmF0ZWUsIHJldEhpZ2hlc3QpIHtcbiAgICAgIHZhbHVlID0gaXRlcmF0ZWUodmFsdWUpO1xuXG4gICAgICB2YXIgbG93ID0gMCxcbiAgICAgICAgICBoaWdoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgdmFsSXNOYU4gPSB2YWx1ZSAhPT0gdmFsdWUsXG4gICAgICAgICAgdmFsSXNOdWxsID0gdmFsdWUgPT09IG51bGwsXG4gICAgICAgICAgdmFsSXNTeW1ib2wgPSBpc1N5bWJvbCh2YWx1ZSksXG4gICAgICAgICAgdmFsSXNVbmRlZmluZWQgPSB2YWx1ZSA9PT0gdW5kZWZpbmVkO1xuXG4gICAgICB3aGlsZSAobG93IDwgaGlnaCkge1xuICAgICAgICB2YXIgbWlkID0gbmF0aXZlRmxvb3IoKGxvdyArIGhpZ2gpIC8gMiksXG4gICAgICAgICAgICBjb21wdXRlZCA9IGl0ZXJhdGVlKGFycmF5W21pZF0pLFxuICAgICAgICAgICAgb3RoSXNEZWZpbmVkID0gY29tcHV0ZWQgIT09IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIG90aElzTnVsbCA9IGNvbXB1dGVkID09PSBudWxsLFxuICAgICAgICAgICAgb3RoSXNSZWZsZXhpdmUgPSBjb21wdXRlZCA9PT0gY29tcHV0ZWQsXG4gICAgICAgICAgICBvdGhJc1N5bWJvbCA9IGlzU3ltYm9sKGNvbXB1dGVkKTtcblxuICAgICAgICBpZiAodmFsSXNOYU4pIHtcbiAgICAgICAgICB2YXIgc2V0TG93ID0gcmV0SGlnaGVzdCB8fCBvdGhJc1JlZmxleGl2ZTtcbiAgICAgICAgfSBlbHNlIGlmICh2YWxJc1VuZGVmaW5lZCkge1xuICAgICAgICAgIHNldExvdyA9IG90aElzUmVmbGV4aXZlICYmIChyZXRIaWdoZXN0IHx8IG90aElzRGVmaW5lZCk7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsSXNOdWxsKSB7XG4gICAgICAgICAgc2V0TG93ID0gb3RoSXNSZWZsZXhpdmUgJiYgb3RoSXNEZWZpbmVkICYmIChyZXRIaWdoZXN0IHx8ICFvdGhJc051bGwpO1xuICAgICAgICB9IGVsc2UgaWYgKHZhbElzU3ltYm9sKSB7XG4gICAgICAgICAgc2V0TG93ID0gb3RoSXNSZWZsZXhpdmUgJiYgb3RoSXNEZWZpbmVkICYmICFvdGhJc051bGwgJiYgKHJldEhpZ2hlc3QgfHwgIW90aElzU3ltYm9sKTtcbiAgICAgICAgfSBlbHNlIGlmIChvdGhJc051bGwgfHwgb3RoSXNTeW1ib2wpIHtcbiAgICAgICAgICBzZXRMb3cgPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZXRMb3cgPSByZXRIaWdoZXN0ID8gKGNvbXB1dGVkIDw9IHZhbHVlKSA6IChjb21wdXRlZCA8IHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2V0TG93KSB7XG4gICAgICAgICAgbG93ID0gbWlkICsgMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBoaWdoID0gbWlkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbmF0aXZlTWluKGhpZ2gsIE1BWF9BUlJBWV9JTkRFWCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc29ydGVkVW5pcWAgYW5kIGBfLnNvcnRlZFVuaXFCeWAgd2l0aG91dFxuICAgICAqIHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZHVwbGljYXRlIGZyZWUgYXJyYXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVNvcnRlZFVuaXEoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgcmVzSW5kZXggPSAwLFxuICAgICAgICAgIHJlc3VsdCA9IFtdO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgICAgICBjb21wdXRlZCA9IGl0ZXJhdGVlID8gaXRlcmF0ZWUodmFsdWUpIDogdmFsdWU7XG5cbiAgICAgICAgaWYgKCFpbmRleCB8fCAhZXEoY29tcHV0ZWQsIHNlZW4pKSB7XG4gICAgICAgICAgdmFyIHNlZW4gPSBjb21wdXRlZDtcbiAgICAgICAgICByZXN1bHRbcmVzSW5kZXgrK10gPSB2YWx1ZSA9PT0gMCA/IDAgOiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy50b051bWJlcmAgd2hpY2ggZG9lc24ndCBlbnN1cmUgY29ycmVjdFxuICAgICAqIGNvbnZlcnNpb25zIG9mIGJpbmFyeSwgaGV4YWRlY2ltYWwsIG9yIG9jdGFsIHN0cmluZyB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgbnVtYmVyLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VUb051bWJlcih2YWx1ZSkge1xuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICBpZiAoaXNTeW1ib2wodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBOQU47XG4gICAgICB9XG4gICAgICByZXR1cm4gK3ZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnRvU3RyaW5nYCB3aGljaCBkb2Vzbid0IGNvbnZlcnQgbnVsbGlzaFxuICAgICAqIHZhbHVlcyB0byBlbXB0eSBzdHJpbmdzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHN0cmluZy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlVG9TdHJpbmcodmFsdWUpIHtcbiAgICAgIC8vIEV4aXQgZWFybHkgZm9yIHN0cmluZ3MgdG8gYXZvaWQgYSBwZXJmb3JtYW5jZSBoaXQgaW4gc29tZSBlbnZpcm9ubWVudHMuXG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAvLyBSZWN1cnNpdmVseSBjb252ZXJ0IHZhbHVlcyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgICByZXR1cm4gYXJyYXlNYXAodmFsdWUsIGJhc2VUb1N0cmluZykgKyAnJztcbiAgICAgIH1cbiAgICAgIGlmIChpc1N5bWJvbCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHN5bWJvbFRvU3RyaW5nID8gc3ltYm9sVG9TdHJpbmcuY2FsbCh2YWx1ZSkgOiAnJztcbiAgICAgIH1cbiAgICAgIHZhciByZXN1bHQgPSAodmFsdWUgKyAnJyk7XG4gICAgICByZXR1cm4gKHJlc3VsdCA9PSAnMCcgJiYgKDEgLyB2YWx1ZSkgPT0gLUlORklOSVRZKSA/ICctMCcgOiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udW5pcUJ5YCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZHVwbGljYXRlIGZyZWUgYXJyYXkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmFzZVVuaXEoYXJyYXksIGl0ZXJhdGVlLCBjb21wYXJhdG9yKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBpbmNsdWRlcyA9IGFycmF5SW5jbHVkZXMsXG4gICAgICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICAgIGlzQ29tbW9uID0gdHJ1ZSxcbiAgICAgICAgICByZXN1bHQgPSBbXSxcbiAgICAgICAgICBzZWVuID0gcmVzdWx0O1xuXG4gICAgICBpZiAoY29tcGFyYXRvcikge1xuICAgICAgICBpc0NvbW1vbiA9IGZhbHNlO1xuICAgICAgICBpbmNsdWRlcyA9IGFycmF5SW5jbHVkZXNXaXRoO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAobGVuZ3RoID49IExBUkdFX0FSUkFZX1NJWkUpIHtcbiAgICAgICAgdmFyIHNldCA9IGl0ZXJhdGVlID8gbnVsbCA6IGNyZWF0ZVNldChhcnJheSk7XG4gICAgICAgIGlmIChzZXQpIHtcbiAgICAgICAgICByZXR1cm4gc2V0VG9BcnJheShzZXQpO1xuICAgICAgICB9XG4gICAgICAgIGlzQ29tbW9uID0gZmFsc2U7XG4gICAgICAgIGluY2x1ZGVzID0gY2FjaGVIYXM7XG4gICAgICAgIHNlZW4gPSBuZXcgU2V0Q2FjaGU7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgc2VlbiA9IGl0ZXJhdGVlID8gW10gOiByZXN1bHQ7XG4gICAgICB9XG4gICAgICBvdXRlcjpcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XSxcbiAgICAgICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUgPyBpdGVyYXRlZSh2YWx1ZSkgOiB2YWx1ZTtcblxuICAgICAgICB2YWx1ZSA9IChjb21wYXJhdG9yIHx8IHZhbHVlICE9PSAwKSA/IHZhbHVlIDogMDtcbiAgICAgICAgaWYgKGlzQ29tbW9uICYmIGNvbXB1dGVkID09PSBjb21wdXRlZCkge1xuICAgICAgICAgIHZhciBzZWVuSW5kZXggPSBzZWVuLmxlbmd0aDtcbiAgICAgICAgICB3aGlsZSAoc2VlbkluZGV4LS0pIHtcbiAgICAgICAgICAgIGlmIChzZWVuW3NlZW5JbmRleF0gPT09IGNvbXB1dGVkKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaXRlcmF0ZWUpIHtcbiAgICAgICAgICAgIHNlZW4ucHVzaChjb21wdXRlZCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghaW5jbHVkZXMoc2VlbiwgY29tcHV0ZWQsIGNvbXBhcmF0b3IpKSB7XG4gICAgICAgICAgaWYgKHNlZW4gIT09IHJlc3VsdCkge1xuICAgICAgICAgICAgc2Vlbi5wdXNoKGNvbXB1dGVkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnVuc2V0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcHJvcGVydHkgcGF0aCB0byB1bnNldC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHByb3BlcnR5IGlzIGRlbGV0ZWQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlVW5zZXQob2JqZWN0LCBwYXRoKSB7XG4gICAgICBwYXRoID0gY2FzdFBhdGgocGF0aCwgb2JqZWN0KTtcbiAgICAgIG9iamVjdCA9IHBhcmVudChvYmplY3QsIHBhdGgpO1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsIHx8IGRlbGV0ZSBvYmplY3RbdG9LZXkobGFzdChwYXRoKSldO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnVwZGF0ZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIHVwZGF0ZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB1cGRhdGVyIFRoZSBmdW5jdGlvbiB0byBwcm9kdWNlIHRoZSB1cGRhdGVkIHZhbHVlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIHBhdGggY3JlYXRpb24uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlVXBkYXRlKG9iamVjdCwgcGF0aCwgdXBkYXRlciwgY3VzdG9taXplcikge1xuICAgICAgcmV0dXJuIGJhc2VTZXQob2JqZWN0LCBwYXRoLCB1cGRhdGVyKGJhc2VHZXQob2JqZWN0LCBwYXRoKSksIGN1c3RvbWl6ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIG1ldGhvZHMgbGlrZSBgXy5kcm9wV2hpbGVgIGFuZCBgXy50YWtlV2hpbGVgXG4gICAgICogd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbaXNEcm9wXSBTcGVjaWZ5IGRyb3BwaW5nIGVsZW1lbnRzIGluc3RlYWQgb2YgdGFraW5nIHRoZW0uXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VXaGlsZShhcnJheSwgcHJlZGljYXRlLCBpc0Ryb3AsIGZyb21SaWdodCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICBpbmRleCA9IGZyb21SaWdodCA/IGxlbmd0aCA6IC0xO1xuXG4gICAgICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSAmJlxuICAgICAgICBwcmVkaWNhdGUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpKSB7fVxuXG4gICAgICByZXR1cm4gaXNEcm9wXG4gICAgICAgID8gYmFzZVNsaWNlKGFycmF5LCAoZnJvbVJpZ2h0ID8gMCA6IGluZGV4KSwgKGZyb21SaWdodCA/IGluZGV4ICsgMSA6IGxlbmd0aCkpXG4gICAgICAgIDogYmFzZVNsaWNlKGFycmF5LCAoZnJvbVJpZ2h0ID8gaW5kZXggKyAxIDogMCksIChmcm9tUmlnaHQgPyBsZW5ndGggOiBpbmRleCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGB3cmFwcGVyVmFsdWVgIHdoaWNoIHJldHVybnMgdGhlIHJlc3VsdCBvZlxuICAgICAqIHBlcmZvcm1pbmcgYSBzZXF1ZW5jZSBvZiBhY3Rpb25zIG9uIHRoZSB1bndyYXBwZWQgYHZhbHVlYCwgd2hlcmUgZWFjaFxuICAgICAqIHN1Y2Nlc3NpdmUgYWN0aW9uIGlzIHN1cHBsaWVkIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIHByZXZpb3VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB1bndyYXBwZWQgdmFsdWUuXG4gICAgICogQHBhcmFtIHtBcnJheX0gYWN0aW9ucyBBY3Rpb25zIHRvIHBlcmZvcm0gdG8gcmVzb2x2ZSB0aGUgdW53cmFwcGVkIHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlV3JhcHBlclZhbHVlKHZhbHVlLCBhY3Rpb25zKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gdmFsdWU7XG4gICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgTGF6eVdyYXBwZXIpIHtcbiAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnZhbHVlKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXlSZWR1Y2UoYWN0aW9ucywgZnVuY3Rpb24ocmVzdWx0LCBhY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuIGFjdGlvbi5mdW5jLmFwcGx5KGFjdGlvbi50aGlzQXJnLCBhcnJheVB1c2goW3Jlc3VsdF0sIGFjdGlvbi5hcmdzKSk7XG4gICAgICB9LCByZXN1bHQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIG1ldGhvZHMgbGlrZSBgXy54b3JgLCB3aXRob3V0IHN1cHBvcnQgZm9yXG4gICAgICogaXRlcmF0ZWUgc2hvcnRoYW5kcywgdGhhdCBhY2NlcHRzIGFuIGFycmF5IG9mIGFycmF5cyB0byBpbnNwZWN0LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheXMgVGhlIGFycmF5cyB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgdmFsdWVzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGJhc2VYb3IoYXJyYXlzLCBpdGVyYXRlZSwgY29tcGFyYXRvcikge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5cy5sZW5ndGg7XG4gICAgICBpZiAobGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm4gbGVuZ3RoID8gYmFzZVVuaXEoYXJyYXlzWzBdKSA6IFtdO1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGFycmF5ID0gYXJyYXlzW2luZGV4XSxcbiAgICAgICAgICAgIG90aEluZGV4ID0gLTE7XG5cbiAgICAgICAgd2hpbGUgKCsrb3RoSW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICBpZiAob3RoSW5kZXggIT0gaW5kZXgpIHtcbiAgICAgICAgICAgIHJlc3VsdFtpbmRleF0gPSBiYXNlRGlmZmVyZW5jZShyZXN1bHRbaW5kZXhdIHx8IGFycmF5LCBhcnJheXNbb3RoSW5kZXhdLCBpdGVyYXRlZSwgY29tcGFyYXRvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZVVuaXEoYmFzZUZsYXR0ZW4ocmVzdWx0LCAxKSwgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy56aXBPYmplY3RgIHdoaWNoIGFzc2lnbnMgdmFsdWVzIHVzaW5nIGBhc3NpZ25GdW5jYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gcHJvcHMgVGhlIHByb3BlcnR5IGlkZW50aWZpZXJzLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgcHJvcGVydHkgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGFzc2lnbkZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFzc2lnbiB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBiYXNlWmlwT2JqZWN0KHByb3BzLCB2YWx1ZXMsIGFzc2lnbkZ1bmMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aCxcbiAgICAgICAgICB2YWxzTGVuZ3RoID0gdmFsdWVzLmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSB7fTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gaW5kZXggPCB2YWxzTGVuZ3RoID8gdmFsdWVzW2luZGV4XSA6IHVuZGVmaW5lZDtcbiAgICAgICAgYXNzaWduRnVuYyhyZXN1bHQsIHByb3BzW2luZGV4XSwgdmFsdWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYXN0cyBgdmFsdWVgIHRvIGFuIGVtcHR5IGFycmF5IGlmIGl0J3Mgbm90IGFuIGFycmF5IGxpa2Ugb2JqZWN0LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R9IFJldHVybnMgdGhlIGNhc3QgYXJyYXktbGlrZSBvYmplY3QuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2FzdEFycmF5TGlrZU9iamVjdCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzQXJyYXlMaWtlT2JqZWN0KHZhbHVlKSA/IHZhbHVlIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FzdHMgYHZhbHVlYCB0byBgaWRlbnRpdHlgIGlmIGl0J3Mgbm90IGEgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGNhc3QgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2FzdEZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdmdW5jdGlvbicgPyB2YWx1ZSA6IGlkZW50aXR5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhc3RzIGB2YWx1ZWAgdG8gYSBwYXRoIGFycmF5IGlmIGl0J3Mgbm90IG9uZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeSBrZXlzIG9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY2FzdCBwcm9wZXJ0eSBwYXRoIGFycmF5LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNhc3RQYXRoKHZhbHVlLCBvYmplY3QpIHtcbiAgICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gaXNLZXkodmFsdWUsIG9iamVjdCkgPyBbdmFsdWVdIDogc3RyaW5nVG9QYXRoKHRvU3RyaW5nKHZhbHVlKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBgYmFzZVJlc3RgIGFsaWFzIHdoaWNoIGNhbiBiZSByZXBsYWNlZCB3aXRoIGBpZGVudGl0eWAgYnkgbW9kdWxlXG4gICAgICogcmVwbGFjZW1lbnQgcGx1Z2lucy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0Z1bmN0aW9ufVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFwcGx5IGEgcmVzdCBwYXJhbWV0ZXIgdG8uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICovXG4gICAgdmFyIGNhc3RSZXN0ID0gYmFzZVJlc3Q7XG5cbiAgICAvKipcbiAgICAgKiBDYXN0cyBgYXJyYXlgIHRvIGEgc2xpY2UgaWYgaXQncyBuZWVkZWQuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydCBUaGUgc3RhcnQgcG9zaXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtlbmQ9YXJyYXkubGVuZ3RoXSBUaGUgZW5kIHBvc2l0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY2FzdCBzbGljZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjYXN0U2xpY2UoYXJyYXksIHN0YXJ0LCBlbmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gICAgICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IGxlbmd0aCA6IGVuZDtcbiAgICAgIHJldHVybiAoIXN0YXJ0ICYmIGVuZCA+PSBsZW5ndGgpID8gYXJyYXkgOiBiYXNlU2xpY2UoYXJyYXksIHN0YXJ0LCBlbmQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc2ltcGxlIHdyYXBwZXIgYXJvdW5kIHRoZSBnbG9iYWwgW2BjbGVhclRpbWVvdXRgXShodHRwczovL21kbi5pby9jbGVhclRpbWVvdXQpLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge251bWJlcnxPYmplY3R9IGlkIFRoZSB0aW1lciBpZCBvciB0aW1lb3V0IG9iamVjdCBvZiB0aGUgdGltZXIgdG8gY2xlYXIuXG4gICAgICovXG4gICAgdmFyIGNsZWFyVGltZW91dCA9IGN0eENsZWFyVGltZW91dCB8fCBmdW5jdGlvbihpZCkge1xuICAgICAgcmV0dXJuIHJvb3QuY2xlYXJUaW1lb3V0KGlkKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNsb25lIG9mICBgYnVmZmVyYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtCdWZmZXJ9IGJ1ZmZlciBUaGUgYnVmZmVyIHRvIGNsb25lLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gICAgICogQHJldHVybnMge0J1ZmZlcn0gUmV0dXJucyB0aGUgY2xvbmVkIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZUJ1ZmZlcihidWZmZXIsIGlzRGVlcCkge1xuICAgICAgaWYgKGlzRGVlcCkge1xuICAgICAgICByZXR1cm4gYnVmZmVyLnNsaWNlKCk7XG4gICAgICB9XG4gICAgICB2YXIgbGVuZ3RoID0gYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSBhbGxvY1Vuc2FmZSA/IGFsbG9jVW5zYWZlKGxlbmd0aCkgOiBuZXcgYnVmZmVyLmNvbnN0cnVjdG9yKGxlbmd0aCk7XG5cbiAgICAgIGJ1ZmZlci5jb3B5KHJlc3VsdCk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjbG9uZSBvZiBgYXJyYXlCdWZmZXJgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5QnVmZmVyfSBhcnJheUJ1ZmZlciBUaGUgYXJyYXkgYnVmZmVyIHRvIGNsb25lLlxuICAgICAqIEByZXR1cm5zIHtBcnJheUJ1ZmZlcn0gUmV0dXJucyB0aGUgY2xvbmVkIGFycmF5IGJ1ZmZlci5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZUFycmF5QnVmZmVyKGFycmF5QnVmZmVyKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbmV3IGFycmF5QnVmZmVyLmNvbnN0cnVjdG9yKGFycmF5QnVmZmVyLmJ5dGVMZW5ndGgpO1xuICAgICAgbmV3IFVpbnQ4QXJyYXkocmVzdWx0KS5zZXQobmV3IFVpbnQ4QXJyYXkoYXJyYXlCdWZmZXIpKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNsb25lIG9mIGBkYXRhVmlld2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhVmlldyBUaGUgZGF0YSB2aWV3IHRvIGNsb25lLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIGRhdGEgdmlldy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZURhdGFWaWV3KGRhdGFWaWV3LCBpc0RlZXApIHtcbiAgICAgIHZhciBidWZmZXIgPSBpc0RlZXAgPyBjbG9uZUFycmF5QnVmZmVyKGRhdGFWaWV3LmJ1ZmZlcikgOiBkYXRhVmlldy5idWZmZXI7XG4gICAgICByZXR1cm4gbmV3IGRhdGFWaWV3LmNvbnN0cnVjdG9yKGJ1ZmZlciwgZGF0YVZpZXcuYnl0ZU9mZnNldCwgZGF0YVZpZXcuYnl0ZUxlbmd0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNsb25lIG9mIGByZWdleHBgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcmVnZXhwIFRoZSByZWdleHAgdG8gY2xvbmUuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2xvbmVkIHJlZ2V4cC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZVJlZ0V4cChyZWdleHApIHtcbiAgICAgIHZhciByZXN1bHQgPSBuZXcgcmVnZXhwLmNvbnN0cnVjdG9yKHJlZ2V4cC5zb3VyY2UsIHJlRmxhZ3MuZXhlYyhyZWdleHApKTtcbiAgICAgIHJlc3VsdC5sYXN0SW5kZXggPSByZWdleHAubGFzdEluZGV4O1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY2xvbmUgb2YgdGhlIGBzeW1ib2xgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHN5bWJvbCBUaGUgc3ltYm9sIG9iamVjdCB0byBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjbG9uZWQgc3ltYm9sIG9iamVjdC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZVN5bWJvbChzeW1ib2wpIHtcbiAgICAgIHJldHVybiBzeW1ib2xWYWx1ZU9mID8gT2JqZWN0KHN5bWJvbFZhbHVlT2YuY2FsbChzeW1ib2wpKSA6IHt9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBjbG9uZSBvZiBgdHlwZWRBcnJheWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSB0eXBlZEFycmF5IFRoZSB0eXBlZCBhcnJheSB0byBjbG9uZS5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGNsb25lLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCB0eXBlZCBhcnJheS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZVR5cGVkQXJyYXkodHlwZWRBcnJheSwgaXNEZWVwKSB7XG4gICAgICB2YXIgYnVmZmVyID0gaXNEZWVwID8gY2xvbmVBcnJheUJ1ZmZlcih0eXBlZEFycmF5LmJ1ZmZlcikgOiB0eXBlZEFycmF5LmJ1ZmZlcjtcbiAgICAgIHJldHVybiBuZXcgdHlwZWRBcnJheS5jb25zdHJ1Y3RvcihidWZmZXIsIHR5cGVkQXJyYXkuYnl0ZU9mZnNldCwgdHlwZWRBcnJheS5sZW5ndGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbXBhcmVzIHZhbHVlcyB0byBzb3J0IHRoZW0gaW4gYXNjZW5kaW5nIG9yZGVyLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc29ydCBvcmRlciBpbmRpY2F0b3IgZm9yIGB2YWx1ZWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29tcGFyZUFzY2VuZGluZyh2YWx1ZSwgb3RoZXIpIHtcbiAgICAgIGlmICh2YWx1ZSAhPT0gb3RoZXIpIHtcbiAgICAgICAgdmFyIHZhbElzRGVmaW5lZCA9IHZhbHVlICE9PSB1bmRlZmluZWQsXG4gICAgICAgICAgICB2YWxJc051bGwgPSB2YWx1ZSA9PT0gbnVsbCxcbiAgICAgICAgICAgIHZhbElzUmVmbGV4aXZlID0gdmFsdWUgPT09IHZhbHVlLFxuICAgICAgICAgICAgdmFsSXNTeW1ib2wgPSBpc1N5bWJvbCh2YWx1ZSk7XG5cbiAgICAgICAgdmFyIG90aElzRGVmaW5lZCA9IG90aGVyICE9PSB1bmRlZmluZWQsXG4gICAgICAgICAgICBvdGhJc051bGwgPSBvdGhlciA9PT0gbnVsbCxcbiAgICAgICAgICAgIG90aElzUmVmbGV4aXZlID0gb3RoZXIgPT09IG90aGVyLFxuICAgICAgICAgICAgb3RoSXNTeW1ib2wgPSBpc1N5bWJvbChvdGhlcik7XG5cbiAgICAgICAgaWYgKCghb3RoSXNOdWxsICYmICFvdGhJc1N5bWJvbCAmJiAhdmFsSXNTeW1ib2wgJiYgdmFsdWUgPiBvdGhlcikgfHxcbiAgICAgICAgICAgICh2YWxJc1N5bWJvbCAmJiBvdGhJc0RlZmluZWQgJiYgb3RoSXNSZWZsZXhpdmUgJiYgIW90aElzTnVsbCAmJiAhb3RoSXNTeW1ib2wpIHx8XG4gICAgICAgICAgICAodmFsSXNOdWxsICYmIG90aElzRGVmaW5lZCAmJiBvdGhJc1JlZmxleGl2ZSkgfHxcbiAgICAgICAgICAgICghdmFsSXNEZWZpbmVkICYmIG90aElzUmVmbGV4aXZlKSB8fFxuICAgICAgICAgICAgIXZhbElzUmVmbGV4aXZlKSB7XG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCghdmFsSXNOdWxsICYmICF2YWxJc1N5bWJvbCAmJiAhb3RoSXNTeW1ib2wgJiYgdmFsdWUgPCBvdGhlcikgfHxcbiAgICAgICAgICAgIChvdGhJc1N5bWJvbCAmJiB2YWxJc0RlZmluZWQgJiYgdmFsSXNSZWZsZXhpdmUgJiYgIXZhbElzTnVsbCAmJiAhdmFsSXNTeW1ib2wpIHx8XG4gICAgICAgICAgICAob3RoSXNOdWxsICYmIHZhbElzRGVmaW5lZCAmJiB2YWxJc1JlZmxleGl2ZSkgfHxcbiAgICAgICAgICAgICghb3RoSXNEZWZpbmVkICYmIHZhbElzUmVmbGV4aXZlKSB8fFxuICAgICAgICAgICAgIW90aElzUmVmbGV4aXZlKSB7XG4gICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2VkIGJ5IGBfLm9yZGVyQnlgIHRvIGNvbXBhcmUgbXVsdGlwbGUgcHJvcGVydGllcyBvZiBhIHZhbHVlIHRvIGFub3RoZXJcbiAgICAgKiBhbmQgc3RhYmxlIHNvcnQgdGhlbS5cbiAgICAgKlxuICAgICAqIElmIGBvcmRlcnNgIGlzIHVuc3BlY2lmaWVkLCBhbGwgdmFsdWVzIGFyZSBzb3J0ZWQgaW4gYXNjZW5kaW5nIG9yZGVyLiBPdGhlcndpc2UsXG4gICAgICogc3BlY2lmeSBhbiBvcmRlciBvZiBcImRlc2NcIiBmb3IgZGVzY2VuZGluZyBvciBcImFzY1wiIGZvciBhc2NlbmRpbmcgc29ydCBvcmRlclxuICAgICAqIG9mIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbltdfHN0cmluZ1tdfSBvcmRlcnMgVGhlIG9yZGVyIHRvIHNvcnQgYnkgZm9yIGVhY2ggcHJvcGVydHkuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgc29ydCBvcmRlciBpbmRpY2F0b3IgZm9yIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbXBhcmVNdWx0aXBsZShvYmplY3QsIG90aGVyLCBvcmRlcnMpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIG9iakNyaXRlcmlhID0gb2JqZWN0LmNyaXRlcmlhLFxuICAgICAgICAgIG90aENyaXRlcmlhID0gb3RoZXIuY3JpdGVyaWEsXG4gICAgICAgICAgbGVuZ3RoID0gb2JqQ3JpdGVyaWEubGVuZ3RoLFxuICAgICAgICAgIG9yZGVyc0xlbmd0aCA9IG9yZGVycy5sZW5ndGg7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBjb21wYXJlQXNjZW5kaW5nKG9iakNyaXRlcmlhW2luZGV4XSwgb3RoQ3JpdGVyaWFbaW5kZXhdKTtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgIGlmIChpbmRleCA+PSBvcmRlcnNMZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhciBvcmRlciA9IG9yZGVyc1tpbmRleF07XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdCAqIChvcmRlciA9PSAnZGVzYycgPyAtMSA6IDEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBGaXhlcyBhbiBgQXJyYXkjc29ydGAgYnVnIGluIHRoZSBKUyBlbmdpbmUgZW1iZWRkZWQgaW4gQWRvYmUgYXBwbGljYXRpb25zXG4gICAgICAvLyB0aGF0IGNhdXNlcyBpdCwgdW5kZXIgY2VydGFpbiBjaXJjdW1zdGFuY2VzLCB0byBwcm92aWRlIHRoZSBzYW1lIHZhbHVlIGZvclxuICAgICAgLy8gYG9iamVjdGAgYW5kIGBvdGhlcmAuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vamFzaGtlbmFzL3VuZGVyc2NvcmUvcHVsbC8xMjQ3XG4gICAgICAvLyBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgLy9cbiAgICAgIC8vIFRoaXMgYWxzbyBlbnN1cmVzIGEgc3RhYmxlIHNvcnQgaW4gVjggYW5kIG90aGVyIGVuZ2luZXMuXG4gICAgICAvLyBTZWUgaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9OTAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgIHJldHVybiBvYmplY3QuaW5kZXggLSBvdGhlci5pbmRleDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IHRoYXQgaXMgdGhlIGNvbXBvc2l0aW9uIG9mIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cyxcbiAgICAgKiBwbGFjZWhvbGRlcnMsIGFuZCBwcm92aWRlZCBhcmd1bWVudHMgaW50byBhIHNpbmdsZSBhcnJheSBvZiBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgVGhlIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXJ0aWFscyBUaGUgYXJndW1lbnRzIHRvIHByZXBlbmQgdG8gdGhvc2UgcHJvdmlkZWQuXG4gICAgICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICAgICAqIEBwYXJhbXMge2Jvb2xlYW59IFtpc0N1cnJpZWRdIFNwZWNpZnkgY29tcG9zaW5nIGZvciBhIGN1cnJpZWQgZnVuY3Rpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tcG9zZWQgYXJndW1lbnRzLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbXBvc2VBcmdzKGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzLCBpc0N1cnJpZWQpIHtcbiAgICAgIHZhciBhcmdzSW5kZXggPSAtMSxcbiAgICAgICAgICBhcmdzTGVuZ3RoID0gYXJncy5sZW5ndGgsXG4gICAgICAgICAgaG9sZGVyc0xlbmd0aCA9IGhvbGRlcnMubGVuZ3RoLFxuICAgICAgICAgIGxlZnRJbmRleCA9IC0xLFxuICAgICAgICAgIGxlZnRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICAgICAgcmFuZ2VMZW5ndGggPSBuYXRpdmVNYXgoYXJnc0xlbmd0aCAtIGhvbGRlcnNMZW5ndGgsIDApLFxuICAgICAgICAgIHJlc3VsdCA9IEFycmF5KGxlZnRMZW5ndGggKyByYW5nZUxlbmd0aCksXG4gICAgICAgICAgaXNVbmN1cnJpZWQgPSAhaXNDdXJyaWVkO1xuXG4gICAgICB3aGlsZSAoKytsZWZ0SW5kZXggPCBsZWZ0TGVuZ3RoKSB7XG4gICAgICAgIHJlc3VsdFtsZWZ0SW5kZXhdID0gcGFydGlhbHNbbGVmdEluZGV4XTtcbiAgICAgIH1cbiAgICAgIHdoaWxlICgrK2FyZ3NJbmRleCA8IGhvbGRlcnNMZW5ndGgpIHtcbiAgICAgICAgaWYgKGlzVW5jdXJyaWVkIHx8IGFyZ3NJbmRleCA8IGFyZ3NMZW5ndGgpIHtcbiAgICAgICAgICByZXN1bHRbaG9sZGVyc1thcmdzSW5kZXhdXSA9IGFyZ3NbYXJnc0luZGV4XTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgd2hpbGUgKHJhbmdlTGVuZ3RoLS0pIHtcbiAgICAgICAgcmVzdWx0W2xlZnRJbmRleCsrXSA9IGFyZ3NbYXJnc0luZGV4KytdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGNvbXBvc2VBcmdzYCBleGNlcHQgdGhhdCB0aGUgYXJndW1lbnRzIGNvbXBvc2l0aW9uXG4gICAgICogaXMgdGFpbG9yZWQgZm9yIGBfLnBhcnRpYWxSaWdodGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgVGhlIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXJ0aWFscyBUaGUgYXJndW1lbnRzIHRvIGFwcGVuZCB0byB0aG9zZSBwcm92aWRlZC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBob2xkZXJzIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAgICogQHBhcmFtcyB7Ym9vbGVhbn0gW2lzQ3VycmllZF0gU3BlY2lmeSBjb21wb3NpbmcgZm9yIGEgY3VycmllZCBmdW5jdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBjb21wb3NlZCBhcmd1bWVudHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29tcG9zZUFyZ3NSaWdodChhcmdzLCBwYXJ0aWFscywgaG9sZGVycywgaXNDdXJyaWVkKSB7XG4gICAgICB2YXIgYXJnc0luZGV4ID0gLTEsXG4gICAgICAgICAgYXJnc0xlbmd0aCA9IGFyZ3MubGVuZ3RoLFxuICAgICAgICAgIGhvbGRlcnNJbmRleCA9IC0xLFxuICAgICAgICAgIGhvbGRlcnNMZW5ndGggPSBob2xkZXJzLmxlbmd0aCxcbiAgICAgICAgICByaWdodEluZGV4ID0gLTEsXG4gICAgICAgICAgcmlnaHRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICAgICAgcmFuZ2VMZW5ndGggPSBuYXRpdmVNYXgoYXJnc0xlbmd0aCAtIGhvbGRlcnNMZW5ndGgsIDApLFxuICAgICAgICAgIHJlc3VsdCA9IEFycmF5KHJhbmdlTGVuZ3RoICsgcmlnaHRMZW5ndGgpLFxuICAgICAgICAgIGlzVW5jdXJyaWVkID0gIWlzQ3VycmllZDtcblxuICAgICAgd2hpbGUgKCsrYXJnc0luZGV4IDwgcmFuZ2VMZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0W2FyZ3NJbmRleF0gPSBhcmdzW2FyZ3NJbmRleF07XG4gICAgICB9XG4gICAgICB2YXIgb2Zmc2V0ID0gYXJnc0luZGV4O1xuICAgICAgd2hpbGUgKCsrcmlnaHRJbmRleCA8IHJpZ2h0TGVuZ3RoKSB7XG4gICAgICAgIHJlc3VsdFtvZmZzZXQgKyByaWdodEluZGV4XSA9IHBhcnRpYWxzW3JpZ2h0SW5kZXhdO1xuICAgICAgfVxuICAgICAgd2hpbGUgKCsraG9sZGVyc0luZGV4IDwgaG9sZGVyc0xlbmd0aCkge1xuICAgICAgICBpZiAoaXNVbmN1cnJpZWQgfHwgYXJnc0luZGV4IDwgYXJnc0xlbmd0aCkge1xuICAgICAgICAgIHJlc3VsdFtvZmZzZXQgKyBob2xkZXJzW2hvbGRlcnNJbmRleF1dID0gYXJnc1thcmdzSW5kZXgrK107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29waWVzIHRoZSB2YWx1ZXMgb2YgYHNvdXJjZWAgdG8gYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gc291cmNlIFRoZSBhcnJheSB0byBjb3B5IHZhbHVlcyBmcm9tLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFthcnJheT1bXV0gVGhlIGFycmF5IHRvIGNvcHkgdmFsdWVzIHRvLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvcHlBcnJheShzb3VyY2UsIGFycmF5KSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBzb3VyY2UubGVuZ3RoO1xuXG4gICAgICBhcnJheSB8fCAoYXJyYXkgPSBBcnJheShsZW5ndGgpKTtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGFycmF5W2luZGV4XSA9IHNvdXJjZVtpbmRleF07XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29waWVzIHByb3BlcnRpZXMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgZnJvbS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgaWRlbnRpZmllcnMgdG8gY29weS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdD17fV0gVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgdG8uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29waWVkIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvcHlPYmplY3Qoc291cmNlLCBwcm9wcywgb2JqZWN0LCBjdXN0b21pemVyKSB7XG4gICAgICB2YXIgaXNOZXcgPSAhb2JqZWN0O1xuICAgICAgb2JqZWN0IHx8IChvYmplY3QgPSB7fSk7XG5cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aDtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcblxuICAgICAgICB2YXIgbmV3VmFsdWUgPSBjdXN0b21pemVyXG4gICAgICAgICAgPyBjdXN0b21pemVyKG9iamVjdFtrZXldLCBzb3VyY2Vba2V5XSwga2V5LCBvYmplY3QsIHNvdXJjZSlcbiAgICAgICAgICA6IHVuZGVmaW5lZDtcblxuICAgICAgICBpZiAobmV3VmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIG5ld1ZhbHVlID0gc291cmNlW2tleV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzTmV3KSB7XG4gICAgICAgICAgYmFzZUFzc2lnblZhbHVlKG9iamVjdCwga2V5LCBuZXdWYWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYXNzaWduVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb3BpZXMgb3duIHN5bWJvbHMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHN5bWJvbHMgZnJvbS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdD17fV0gVGhlIG9iamVjdCB0byBjb3B5IHN5bWJvbHMgdG8uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb3B5U3ltYm9scyhzb3VyY2UsIG9iamVjdCkge1xuICAgICAgcmV0dXJuIGNvcHlPYmplY3Qoc291cmNlLCBnZXRTeW1ib2xzKHNvdXJjZSksIG9iamVjdCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29waWVzIG93biBhbmQgaW5oZXJpdGVkIHN5bWJvbHMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHN5bWJvbHMgZnJvbS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29iamVjdD17fV0gVGhlIG9iamVjdCB0byBjb3B5IHN5bWJvbHMgdG8uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb3B5U3ltYm9sc0luKHNvdXJjZSwgb2JqZWN0KSB7XG4gICAgICByZXR1cm4gY29weU9iamVjdChzb3VyY2UsIGdldFN5bWJvbHNJbihzb3VyY2UpLCBvYmplY3QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiBsaWtlIGBfLmdyb3VwQnlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZXR0ZXIgVGhlIGZ1bmN0aW9uIHRvIHNldCBhY2N1bXVsYXRvciB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2luaXRpYWxpemVyXSBUaGUgYWNjdW11bGF0b3Igb2JqZWN0IGluaXRpYWxpemVyLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGFnZ3JlZ2F0b3IgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlQWdncmVnYXRvcihzZXR0ZXIsIGluaXRpYWxpemVyKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlBZ2dyZWdhdG9yIDogYmFzZUFnZ3JlZ2F0b3IsXG4gICAgICAgICAgICBhY2N1bXVsYXRvciA9IGluaXRpYWxpemVyID8gaW5pdGlhbGl6ZXIoKSA6IHt9O1xuXG4gICAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIHNldHRlciwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpLCBhY2N1bXVsYXRvcik7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiBsaWtlIGBfLmFzc2lnbmAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGFzc2lnbmVyIFRoZSBmdW5jdGlvbiB0byBhc3NpZ24gdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGFzc2lnbmVyIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUFzc2lnbmVyKGFzc2lnbmVyKSB7XG4gICAgICByZXR1cm4gYmFzZVJlc3QoZnVuY3Rpb24ob2JqZWN0LCBzb3VyY2VzKSB7XG4gICAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgICAgbGVuZ3RoID0gc291cmNlcy5sZW5ndGgsXG4gICAgICAgICAgICBjdXN0b21pemVyID0gbGVuZ3RoID4gMSA/IHNvdXJjZXNbbGVuZ3RoIC0gMV0gOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBndWFyZCA9IGxlbmd0aCA+IDIgPyBzb3VyY2VzWzJdIDogdW5kZWZpbmVkO1xuXG4gICAgICAgIGN1c3RvbWl6ZXIgPSAoYXNzaWduZXIubGVuZ3RoID4gMyAmJiB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nKVxuICAgICAgICAgID8gKGxlbmd0aC0tLCBjdXN0b21pemVyKVxuICAgICAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgICAgIGlmIChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbChzb3VyY2VzWzBdLCBzb3VyY2VzWzFdLCBndWFyZCkpIHtcbiAgICAgICAgICBjdXN0b21pemVyID0gbGVuZ3RoIDwgMyA/IHVuZGVmaW5lZCA6IGN1c3RvbWl6ZXI7XG4gICAgICAgICAgbGVuZ3RoID0gMTtcbiAgICAgICAgfVxuICAgICAgICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTtcbiAgICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICB2YXIgc291cmNlID0gc291cmNlc1tpbmRleF07XG4gICAgICAgICAgaWYgKHNvdXJjZSkge1xuICAgICAgICAgICAgYXNzaWduZXIob2JqZWN0LCBzb3VyY2UsIGluZGV4LCBjdXN0b21pemVyKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgYmFzZUVhY2hgIG9yIGBiYXNlRWFjaFJpZ2h0YCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhIGNvbGxlY3Rpb24uXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYmFzZSBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVCYXNlRWFjaChlYWNoRnVuYywgZnJvbVJpZ2h0KSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgICAgICAgaWYgKGNvbGxlY3Rpb24gPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiBjb2xsZWN0aW9uO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNBcnJheUxpa2UoY29sbGVjdGlvbikpIHtcbiAgICAgICAgICByZXR1cm4gZWFjaEZ1bmMoY29sbGVjdGlvbiwgaXRlcmF0ZWUpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBsZW5ndGggPSBjb2xsZWN0aW9uLmxlbmd0aCxcbiAgICAgICAgICAgIGluZGV4ID0gZnJvbVJpZ2h0ID8gbGVuZ3RoIDogLTEsXG4gICAgICAgICAgICBpdGVyYWJsZSA9IE9iamVjdChjb2xsZWN0aW9uKTtcblxuICAgICAgICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgICAgICAgIGlmIChpdGVyYXRlZShpdGVyYWJsZVtpbmRleF0sIGluZGV4LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb247XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBiYXNlIGZ1bmN0aW9uIGZvciBtZXRob2RzIGxpa2UgYF8uZm9ySW5gIGFuZCBgXy5mb3JPd25gLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBiYXNlIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUJhc2VGb3IoZnJvbVJpZ2h0KSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0LCBpdGVyYXRlZSwga2V5c0Z1bmMpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgICBpdGVyYWJsZSA9IE9iamVjdChvYmplY3QpLFxuICAgICAgICAgICAgcHJvcHMgPSBrZXlzRnVuYyhvYmplY3QpLFxuICAgICAgICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoO1xuXG4gICAgICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgICAgIHZhciBrZXkgPSBwcm9wc1tmcm9tUmlnaHQgPyBsZW5ndGggOiArK2luZGV4XTtcbiAgICAgICAgICBpZiAoaXRlcmF0ZWUoaXRlcmFibGVba2V5XSwga2V5LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIHRvIGludm9rZSBpdCB3aXRoIHRoZSBvcHRpb25hbCBgdGhpc2BcbiAgICAgKiBiaW5kaW5nIG9mIGB0aGlzQXJnYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gd3JhcC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBjcmVhdGVXcmFwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgd3JhcHBlZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVCaW5kKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcpIHtcbiAgICAgIHZhciBpc0JpbmQgPSBiaXRtYXNrICYgV1JBUF9CSU5EX0ZMQUcsXG4gICAgICAgICAgQ3RvciA9IGNyZWF0ZUN0b3IoZnVuYyk7XG5cbiAgICAgIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgICAgIHZhciBmbiA9ICh0aGlzICYmIHRoaXMgIT09IHJvb3QgJiYgdGhpcyBpbnN0YW5jZW9mIHdyYXBwZXIpID8gQ3RvciA6IGZ1bmM7XG4gICAgICAgIHJldHVybiBmbi5hcHBseShpc0JpbmQgPyB0aGlzQXJnIDogdGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB3cmFwcGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiBsaWtlIGBfLmxvd2VyRmlyc3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWV0aG9kTmFtZSBUaGUgbmFtZSBvZiB0aGUgYFN0cmluZ2AgY2FzZSBtZXRob2QgdG8gdXNlLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGNhc2UgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlQ2FzZUZpcnN0KG1ldGhvZE5hbWUpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihzdHJpbmcpIHtcbiAgICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcblxuICAgICAgICB2YXIgc3RyU3ltYm9scyA9IGhhc1VuaWNvZGUoc3RyaW5nKVxuICAgICAgICAgID8gc3RyaW5nVG9BcnJheShzdHJpbmcpXG4gICAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgdmFyIGNociA9IHN0clN5bWJvbHNcbiAgICAgICAgICA/IHN0clN5bWJvbHNbMF1cbiAgICAgICAgICA6IHN0cmluZy5jaGFyQXQoMCk7XG5cbiAgICAgICAgdmFyIHRyYWlsaW5nID0gc3RyU3ltYm9sc1xuICAgICAgICAgID8gY2FzdFNsaWNlKHN0clN5bWJvbHMsIDEpLmpvaW4oJycpXG4gICAgICAgICAgOiBzdHJpbmcuc2xpY2UoMSk7XG5cbiAgICAgICAgcmV0dXJuIGNoclttZXRob2ROYW1lXSgpICsgdHJhaWxpbmc7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiBsaWtlIGBfLmNhbWVsQ2FzZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIFRoZSBmdW5jdGlvbiB0byBjb21iaW5lIGVhY2ggd29yZC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjb21wb3VuZGVyIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUNvbXBvdW5kZXIoY2FsbGJhY2spIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihzdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIGFycmF5UmVkdWNlKHdvcmRzKGRlYnVycihzdHJpbmcpLnJlcGxhY2UocmVBcG9zLCAnJykpLCBjYWxsYmFjaywgJycpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBwcm9kdWNlcyBhbiBpbnN0YW5jZSBvZiBgQ3RvcmAgcmVnYXJkbGVzcyBvZlxuICAgICAqIHdoZXRoZXIgaXQgd2FzIGludm9rZWQgYXMgcGFydCBvZiBhIGBuZXdgIGV4cHJlc3Npb24gb3IgYnkgYGNhbGxgIG9yIGBhcHBseWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IEN0b3IgVGhlIGNvbnN0cnVjdG9yIHRvIHdyYXAuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgd3JhcHBlZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVDdG9yKEN0b3IpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgLy8gVXNlIGEgYHN3aXRjaGAgc3RhdGVtZW50IHRvIHdvcmsgd2l0aCBjbGFzcyBjb25zdHJ1Y3RvcnMuIFNlZVxuICAgICAgICAvLyBodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1lY21hc2NyaXB0LWZ1bmN0aW9uLW9iamVjdHMtY2FsbC10aGlzYXJndW1lbnQtYXJndW1lbnRzbGlzdFxuICAgICAgICAvLyBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgICAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgICAgICAgIGNhc2UgMDogcmV0dXJuIG5ldyBDdG9yO1xuICAgICAgICAgIGNhc2UgMTogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0pO1xuICAgICAgICAgIGNhc2UgMjogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgICAgICAgIGNhc2UgMzogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgIGNhc2UgNDogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pO1xuICAgICAgICAgIGNhc2UgNTogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0pO1xuICAgICAgICAgIGNhc2UgNjogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0sIGFyZ3NbNV0pO1xuICAgICAgICAgIGNhc2UgNzogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0sIGFyZ3NbNV0sIGFyZ3NbNl0pO1xuICAgICAgICB9XG4gICAgICAgIHZhciB0aGlzQmluZGluZyA9IGJhc2VDcmVhdGUoQ3Rvci5wcm90b3R5cGUpLFxuICAgICAgICAgICAgcmVzdWx0ID0gQ3Rvci5hcHBseSh0aGlzQmluZGluZywgYXJncyk7XG5cbiAgICAgICAgLy8gTWltaWMgdGhlIGNvbnN0cnVjdG9yJ3MgYHJldHVybmAgYmVoYXZpb3IuXG4gICAgICAgIC8vIFNlZSBodHRwczovL2VzNS5naXRodWIuaW8vI3gxMy4yLjIgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgICAgcmV0dXJuIGlzT2JqZWN0KHJlc3VsdCkgPyByZXN1bHQgOiB0aGlzQmluZGluZztcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIHRvIGVuYWJsZSBjdXJyeWluZy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gd3JhcC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBjcmVhdGVXcmFwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBhcml0eSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlQ3VycnkoZnVuYywgYml0bWFzaywgYXJpdHkpIHtcbiAgICAgIHZhciBDdG9yID0gY3JlYXRlQ3RvcihmdW5jKTtcblxuICAgICAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICAgICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG4gICAgICAgICAgICBhcmdzID0gQXJyYXkobGVuZ3RoKSxcbiAgICAgICAgICAgIGluZGV4ID0gbGVuZ3RoLFxuICAgICAgICAgICAgcGxhY2Vob2xkZXIgPSBnZXRIb2xkZXIod3JhcHBlcik7XG5cbiAgICAgICAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICAgICAgICBhcmdzW2luZGV4XSA9IGFyZ3VtZW50c1tpbmRleF07XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGhvbGRlcnMgPSAobGVuZ3RoIDwgMyAmJiBhcmdzWzBdICE9PSBwbGFjZWhvbGRlciAmJiBhcmdzW2xlbmd0aCAtIDFdICE9PSBwbGFjZWhvbGRlcilcbiAgICAgICAgICA/IFtdXG4gICAgICAgICAgOiByZXBsYWNlSG9sZGVycyhhcmdzLCBwbGFjZWhvbGRlcik7XG5cbiAgICAgICAgbGVuZ3RoIC09IGhvbGRlcnMubGVuZ3RoO1xuICAgICAgICBpZiAobGVuZ3RoIDwgYXJpdHkpIHtcbiAgICAgICAgICByZXR1cm4gY3JlYXRlUmVjdXJyeShcbiAgICAgICAgICAgIGZ1bmMsIGJpdG1hc2ssIGNyZWF0ZUh5YnJpZCwgd3JhcHBlci5wbGFjZWhvbGRlciwgdW5kZWZpbmVkLFxuICAgICAgICAgICAgYXJncywgaG9sZGVycywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGFyaXR5IC0gbGVuZ3RoKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZm4gPSAodGhpcyAmJiB0aGlzICE9PSByb290ICYmIHRoaXMgaW5zdGFuY2VvZiB3cmFwcGVyKSA/IEN0b3IgOiBmdW5jO1xuICAgICAgICByZXR1cm4gYXBwbHkoZm4sIHRoaXMsIGFyZ3MpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHdyYXBwZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGBfLmZpbmRgIG9yIGBfLmZpbmRMYXN0YCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZmluZEluZGV4RnVuYyBUaGUgZnVuY3Rpb24gdG8gZmluZCB0aGUgY29sbGVjdGlvbiBpbmRleC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmaW5kIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZUZpbmQoZmluZEluZGV4RnVuYykge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZnJvbUluZGV4KSB7XG4gICAgICAgIHZhciBpdGVyYWJsZSA9IE9iamVjdChjb2xsZWN0aW9uKTtcbiAgICAgICAgaWYgKCFpc0FycmF5TGlrZShjb2xsZWN0aW9uKSkge1xuICAgICAgICAgIHZhciBpdGVyYXRlZSA9IGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyk7XG4gICAgICAgICAgY29sbGVjdGlvbiA9IGtleXMoY29sbGVjdGlvbik7XG4gICAgICAgICAgcHJlZGljYXRlID0gZnVuY3Rpb24oa2V5KSB7IHJldHVybiBpdGVyYXRlZShpdGVyYWJsZVtrZXldLCBrZXksIGl0ZXJhYmxlKTsgfTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaW5kZXggPSBmaW5kSW5kZXhGdW5jKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZnJvbUluZGV4KTtcbiAgICAgICAgcmV0dXJuIGluZGV4ID4gLTEgPyBpdGVyYWJsZVtpdGVyYXRlZSA/IGNvbGxlY3Rpb25baW5kZXhdIDogaW5kZXhdIDogdW5kZWZpbmVkO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgYF8uZmxvd2Agb3IgYF8uZmxvd1JpZ2h0YCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmxvdyBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVGbG93KGZyb21SaWdodCkge1xuICAgICAgcmV0dXJuIGZsYXRSZXN0KGZ1bmN0aW9uKGZ1bmNzKSB7XG4gICAgICAgIHZhciBsZW5ndGggPSBmdW5jcy5sZW5ndGgsXG4gICAgICAgICAgICBpbmRleCA9IGxlbmd0aCxcbiAgICAgICAgICAgIHByZXJlcSA9IExvZGFzaFdyYXBwZXIucHJvdG90eXBlLnRocnU7XG5cbiAgICAgICAgaWYgKGZyb21SaWdodCkge1xuICAgICAgICAgIGZ1bmNzLnJldmVyc2UoKTtcbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAoaW5kZXgtLSkge1xuICAgICAgICAgIHZhciBmdW5jID0gZnVuY3NbaW5kZXhdO1xuICAgICAgICAgIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChwcmVyZXEgJiYgIXdyYXBwZXIgJiYgZ2V0RnVuY05hbWUoZnVuYykgPT0gJ3dyYXBwZXInKSB7XG4gICAgICAgICAgICB2YXIgd3JhcHBlciA9IG5ldyBMb2Rhc2hXcmFwcGVyKFtdLCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaW5kZXggPSB3cmFwcGVyID8gaW5kZXggOiBsZW5ndGg7XG4gICAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgZnVuYyA9IGZ1bmNzW2luZGV4XTtcblxuICAgICAgICAgIHZhciBmdW5jTmFtZSA9IGdldEZ1bmNOYW1lKGZ1bmMpLFxuICAgICAgICAgICAgICBkYXRhID0gZnVuY05hbWUgPT0gJ3dyYXBwZXInID8gZ2V0RGF0YShmdW5jKSA6IHVuZGVmaW5lZDtcblxuICAgICAgICAgIGlmIChkYXRhICYmIGlzTGF6aWFibGUoZGF0YVswXSkgJiZcbiAgICAgICAgICAgICAgICBkYXRhWzFdID09IChXUkFQX0FSWV9GTEFHIHwgV1JBUF9DVVJSWV9GTEFHIHwgV1JBUF9QQVJUSUFMX0ZMQUcgfCBXUkFQX1JFQVJHX0ZMQUcpICYmXG4gICAgICAgICAgICAgICAgIWRhdGFbNF0ubGVuZ3RoICYmIGRhdGFbOV0gPT0gMVxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgIHdyYXBwZXIgPSB3cmFwcGVyW2dldEZ1bmNOYW1lKGRhdGFbMF0pXS5hcHBseSh3cmFwcGVyLCBkYXRhWzNdKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgd3JhcHBlciA9IChmdW5jLmxlbmd0aCA9PSAxICYmIGlzTGF6aWFibGUoZnVuYykpXG4gICAgICAgICAgICAgID8gd3JhcHBlcltmdW5jTmFtZV0oKVxuICAgICAgICAgICAgICA6IHdyYXBwZXIudGhydShmdW5jKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICAgICAgICB2YWx1ZSA9IGFyZ3NbMF07XG5cbiAgICAgICAgICBpZiAod3JhcHBlciAmJiBhcmdzLmxlbmd0aCA9PSAxICYmIGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gd3JhcHBlci5wbGFudCh2YWx1ZSkudmFsdWUoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIGluZGV4ID0gMCxcbiAgICAgICAgICAgICAgcmVzdWx0ID0gbGVuZ3RoID8gZnVuY3NbaW5kZXhdLmFwcGx5KHRoaXMsIGFyZ3MpIDogdmFsdWU7XG5cbiAgICAgICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgcmVzdWx0ID0gZnVuY3NbaW5kZXhdLmNhbGwodGhpcywgcmVzdWx0KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCB0byBpbnZva2UgaXQgd2l0aCBvcHRpb25hbCBgdGhpc2BcbiAgICAgKiBiaW5kaW5nIG9mIGB0aGlzQXJnYCwgcGFydGlhbCBhcHBsaWNhdGlvbiwgYW5kIGN1cnJ5aW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gZnVuYyBUaGUgZnVuY3Rpb24gb3IgbWV0aG9kIG5hbWUgdG8gd3JhcC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBjcmVhdGVXcmFwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIHByZXBlbmQgdG8gdGhvc2UgcHJvdmlkZWQgdG9cbiAgICAgKiAgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbaG9sZGVyc10gVGhlIGBwYXJ0aWFsc2AgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNSaWdodF0gVGhlIGFyZ3VtZW50cyB0byBhcHBlbmQgdG8gdGhvc2UgcHJvdmlkZWRcbiAgICAgKiAgdG8gdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbaG9sZGVyc1JpZ2h0XSBUaGUgYHBhcnRpYWxzUmlnaHRgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FyZ1Bvc10gVGhlIGFyZ3VtZW50IHBvc2l0aW9ucyBvZiB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5XSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlSHlicmlkKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBwYXJ0aWFsc1JpZ2h0LCBob2xkZXJzUmlnaHQsIGFyZ1BvcywgYXJ5LCBhcml0eSkge1xuICAgICAgdmFyIGlzQXJ5ID0gYml0bWFzayAmIFdSQVBfQVJZX0ZMQUcsXG4gICAgICAgICAgaXNCaW5kID0gYml0bWFzayAmIFdSQVBfQklORF9GTEFHLFxuICAgICAgICAgIGlzQmluZEtleSA9IGJpdG1hc2sgJiBXUkFQX0JJTkRfS0VZX0ZMQUcsXG4gICAgICAgICAgaXNDdXJyaWVkID0gYml0bWFzayAmIChXUkFQX0NVUlJZX0ZMQUcgfCBXUkFQX0NVUlJZX1JJR0hUX0ZMQUcpLFxuICAgICAgICAgIGlzRmxpcCA9IGJpdG1hc2sgJiBXUkFQX0ZMSVBfRkxBRyxcbiAgICAgICAgICBDdG9yID0gaXNCaW5kS2V5ID8gdW5kZWZpbmVkIDogY3JlYXRlQ3RvcihmdW5jKTtcblxuICAgICAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICAgICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG4gICAgICAgICAgICBhcmdzID0gQXJyYXkobGVuZ3RoKSxcbiAgICAgICAgICAgIGluZGV4ID0gbGVuZ3RoO1xuXG4gICAgICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICAgICAgYXJnc1tpbmRleF0gPSBhcmd1bWVudHNbaW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc0N1cnJpZWQpIHtcbiAgICAgICAgICB2YXIgcGxhY2Vob2xkZXIgPSBnZXRIb2xkZXIod3JhcHBlciksXG4gICAgICAgICAgICAgIGhvbGRlcnNDb3VudCA9IGNvdW50SG9sZGVycyhhcmdzLCBwbGFjZWhvbGRlcik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhcnRpYWxzKSB7XG4gICAgICAgICAgYXJncyA9IGNvbXBvc2VBcmdzKGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzLCBpc0N1cnJpZWQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYXJ0aWFsc1JpZ2h0KSB7XG4gICAgICAgICAgYXJncyA9IGNvbXBvc2VBcmdzUmlnaHQoYXJncywgcGFydGlhbHNSaWdodCwgaG9sZGVyc1JpZ2h0LCBpc0N1cnJpZWQpO1xuICAgICAgICB9XG4gICAgICAgIGxlbmd0aCAtPSBob2xkZXJzQ291bnQ7XG4gICAgICAgIGlmIChpc0N1cnJpZWQgJiYgbGVuZ3RoIDwgYXJpdHkpIHtcbiAgICAgICAgICB2YXIgbmV3SG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKGFyZ3MsIHBsYWNlaG9sZGVyKTtcbiAgICAgICAgICByZXR1cm4gY3JlYXRlUmVjdXJyeShcbiAgICAgICAgICAgIGZ1bmMsIGJpdG1hc2ssIGNyZWF0ZUh5YnJpZCwgd3JhcHBlci5wbGFjZWhvbGRlciwgdGhpc0FyZyxcbiAgICAgICAgICAgIGFyZ3MsIG5ld0hvbGRlcnMsIGFyZ1BvcywgYXJ5LCBhcml0eSAtIGxlbmd0aFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHRoaXNCaW5kaW5nID0gaXNCaW5kID8gdGhpc0FyZyA6IHRoaXMsXG4gICAgICAgICAgICBmbiA9IGlzQmluZEtleSA/IHRoaXNCaW5kaW5nW2Z1bmNdIDogZnVuYztcblxuICAgICAgICBsZW5ndGggPSBhcmdzLmxlbmd0aDtcbiAgICAgICAgaWYgKGFyZ1Bvcykge1xuICAgICAgICAgIGFyZ3MgPSByZW9yZGVyKGFyZ3MsIGFyZ1Bvcyk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNGbGlwICYmIGxlbmd0aCA+IDEpIHtcbiAgICAgICAgICBhcmdzLnJldmVyc2UoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNBcnkgJiYgYXJ5IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgYXJncy5sZW5ndGggPSBhcnk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMgJiYgdGhpcyAhPT0gcm9vdCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikge1xuICAgICAgICAgIGZuID0gQ3RvciB8fCBjcmVhdGVDdG9yKGZuKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZm4uYXBwbHkodGhpc0JpbmRpbmcsIGFyZ3MpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHdyYXBwZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIGxpa2UgYF8uaW52ZXJ0QnlgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZXR0ZXIgVGhlIGZ1bmN0aW9uIHRvIHNldCBhY2N1bXVsYXRvciB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gdG9JdGVyYXRlZSBUaGUgZnVuY3Rpb24gdG8gcmVzb2x2ZSBpdGVyYXRlZXMuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgaW52ZXJ0ZXIgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlSW52ZXJ0ZXIoc2V0dGVyLCB0b0l0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0LCBpdGVyYXRlZSkge1xuICAgICAgICByZXR1cm4gYmFzZUludmVydGVyKG9iamVjdCwgc2V0dGVyLCB0b0l0ZXJhdGVlKGl0ZXJhdGVlKSwge30pO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBwZXJmb3JtcyBhIG1hdGhlbWF0aWNhbCBvcGVyYXRpb24gb24gdHdvIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gb3BlcmF0b3IgVGhlIGZ1bmN0aW9uIHRvIHBlcmZvcm0gdGhlIG9wZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2RlZmF1bHRWYWx1ZV0gVGhlIHZhbHVlIHVzZWQgZm9yIGB1bmRlZmluZWRgIGFyZ3VtZW50cy5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBtYXRoZW1hdGljYWwgb3BlcmF0aW9uIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZU1hdGhPcGVyYXRpb24ob3BlcmF0b3IsIGRlZmF1bHRWYWx1ZSkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBvdGhlcikge1xuICAgICAgICB2YXIgcmVzdWx0O1xuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCAmJiBvdGhlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJlc3VsdCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvdGhlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKHJlc3VsdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gb3RoZXI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgfHwgdHlwZW9mIG90aGVyID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IGJhc2VUb1N0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICBvdGhlciA9IGJhc2VUb1N0cmluZyhvdGhlcik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhbHVlID0gYmFzZVRvTnVtYmVyKHZhbHVlKTtcbiAgICAgICAgICAgIG90aGVyID0gYmFzZVRvTnVtYmVyKG90aGVyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzdWx0ID0gb3BlcmF0b3IodmFsdWUsIG90aGVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gbGlrZSBgXy5vdmVyYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYXJyYXlGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgaXRlcmF0ZWVzLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IG92ZXIgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlT3ZlcihhcnJheUZ1bmMpIHtcbiAgICAgIHJldHVybiBmbGF0UmVzdChmdW5jdGlvbihpdGVyYXRlZXMpIHtcbiAgICAgICAgaXRlcmF0ZWVzID0gYXJyYXlNYXAoaXRlcmF0ZWVzLCBiYXNlVW5hcnkoZ2V0SXRlcmF0ZWUoKSkpO1xuICAgICAgICByZXR1cm4gYmFzZVJlc3QoZnVuY3Rpb24oYXJncykge1xuICAgICAgICAgIHZhciB0aGlzQXJnID0gdGhpcztcbiAgICAgICAgICByZXR1cm4gYXJyYXlGdW5jKGl0ZXJhdGVlcywgZnVuY3Rpb24oaXRlcmF0ZWUpIHtcbiAgICAgICAgICAgIHJldHVybiBhcHBseShpdGVyYXRlZSwgdGhpc0FyZywgYXJncyk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyB0aGUgcGFkZGluZyBmb3IgYHN0cmluZ2AgYmFzZWQgb24gYGxlbmd0aGAuIFRoZSBgY2hhcnNgIHN0cmluZ1xuICAgICAqIGlzIHRydW5jYXRlZCBpZiB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgZXhjZWVkcyBgbGVuZ3RoYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCBUaGUgcGFkZGluZyBsZW5ndGguXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtjaGFycz0nICddIFRoZSBzdHJpbmcgdXNlZCBhcyBwYWRkaW5nLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHBhZGRpbmcgZm9yIGBzdHJpbmdgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZVBhZGRpbmcobGVuZ3RoLCBjaGFycykge1xuICAgICAgY2hhcnMgPSBjaGFycyA9PT0gdW5kZWZpbmVkID8gJyAnIDogYmFzZVRvU3RyaW5nKGNoYXJzKTtcblxuICAgICAgdmFyIGNoYXJzTGVuZ3RoID0gY2hhcnMubGVuZ3RoO1xuICAgICAgaWYgKGNoYXJzTGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm4gY2hhcnNMZW5ndGggPyBiYXNlUmVwZWF0KGNoYXJzLCBsZW5ndGgpIDogY2hhcnM7XG4gICAgICB9XG4gICAgICB2YXIgcmVzdWx0ID0gYmFzZVJlcGVhdChjaGFycywgbmF0aXZlQ2VpbChsZW5ndGggLyBzdHJpbmdTaXplKGNoYXJzKSkpO1xuICAgICAgcmV0dXJuIGhhc1VuaWNvZGUoY2hhcnMpXG4gICAgICAgID8gY2FzdFNsaWNlKHN0cmluZ1RvQXJyYXkocmVzdWx0KSwgMCwgbGVuZ3RoKS5qb2luKCcnKVxuICAgICAgICA6IHJlc3VsdC5zbGljZSgwLCBsZW5ndGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCB0byBpbnZva2UgaXQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmdcbiAgICAgKiBvZiBgdGhpc0FyZ2AgYW5kIGBwYXJ0aWFsc2AgcHJlcGVuZGVkIHRvIHRoZSBhcmd1bWVudHMgaXQgcmVjZWl2ZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBwYXJ0aWFscyBUaGUgYXJndW1lbnRzIHRvIHByZXBlbmQgdG8gdGhvc2UgcHJvdmlkZWQgdG9cbiAgICAgKiAgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZVBhcnRpYWwoZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMpIHtcbiAgICAgIHZhciBpc0JpbmQgPSBiaXRtYXNrICYgV1JBUF9CSU5EX0ZMQUcsXG4gICAgICAgICAgQ3RvciA9IGNyZWF0ZUN0b3IoZnVuYyk7XG5cbiAgICAgIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgICAgIHZhciBhcmdzSW5kZXggPSAtMSxcbiAgICAgICAgICAgIGFyZ3NMZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxuICAgICAgICAgICAgbGVmdEluZGV4ID0gLTEsXG4gICAgICAgICAgICBsZWZ0TGVuZ3RoID0gcGFydGlhbHMubGVuZ3RoLFxuICAgICAgICAgICAgYXJncyA9IEFycmF5KGxlZnRMZW5ndGggKyBhcmdzTGVuZ3RoKSxcbiAgICAgICAgICAgIGZuID0gKHRoaXMgJiYgdGhpcyAhPT0gcm9vdCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcblxuICAgICAgICB3aGlsZSAoKytsZWZ0SW5kZXggPCBsZWZ0TGVuZ3RoKSB7XG4gICAgICAgICAgYXJnc1tsZWZ0SW5kZXhdID0gcGFydGlhbHNbbGVmdEluZGV4XTtcbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAoYXJnc0xlbmd0aC0tKSB7XG4gICAgICAgICAgYXJnc1tsZWZ0SW5kZXgrK10gPSBhcmd1bWVudHNbKythcmdzSW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhcHBseShmbiwgaXNCaW5kID8gdGhpc0FyZyA6IHRoaXMsIGFyZ3MpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHdyYXBwZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGBfLnJhbmdlYCBvciBgXy5yYW5nZVJpZ2h0YCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcmFuZ2UgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlUmFuZ2UoZnJvbVJpZ2h0KSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oc3RhcnQsIGVuZCwgc3RlcCkge1xuICAgICAgICBpZiAoc3RlcCAmJiB0eXBlb2Ygc3RlcCAhPSAnbnVtYmVyJyAmJiBpc0l0ZXJhdGVlQ2FsbChzdGFydCwgZW5kLCBzdGVwKSkge1xuICAgICAgICAgIGVuZCA9IHN0ZXAgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRW5zdXJlIHRoZSBzaWduIG9mIGAtMGAgaXMgcHJlc2VydmVkLlxuICAgICAgICBzdGFydCA9IHRvRmluaXRlKHN0YXJ0KTtcbiAgICAgICAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgZW5kID0gc3RhcnQ7XG4gICAgICAgICAgc3RhcnQgPSAwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVuZCA9IHRvRmluaXRlKGVuZCk7XG4gICAgICAgIH1cbiAgICAgICAgc3RlcCA9IHN0ZXAgPT09IHVuZGVmaW5lZCA/IChzdGFydCA8IGVuZCA/IDEgOiAtMSkgOiB0b0Zpbml0ZShzdGVwKTtcbiAgICAgICAgcmV0dXJuIGJhc2VSYW5nZShzdGFydCwgZW5kLCBzdGVwLCBmcm9tUmlnaHQpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBwZXJmb3JtcyBhIHJlbGF0aW9uYWwgb3BlcmF0aW9uIG9uIHR3byB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IG9wZXJhdG9yIFRoZSBmdW5jdGlvbiB0byBwZXJmb3JtIHRoZSBvcGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcmVsYXRpb25hbCBvcGVyYXRpb24gZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlUmVsYXRpb25hbE9wZXJhdGlvbihvcGVyYXRvcikge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBvdGhlcikge1xuICAgICAgICBpZiAoISh0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgJiYgdHlwZW9mIG90aGVyID09ICdzdHJpbmcnKSkge1xuICAgICAgICAgIHZhbHVlID0gdG9OdW1iZXIodmFsdWUpO1xuICAgICAgICAgIG90aGVyID0gdG9OdW1iZXIob3RoZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvcGVyYXRvcih2YWx1ZSwgb3RoZXIpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgdG8gY29udGludWUgY3VycnlpbmcuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB3cmFwRnVuYyBUaGUgZnVuY3Rpb24gdG8gY3JlYXRlIHRoZSBgZnVuY2Agd3JhcHBlci5cbiAgICAgKiBAcGFyYW0geyp9IHBsYWNlaG9sZGVyIFRoZSBwbGFjZWhvbGRlciB2YWx1ZS5cbiAgICAgKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvXG4gICAgICogIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FyZ1Bvc10gVGhlIGFyZ3VtZW50IHBvc2l0aW9ucyBvZiB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5XSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlUmVjdXJyeShmdW5jLCBiaXRtYXNrLCB3cmFwRnVuYywgcGxhY2Vob2xkZXIsIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBhcmdQb3MsIGFyeSwgYXJpdHkpIHtcbiAgICAgIHZhciBpc0N1cnJ5ID0gYml0bWFzayAmIFdSQVBfQ1VSUllfRkxBRyxcbiAgICAgICAgICBuZXdIb2xkZXJzID0gaXNDdXJyeSA/IGhvbGRlcnMgOiB1bmRlZmluZWQsXG4gICAgICAgICAgbmV3SG9sZGVyc1JpZ2h0ID0gaXNDdXJyeSA/IHVuZGVmaW5lZCA6IGhvbGRlcnMsXG4gICAgICAgICAgbmV3UGFydGlhbHMgPSBpc0N1cnJ5ID8gcGFydGlhbHMgOiB1bmRlZmluZWQsXG4gICAgICAgICAgbmV3UGFydGlhbHNSaWdodCA9IGlzQ3VycnkgPyB1bmRlZmluZWQgOiBwYXJ0aWFscztcblxuICAgICAgYml0bWFzayB8PSAoaXNDdXJyeSA/IFdSQVBfUEFSVElBTF9GTEFHIDogV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcpO1xuICAgICAgYml0bWFzayAmPSB+KGlzQ3VycnkgPyBXUkFQX1BBUlRJQUxfUklHSFRfRkxBRyA6IFdSQVBfUEFSVElBTF9GTEFHKTtcblxuICAgICAgaWYgKCEoYml0bWFzayAmIFdSQVBfQ1VSUllfQk9VTkRfRkxBRykpIHtcbiAgICAgICAgYml0bWFzayAmPSB+KFdSQVBfQklORF9GTEFHIHwgV1JBUF9CSU5EX0tFWV9GTEFHKTtcbiAgICAgIH1cbiAgICAgIHZhciBuZXdEYXRhID0gW1xuICAgICAgICBmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBuZXdQYXJ0aWFscywgbmV3SG9sZGVycywgbmV3UGFydGlhbHNSaWdodCxcbiAgICAgICAgbmV3SG9sZGVyc1JpZ2h0LCBhcmdQb3MsIGFyeSwgYXJpdHlcbiAgICAgIF07XG5cbiAgICAgIHZhciByZXN1bHQgPSB3cmFwRnVuYy5hcHBseSh1bmRlZmluZWQsIG5ld0RhdGEpO1xuICAgICAgaWYgKGlzTGF6aWFibGUoZnVuYykpIHtcbiAgICAgICAgc2V0RGF0YShyZXN1bHQsIG5ld0RhdGEpO1xuICAgICAgfVxuICAgICAgcmVzdWx0LnBsYWNlaG9sZGVyID0gcGxhY2Vob2xkZXI7XG4gICAgICByZXR1cm4gc2V0V3JhcFRvU3RyaW5nKHJlc3VsdCwgZnVuYywgYml0bWFzayk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIGxpa2UgYF8ucm91bmRgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWV0aG9kTmFtZSBUaGUgbmFtZSBvZiB0aGUgYE1hdGhgIG1ldGhvZCB0byB1c2Ugd2hlbiByb3VuZGluZy5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyByb3VuZCBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGVSb3VuZChtZXRob2ROYW1lKSB7XG4gICAgICB2YXIgZnVuYyA9IE1hdGhbbWV0aG9kTmFtZV07XG4gICAgICByZXR1cm4gZnVuY3Rpb24obnVtYmVyLCBwcmVjaXNpb24pIHtcbiAgICAgICAgbnVtYmVyID0gdG9OdW1iZXIobnVtYmVyKTtcbiAgICAgICAgcHJlY2lzaW9uID0gcHJlY2lzaW9uID09IG51bGwgPyAwIDogbmF0aXZlTWluKHRvSW50ZWdlcihwcmVjaXNpb24pLCAyOTIpO1xuICAgICAgICBpZiAocHJlY2lzaW9uKSB7XG4gICAgICAgICAgLy8gU2hpZnQgd2l0aCBleHBvbmVudGlhbCBub3RhdGlvbiB0byBhdm9pZCBmbG9hdGluZy1wb2ludCBpc3N1ZXMuXG4gICAgICAgICAgLy8gU2VlIFtNRE5dKGh0dHBzOi8vbWRuLmlvL3JvdW5kI0V4YW1wbGVzKSBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgICAgIHZhciBwYWlyID0gKHRvU3RyaW5nKG51bWJlcikgKyAnZScpLnNwbGl0KCdlJyksXG4gICAgICAgICAgICAgIHZhbHVlID0gZnVuYyhwYWlyWzBdICsgJ2UnICsgKCtwYWlyWzFdICsgcHJlY2lzaW9uKSk7XG5cbiAgICAgICAgICBwYWlyID0gKHRvU3RyaW5nKHZhbHVlKSArICdlJykuc3BsaXQoJ2UnKTtcbiAgICAgICAgICByZXR1cm4gKyhwYWlyWzBdICsgJ2UnICsgKCtwYWlyWzFdIC0gcHJlY2lzaW9uKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZ1bmMobnVtYmVyKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNldCBvYmplY3Qgb2YgYHZhbHVlc2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIGFkZCB0byB0aGUgc2V0LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBzZXQuXG4gICAgICovXG4gICAgdmFyIGNyZWF0ZVNldCA9ICEoU2V0ICYmICgxIC8gc2V0VG9BcnJheShuZXcgU2V0KFssLTBdKSlbMV0pID09IElORklOSVRZKSA/IG5vb3AgOiBmdW5jdGlvbih2YWx1ZXMpIHtcbiAgICAgIHJldHVybiBuZXcgU2V0KHZhbHVlcyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBgXy50b1BhaXJzYCBvciBgXy50b1BhaXJzSW5gIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBrZXlzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBrZXlzIG9mIGEgZ2l2ZW4gb2JqZWN0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHBhaXJzIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNyZWF0ZVRvUGFpcnMoa2V5c0Z1bmMpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgICAgdmFyIHRhZyA9IGdldFRhZyhvYmplY3QpO1xuICAgICAgICBpZiAodGFnID09IG1hcFRhZykge1xuICAgICAgICAgIHJldHVybiBtYXBUb0FycmF5KG9iamVjdCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRhZyA9PSBzZXRUYWcpIHtcbiAgICAgICAgICByZXR1cm4gc2V0VG9QYWlycyhvYmplY3QpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiYXNlVG9QYWlycyhvYmplY3QsIGtleXNGdW5jKG9iamVjdCkpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBlaXRoZXIgY3VycmllcyBvciBpbnZva2VzIGBmdW5jYCB3aXRoIG9wdGlvbmFsXG4gICAgICogYHRoaXNgIGJpbmRpbmcgYW5kIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbnxzdHJpbmd9IGZ1bmMgVGhlIGZ1bmN0aW9uIG9yIG1ldGhvZCBuYW1lIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuXG4gICAgICogICAgMSAtIGBfLmJpbmRgXG4gICAgICogICAgMiAtIGBfLmJpbmRLZXlgXG4gICAgICogICAgNCAtIGBfLmN1cnJ5YCBvciBgXy5jdXJyeVJpZ2h0YCBvZiBhIGJvdW5kIGZ1bmN0aW9uXG4gICAgICogICAgOCAtIGBfLmN1cnJ5YFxuICAgICAqICAgMTYgLSBgXy5jdXJyeVJpZ2h0YFxuICAgICAqICAgMzIgLSBgXy5wYXJ0aWFsYFxuICAgICAqICAgNjQgLSBgXy5wYXJ0aWFsUmlnaHRgXG4gICAgICogIDEyOCAtIGBfLnJlYXJnYFxuICAgICAqICAyNTYgLSBgXy5hcnlgXG4gICAgICogIDUxMiAtIGBfLmZsaXBgXG4gICAgICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gYmUgcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FyZ1Bvc10gVGhlIGFyZ3VtZW50IHBvc2l0aW9ucyBvZiB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5XSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3JlYXRlV3JhcChmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgYXJnUG9zLCBhcnksIGFyaXR5KSB7XG4gICAgICB2YXIgaXNCaW5kS2V5ID0gYml0bWFzayAmIFdSQVBfQklORF9LRVlfRkxBRztcbiAgICAgIGlmICghaXNCaW5kS2V5ICYmIHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgdmFyIGxlbmd0aCA9IHBhcnRpYWxzID8gcGFydGlhbHMubGVuZ3RoIDogMDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIGJpdG1hc2sgJj0gfihXUkFQX1BBUlRJQUxfRkxBRyB8IFdSQVBfUEFSVElBTF9SSUdIVF9GTEFHKTtcbiAgICAgICAgcGFydGlhbHMgPSBob2xkZXJzID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgYXJ5ID0gYXJ5ID09PSB1bmRlZmluZWQgPyBhcnkgOiBuYXRpdmVNYXgodG9JbnRlZ2VyKGFyeSksIDApO1xuICAgICAgYXJpdHkgPSBhcml0eSA9PT0gdW5kZWZpbmVkID8gYXJpdHkgOiB0b0ludGVnZXIoYXJpdHkpO1xuICAgICAgbGVuZ3RoIC09IGhvbGRlcnMgPyBob2xkZXJzLmxlbmd0aCA6IDA7XG5cbiAgICAgIGlmIChiaXRtYXNrICYgV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcpIHtcbiAgICAgICAgdmFyIHBhcnRpYWxzUmlnaHQgPSBwYXJ0aWFscyxcbiAgICAgICAgICAgIGhvbGRlcnNSaWdodCA9IGhvbGRlcnM7XG5cbiAgICAgICAgcGFydGlhbHMgPSBob2xkZXJzID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgdmFyIGRhdGEgPSBpc0JpbmRLZXkgPyB1bmRlZmluZWQgOiBnZXREYXRhKGZ1bmMpO1xuXG4gICAgICB2YXIgbmV3RGF0YSA9IFtcbiAgICAgICAgZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMsIGhvbGRlcnMsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCxcbiAgICAgICAgYXJnUG9zLCBhcnksIGFyaXR5XG4gICAgICBdO1xuXG4gICAgICBpZiAoZGF0YSkge1xuICAgICAgICBtZXJnZURhdGEobmV3RGF0YSwgZGF0YSk7XG4gICAgICB9XG4gICAgICBmdW5jID0gbmV3RGF0YVswXTtcbiAgICAgIGJpdG1hc2sgPSBuZXdEYXRhWzFdO1xuICAgICAgdGhpc0FyZyA9IG5ld0RhdGFbMl07XG4gICAgICBwYXJ0aWFscyA9IG5ld0RhdGFbM107XG4gICAgICBob2xkZXJzID0gbmV3RGF0YVs0XTtcbiAgICAgIGFyaXR5ID0gbmV3RGF0YVs5XSA9IG5ld0RhdGFbOV0gPT09IHVuZGVmaW5lZFxuICAgICAgICA/IChpc0JpbmRLZXkgPyAwIDogZnVuYy5sZW5ndGgpXG4gICAgICAgIDogbmF0aXZlTWF4KG5ld0RhdGFbOV0gLSBsZW5ndGgsIDApO1xuXG4gICAgICBpZiAoIWFyaXR5ICYmIGJpdG1hc2sgJiAoV1JBUF9DVVJSWV9GTEFHIHwgV1JBUF9DVVJSWV9SSUdIVF9GTEFHKSkge1xuICAgICAgICBiaXRtYXNrICY9IH4oV1JBUF9DVVJSWV9GTEFHIHwgV1JBUF9DVVJSWV9SSUdIVF9GTEFHKTtcbiAgICAgIH1cbiAgICAgIGlmICghYml0bWFzayB8fCBiaXRtYXNrID09IFdSQVBfQklORF9GTEFHKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBjcmVhdGVCaW5kKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcpO1xuICAgICAgfSBlbHNlIGlmIChiaXRtYXNrID09IFdSQVBfQ1VSUllfRkxBRyB8fCBiaXRtYXNrID09IFdSQVBfQ1VSUllfUklHSFRfRkxBRykge1xuICAgICAgICByZXN1bHQgPSBjcmVhdGVDdXJyeShmdW5jLCBiaXRtYXNrLCBhcml0eSk7XG4gICAgICB9IGVsc2UgaWYgKChiaXRtYXNrID09IFdSQVBfUEFSVElBTF9GTEFHIHx8IGJpdG1hc2sgPT0gKFdSQVBfQklORF9GTEFHIHwgV1JBUF9QQVJUSUFMX0ZMQUcpKSAmJiAhaG9sZGVycy5sZW5ndGgpIHtcbiAgICAgICAgcmVzdWx0ID0gY3JlYXRlUGFydGlhbChmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHQgPSBjcmVhdGVIeWJyaWQuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcbiAgICAgIH1cbiAgICAgIHZhciBzZXR0ZXIgPSBkYXRhID8gYmFzZVNldERhdGEgOiBzZXREYXRhO1xuICAgICAgcmV0dXJuIHNldFdyYXBUb1N0cmluZyhzZXR0ZXIocmVzdWx0LCBuZXdEYXRhKSwgZnVuYywgYml0bWFzayk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXNlZCBieSBgXy5kZWZhdWx0c2AgdG8gY3VzdG9taXplIGl0cyBgXy5hc3NpZ25JbmAgdXNlIHRvIGFzc2lnbiBwcm9wZXJ0aWVzXG4gICAgICogb2Ygc291cmNlIG9iamVjdHMgdG8gdGhlIGRlc3RpbmF0aW9uIG9iamVjdCBmb3IgYWxsIGRlc3RpbmF0aW9uIHByb3BlcnRpZXNcbiAgICAgKiB0aGF0IHJlc29sdmUgdG8gYHVuZGVmaW5lZGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gb2JqVmFsdWUgVGhlIGRlc3RpbmF0aW9uIHZhbHVlLlxuICAgICAqIEBwYXJhbSB7Kn0gc3JjVmFsdWUgVGhlIHNvdXJjZSB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGFzc2lnbi5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBwYXJlbnQgb2JqZWN0IG9mIGBvYmpWYWx1ZWAuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHZhbHVlIHRvIGFzc2lnbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjdXN0b21EZWZhdWx0c0Fzc2lnbkluKG9ialZhbHVlLCBzcmNWYWx1ZSwga2V5LCBvYmplY3QpIHtcbiAgICAgIGlmIChvYmpWYWx1ZSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgKGVxKG9ialZhbHVlLCBvYmplY3RQcm90b1trZXldKSAmJiAhaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpKSB7XG4gICAgICAgIHJldHVybiBzcmNWYWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmpWYWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2VkIGJ5IGBfLmRlZmF1bHRzRGVlcGAgdG8gY3VzdG9taXplIGl0cyBgXy5tZXJnZWAgdXNlIHRvIG1lcmdlIHNvdXJjZVxuICAgICAqIG9iamVjdHMgaW50byBkZXN0aW5hdGlvbiBvYmplY3RzIHRoYXQgYXJlIHBhc3NlZCB0aHJ1LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IG9ialZhbHVlIFRoZSBkZXN0aW5hdGlvbiB2YWx1ZS5cbiAgICAgKiBAcGFyYW0geyp9IHNyY1ZhbHVlIFRoZSBzb3VyY2UgdmFsdWUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBtZXJnZS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBwYXJlbnQgb2JqZWN0IG9mIGBvYmpWYWx1ZWAuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgcGFyZW50IG9iamVjdCBvZiBgc3JjVmFsdWVgLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbc3RhY2tdIFRyYWNrcyB0cmF2ZXJzZWQgc291cmNlIHZhbHVlcyBhbmQgdGhlaXIgbWVyZ2VkXG4gICAgICogIGNvdW50ZXJwYXJ0cy5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgdmFsdWUgdG8gYXNzaWduLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGN1c3RvbURlZmF1bHRzTWVyZ2Uob2JqVmFsdWUsIHNyY1ZhbHVlLCBrZXksIG9iamVjdCwgc291cmNlLCBzdGFjaykge1xuICAgICAgaWYgKGlzT2JqZWN0KG9ialZhbHVlKSAmJiBpc09iamVjdChzcmNWYWx1ZSkpIHtcbiAgICAgICAgLy8gUmVjdXJzaXZlbHkgbWVyZ2Ugb2JqZWN0cyBhbmQgYXJyYXlzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICAgIHN0YWNrLnNldChzcmNWYWx1ZSwgb2JqVmFsdWUpO1xuICAgICAgICBiYXNlTWVyZ2Uob2JqVmFsdWUsIHNyY1ZhbHVlLCB1bmRlZmluZWQsIGN1c3RvbURlZmF1bHRzTWVyZ2UsIHN0YWNrKTtcbiAgICAgICAgc3RhY2tbJ2RlbGV0ZSddKHNyY1ZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvYmpWYWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVc2VkIGJ5IGBfLm9taXRgIHRvIGN1c3RvbWl6ZSBpdHMgYF8uY2xvbmVEZWVwYCB1c2UgdG8gb25seSBjbG9uZSBwbGFpblxuICAgICAqIG9iamVjdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSB1bmNsb25lZCB2YWx1ZSBvciBgdW5kZWZpbmVkYCB0byBkZWZlciBjbG9uaW5nIHRvIGBfLmNsb25lRGVlcGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3VzdG9tT21pdENsb25lKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNQbGFpbk9iamVjdCh2YWx1ZSkgPyB1bmRlZmluZWQgOiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIGFycmF5cyB3aXRoIHN1cHBvcnQgZm9yXG4gICAgICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBvdGhlciBUaGUgb3RoZXIgYXJyYXkgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBiYXNlSXNFcXVhbGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjdXN0b21pemVyIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzdGFjayBUcmFja3MgdHJhdmVyc2VkIGBhcnJheWAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGFycmF5cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGVxdWFsQXJyYXlzKGFycmF5LCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykge1xuICAgICAgdmFyIGlzUGFydGlhbCA9IGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRyxcbiAgICAgICAgICBhcnJMZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgb3RoTGVuZ3RoID0gb3RoZXIubGVuZ3RoO1xuXG4gICAgICBpZiAoYXJyTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhKGlzUGFydGlhbCAmJiBvdGhMZW5ndGggPiBhcnJMZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIC8vIEFzc3VtZSBjeWNsaWMgdmFsdWVzIGFyZSBlcXVhbC5cbiAgICAgIHZhciBzdGFja2VkID0gc3RhY2suZ2V0KGFycmF5KTtcbiAgICAgIGlmIChzdGFja2VkICYmIHN0YWNrLmdldChvdGhlcikpIHtcbiAgICAgICAgcmV0dXJuIHN0YWNrZWQgPT0gb3RoZXI7XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICByZXN1bHQgPSB0cnVlLFxuICAgICAgICAgIHNlZW4gPSAoYml0bWFzayAmIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcpID8gbmV3IFNldENhY2hlIDogdW5kZWZpbmVkO1xuXG4gICAgICBzdGFjay5zZXQoYXJyYXksIG90aGVyKTtcbiAgICAgIHN0YWNrLnNldChvdGhlciwgYXJyYXkpO1xuXG4gICAgICAvLyBJZ25vcmUgbm9uLWluZGV4IHByb3BlcnRpZXMuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGFyckxlbmd0aCkge1xuICAgICAgICB2YXIgYXJyVmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2luZGV4XTtcblxuICAgICAgICBpZiAoY3VzdG9taXplcikge1xuICAgICAgICAgIHZhciBjb21wYXJlZCA9IGlzUGFydGlhbFxuICAgICAgICAgICAgPyBjdXN0b21pemVyKG90aFZhbHVlLCBhcnJWYWx1ZSwgaW5kZXgsIG90aGVyLCBhcnJheSwgc3RhY2spXG4gICAgICAgICAgICA6IGN1c3RvbWl6ZXIoYXJyVmFsdWUsIG90aFZhbHVlLCBpbmRleCwgYXJyYXksIG90aGVyLCBzdGFjayk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbXBhcmVkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBpZiAoY29tcGFyZWQpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXN1bHQgPSBmYWxzZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIGFycmF5cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgICBpZiAoc2Vlbikge1xuICAgICAgICAgIGlmICghYXJyYXlTb21lKG90aGVyLCBmdW5jdGlvbihvdGhWYWx1ZSwgb3RoSW5kZXgpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWNhY2hlSGFzKHNlZW4sIG90aEluZGV4KSAmJlxuICAgICAgICAgICAgICAgICAgICAoYXJyVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSkpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBzZWVuLnB1c2gob3RoSW5kZXgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSkpIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCEoXG4gICAgICAgICAgICAgIGFyclZhbHVlID09PSBvdGhWYWx1ZSB8fFxuICAgICAgICAgICAgICAgIGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKVxuICAgICAgICAgICAgKSkge1xuICAgICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBzdGFja1snZGVsZXRlJ10oYXJyYXkpO1xuICAgICAgc3RhY2tbJ2RlbGV0ZSddKG90aGVyKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBjb21wYXJpbmcgb2JqZWN0cyBvZlxuICAgICAqIHRoZSBzYW1lIGB0b1N0cmluZ1RhZ2AuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNvbXBhcmluZyB2YWx1ZXMgd2l0aCB0YWdzIG9mXG4gICAgICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRhZyBUaGUgYHRvU3RyaW5nVGFnYCBvZiB0aGUgb2JqZWN0cyB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYG9iamVjdGAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIHRhZywgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykge1xuICAgICAgc3dpdGNoICh0YWcpIHtcbiAgICAgICAgY2FzZSBkYXRhVmlld1RhZzpcbiAgICAgICAgICBpZiAoKG9iamVjdC5ieXRlTGVuZ3RoICE9IG90aGVyLmJ5dGVMZW5ndGgpIHx8XG4gICAgICAgICAgICAgIChvYmplY3QuYnl0ZU9mZnNldCAhPSBvdGhlci5ieXRlT2Zmc2V0KSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBvYmplY3QgPSBvYmplY3QuYnVmZmVyO1xuICAgICAgICAgIG90aGVyID0gb3RoZXIuYnVmZmVyO1xuXG4gICAgICAgIGNhc2UgYXJyYXlCdWZmZXJUYWc6XG4gICAgICAgICAgaWYgKChvYmplY3QuYnl0ZUxlbmd0aCAhPSBvdGhlci5ieXRlTGVuZ3RoKSB8fFxuICAgICAgICAgICAgICAhZXF1YWxGdW5jKG5ldyBVaW50OEFycmF5KG9iamVjdCksIG5ldyBVaW50OEFycmF5KG90aGVyKSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICAgICAgY2FzZSBib29sVGFnOlxuICAgICAgICBjYXNlIGRhdGVUYWc6XG4gICAgICAgIGNhc2UgbnVtYmVyVGFnOlxuICAgICAgICAgIC8vIENvZXJjZSBib29sZWFucyB0byBgMWAgb3IgYDBgIGFuZCBkYXRlcyB0byBtaWxsaXNlY29uZHMuXG4gICAgICAgICAgLy8gSW52YWxpZCBkYXRlcyBhcmUgY29lcmNlZCB0byBgTmFOYC5cbiAgICAgICAgICByZXR1cm4gZXEoK29iamVjdCwgK290aGVyKTtcblxuICAgICAgICBjYXNlIGVycm9yVGFnOlxuICAgICAgICAgIHJldHVybiBvYmplY3QubmFtZSA9PSBvdGhlci5uYW1lICYmIG9iamVjdC5tZXNzYWdlID09IG90aGVyLm1lc3NhZ2U7XG5cbiAgICAgICAgY2FzZSByZWdleHBUYWc6XG4gICAgICAgIGNhc2Ugc3RyaW5nVGFnOlxuICAgICAgICAgIC8vIENvZXJjZSByZWdleGVzIHRvIHN0cmluZ3MgYW5kIHRyZWF0IHN0cmluZ3MsIHByaW1pdGl2ZXMgYW5kIG9iamVjdHMsXG4gICAgICAgICAgLy8gYXMgZXF1YWwuIFNlZSBodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtcmVnZXhwLnByb3RvdHlwZS50b3N0cmluZ1xuICAgICAgICAgIC8vIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICAgICAgcmV0dXJuIG9iamVjdCA9PSAob3RoZXIgKyAnJyk7XG5cbiAgICAgICAgY2FzZSBtYXBUYWc6XG4gICAgICAgICAgdmFyIGNvbnZlcnQgPSBtYXBUb0FycmF5O1xuXG4gICAgICAgIGNhc2Ugc2V0VGFnOlxuICAgICAgICAgIHZhciBpc1BhcnRpYWwgPSBiaXRtYXNrICYgQ09NUEFSRV9QQVJUSUFMX0ZMQUc7XG4gICAgICAgICAgY29udmVydCB8fCAoY29udmVydCA9IHNldFRvQXJyYXkpO1xuXG4gICAgICAgICAgaWYgKG9iamVjdC5zaXplICE9IG90aGVyLnNpemUgJiYgIWlzUGFydGlhbCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBBc3N1bWUgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gICAgICAgICAgdmFyIHN0YWNrZWQgPSBzdGFjay5nZXQob2JqZWN0KTtcbiAgICAgICAgICBpZiAoc3RhY2tlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHN0YWNrZWQgPT0gb3RoZXI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJpdG1hc2sgfD0gQ09NUEFSRV9VTk9SREVSRURfRkxBRztcblxuICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgb2JqZWN0cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgICAgIHN0YWNrLnNldChvYmplY3QsIG90aGVyKTtcbiAgICAgICAgICB2YXIgcmVzdWx0ID0gZXF1YWxBcnJheXMoY29udmVydChvYmplY3QpLCBjb252ZXJ0KG90aGVyKSwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjayk7XG4gICAgICAgICAgc3RhY2tbJ2RlbGV0ZSddKG9iamVjdCk7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcblxuICAgICAgICBjYXNlIHN5bWJvbFRhZzpcbiAgICAgICAgICBpZiAoc3ltYm9sVmFsdWVPZikge1xuICAgICAgICAgICAgcmV0dXJuIHN5bWJvbFZhbHVlT2YuY2FsbChvYmplY3QpID09IHN5bWJvbFZhbHVlT2YuY2FsbChvdGhlcik7XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3Igb2JqZWN0cyB3aXRoIHN1cHBvcnQgZm9yXG4gICAgICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBlcXVhbEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRldGVybWluZSBlcXVpdmFsZW50cyBvZiB2YWx1ZXMuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYG9iamVjdGAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBlcXVhbE9iamVjdHMob2JqZWN0LCBvdGhlciwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykge1xuICAgICAgdmFyIGlzUGFydGlhbCA9IGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRyxcbiAgICAgICAgICBvYmpQcm9wcyA9IGdldEFsbEtleXMob2JqZWN0KSxcbiAgICAgICAgICBvYmpMZW5ndGggPSBvYmpQcm9wcy5sZW5ndGgsXG4gICAgICAgICAgb3RoUHJvcHMgPSBnZXRBbGxLZXlzKG90aGVyKSxcbiAgICAgICAgICBvdGhMZW5ndGggPSBvdGhQcm9wcy5sZW5ndGg7XG5cbiAgICAgIGlmIChvYmpMZW5ndGggIT0gb3RoTGVuZ3RoICYmICFpc1BhcnRpYWwpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gb2JqTGVuZ3RoO1xuICAgICAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICAgICAgdmFyIGtleSA9IG9ialByb3BzW2luZGV4XTtcbiAgICAgICAgaWYgKCEoaXNQYXJ0aWFsID8ga2V5IGluIG90aGVyIDogaGFzT3duUHJvcGVydHkuY2FsbChvdGhlciwga2V5KSkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIEFzc3VtZSBjeWNsaWMgdmFsdWVzIGFyZSBlcXVhbC5cbiAgICAgIHZhciBzdGFja2VkID0gc3RhY2suZ2V0KG9iamVjdCk7XG4gICAgICBpZiAoc3RhY2tlZCAmJiBzdGFjay5nZXQob3RoZXIpKSB7XG4gICAgICAgIHJldHVybiBzdGFja2VkID09IG90aGVyO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9IHRydWU7XG4gICAgICBzdGFjay5zZXQob2JqZWN0LCBvdGhlcik7XG4gICAgICBzdGFjay5zZXQob3RoZXIsIG9iamVjdCk7XG5cbiAgICAgIHZhciBza2lwQ3RvciA9IGlzUGFydGlhbDtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgb2JqTGVuZ3RoKSB7XG4gICAgICAgIGtleSA9IG9ialByb3BzW2luZGV4XTtcbiAgICAgICAgdmFyIG9ialZhbHVlID0gb2JqZWN0W2tleV0sXG4gICAgICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2tleV07XG5cbiAgICAgICAgaWYgKGN1c3RvbWl6ZXIpIHtcbiAgICAgICAgICB2YXIgY29tcGFyZWQgPSBpc1BhcnRpYWxcbiAgICAgICAgICAgID8gY3VzdG9taXplcihvdGhWYWx1ZSwgb2JqVmFsdWUsIGtleSwgb3RoZXIsIG9iamVjdCwgc3RhY2spXG4gICAgICAgICAgICA6IGN1c3RvbWl6ZXIob2JqVmFsdWUsIG90aFZhbHVlLCBrZXksIG9iamVjdCwgb3RoZXIsIHN0YWNrKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIG9iamVjdHMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICAgICAgaWYgKCEoY29tcGFyZWQgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICA/IChvYmpWYWx1ZSA9PT0gb3RoVmFsdWUgfHwgZXF1YWxGdW5jKG9ialZhbHVlLCBvdGhWYWx1ZSwgYml0bWFzaywgY3VzdG9taXplciwgc3RhY2spKVxuICAgICAgICAgICAgICA6IGNvbXBhcmVkXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgc2tpcEN0b3IgfHwgKHNraXBDdG9yID0ga2V5ID09ICdjb25zdHJ1Y3RvcicpO1xuICAgICAgfVxuICAgICAgaWYgKHJlc3VsdCAmJiAhc2tpcEN0b3IpIHtcbiAgICAgICAgdmFyIG9iakN0b3IgPSBvYmplY3QuY29uc3RydWN0b3IsXG4gICAgICAgICAgICBvdGhDdG9yID0gb3RoZXIuY29uc3RydWN0b3I7XG5cbiAgICAgICAgLy8gTm9uIGBPYmplY3RgIG9iamVjdCBpbnN0YW5jZXMgd2l0aCBkaWZmZXJlbnQgY29uc3RydWN0b3JzIGFyZSBub3QgZXF1YWwuXG4gICAgICAgIGlmIChvYmpDdG9yICE9IG90aEN0b3IgJiZcbiAgICAgICAgICAgICgnY29uc3RydWN0b3InIGluIG9iamVjdCAmJiAnY29uc3RydWN0b3InIGluIG90aGVyKSAmJlxuICAgICAgICAgICAgISh0eXBlb2Ygb2JqQ3RvciA9PSAnZnVuY3Rpb24nICYmIG9iakN0b3IgaW5zdGFuY2VvZiBvYmpDdG9yICYmXG4gICAgICAgICAgICAgIHR5cGVvZiBvdGhDdG9yID09ICdmdW5jdGlvbicgJiYgb3RoQ3RvciBpbnN0YW5jZW9mIG90aEN0b3IpKSB7XG4gICAgICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHN0YWNrWydkZWxldGUnXShvYmplY3QpO1xuICAgICAgc3RhY2tbJ2RlbGV0ZSddKG90aGVyKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlUmVzdGAgd2hpY2ggZmxhdHRlbnMgdGhlIHJlc3QgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFwcGx5IGEgcmVzdCBwYXJhbWV0ZXIgdG8uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmxhdFJlc3QoZnVuYykge1xuICAgICAgcmV0dXJuIHNldFRvU3RyaW5nKG92ZXJSZXN0KGZ1bmMsIHVuZGVmaW5lZCwgZmxhdHRlbiksIGZ1bmMgKyAnJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMgYW5kIHN5bWJvbHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0QWxsS2V5cyhvYmplY3QpIHtcbiAgICAgIHJldHVybiBiYXNlR2V0QWxsS2V5cyhvYmplY3QsIGtleXMsIGdldFN5bWJvbHMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2Ygb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBhbmRcbiAgICAgKiBzeW1ib2xzIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRBbGxLZXlzSW4ob2JqZWN0KSB7XG4gICAgICByZXR1cm4gYmFzZUdldEFsbEtleXMob2JqZWN0LCBrZXlzSW4sIGdldFN5bWJvbHNJbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBtZXRhZGF0YSBmb3IgYGZ1bmNgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWV0YWRhdGEgZm9yIGBmdW5jYC5cbiAgICAgKi9cbiAgICB2YXIgZ2V0RGF0YSA9ICFtZXRhTWFwID8gbm9vcCA6IGZ1bmN0aW9uKGZ1bmMpIHtcbiAgICAgIHJldHVybiBtZXRhTWFwLmdldChmdW5jKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgbmFtZSBvZiBgZnVuY2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGZ1bmN0aW9uIG5hbWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0RnVuY05hbWUoZnVuYykge1xuICAgICAgdmFyIHJlc3VsdCA9IChmdW5jLm5hbWUgKyAnJyksXG4gICAgICAgICAgYXJyYXkgPSByZWFsTmFtZXNbcmVzdWx0XSxcbiAgICAgICAgICBsZW5ndGggPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKHJlYWxOYW1lcywgcmVzdWx0KSA/IGFycmF5Lmxlbmd0aCA6IDA7XG5cbiAgICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgICB2YXIgZGF0YSA9IGFycmF5W2xlbmd0aF0sXG4gICAgICAgICAgICBvdGhlckZ1bmMgPSBkYXRhLmZ1bmM7XG4gICAgICAgIGlmIChvdGhlckZ1bmMgPT0gbnVsbCB8fCBvdGhlckZ1bmMgPT0gZnVuYykge1xuICAgICAgICAgIHJldHVybiBkYXRhLm5hbWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgYXJndW1lbnQgcGxhY2Vob2xkZXIgdmFsdWUgZm9yIGBmdW5jYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcGxhY2Vob2xkZXIgdmFsdWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0SG9sZGVyKGZ1bmMpIHtcbiAgICAgIHZhciBvYmplY3QgPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKGxvZGFzaCwgJ3BsYWNlaG9sZGVyJykgPyBsb2Rhc2ggOiBmdW5jO1xuICAgICAgcmV0dXJuIG9iamVjdC5wbGFjZWhvbGRlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBhcHByb3ByaWF0ZSBcIml0ZXJhdGVlXCIgZnVuY3Rpb24uIElmIGBfLml0ZXJhdGVlYCBpcyBjdXN0b21pemVkLFxuICAgICAqIHRoaXMgZnVuY3Rpb24gcmV0dXJucyB0aGUgY3VzdG9tIG1ldGhvZCwgb3RoZXJ3aXNlIGl0IHJldHVybnMgYGJhc2VJdGVyYXRlZWAuXG4gICAgICogSWYgYXJndW1lbnRzIGFyZSBwcm92aWRlZCwgdGhlIGNob3NlbiBmdW5jdGlvbiBpcyBpbnZva2VkIHdpdGggdGhlbSBhbmRcbiAgICAgKiBpdHMgcmVzdWx0IGlzIHJldHVybmVkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IFt2YWx1ZV0gVGhlIHZhbHVlIHRvIGNvbnZlcnQgdG8gYW4gaXRlcmF0ZWUuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFthcml0eV0gVGhlIGFyaXR5IG9mIHRoZSBjcmVhdGVkIGl0ZXJhdGVlLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgY2hvc2VuIGZ1bmN0aW9uIG9yIGl0cyByZXN1bHQuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0SXRlcmF0ZWUoKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbG9kYXNoLml0ZXJhdGVlIHx8IGl0ZXJhdGVlO1xuICAgICAgcmVzdWx0ID0gcmVzdWx0ID09PSBpdGVyYXRlZSA/IGJhc2VJdGVyYXRlZSA6IHJlc3VsdDtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gcmVzdWx0KGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdKSA6IHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkYXRhIGZvciBgbWFwYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG1hcCBUaGUgbWFwIHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHJlZmVyZW5jZSBrZXkuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1hcCBkYXRhLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE1hcERhdGEobWFwLCBrZXkpIHtcbiAgICAgIHZhciBkYXRhID0gbWFwLl9fZGF0YV9fO1xuICAgICAgcmV0dXJuIGlzS2V5YWJsZShrZXkpXG4gICAgICAgID8gZGF0YVt0eXBlb2Yga2V5ID09ICdzdHJpbmcnID8gJ3N0cmluZycgOiAnaGFzaCddXG4gICAgICAgIDogZGF0YS5tYXA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgcHJvcGVydHkgbmFtZXMsIHZhbHVlcywgYW5kIGNvbXBhcmUgZmxhZ3Mgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG1hdGNoIGRhdGEgb2YgYG9iamVjdGAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0TWF0Y2hEYXRhKG9iamVjdCkge1xuICAgICAgdmFyIHJlc3VsdCA9IGtleXMob2JqZWN0KSxcbiAgICAgICAgICBsZW5ndGggPSByZXN1bHQubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgICAgdmFyIGtleSA9IHJlc3VsdFtsZW5ndGhdLFxuICAgICAgICAgICAgdmFsdWUgPSBvYmplY3Rba2V5XTtcblxuICAgICAgICByZXN1bHRbbGVuZ3RoXSA9IFtrZXksIHZhbHVlLCBpc1N0cmljdENvbXBhcmFibGUodmFsdWUpXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgbmF0aXZlIGZ1bmN0aW9uIGF0IGBrZXlgIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBtZXRob2QgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBpZiBpdCdzIG5hdGl2ZSwgZWxzZSBgdW5kZWZpbmVkYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXROYXRpdmUob2JqZWN0LCBrZXkpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGdldFZhbHVlKG9iamVjdCwga2V5KTtcbiAgICAgIHJldHVybiBiYXNlSXNOYXRpdmUodmFsdWUpID8gdmFsdWUgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlR2V0VGFnYCB3aGljaCBpZ25vcmVzIGBTeW1ib2wudG9TdHJpbmdUYWdgIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgcmF3IGB0b1N0cmluZ1RhZ2AuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0UmF3VGFnKHZhbHVlKSB7XG4gICAgICB2YXIgaXNPd24gPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCBzeW1Ub1N0cmluZ1RhZyksXG4gICAgICAgICAgdGFnID0gdmFsdWVbc3ltVG9TdHJpbmdUYWddO1xuXG4gICAgICB0cnkge1xuICAgICAgICB2YWx1ZVtzeW1Ub1N0cmluZ1RhZ10gPSB1bmRlZmluZWQ7XG4gICAgICAgIHZhciB1bm1hc2tlZCA9IHRydWU7XG4gICAgICB9IGNhdGNoIChlKSB7fVxuXG4gICAgICB2YXIgcmVzdWx0ID0gbmF0aXZlT2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG4gICAgICBpZiAodW5tYXNrZWQpIHtcbiAgICAgICAgaWYgKGlzT3duKSB7XG4gICAgICAgICAgdmFsdWVbc3ltVG9TdHJpbmdUYWddID0gdGFnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSB2YWx1ZVtzeW1Ub1N0cmluZ1RhZ107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2Ygc3ltYm9scy5cbiAgICAgKi9cbiAgICB2YXIgZ2V0U3ltYm9scyA9ICFuYXRpdmVHZXRTeW1ib2xzID8gc3R1YkFycmF5IDogZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgb2JqZWN0ID0gT2JqZWN0KG9iamVjdCk7XG4gICAgICByZXR1cm4gYXJyYXlGaWx0ZXIobmF0aXZlR2V0U3ltYm9scyhvYmplY3QpLCBmdW5jdGlvbihzeW1ib2wpIHtcbiAgICAgICAgcmV0dXJuIHByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwob2JqZWN0LCBzeW1ib2wpO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2Ygc3ltYm9scy5cbiAgICAgKi9cbiAgICB2YXIgZ2V0U3ltYm9sc0luID0gIW5hdGl2ZUdldFN5bWJvbHMgPyBzdHViQXJyYXkgOiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICAgIHdoaWxlIChvYmplY3QpIHtcbiAgICAgICAgYXJyYXlQdXNoKHJlc3VsdCwgZ2V0U3ltYm9scyhvYmplY3QpKTtcbiAgICAgICAgb2JqZWN0ID0gZ2V0UHJvdG90eXBlKG9iamVjdCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBgdG9TdHJpbmdUYWdgIG9mIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGB0b1N0cmluZ1RhZ2AuXG4gICAgICovXG4gICAgdmFyIGdldFRhZyA9IGJhc2VHZXRUYWc7XG5cbiAgICAvLyBGYWxsYmFjayBmb3IgZGF0YSB2aWV3cywgbWFwcywgc2V0cywgYW5kIHdlYWsgbWFwcyBpbiBJRSAxMSBhbmQgcHJvbWlzZXMgaW4gTm9kZS5qcyA8IDYuXG4gICAgaWYgKChEYXRhVmlldyAmJiBnZXRUYWcobmV3IERhdGFWaWV3KG5ldyBBcnJheUJ1ZmZlcigxKSkpICE9IGRhdGFWaWV3VGFnKSB8fFxuICAgICAgICAoTWFwICYmIGdldFRhZyhuZXcgTWFwKSAhPSBtYXBUYWcpIHx8XG4gICAgICAgIChQcm9taXNlICYmIGdldFRhZyhQcm9taXNlLnJlc29sdmUoKSkgIT0gcHJvbWlzZVRhZykgfHxcbiAgICAgICAgKFNldCAmJiBnZXRUYWcobmV3IFNldCkgIT0gc2V0VGFnKSB8fFxuICAgICAgICAoV2Vha01hcCAmJiBnZXRUYWcobmV3IFdlYWtNYXApICE9IHdlYWtNYXBUYWcpKSB7XG4gICAgICBnZXRUYWcgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gYmFzZUdldFRhZyh2YWx1ZSksXG4gICAgICAgICAgICBDdG9yID0gcmVzdWx0ID09IG9iamVjdFRhZyA/IHZhbHVlLmNvbnN0cnVjdG9yIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgY3RvclN0cmluZyA9IEN0b3IgPyB0b1NvdXJjZShDdG9yKSA6ICcnO1xuXG4gICAgICAgIGlmIChjdG9yU3RyaW5nKSB7XG4gICAgICAgICAgc3dpdGNoIChjdG9yU3RyaW5nKSB7XG4gICAgICAgICAgICBjYXNlIGRhdGFWaWV3Q3RvclN0cmluZzogcmV0dXJuIGRhdGFWaWV3VGFnO1xuICAgICAgICAgICAgY2FzZSBtYXBDdG9yU3RyaW5nOiByZXR1cm4gbWFwVGFnO1xuICAgICAgICAgICAgY2FzZSBwcm9taXNlQ3RvclN0cmluZzogcmV0dXJuIHByb21pc2VUYWc7XG4gICAgICAgICAgICBjYXNlIHNldEN0b3JTdHJpbmc6IHJldHVybiBzZXRUYWc7XG4gICAgICAgICAgICBjYXNlIHdlYWtNYXBDdG9yU3RyaW5nOiByZXR1cm4gd2Vha01hcFRhZztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgdmlldywgYXBwbHlpbmcgYW55IGB0cmFuc2Zvcm1zYCB0byB0aGUgYHN0YXJ0YCBhbmQgYGVuZGAgcG9zaXRpb25zLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgVGhlIHN0YXJ0IG9mIHRoZSB2aWV3LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgVGhlIGVuZCBvZiB0aGUgdmlldy5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSB0cmFuc2Zvcm1zIFRoZSB0cmFuc2Zvcm1hdGlvbnMgdG8gYXBwbHkgdG8gdGhlIHZpZXcuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgYHN0YXJ0YCBhbmQgYGVuZGBcbiAgICAgKiAgcG9zaXRpb25zIG9mIHRoZSB2aWV3LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFZpZXcoc3RhcnQsIGVuZCwgdHJhbnNmb3Jtcykge1xuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgbGVuZ3RoID0gdHJhbnNmb3Jtcy5sZW5ndGg7XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciBkYXRhID0gdHJhbnNmb3Jtc1tpbmRleF0sXG4gICAgICAgICAgICBzaXplID0gZGF0YS5zaXplO1xuXG4gICAgICAgIHN3aXRjaCAoZGF0YS50eXBlKSB7XG4gICAgICAgICAgY2FzZSAnZHJvcCc6ICAgICAgc3RhcnQgKz0gc2l6ZTsgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZHJvcFJpZ2h0JzogZW5kIC09IHNpemU7IGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ3Rha2UnOiAgICAgIGVuZCA9IG5hdGl2ZU1pbihlbmQsIHN0YXJ0ICsgc2l6ZSk7IGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ3Rha2VSaWdodCc6IHN0YXJ0ID0gbmF0aXZlTWF4KHN0YXJ0LCBlbmQgLSBzaXplKTsgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB7ICdzdGFydCc6IHN0YXJ0LCAnZW5kJzogZW5kIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdHMgd3JhcHBlciBkZXRhaWxzIGZyb20gdGhlIGBzb3VyY2VgIGJvZHkgY29tbWVudC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSBUaGUgc291cmNlIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSB3cmFwcGVyIGRldGFpbHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0V3JhcERldGFpbHMoc291cmNlKSB7XG4gICAgICB2YXIgbWF0Y2ggPSBzb3VyY2UubWF0Y2gocmVXcmFwRGV0YWlscyk7XG4gICAgICByZXR1cm4gbWF0Y2ggPyBtYXRjaFsxXS5zcGxpdChyZVNwbGl0RGV0YWlscykgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHBhdGhgIGV4aXN0cyBvbiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIHRvIGNoZWNrLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGhhc0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGNoZWNrIHByb3BlcnRpZXMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBwYXRoYCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBoYXNQYXRoKG9iamVjdCwgcGF0aCwgaGFzRnVuYykge1xuICAgICAgcGF0aCA9IGNhc3RQYXRoKHBhdGgsIG9iamVjdCk7XG5cbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IHBhdGgubGVuZ3RoLFxuICAgICAgICAgIHJlc3VsdCA9IGZhbHNlO1xuXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICB2YXIga2V5ID0gdG9LZXkocGF0aFtpbmRleF0pO1xuICAgICAgICBpZiAoIShyZXN1bHQgPSBvYmplY3QgIT0gbnVsbCAmJiBoYXNGdW5jKG9iamVjdCwga2V5KSkpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBvYmplY3QgPSBvYmplY3Rba2V5XTtcbiAgICAgIH1cbiAgICAgIGlmIChyZXN1bHQgfHwgKytpbmRleCAhPSBsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIGxlbmd0aCA9IG9iamVjdCA9PSBudWxsID8gMCA6IG9iamVjdC5sZW5ndGg7XG4gICAgICByZXR1cm4gISFsZW5ndGggJiYgaXNMZW5ndGgobGVuZ3RoKSAmJiBpc0luZGV4KGtleSwgbGVuZ3RoKSAmJlxuICAgICAgICAoaXNBcnJheShvYmplY3QpIHx8IGlzQXJndW1lbnRzKG9iamVjdCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemVzIGFuIGFycmF5IGNsb25lLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gY2xvbmUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbml0Q2xvbmVBcnJheShhcnJheSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSBuZXcgYXJyYXkuY29uc3RydWN0b3IobGVuZ3RoKTtcblxuICAgICAgLy8gQWRkIHByb3BlcnRpZXMgYXNzaWduZWQgYnkgYFJlZ0V4cCNleGVjYC5cbiAgICAgIGlmIChsZW5ndGggJiYgdHlwZW9mIGFycmF5WzBdID09ICdzdHJpbmcnICYmIGhhc093blByb3BlcnR5LmNhbGwoYXJyYXksICdpbmRleCcpKSB7XG4gICAgICAgIHJlc3VsdC5pbmRleCA9IGFycmF5LmluZGV4O1xuICAgICAgICByZXN1bHQuaW5wdXQgPSBhcnJheS5pbnB1dDtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5pdGlhbGl6ZXMgYW4gb2JqZWN0IGNsb25lLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2xvbmUuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgaW5pdGlhbGl6ZWQgY2xvbmUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5pdENsb25lT2JqZWN0KG9iamVjdCkge1xuICAgICAgcmV0dXJuICh0eXBlb2Ygb2JqZWN0LmNvbnN0cnVjdG9yID09ICdmdW5jdGlvbicgJiYgIWlzUHJvdG90eXBlKG9iamVjdCkpXG4gICAgICAgID8gYmFzZUNyZWF0ZShnZXRQcm90b3R5cGUob2JqZWN0KSlcbiAgICAgICAgOiB7fTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplcyBhbiBvYmplY3QgY2xvbmUgYmFzZWQgb24gaXRzIGB0b1N0cmluZ1RhZ2AuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNsb25pbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICAgICAqIGBCb29sZWFuYCwgYERhdGVgLCBgRXJyb3JgLCBgTWFwYCwgYE51bWJlcmAsIGBSZWdFeHBgLCBgU2V0YCwgb3IgYFN0cmluZ2AuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjbG9uZS5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdGFnIFRoZSBgdG9TdHJpbmdUYWdgIG9mIHRoZSBvYmplY3QgdG8gY2xvbmUuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbml0Q2xvbmVCeVRhZyhvYmplY3QsIHRhZywgaXNEZWVwKSB7XG4gICAgICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgICAgIHN3aXRjaCAodGFnKSB7XG4gICAgICAgIGNhc2UgYXJyYXlCdWZmZXJUYWc6XG4gICAgICAgICAgcmV0dXJuIGNsb25lQXJyYXlCdWZmZXIob2JqZWN0KTtcblxuICAgICAgICBjYXNlIGJvb2xUYWc6XG4gICAgICAgIGNhc2UgZGF0ZVRhZzpcbiAgICAgICAgICByZXR1cm4gbmV3IEN0b3IoK29iamVjdCk7XG5cbiAgICAgICAgY2FzZSBkYXRhVmlld1RhZzpcbiAgICAgICAgICByZXR1cm4gY2xvbmVEYXRhVmlldyhvYmplY3QsIGlzRGVlcCk7XG5cbiAgICAgICAgY2FzZSBmbG9hdDMyVGFnOiBjYXNlIGZsb2F0NjRUYWc6XG4gICAgICAgIGNhc2UgaW50OFRhZzogY2FzZSBpbnQxNlRhZzogY2FzZSBpbnQzMlRhZzpcbiAgICAgICAgY2FzZSB1aW50OFRhZzogY2FzZSB1aW50OENsYW1wZWRUYWc6IGNhc2UgdWludDE2VGFnOiBjYXNlIHVpbnQzMlRhZzpcbiAgICAgICAgICByZXR1cm4gY2xvbmVUeXBlZEFycmF5KG9iamVjdCwgaXNEZWVwKTtcblxuICAgICAgICBjYXNlIG1hcFRhZzpcbiAgICAgICAgICByZXR1cm4gbmV3IEN0b3I7XG5cbiAgICAgICAgY2FzZSBudW1iZXJUYWc6XG4gICAgICAgIGNhc2Ugc3RyaW5nVGFnOlxuICAgICAgICAgIHJldHVybiBuZXcgQ3RvcihvYmplY3QpO1xuXG4gICAgICAgIGNhc2UgcmVnZXhwVGFnOlxuICAgICAgICAgIHJldHVybiBjbG9uZVJlZ0V4cChvYmplY3QpO1xuXG4gICAgICAgIGNhc2Ugc2V0VGFnOlxuICAgICAgICAgIHJldHVybiBuZXcgQ3RvcjtcblxuICAgICAgICBjYXNlIHN5bWJvbFRhZzpcbiAgICAgICAgICByZXR1cm4gY2xvbmVTeW1ib2wob2JqZWN0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbnNlcnRzIHdyYXBwZXIgYGRldGFpbHNgIGluIGEgY29tbWVudCBhdCB0aGUgdG9wIG9mIHRoZSBgc291cmNlYCBib2R5LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIFRoZSBzb3VyY2UgdG8gbW9kaWZ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gZGV0YWlscyBUaGUgZGV0YWlscyB0byBpbnNlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgbW9kaWZpZWQgc291cmNlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGluc2VydFdyYXBEZXRhaWxzKHNvdXJjZSwgZGV0YWlscykge1xuICAgICAgdmFyIGxlbmd0aCA9IGRldGFpbHMubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIHNvdXJjZTtcbiAgICAgIH1cbiAgICAgIHZhciBsYXN0SW5kZXggPSBsZW5ndGggLSAxO1xuICAgICAgZGV0YWlsc1tsYXN0SW5kZXhdID0gKGxlbmd0aCA+IDEgPyAnJiAnIDogJycpICsgZGV0YWlsc1tsYXN0SW5kZXhdO1xuICAgICAgZGV0YWlscyA9IGRldGFpbHMuam9pbihsZW5ndGggPiAyID8gJywgJyA6ICcgJyk7XG4gICAgICByZXR1cm4gc291cmNlLnJlcGxhY2UocmVXcmFwQ29tbWVudCwgJ3tcXG4vKiBbd3JhcHBlZCB3aXRoICcgKyBkZXRhaWxzICsgJ10gKi9cXG4nKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIGZsYXR0ZW5hYmxlIGBhcmd1bWVudHNgIG9iamVjdCBvciBhcnJheS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZmxhdHRlbmFibGUsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0ZsYXR0ZW5hYmxlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNBcnJheSh2YWx1ZSkgfHwgaXNBcmd1bWVudHModmFsdWUpIHx8XG4gICAgICAgICEhKHNwcmVhZGFibGVTeW1ib2wgJiYgdmFsdWUgJiYgdmFsdWVbc3ByZWFkYWJsZVN5bWJvbF0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBpbmRleC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGg9TUFYX1NBRkVfSU5URUdFUl0gVGhlIHVwcGVyIGJvdW5kcyBvZiBhIHZhbGlkIGluZGV4LlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgaW5kZXgsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0luZGV4KHZhbHVlLCBsZW5ndGgpIHtcbiAgICAgIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICAgICAgbGVuZ3RoID0gbGVuZ3RoID09IG51bGwgPyBNQVhfU0FGRV9JTlRFR0VSIDogbGVuZ3RoO1xuXG4gICAgICByZXR1cm4gISFsZW5ndGggJiZcbiAgICAgICAgKHR5cGUgPT0gJ251bWJlcicgfHxcbiAgICAgICAgICAodHlwZSAhPSAnc3ltYm9sJyAmJiByZUlzVWludC50ZXN0KHZhbHVlKSkpICYmXG4gICAgICAgICAgICAodmFsdWUgPiAtMSAmJiB2YWx1ZSAlIDEgPT0gMCAmJiB2YWx1ZSA8IGxlbmd0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBhcmd1bWVudHMgYXJlIGZyb20gYW4gaXRlcmF0ZWUgY2FsbC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIHZhbHVlIGFyZ3VtZW50LlxuICAgICAqIEBwYXJhbSB7Kn0gaW5kZXggVGhlIHBvdGVudGlhbCBpdGVyYXRlZSBpbmRleCBvciBrZXkgYXJndW1lbnQuXG4gICAgICogQHBhcmFtIHsqfSBvYmplY3QgVGhlIHBvdGVudGlhbCBpdGVyYXRlZSBvYmplY3QgYXJndW1lbnQuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBhcmd1bWVudHMgYXJlIGZyb20gYW4gaXRlcmF0ZWUgY2FsbCxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzSXRlcmF0ZWVDYWxsKHZhbHVlLCBpbmRleCwgb2JqZWN0KSB7XG4gICAgICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIHR5cGUgPSB0eXBlb2YgaW5kZXg7XG4gICAgICBpZiAodHlwZSA9PSAnbnVtYmVyJ1xuICAgICAgICAgICAgPyAoaXNBcnJheUxpa2Uob2JqZWN0KSAmJiBpc0luZGV4KGluZGV4LCBvYmplY3QubGVuZ3RoKSlcbiAgICAgICAgICAgIDogKHR5cGUgPT0gJ3N0cmluZycgJiYgaW5kZXggaW4gb2JqZWN0KVxuICAgICAgICAgICkge1xuICAgICAgICByZXR1cm4gZXEob2JqZWN0W2luZGV4XSwgdmFsdWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgcHJvcGVydHkgbmFtZSBhbmQgbm90IGEgcHJvcGVydHkgcGF0aC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3RdIFRoZSBvYmplY3QgdG8gcXVlcnkga2V5cyBvbi5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHByb3BlcnR5IG5hbWUsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0tleSh2YWx1ZSwgb2JqZWN0KSB7XG4gICAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gICAgICBpZiAodHlwZSA9PSAnbnVtYmVyJyB8fCB0eXBlID09ICdzeW1ib2wnIHx8IHR5cGUgPT0gJ2Jvb2xlYW4nIHx8XG4gICAgICAgICAgdmFsdWUgPT0gbnVsbCB8fCBpc1N5bWJvbCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVJc1BsYWluUHJvcC50ZXN0KHZhbHVlKSB8fCAhcmVJc0RlZXBQcm9wLnRlc3QodmFsdWUpIHx8XG4gICAgICAgIChvYmplY3QgIT0gbnVsbCAmJiB2YWx1ZSBpbiBPYmplY3Qob2JqZWN0KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgc3VpdGFibGUgZm9yIHVzZSBhcyB1bmlxdWUgb2JqZWN0IGtleS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgc3VpdGFibGUsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0tleWFibGUodmFsdWUpIHtcbiAgICAgIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICAgICAgcmV0dXJuICh0eXBlID09ICdzdHJpbmcnIHx8IHR5cGUgPT0gJ251bWJlcicgfHwgdHlwZSA9PSAnc3ltYm9sJyB8fCB0eXBlID09ICdib29sZWFuJylcbiAgICAgICAgPyAodmFsdWUgIT09ICdfX3Byb3RvX18nKVxuICAgICAgICA6ICh2YWx1ZSA9PT0gbnVsbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBmdW5jYCBoYXMgYSBsYXp5IGNvdW50ZXJwYXJ0LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYGZ1bmNgIGhhcyBhIGxhenkgY291bnRlcnBhcnQsXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0xhemlhYmxlKGZ1bmMpIHtcbiAgICAgIHZhciBmdW5jTmFtZSA9IGdldEZ1bmNOYW1lKGZ1bmMpLFxuICAgICAgICAgIG90aGVyID0gbG9kYXNoW2Z1bmNOYW1lXTtcblxuICAgICAgaWYgKHR5cGVvZiBvdGhlciAhPSAnZnVuY3Rpb24nIHx8ICEoZnVuY05hbWUgaW4gTGF6eVdyYXBwZXIucHJvdG90eXBlKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoZnVuYyA9PT0gb3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICB2YXIgZGF0YSA9IGdldERhdGEob3RoZXIpO1xuICAgICAgcmV0dXJuICEhZGF0YSAmJiBmdW5jID09PSBkYXRhWzBdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgZnVuY2AgaGFzIGl0cyBzb3VyY2UgbWFza2VkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYGZ1bmNgIGlzIG1hc2tlZCwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzTWFza2VkKGZ1bmMpIHtcbiAgICAgIHJldHVybiAhIW1hc2tTcmNLZXkgJiYgKG1hc2tTcmNLZXkgaW4gZnVuYyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBmdW5jYCBpcyBjYXBhYmxlIG9mIGJlaW5nIG1hc2tlZC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBmdW5jYCBpcyBtYXNrYWJsZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIHZhciBpc01hc2thYmxlID0gY29yZUpzRGF0YSA/IGlzRnVuY3Rpb24gOiBzdHViRmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBsaWtlbHkgYSBwcm90b3R5cGUgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHByb3RvdHlwZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzUHJvdG90eXBlKHZhbHVlKSB7XG4gICAgICB2YXIgQ3RvciA9IHZhbHVlICYmIHZhbHVlLmNvbnN0cnVjdG9yLFxuICAgICAgICAgIHByb3RvID0gKHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgQ3Rvci5wcm90b3R5cGUpIHx8IG9iamVjdFByb3RvO1xuXG4gICAgICByZXR1cm4gdmFsdWUgPT09IHByb3RvO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlIGZvciBzdHJpY3QgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGkuZS4gYD09PWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlmIHN1aXRhYmxlIGZvciBzdHJpY3RcbiAgICAgKiAgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1N0cmljdENvbXBhcmFibGUodmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gdmFsdWUgJiYgIWlzT2JqZWN0KHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYG1hdGNoZXNQcm9wZXJ0eWAgZm9yIHNvdXJjZSB2YWx1ZXMgc3VpdGFibGVcbiAgICAgKiBmb3Igc3RyaWN0IGVxdWFsaXR5IGNvbXBhcmlzb25zLCBpLmUuIGA9PT1gLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAgICAgKiBAcGFyYW0geyp9IHNyY1ZhbHVlIFRoZSB2YWx1ZSB0byBtYXRjaC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hdGNoZXNTdHJpY3RDb21wYXJhYmxlKGtleSwgc3JjVmFsdWUpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmplY3Rba2V5XSA9PT0gc3JjVmFsdWUgJiZcbiAgICAgICAgICAoc3JjVmFsdWUgIT09IHVuZGVmaW5lZCB8fCAoa2V5IGluIE9iamVjdChvYmplY3QpKSk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5tZW1vaXplYCB3aGljaCBjbGVhcnMgdGhlIG1lbW9pemVkIGZ1bmN0aW9uJ3NcbiAgICAgKiBjYWNoZSB3aGVuIGl0IGV4Y2VlZHMgYE1BWF9NRU1PSVpFX1NJWkVgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBoYXZlIGl0cyBvdXRwdXQgbWVtb2l6ZWQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgbWVtb2l6ZWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWVtb2l6ZUNhcHBlZChmdW5jKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbWVtb2l6ZShmdW5jLCBmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgaWYgKGNhY2hlLnNpemUgPT09IE1BWF9NRU1PSVpFX1NJWkUpIHtcbiAgICAgICAgICBjYWNoZS5jbGVhcigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBrZXk7XG4gICAgICB9KTtcblxuICAgICAgdmFyIGNhY2hlID0gcmVzdWx0LmNhY2hlO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNZXJnZXMgdGhlIGZ1bmN0aW9uIG1ldGFkYXRhIG9mIGBzb3VyY2VgIGludG8gYGRhdGFgLlxuICAgICAqXG4gICAgICogTWVyZ2luZyBtZXRhZGF0YSByZWR1Y2VzIHRoZSBudW1iZXIgb2Ygd3JhcHBlcnMgdXNlZCB0byBpbnZva2UgYSBmdW5jdGlvbi5cbiAgICAgKiBUaGlzIGlzIHBvc3NpYmxlIGJlY2F1c2UgbWV0aG9kcyBsaWtlIGBfLmJpbmRgLCBgXy5jdXJyeWAsIGFuZCBgXy5wYXJ0aWFsYFxuICAgICAqIG1heSBiZSBhcHBsaWVkIHJlZ2FyZGxlc3Mgb2YgZXhlY3V0aW9uIG9yZGVyLiBNZXRob2RzIGxpa2UgYF8uYXJ5YCBhbmRcbiAgICAgKiBgXy5yZWFyZ2AgbW9kaWZ5IGZ1bmN0aW9uIGFyZ3VtZW50cywgbWFraW5nIHRoZSBvcmRlciBpbiB3aGljaCB0aGV5IGFyZVxuICAgICAqIGV4ZWN1dGVkIGltcG9ydGFudCwgcHJldmVudGluZyB0aGUgbWVyZ2luZyBvZiBtZXRhZGF0YS4gSG93ZXZlciwgd2UgbWFrZVxuICAgICAqIGFuIGV4Y2VwdGlvbiBmb3IgYSBzYWZlIGNvbWJpbmVkIGNhc2Ugd2hlcmUgY3VycmllZCBmdW5jdGlvbnMgaGF2ZSBgXy5hcnlgXG4gICAgICogYW5kIG9yIGBfLnJlYXJnYCBhcHBsaWVkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBkYXRhIFRoZSBkZXN0aW5hdGlvbiBtZXRhZGF0YS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBzb3VyY2UgVGhlIHNvdXJjZSBtZXRhZGF0YS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGRhdGFgLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1lcmdlRGF0YShkYXRhLCBzb3VyY2UpIHtcbiAgICAgIHZhciBiaXRtYXNrID0gZGF0YVsxXSxcbiAgICAgICAgICBzcmNCaXRtYXNrID0gc291cmNlWzFdLFxuICAgICAgICAgIG5ld0JpdG1hc2sgPSBiaXRtYXNrIHwgc3JjQml0bWFzayxcbiAgICAgICAgICBpc0NvbW1vbiA9IG5ld0JpdG1hc2sgPCAoV1JBUF9CSU5EX0ZMQUcgfCBXUkFQX0JJTkRfS0VZX0ZMQUcgfCBXUkFQX0FSWV9GTEFHKTtcblxuICAgICAgdmFyIGlzQ29tYm8gPVxuICAgICAgICAoKHNyY0JpdG1hc2sgPT0gV1JBUF9BUllfRkxBRykgJiYgKGJpdG1hc2sgPT0gV1JBUF9DVVJSWV9GTEFHKSkgfHxcbiAgICAgICAgKChzcmNCaXRtYXNrID09IFdSQVBfQVJZX0ZMQUcpICYmIChiaXRtYXNrID09IFdSQVBfUkVBUkdfRkxBRykgJiYgKGRhdGFbN10ubGVuZ3RoIDw9IHNvdXJjZVs4XSkpIHx8XG4gICAgICAgICgoc3JjQml0bWFzayA9PSAoV1JBUF9BUllfRkxBRyB8IFdSQVBfUkVBUkdfRkxBRykpICYmIChzb3VyY2VbN10ubGVuZ3RoIDw9IHNvdXJjZVs4XSkgJiYgKGJpdG1hc2sgPT0gV1JBUF9DVVJSWV9GTEFHKSk7XG5cbiAgICAgIC8vIEV4aXQgZWFybHkgaWYgbWV0YWRhdGEgY2FuJ3QgYmUgbWVyZ2VkLlxuICAgICAgaWYgKCEoaXNDb21tb24gfHwgaXNDb21ibykpIHtcbiAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICB9XG4gICAgICAvLyBVc2Ugc291cmNlIGB0aGlzQXJnYCBpZiBhdmFpbGFibGUuXG4gICAgICBpZiAoc3JjQml0bWFzayAmIFdSQVBfQklORF9GTEFHKSB7XG4gICAgICAgIGRhdGFbMl0gPSBzb3VyY2VbMl07XG4gICAgICAgIC8vIFNldCB3aGVuIGN1cnJ5aW5nIGEgYm91bmQgZnVuY3Rpb24uXG4gICAgICAgIG5ld0JpdG1hc2sgfD0gYml0bWFzayAmIFdSQVBfQklORF9GTEFHID8gMCA6IFdSQVBfQ1VSUllfQk9VTkRfRkxBRztcbiAgICAgIH1cbiAgICAgIC8vIENvbXBvc2UgcGFydGlhbCBhcmd1bWVudHMuXG4gICAgICB2YXIgdmFsdWUgPSBzb3VyY2VbM107XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgdmFyIHBhcnRpYWxzID0gZGF0YVszXTtcbiAgICAgICAgZGF0YVszXSA9IHBhcnRpYWxzID8gY29tcG9zZUFyZ3MocGFydGlhbHMsIHZhbHVlLCBzb3VyY2VbNF0pIDogdmFsdWU7XG4gICAgICAgIGRhdGFbNF0gPSBwYXJ0aWFscyA/IHJlcGxhY2VIb2xkZXJzKGRhdGFbM10sIFBMQUNFSE9MREVSKSA6IHNvdXJjZVs0XTtcbiAgICAgIH1cbiAgICAgIC8vIENvbXBvc2UgcGFydGlhbCByaWdodCBhcmd1bWVudHMuXG4gICAgICB2YWx1ZSA9IHNvdXJjZVs1XTtcbiAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICBwYXJ0aWFscyA9IGRhdGFbNV07XG4gICAgICAgIGRhdGFbNV0gPSBwYXJ0aWFscyA/IGNvbXBvc2VBcmdzUmlnaHQocGFydGlhbHMsIHZhbHVlLCBzb3VyY2VbNl0pIDogdmFsdWU7XG4gICAgICAgIGRhdGFbNl0gPSBwYXJ0aWFscyA/IHJlcGxhY2VIb2xkZXJzKGRhdGFbNV0sIFBMQUNFSE9MREVSKSA6IHNvdXJjZVs2XTtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSBzb3VyY2UgYGFyZ1Bvc2AgaWYgYXZhaWxhYmxlLlxuICAgICAgdmFsdWUgPSBzb3VyY2VbN107XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgZGF0YVs3XSA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgLy8gVXNlIHNvdXJjZSBgYXJ5YCBpZiBpdCdzIHNtYWxsZXIuXG4gICAgICBpZiAoc3JjQml0bWFzayAmIFdSQVBfQVJZX0ZMQUcpIHtcbiAgICAgICAgZGF0YVs4XSA9IGRhdGFbOF0gPT0gbnVsbCA/IHNvdXJjZVs4XSA6IG5hdGl2ZU1pbihkYXRhWzhdLCBzb3VyY2VbOF0pO1xuICAgICAgfVxuICAgICAgLy8gVXNlIHNvdXJjZSBgYXJpdHlgIGlmIG9uZSBpcyBub3QgcHJvdmlkZWQuXG4gICAgICBpZiAoZGF0YVs5XSA9PSBudWxsKSB7XG4gICAgICAgIGRhdGFbOV0gPSBzb3VyY2VbOV07XG4gICAgICB9XG4gICAgICAvLyBVc2Ugc291cmNlIGBmdW5jYCBhbmQgbWVyZ2UgYml0bWFza3MuXG4gICAgICBkYXRhWzBdID0gc291cmNlWzBdO1xuICAgICAgZGF0YVsxXSA9IG5ld0JpdG1hc2s7XG5cbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gaXMgbGlrZVxuICAgICAqIFtgT2JqZWN0LmtleXNgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3Qua2V5cylcbiAgICAgKiBleGNlcHQgdGhhdCBpdCBpbmNsdWRlcyBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBuYXRpdmVLZXlzSW4ob2JqZWN0KSB7XG4gICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICBpZiAob2JqZWN0ICE9IG51bGwpIHtcbiAgICAgICAgZm9yICh2YXIga2V5IGluIE9iamVjdChvYmplY3QpKSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2goa2V5KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nIHVzaW5nIGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgc3RyaW5nLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKHZhbHVlKSB7XG4gICAgICByZXR1cm4gbmF0aXZlT2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlUmVzdGAgd2hpY2ggdHJhbnNmb3JtcyB0aGUgcmVzdCBhcnJheS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXBwbHkgYSByZXN0IHBhcmFtZXRlciB0by5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PWZ1bmMubGVuZ3RoLTFdIFRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgcmVzdCBwYXJhbWV0ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gdHJhbnNmb3JtIFRoZSByZXN0IGFycmF5IHRyYW5zZm9ybS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBvdmVyUmVzdChmdW5jLCBzdGFydCwgdHJhbnNmb3JtKSB7XG4gICAgICBzdGFydCA9IG5hdGl2ZU1heChzdGFydCA9PT0gdW5kZWZpbmVkID8gKGZ1bmMubGVuZ3RoIC0gMSkgOiBzdGFydCwgMCk7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICAgICAgaW5kZXggPSAtMSxcbiAgICAgICAgICAgIGxlbmd0aCA9IG5hdGl2ZU1heChhcmdzLmxlbmd0aCAtIHN0YXJ0LCAwKSxcbiAgICAgICAgICAgIGFycmF5ID0gQXJyYXkobGVuZ3RoKTtcblxuICAgICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgIGFycmF5W2luZGV4XSA9IGFyZ3Nbc3RhcnQgKyBpbmRleF07XG4gICAgICAgIH1cbiAgICAgICAgaW5kZXggPSAtMTtcbiAgICAgICAgdmFyIG90aGVyQXJncyA9IEFycmF5KHN0YXJ0ICsgMSk7XG4gICAgICAgIHdoaWxlICgrK2luZGV4IDwgc3RhcnQpIHtcbiAgICAgICAgICBvdGhlckFyZ3NbaW5kZXhdID0gYXJnc1tpbmRleF07XG4gICAgICAgIH1cbiAgICAgICAgb3RoZXJBcmdzW3N0YXJ0XSA9IHRyYW5zZm9ybShhcnJheSk7XG4gICAgICAgIHJldHVybiBhcHBseShmdW5jLCB0aGlzLCBvdGhlckFyZ3MpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBwYXJlbnQgdmFsdWUgYXQgYHBhdGhgIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheX0gcGF0aCBUaGUgcGF0aCB0byBnZXQgdGhlIHBhcmVudCB2YWx1ZSBvZi5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcGFyZW50IHZhbHVlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHBhcmVudChvYmplY3QsIHBhdGgpIHtcbiAgICAgIHJldHVybiBwYXRoLmxlbmd0aCA8IDIgPyBvYmplY3QgOiBiYXNlR2V0KG9iamVjdCwgYmFzZVNsaWNlKHBhdGgsIDAsIC0xKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVvcmRlciBgYXJyYXlgIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIGluZGV4ZXMgd2hlcmUgdGhlIGVsZW1lbnQgYXRcbiAgICAgKiB0aGUgZmlyc3QgaW5kZXggaXMgYXNzaWduZWQgYXMgdGhlIGZpcnN0IGVsZW1lbnQsIHRoZSBlbGVtZW50IGF0XG4gICAgICogdGhlIHNlY29uZCBpbmRleCBpcyBhc3NpZ25lZCBhcyB0aGUgc2Vjb25kIGVsZW1lbnQsIGFuZCBzbyBvbi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHJlb3JkZXIuXG4gICAgICogQHBhcmFtIHtBcnJheX0gaW5kZXhlcyBUaGUgYXJyYW5nZWQgYXJyYXkgaW5kZXhlcy5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZW9yZGVyKGFycmF5LCBpbmRleGVzKSB7XG4gICAgICB2YXIgYXJyTGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICAgIGxlbmd0aCA9IG5hdGl2ZU1pbihpbmRleGVzLmxlbmd0aCwgYXJyTGVuZ3RoKSxcbiAgICAgICAgICBvbGRBcnJheSA9IGNvcHlBcnJheShhcnJheSk7XG5cbiAgICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgICB2YXIgaW5kZXggPSBpbmRleGVzW2xlbmd0aF07XG4gICAgICAgIGFycmF5W2xlbmd0aF0gPSBpc0luZGV4KGluZGV4LCBhcnJMZW5ndGgpID8gb2xkQXJyYXlbaW5kZXhdIDogdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHZhbHVlIGF0IGBrZXlgLCB1bmxlc3MgYGtleWAgaXMgXCJfX3Byb3RvX19cIi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzYWZlR2V0KG9iamVjdCwga2V5KSB7XG4gICAgICBpZiAoa2V5ID09ICdfX3Byb3RvX18nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG9iamVjdFtrZXldO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgbWV0YWRhdGEgZm9yIGBmdW5jYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBJZiB0aGlzIGZ1bmN0aW9uIGJlY29tZXMgaG90LCBpLmUuIGlzIGludm9rZWQgYSBsb3QgaW4gYSBzaG9ydFxuICAgICAqIHBlcmlvZCBvZiB0aW1lLCBpdCB3aWxsIHRyaXAgaXRzIGJyZWFrZXIgYW5kIHRyYW5zaXRpb24gdG8gYW4gaWRlbnRpdHlcbiAgICAgKiBmdW5jdGlvbiB0byBhdm9pZCBnYXJiYWdlIGNvbGxlY3Rpb24gcGF1c2VzIGluIFY4LiBTZWVcbiAgICAgKiBbVjggaXNzdWUgMjA3MF0oaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MjA3MClcbiAgICAgKiBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhc3NvY2lhdGUgbWV0YWRhdGEgd2l0aC5cbiAgICAgKiBAcGFyYW0geyp9IGRhdGEgVGhlIG1ldGFkYXRhLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gICAgICovXG4gICAgdmFyIHNldERhdGEgPSBzaG9ydE91dChiYXNlU2V0RGF0YSk7XG5cbiAgICAvKipcbiAgICAgKiBBIHNpbXBsZSB3cmFwcGVyIGFyb3VuZCB0aGUgZ2xvYmFsIFtgc2V0VGltZW91dGBdKGh0dHBzOi8vbWRuLmlvL3NldFRpbWVvdXQpLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBkZWxheS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gd2FpdCBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byBkZWxheSBpbnZvY2F0aW9uLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ8T2JqZWN0fSBSZXR1cm5zIHRoZSB0aW1lciBpZCBvciB0aW1lb3V0IG9iamVjdC5cbiAgICAgKi9cbiAgICB2YXIgc2V0VGltZW91dCA9IGN0eFNldFRpbWVvdXQgfHwgZnVuY3Rpb24oZnVuYywgd2FpdCkge1xuICAgICAgcmV0dXJuIHJvb3Quc2V0VGltZW91dChmdW5jLCB3YWl0KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgYHRvU3RyaW5nYCBtZXRob2Qgb2YgYGZ1bmNgIHRvIHJldHVybiBgc3RyaW5nYC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHN0cmluZyBUaGUgYHRvU3RyaW5nYCByZXN1bHQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBmdW5jYC5cbiAgICAgKi9cbiAgICB2YXIgc2V0VG9TdHJpbmcgPSBzaG9ydE91dChiYXNlU2V0VG9TdHJpbmcpO1xuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgYHRvU3RyaW5nYCBtZXRob2Qgb2YgYHdyYXBwZXJgIHRvIG1pbWljIHRoZSBzb3VyY2Ugb2YgYHJlZmVyZW5jZWBcbiAgICAgKiB3aXRoIHdyYXBwZXIgZGV0YWlscyBpbiBhIGNvbW1lbnQgYXQgdGhlIHRvcCBvZiB0aGUgc291cmNlIGJvZHkuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHdyYXBwZXIgVGhlIGZ1bmN0aW9uIHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSByZWZlcmVuY2UgVGhlIHJlZmVyZW5jZSBmdW5jdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBjcmVhdGVXcmFwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgd3JhcHBlcmAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gc2V0V3JhcFRvU3RyaW5nKHdyYXBwZXIsIHJlZmVyZW5jZSwgYml0bWFzaykge1xuICAgICAgdmFyIHNvdXJjZSA9IChyZWZlcmVuY2UgKyAnJyk7XG4gICAgICByZXR1cm4gc2V0VG9TdHJpbmcod3JhcHBlciwgaW5zZXJ0V3JhcERldGFpbHMoc291cmNlLCB1cGRhdGVXcmFwRGV0YWlscyhnZXRXcmFwRGV0YWlscyhzb3VyY2UpLCBiaXRtYXNrKSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0J2xsIHNob3J0IG91dCBhbmQgaW52b2tlIGBpZGVudGl0eWAgaW5zdGVhZFxuICAgICAqIG9mIGBmdW5jYCB3aGVuIGl0J3MgY2FsbGVkIGBIT1RfQ09VTlRgIG9yIG1vcmUgdGltZXMgaW4gYEhPVF9TUEFOYFxuICAgICAqIG1pbGxpc2Vjb25kcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcmVzdHJpY3QuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgc2hvcnRhYmxlIGZ1bmN0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNob3J0T3V0KGZ1bmMpIHtcbiAgICAgIHZhciBjb3VudCA9IDAsXG4gICAgICAgICAgbGFzdENhbGxlZCA9IDA7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHN0YW1wID0gbmF0aXZlTm93KCksXG4gICAgICAgICAgICByZW1haW5pbmcgPSBIT1RfU1BBTiAtIChzdGFtcCAtIGxhc3RDYWxsZWQpO1xuXG4gICAgICAgIGxhc3RDYWxsZWQgPSBzdGFtcDtcbiAgICAgICAgaWYgKHJlbWFpbmluZyA+IDApIHtcbiAgICAgICAgICBpZiAoKytjb3VudCA+PSBIT1RfQ09VTlQpIHtcbiAgICAgICAgICAgIHJldHVybiBhcmd1bWVudHNbMF07XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvdW50ID0gMDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZnVuYy5hcHBseSh1bmRlZmluZWQsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5zaHVmZmxlYCB3aGljaCBtdXRhdGVzIGFuZCBzZXRzIHRoZSBzaXplIG9mIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzaHVmZmxlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc2l6ZT1hcnJheS5sZW5ndGhdIFRoZSBzaXplIG9mIGBhcnJheWAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICovXG4gICAgZnVuY3Rpb24gc2h1ZmZsZVNlbGYoYXJyYXksIHNpemUpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICBsYXN0SW5kZXggPSBsZW5ndGggLSAxO1xuXG4gICAgICBzaXplID0gc2l6ZSA9PT0gdW5kZWZpbmVkID8gbGVuZ3RoIDogc2l6ZTtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgc2l6ZSkge1xuICAgICAgICB2YXIgcmFuZCA9IGJhc2VSYW5kb20oaW5kZXgsIGxhc3RJbmRleCksXG4gICAgICAgICAgICB2YWx1ZSA9IGFycmF5W3JhbmRdO1xuXG4gICAgICAgIGFycmF5W3JhbmRdID0gYXJyYXlbaW5kZXhdO1xuICAgICAgICBhcnJheVtpbmRleF0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIGFycmF5Lmxlbmd0aCA9IHNpemU7XG4gICAgICByZXR1cm4gYXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHN0cmluZ2AgdG8gYSBwcm9wZXJ0eSBwYXRoIGFycmF5LlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHByb3BlcnR5IHBhdGggYXJyYXkuXG4gICAgICovXG4gICAgdmFyIHN0cmluZ1RvUGF0aCA9IG1lbW9pemVDYXBwZWQoZnVuY3Rpb24oc3RyaW5nKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICBpZiAoc3RyaW5nLmNoYXJDb2RlQXQoMCkgPT09IDQ2IC8qIC4gKi8pIHtcbiAgICAgICAgcmVzdWx0LnB1c2goJycpO1xuICAgICAgfVxuICAgICAgc3RyaW5nLnJlcGxhY2UocmVQcm9wTmFtZSwgZnVuY3Rpb24obWF0Y2gsIG51bWJlciwgcXVvdGUsIHN1YlN0cmluZykge1xuICAgICAgICByZXN1bHQucHVzaChxdW90ZSA/IHN1YlN0cmluZy5yZXBsYWNlKHJlRXNjYXBlQ2hhciwgJyQxJykgOiAobnVtYmVyIHx8IG1hdGNoKSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nIGtleSBpZiBpdCdzIG5vdCBhIHN0cmluZyBvciBzeW1ib2wuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge3N0cmluZ3xzeW1ib2x9IFJldHVybnMgdGhlIGtleS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b0tleSh2YWx1ZSkge1xuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJyB8fCBpc1N5bWJvbCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9ICh2YWx1ZSArICcnKTtcbiAgICAgIHJldHVybiAocmVzdWx0ID09ICcwJyAmJiAoMSAvIHZhbHVlKSA9PSAtSU5GSU5JVFkpID8gJy0wJyA6IHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgZnVuY2AgdG8gaXRzIHNvdXJjZSBjb2RlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHNvdXJjZSBjb2RlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvU291cmNlKGZ1bmMpIHtcbiAgICAgIGlmIChmdW5jICE9IG51bGwpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gZnVuY1RvU3RyaW5nLmNhbGwoZnVuYyk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIChmdW5jICsgJycpO1xuICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgfVxuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVwZGF0ZXMgd3JhcHBlciBgZGV0YWlsc2AgYmFzZWQgb24gYGJpdG1hc2tgIGZsYWdzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IGRldGFpbHMgVGhlIGRldGFpbHMgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGNyZWF0ZVdyYXBgIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBkZXRhaWxzYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1cGRhdGVXcmFwRGV0YWlscyhkZXRhaWxzLCBiaXRtYXNrKSB7XG4gICAgICBhcnJheUVhY2god3JhcEZsYWdzLCBmdW5jdGlvbihwYWlyKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9ICdfLicgKyBwYWlyWzBdO1xuICAgICAgICBpZiAoKGJpdG1hc2sgJiBwYWlyWzFdKSAmJiAhYXJyYXlJbmNsdWRlcyhkZXRhaWxzLCB2YWx1ZSkpIHtcbiAgICAgICAgICBkZXRhaWxzLnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBkZXRhaWxzLnNvcnQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY2xvbmUgb2YgYHdyYXBwZXJgLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gd3JhcHBlciBUaGUgd3JhcHBlciB0byBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjbG9uZWQgd3JhcHBlci5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB3cmFwcGVyQ2xvbmUod3JhcHBlcikge1xuICAgICAgaWYgKHdyYXBwZXIgaW5zdGFuY2VvZiBMYXp5V3JhcHBlcikge1xuICAgICAgICByZXR1cm4gd3JhcHBlci5jbG9uZSgpO1xuICAgICAgfVxuICAgICAgdmFyIHJlc3VsdCA9IG5ldyBMb2Rhc2hXcmFwcGVyKHdyYXBwZXIuX193cmFwcGVkX18sIHdyYXBwZXIuX19jaGFpbl9fKTtcbiAgICAgIHJlc3VsdC5fX2FjdGlvbnNfXyA9IGNvcHlBcnJheSh3cmFwcGVyLl9fYWN0aW9uc19fKTtcbiAgICAgIHJlc3VsdC5fX2luZGV4X18gID0gd3JhcHBlci5fX2luZGV4X187XG4gICAgICByZXN1bHQuX192YWx1ZXNfXyA9IHdyYXBwZXIuX192YWx1ZXNfXztcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBlbGVtZW50cyBzcGxpdCBpbnRvIGdyb3VwcyB0aGUgbGVuZ3RoIG9mIGBzaXplYC5cbiAgICAgKiBJZiBgYXJyYXlgIGNhbid0IGJlIHNwbGl0IGV2ZW5seSwgdGhlIGZpbmFsIGNodW5rIHdpbGwgYmUgdGhlIHJlbWFpbmluZ1xuICAgICAqIGVsZW1lbnRzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHByb2Nlc3MuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzaXplPTFdIFRoZSBsZW5ndGggb2YgZWFjaCBjaHVua1xuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY2h1bmtzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmNodW5rKFsnYScsICdiJywgJ2MnLCAnZCddLCAyKTtcbiAgICAgKiAvLyA9PiBbWydhJywgJ2InXSwgWydjJywgJ2QnXV1cbiAgICAgKlxuICAgICAqIF8uY2h1bmsoWydhJywgJ2InLCAnYycsICdkJ10sIDMpO1xuICAgICAqIC8vID0+IFtbJ2EnLCAnYicsICdjJ10sIFsnZCddXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNodW5rKGFycmF5LCBzaXplLCBndWFyZCkge1xuICAgICAgaWYgKChndWFyZCA/IGlzSXRlcmF0ZWVDYWxsKGFycmF5LCBzaXplLCBndWFyZCkgOiBzaXplID09PSB1bmRlZmluZWQpKSB7XG4gICAgICAgIHNpemUgPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2l6ZSA9IG5hdGl2ZU1heCh0b0ludGVnZXIoc2l6ZSksIDApO1xuICAgICAgfVxuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGggfHwgc2l6ZSA8IDEpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gMCxcbiAgICAgICAgICByZXNJbmRleCA9IDAsXG4gICAgICAgICAgcmVzdWx0ID0gQXJyYXkobmF0aXZlQ2VpbChsZW5ndGggLyBzaXplKSk7XG5cbiAgICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICByZXN1bHRbcmVzSW5kZXgrK10gPSBiYXNlU2xpY2UoYXJyYXksIGluZGV4LCAoaW5kZXggKz0gc2l6ZSkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IHdpdGggYWxsIGZhbHNleSB2YWx1ZXMgcmVtb3ZlZC4gVGhlIHZhbHVlcyBgZmFsc2VgLCBgbnVsbGAsXG4gICAgICogYDBgLCBgXCJcImAsIGB1bmRlZmluZWRgLCBhbmQgYE5hTmAgYXJlIGZhbHNleS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBjb21wYWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGZpbHRlcmVkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jb21wYWN0KFswLCAxLCBmYWxzZSwgMiwgJycsIDNdKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb21wYWN0KGFycmF5KSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aCxcbiAgICAgICAgICByZXNJbmRleCA9IDAsXG4gICAgICAgICAgcmVzdWx0ID0gW107XG5cbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgcmVzdWx0W3Jlc0luZGV4KytdID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBhcnJheSBjb25jYXRlbmF0aW5nIGBhcnJheWAgd2l0aCBhbnkgYWRkaXRpb25hbCBhcnJheXNcbiAgICAgKiBhbmQvb3IgdmFsdWVzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNvbmNhdGVuYXRlLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW3ZhbHVlc10gVGhlIHZhbHVlcyB0byBjb25jYXRlbmF0ZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBjb25jYXRlbmF0ZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxXTtcbiAgICAgKiB2YXIgb3RoZXIgPSBfLmNvbmNhdChhcnJheSwgMiwgWzNdLCBbWzRdXSk7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhvdGhlcik7XG4gICAgICogLy8gPT4gWzEsIDIsIDMsIFs0XV1cbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbMV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjb25jYXQoKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIHZhciBhcmdzID0gQXJyYXkobGVuZ3RoIC0gMSksXG4gICAgICAgICAgYXJyYXkgPSBhcmd1bWVudHNbMF0sXG4gICAgICAgICAgaW5kZXggPSBsZW5ndGg7XG5cbiAgICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICAgIGFyZ3NbaW5kZXggLSAxXSA9IGFyZ3VtZW50c1tpbmRleF07XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyYXlQdXNoKGlzQXJyYXkoYXJyYXkpID8gY29weUFycmF5KGFycmF5KSA6IFthcnJheV0sIGJhc2VGbGF0dGVuKGFyZ3MsIDEpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIGBhcnJheWAgdmFsdWVzIG5vdCBpbmNsdWRlZCBpbiB0aGUgb3RoZXIgZ2l2ZW4gYXJyYXlzXG4gICAgICogdXNpbmcgW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuIFRoZSBvcmRlciBhbmQgcmVmZXJlbmNlcyBvZiByZXN1bHQgdmFsdWVzIGFyZVxuICAgICAqIGRldGVybWluZWQgYnkgdGhlIGZpcnN0IGFycmF5LlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5wdWxsQWxsYCwgdGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gZXhjbHVkZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gICAgICogQHNlZSBfLndpdGhvdXQsIF8ueG9yXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZGlmZmVyZW5jZShbMiwgMV0sIFsyLCAzXSk7XG4gICAgICogLy8gPT4gWzFdXG4gICAgICovXG4gICAgdmFyIGRpZmZlcmVuY2UgPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheSwgdmFsdWVzKSB7XG4gICAgICByZXR1cm4gaXNBcnJheUxpa2VPYmplY3QoYXJyYXkpXG4gICAgICAgID8gYmFzZURpZmZlcmVuY2UoYXJyYXksIGJhc2VGbGF0dGVuKHZhbHVlcywgMSwgaXNBcnJheUxpa2VPYmplY3QsIHRydWUpKVxuICAgICAgICA6IFtdO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5kaWZmZXJlbmNlYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWAgd2hpY2hcbiAgICAgKiBpcyBpbnZva2VkIGZvciBlYWNoIGVsZW1lbnQgb2YgYGFycmF5YCBhbmQgYHZhbHVlc2AgdG8gZ2VuZXJhdGUgdGhlIGNyaXRlcmlvblxuICAgICAqIGJ5IHdoaWNoIHRoZXkncmUgY29tcGFyZWQuIFRoZSBvcmRlciBhbmQgcmVmZXJlbmNlcyBvZiByZXN1bHQgdmFsdWVzIGFyZVxuICAgICAqIGRldGVybWluZWQgYnkgdGhlIGZpcnN0IGFycmF5LiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDpcbiAgICAgKiAodmFsdWUpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5wdWxsQWxsQnlgLCB0aGlzIG1ldGhvZCByZXR1cm5zIGEgbmV3IGFycmF5LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsuLi5BcnJheX0gW3ZhbHVlc10gVGhlIHZhbHVlcyB0byBleGNsdWRlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZGlmZmVyZW5jZUJ5KFsyLjEsIDEuMl0sIFsyLjMsIDMuNF0sIE1hdGguZmxvb3IpO1xuICAgICAqIC8vID0+IFsxLjJdXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmRpZmZlcmVuY2VCeShbeyAneCc6IDIgfSwgeyAneCc6IDEgfV0sIFt7ICd4JzogMSB9XSwgJ3gnKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDIgfV1cbiAgICAgKi9cbiAgICB2YXIgZGlmZmVyZW5jZUJ5ID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXksIHZhbHVlcykge1xuICAgICAgdmFyIGl0ZXJhdGVlID0gbGFzdCh2YWx1ZXMpO1xuICAgICAgaWYgKGlzQXJyYXlMaWtlT2JqZWN0KGl0ZXJhdGVlKSkge1xuICAgICAgICBpdGVyYXRlZSA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBpc0FycmF5TGlrZU9iamVjdChhcnJheSlcbiAgICAgICAgPyBiYXNlRGlmZmVyZW5jZShhcnJheSwgYmFzZUZsYXR0ZW4odmFsdWVzLCAxLCBpc0FycmF5TGlrZU9iamVjdCwgdHJ1ZSksIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSlcbiAgICAgICAgOiBbXTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZGlmZmVyZW5jZWAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgY29tcGFyYXRvcmBcbiAgICAgKiB3aGljaCBpcyBpbnZva2VkIHRvIGNvbXBhcmUgZWxlbWVudHMgb2YgYGFycmF5YCB0byBgdmFsdWVzYC4gVGhlIG9yZGVyIGFuZFxuICAgICAqIHJlZmVyZW5jZXMgb2YgcmVzdWx0IHZhbHVlcyBhcmUgZGV0ZXJtaW5lZCBieSB0aGUgZmlyc3QgYXJyYXkuIFRoZSBjb21wYXJhdG9yXG4gICAgICogaXMgaW52b2tlZCB3aXRoIHR3byBhcmd1bWVudHM6IChhcnJWYWwsIG90aFZhbCkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVW5saWtlIGBfLnB1bGxBbGxXaXRoYCwgdGhpcyBtZXRob2QgcmV0dXJucyBhIG5ldyBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gZXhjbHVkZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ3gnOiAxLCAneSc6IDIgfSwgeyAneCc6IDIsICd5JzogMSB9XTtcbiAgICAgKlxuICAgICAqIF8uZGlmZmVyZW5jZVdpdGgob2JqZWN0cywgW3sgJ3gnOiAxLCAneSc6IDIgfV0sIF8uaXNFcXVhbCk7XG4gICAgICogLy8gPT4gW3sgJ3gnOiAyLCAneSc6IDEgfV1cbiAgICAgKi9cbiAgICB2YXIgZGlmZmVyZW5jZVdpdGggPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheSwgdmFsdWVzKSB7XG4gICAgICB2YXIgY29tcGFyYXRvciA9IGxhc3QodmFsdWVzKTtcbiAgICAgIGlmIChpc0FycmF5TGlrZU9iamVjdChjb21wYXJhdG9yKSkge1xuICAgICAgICBjb21wYXJhdG9yID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGlzQXJyYXlMaWtlT2JqZWN0KGFycmF5KVxuICAgICAgICA/IGJhc2VEaWZmZXJlbmNlKGFycmF5LCBiYXNlRmxhdHRlbih2YWx1ZXMsIDEsIGlzQXJyYXlMaWtlT2JqZWN0LCB0cnVlKSwgdW5kZWZpbmVkLCBjb21wYXJhdG9yKVxuICAgICAgICA6IFtdO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNsaWNlIG9mIGBhcnJheWAgd2l0aCBgbmAgZWxlbWVudHMgZHJvcHBlZCBmcm9tIHRoZSBiZWdpbm5pbmcuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC41LjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtuPTFdIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgdG8gZHJvcC5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kcm9wKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gWzIsIDNdXG4gICAgICpcbiAgICAgKiBfLmRyb3AoWzEsIDIsIDNdLCAyKTtcbiAgICAgKiAvLyA9PiBbM11cbiAgICAgKlxuICAgICAqIF8uZHJvcChbMSwgMiwgM10sIDUpO1xuICAgICAqIC8vID0+IFtdXG4gICAgICpcbiAgICAgKiBfLmRyb3AoWzEsIDIsIDNdLCAwKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBkcm9wKGFycmF5LCBuLCBndWFyZCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgbiA9IChndWFyZCB8fCBuID09PSB1bmRlZmluZWQpID8gMSA6IHRvSW50ZWdlcihuKTtcbiAgICAgIHJldHVybiBiYXNlU2xpY2UoYXJyYXksIG4gPCAwID8gMCA6IG4sIGxlbmd0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNsaWNlIG9mIGBhcnJheWAgd2l0aCBgbmAgZWxlbWVudHMgZHJvcHBlZCBmcm9tIHRoZSBlbmQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtuPTFdIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgdG8gZHJvcC5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kcm9wUmlnaHQoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiBbMSwgMl1cbiAgICAgKlxuICAgICAqIF8uZHJvcFJpZ2h0KFsxLCAyLCAzXSwgMik7XG4gICAgICogLy8gPT4gWzFdXG4gICAgICpcbiAgICAgKiBfLmRyb3BSaWdodChbMSwgMiwgM10sIDUpO1xuICAgICAqIC8vID0+IFtdXG4gICAgICpcbiAgICAgKiBfLmRyb3BSaWdodChbMSwgMiwgM10sIDApO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGRyb3BSaWdodChhcnJheSwgbiwgZ3VhcmQpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIG4gPSAoZ3VhcmQgfHwgbiA9PT0gdW5kZWZpbmVkKSA/IDEgOiB0b0ludGVnZXIobik7XG4gICAgICBuID0gbGVuZ3RoIC0gbjtcbiAgICAgIHJldHVybiBiYXNlU2xpY2UoYXJyYXksIDAsIG4gPCAwID8gMCA6IG4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIGV4Y2x1ZGluZyBlbGVtZW50cyBkcm9wcGVkIGZyb20gdGhlIGVuZC5cbiAgICAgKiBFbGVtZW50cyBhcmUgZHJvcHBlZCB1bnRpbCBgcHJlZGljYXRlYCByZXR1cm5zIGZhbHNleS4gVGhlIHByZWRpY2F0ZSBpc1xuICAgICAqIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXgsIGFycmF5KS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWN0aXZlJzogdHJ1ZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWN0aXZlJzogZmFsc2UgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLmRyb3BSaWdodFdoaWxlKHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiAhby5hY3RpdmU7IH0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsnYmFybmV5J11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5kcm9wUmlnaHRXaGlsZSh1c2VycywgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IGZhbHNlIH0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsnYmFybmV5JywgJ2ZyZWQnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZHJvcFJpZ2h0V2hpbGUodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmRyb3BSaWdodFdoaWxlKHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknLCAnZnJlZCcsICdwZWJibGVzJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBkcm9wUmlnaHRXaGlsZShhcnJheSwgcHJlZGljYXRlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlV2hpbGUoYXJyYXksIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyksIHRydWUsIHRydWUpXG4gICAgICAgIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNsaWNlIG9mIGBhcnJheWAgZXhjbHVkaW5nIGVsZW1lbnRzIGRyb3BwZWQgZnJvbSB0aGUgYmVnaW5uaW5nLlxuICAgICAqIEVsZW1lbnRzIGFyZSBkcm9wcGVkIHVudGlsIGBwcmVkaWNhdGVgIHJldHVybnMgZmFsc2V5LiBUaGUgcHJlZGljYXRlIGlzXG4gICAgICogaW52b2tlZCB3aXRoIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleCwgYXJyYXkpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWN0aXZlJzogdHJ1ZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8uZHJvcFdoaWxlKHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiAhby5hY3RpdmU7IH0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsncGViYmxlcyddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZHJvcFdoaWxlKHVzZXJzLCB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnLCAncGViYmxlcyddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5kcm9wV2hpbGUodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5kcm9wV2hpbGUodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leScsICdmcmVkJywgJ3BlYmJsZXMnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGRyb3BXaGlsZShhcnJheSwgcHJlZGljYXRlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlV2hpbGUoYXJyYXksIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyksIHRydWUpXG4gICAgICAgIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmlsbHMgZWxlbWVudHMgb2YgYGFycmF5YCB3aXRoIGB2YWx1ZWAgZnJvbSBgc3RhcnRgIHVwIHRvLCBidXQgbm90XG4gICAgICogaW5jbHVkaW5nLCBgZW5kYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4yLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gZmlsbC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBmaWxsIGBhcnJheWAgd2l0aC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PTBdIFRoZSBzdGFydCBwb3NpdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2VuZD1hcnJheS5sZW5ndGhdIFRoZSBlbmQgcG9zaXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyLCAzXTtcbiAgICAgKlxuICAgICAqIF8uZmlsbChhcnJheSwgJ2EnKTtcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWydhJywgJ2EnLCAnYSddXG4gICAgICpcbiAgICAgKiBfLmZpbGwoQXJyYXkoMyksIDIpO1xuICAgICAqIC8vID0+IFsyLCAyLCAyXVxuICAgICAqXG4gICAgICogXy5maWxsKFs0LCA2LCA4LCAxMF0sICcqJywgMSwgMyk7XG4gICAgICogLy8gPT4gWzQsICcqJywgJyonLCAxMF1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmaWxsKGFycmF5LCB2YWx1ZSwgc3RhcnQsIGVuZCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgaWYgKHN0YXJ0ICYmIHR5cGVvZiBzdGFydCAhPSAnbnVtYmVyJyAmJiBpc0l0ZXJhdGVlQ2FsbChhcnJheSwgdmFsdWUsIHN0YXJ0KSkge1xuICAgICAgICBzdGFydCA9IDA7XG4gICAgICAgIGVuZCA9IGxlbmd0aDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlRmlsbChhcnJheSwgdmFsdWUsIHN0YXJ0LCBlbmQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZmluZGAgZXhjZXB0IHRoYXQgaXQgcmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGZpcnN0XG4gICAgICogZWxlbWVudCBgcHJlZGljYXRlYCByZXR1cm5zIHRydXRoeSBmb3IgaW5zdGVhZCBvZiB0aGUgZWxlbWVudCBpdHNlbGYuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMS4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9MF0gVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBmb3VuZCBlbGVtZW50LCBlbHNlIGAtMWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWN0aXZlJzogdHJ1ZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8uZmluZEluZGV4KHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLnVzZXIgPT0gJ2Jhcm5leSc7IH0pO1xuICAgICAqIC8vID0+IDBcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kSW5kZXgodXNlcnMsIHsgJ3VzZXInOiAnZnJlZCcsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kSW5kZXgodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmRJbmRleCh1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+IDJcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmaW5kSW5kZXgoYXJyYXksIHByZWRpY2F0ZSwgZnJvbUluZGV4KSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICBpZiAoIWxlbmd0aCkge1xuICAgICAgICByZXR1cm4gLTE7XG4gICAgICB9XG4gICAgICB2YXIgaW5kZXggPSBmcm9tSW5kZXggPT0gbnVsbCA/IDAgOiB0b0ludGVnZXIoZnJvbUluZGV4KTtcbiAgICAgIGlmIChpbmRleCA8IDApIHtcbiAgICAgICAgaW5kZXggPSBuYXRpdmVNYXgobGVuZ3RoICsgaW5kZXgsIDApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VGaW5kSW5kZXgoYXJyYXksIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyksIGluZGV4KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmZpbmRJbmRleGAgZXhjZXB0IHRoYXQgaXQgaXRlcmF0ZXMgb3ZlciBlbGVtZW50c1xuICAgICAqIG9mIGBjb2xsZWN0aW9uYCBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9YXJyYXkubGVuZ3RoLTFdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZm91bmQgZWxlbWVudCwgZWxzZSBgLTFgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWN0aXZlJzogdHJ1ZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWN0aXZlJzogZmFsc2UgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLmZpbmRMYXN0SW5kZXgodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8udXNlciA9PSAncGViYmxlcyc7IH0pO1xuICAgICAqIC8vID0+IDJcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kTGFzdEluZGV4KHVzZXJzLCB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiB0cnVlIH0pO1xuICAgICAqIC8vID0+IDBcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmRMYXN0SW5kZXgodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiAyXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmRMYXN0SW5kZXgodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmluZExhc3RJbmRleChhcnJheSwgcHJlZGljYXRlLCBmcm9tSW5kZXgpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRleCA9IGxlbmd0aCAtIDE7XG4gICAgICBpZiAoZnJvbUluZGV4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaW5kZXggPSB0b0ludGVnZXIoZnJvbUluZGV4KTtcbiAgICAgICAgaW5kZXggPSBmcm9tSW5kZXggPCAwXG4gICAgICAgICAgPyBuYXRpdmVNYXgobGVuZ3RoICsgaW5kZXgsIDApXG4gICAgICAgICAgOiBuYXRpdmVNaW4oaW5kZXgsIGxlbmd0aCAtIDEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VGaW5kSW5kZXgoYXJyYXksIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyksIGluZGV4LCB0cnVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGbGF0dGVucyBgYXJyYXlgIGEgc2luZ2xlIGxldmVsIGRlZXAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gZmxhdHRlbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBmbGF0dGVuZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZmxhdHRlbihbMSwgWzIsIFszLCBbNF1dLCA1XV0pO1xuICAgICAqIC8vID0+IFsxLCAyLCBbMywgWzRdXSwgNV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmbGF0dGVuKGFycmF5KSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICByZXR1cm4gbGVuZ3RoID8gYmFzZUZsYXR0ZW4oYXJyYXksIDEpIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVjdXJzaXZlbHkgZmxhdHRlbnMgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBmbGF0dGVuLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5mbGF0dGVuRGVlcChbMSwgWzIsIFszLCBbNF1dLCA1XV0pO1xuICAgICAqIC8vID0+IFsxLCAyLCAzLCA0LCA1XVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZsYXR0ZW5EZWVwKGFycmF5KSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICByZXR1cm4gbGVuZ3RoID8gYmFzZUZsYXR0ZW4oYXJyYXksIElORklOSVRZKSA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlY3Vyc2l2ZWx5IGZsYXR0ZW4gYGFycmF5YCB1cCB0byBgZGVwdGhgIHRpbWVzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGZsYXR0ZW4uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtkZXB0aD0xXSBUaGUgbWF4aW11bSByZWN1cnNpb24gZGVwdGguXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbMSwgWzIsIFszLCBbNF1dLCA1XV07XG4gICAgICpcbiAgICAgKiBfLmZsYXR0ZW5EZXB0aChhcnJheSwgMSk7XG4gICAgICogLy8gPT4gWzEsIDIsIFszLCBbNF1dLCA1XVxuICAgICAqXG4gICAgICogXy5mbGF0dGVuRGVwdGgoYXJyYXksIDIpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzLCBbNF0sIDVdXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmxhdHRlbkRlcHRoKGFycmF5LCBkZXB0aCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgZGVwdGggPSBkZXB0aCA9PT0gdW5kZWZpbmVkID8gMSA6IHRvSW50ZWdlcihkZXB0aCk7XG4gICAgICByZXR1cm4gYmFzZUZsYXR0ZW4oYXJyYXksIGRlcHRoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgaW52ZXJzZSBvZiBgXy50b1BhaXJzYDsgdGhpcyBtZXRob2QgcmV0dXJucyBhbiBvYmplY3QgY29tcG9zZWRcbiAgICAgKiBmcm9tIGtleS12YWx1ZSBgcGFpcnNgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gcGFpcnMgVGhlIGtleS12YWx1ZSBwYWlycy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmZyb21QYWlycyhbWydhJywgMV0sIFsnYicsIDJdXSk7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdiJzogMiB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gZnJvbVBhaXJzKHBhaXJzKSB7XG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBwYWlycyA9PSBudWxsID8gMCA6IHBhaXJzLmxlbmd0aCxcbiAgICAgICAgICByZXN1bHQgPSB7fTtcblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHBhaXIgPSBwYWlyc1tpbmRleF07XG4gICAgICAgIHJlc3VsdFtwYWlyWzBdXSA9IHBhaXJbMV07XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGZpcnN0IGVsZW1lbnQgb2YgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBhbGlhcyBmaXJzdFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZmlyc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmhlYWQoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICpcbiAgICAgKiBfLmhlYWQoW10pO1xuICAgICAqIC8vID0+IHVuZGVmaW5lZFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGhlYWQoYXJyYXkpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKSA/IGFycmF5WzBdIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGluZGV4IGF0IHdoaWNoIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIGB2YWx1ZWAgaXMgZm91bmQgaW4gYGFycmF5YFxuICAgICAqIHVzaW5nIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogZm9yIGVxdWFsaXR5IGNvbXBhcmlzb25zLiBJZiBgZnJvbUluZGV4YCBpcyBuZWdhdGl2ZSwgaXQncyB1c2VkIGFzIHRoZVxuICAgICAqIG9mZnNldCBmcm9tIHRoZSBlbmQgb2YgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9MF0gVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaW5kZXhPZihbMSwgMiwgMSwgMl0sIDIpO1xuICAgICAqIC8vID0+IDFcbiAgICAgKlxuICAgICAqIC8vIFNlYXJjaCBmcm9tIHRoZSBgZnJvbUluZGV4YC5cbiAgICAgKiBfLmluZGV4T2YoWzEsIDIsIDEsIDJdLCAyLCAyKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gZnJvbUluZGV4ID09IG51bGwgPyAwIDogdG9JbnRlZ2VyKGZyb21JbmRleCk7XG4gICAgICBpZiAoaW5kZXggPCAwKSB7XG4gICAgICAgIGluZGV4ID0gbmF0aXZlTWF4KGxlbmd0aCArIGluZGV4LCAwKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlSW5kZXhPZihhcnJheSwgdmFsdWUsIGluZGV4KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGFsbCBidXQgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pbml0aWFsKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5pdGlhbChhcnJheSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgcmV0dXJuIGxlbmd0aCA/IGJhc2VTbGljZShhcnJheSwgMCwgLTEpIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB1bmlxdWUgdmFsdWVzIHRoYXQgYXJlIGluY2x1ZGVkIGluIGFsbCBnaXZlbiBhcnJheXNcbiAgICAgKiB1c2luZyBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICAgICAqIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy4gVGhlIG9yZGVyIGFuZCByZWZlcmVuY2VzIG9mIHJlc3VsdCB2YWx1ZXMgYXJlXG4gICAgICogZGV0ZXJtaW5lZCBieSB0aGUgZmlyc3QgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgaW50ZXJzZWN0aW5nIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pbnRlcnNlY3Rpb24oWzIsIDFdLCBbMiwgM10pO1xuICAgICAqIC8vID0+IFsyXVxuICAgICAqL1xuICAgIHZhciBpbnRlcnNlY3Rpb24gPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgICAgIHZhciBtYXBwZWQgPSBhcnJheU1hcChhcnJheXMsIGNhc3RBcnJheUxpa2VPYmplY3QpO1xuICAgICAgcmV0dXJuIChtYXBwZWQubGVuZ3RoICYmIG1hcHBlZFswXSA9PT0gYXJyYXlzWzBdKVxuICAgICAgICA/IGJhc2VJbnRlcnNlY3Rpb24obWFwcGVkKVxuICAgICAgICA6IFtdO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5pbnRlcnNlY3Rpb25gIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYFxuICAgICAqIHdoaWNoIGlzIGludm9rZWQgZm9yIGVhY2ggZWxlbWVudCBvZiBlYWNoIGBhcnJheXNgIHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb25cbiAgICAgKiBieSB3aGljaCB0aGV5J3JlIGNvbXBhcmVkLiBUaGUgb3JkZXIgYW5kIHJlZmVyZW5jZXMgb2YgcmVzdWx0IHZhbHVlcyBhcmVcbiAgICAgKiBkZXRlcm1pbmVkIGJ5IHRoZSBmaXJzdCBhcnJheS4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6XG4gICAgICogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgaW50ZXJzZWN0aW5nIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pbnRlcnNlY3Rpb25CeShbMi4xLCAxLjJdLCBbMi4zLCAzLjRdLCBNYXRoLmZsb29yKTtcbiAgICAgKiAvLyA9PiBbMi4xXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5pbnRlcnNlY3Rpb25CeShbeyAneCc6IDEgfV0sIFt7ICd4JzogMiB9LCB7ICd4JzogMSB9XSwgJ3gnKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDEgfV1cbiAgICAgKi9cbiAgICB2YXIgaW50ZXJzZWN0aW9uQnkgPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgICAgIHZhciBpdGVyYXRlZSA9IGxhc3QoYXJyYXlzKSxcbiAgICAgICAgICBtYXBwZWQgPSBhcnJheU1hcChhcnJheXMsIGNhc3RBcnJheUxpa2VPYmplY3QpO1xuXG4gICAgICBpZiAoaXRlcmF0ZWUgPT09IGxhc3QobWFwcGVkKSkge1xuICAgICAgICBpdGVyYXRlZSA9IHVuZGVmaW5lZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1hcHBlZC5wb3AoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiAobWFwcGVkLmxlbmd0aCAmJiBtYXBwZWRbMF0gPT09IGFycmF5c1swXSlcbiAgICAgICAgPyBiYXNlSW50ZXJzZWN0aW9uKG1hcHBlZCwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpKVxuICAgICAgICA6IFtdO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5pbnRlcnNlY3Rpb25gIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGNvbXBhcmF0b3JgXG4gICAgICogd2hpY2ggaXMgaW52b2tlZCB0byBjb21wYXJlIGVsZW1lbnRzIG9mIGBhcnJheXNgLiBUaGUgb3JkZXIgYW5kIHJlZmVyZW5jZXNcbiAgICAgKiBvZiByZXN1bHQgdmFsdWVzIGFyZSBkZXRlcm1pbmVkIGJ5IHRoZSBmaXJzdCBhcnJheS4gVGhlIGNvbXBhcmF0b3IgaXNcbiAgICAgKiBpbnZva2VkIHdpdGggdHdvIGFyZ3VtZW50czogKGFyclZhbCwgb3RoVmFsKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBpbnRlcnNlY3RpbmcgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFt7ICd4JzogMSwgJ3knOiAyIH0sIHsgJ3gnOiAyLCAneSc6IDEgfV07XG4gICAgICogdmFyIG90aGVycyA9IFt7ICd4JzogMSwgJ3knOiAxIH0sIHsgJ3gnOiAxLCAneSc6IDIgfV07XG4gICAgICpcbiAgICAgKiBfLmludGVyc2VjdGlvbldpdGgob2JqZWN0cywgb3RoZXJzLCBfLmlzRXF1YWwpO1xuICAgICAqIC8vID0+IFt7ICd4JzogMSwgJ3knOiAyIH1dXG4gICAgICovXG4gICAgdmFyIGludGVyc2VjdGlvbldpdGggPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgICAgIHZhciBjb21wYXJhdG9yID0gbGFzdChhcnJheXMpLFxuICAgICAgICAgIG1hcHBlZCA9IGFycmF5TWFwKGFycmF5cywgY2FzdEFycmF5TGlrZU9iamVjdCk7XG5cbiAgICAgIGNvbXBhcmF0b3IgPSB0eXBlb2YgY29tcGFyYXRvciA9PSAnZnVuY3Rpb24nID8gY29tcGFyYXRvciA6IHVuZGVmaW5lZDtcbiAgICAgIGlmIChjb21wYXJhdG9yKSB7XG4gICAgICAgIG1hcHBlZC5wb3AoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiAobWFwcGVkLmxlbmd0aCAmJiBtYXBwZWRbMF0gPT09IGFycmF5c1swXSlcbiAgICAgICAgPyBiYXNlSW50ZXJzZWN0aW9uKG1hcHBlZCwgdW5kZWZpbmVkLCBjb21wYXJhdG9yKVxuICAgICAgICA6IFtdO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYWxsIGVsZW1lbnRzIGluIGBhcnJheWAgaW50byBhIHN0cmluZyBzZXBhcmF0ZWQgYnkgYHNlcGFyYXRvcmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gY29udmVydC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3NlcGFyYXRvcj0nLCddIFRoZSBlbGVtZW50IHNlcGFyYXRvci5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBqb2luZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmpvaW4oWydhJywgJ2InLCAnYyddLCAnficpO1xuICAgICAqIC8vID0+ICdhfmJ+YydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBqb2luKGFycmF5LCBzZXBhcmF0b3IpIHtcbiAgICAgIHJldHVybiBhcnJheSA9PSBudWxsID8gJycgOiBuYXRpdmVKb2luLmNhbGwoYXJyYXksIHNlcGFyYXRvcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgbGFzdCBlbGVtZW50IG9mIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmxhc3QoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICovXG4gICAgZnVuY3Rpb24gbGFzdChhcnJheSkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgcmV0dXJuIGxlbmd0aCA/IGFycmF5W2xlbmd0aCAtIDFdIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uaW5kZXhPZmAgZXhjZXB0IHRoYXQgaXQgaXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZlxuICAgICAqIGBhcnJheWAgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2Zyb21JbmRleD1hcnJheS5sZW5ndGgtMV0gVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubGFzdEluZGV4T2YoWzEsIDIsIDEsIDJdLCAyKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiAvLyBTZWFyY2ggZnJvbSB0aGUgYGZyb21JbmRleGAuXG4gICAgICogXy5sYXN0SW5kZXhPZihbMSwgMiwgMSwgMl0sIDIsIDIpO1xuICAgICAqIC8vID0+IDFcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBsYXN0SW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gbGVuZ3RoO1xuICAgICAgaWYgKGZyb21JbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGluZGV4ID0gdG9JbnRlZ2VyKGZyb21JbmRleCk7XG4gICAgICAgIGluZGV4ID0gaW5kZXggPCAwID8gbmF0aXZlTWF4KGxlbmd0aCArIGluZGV4LCAwKSA6IG5hdGl2ZU1pbihpbmRleCwgbGVuZ3RoIC0gMSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdmFsdWUgPT09IHZhbHVlXG4gICAgICAgID8gc3RyaWN0TGFzdEluZGV4T2YoYXJyYXksIHZhbHVlLCBpbmRleClcbiAgICAgICAgOiBiYXNlRmluZEluZGV4KGFycmF5LCBiYXNlSXNOYU4sIGluZGV4LCB0cnVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBlbGVtZW50IGF0IGluZGV4IGBuYCBvZiBgYXJyYXlgLiBJZiBgbmAgaXMgbmVnYXRpdmUsIHRoZSBudGhcbiAgICAgKiBlbGVtZW50IGZyb20gdGhlIGVuZCBpcyByZXR1cm5lZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjExLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtuPTBdIFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCB0byByZXR1cm4uXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG50aCBlbGVtZW50IG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsnYScsICdiJywgJ2MnLCAnZCddO1xuICAgICAqXG4gICAgICogXy5udGgoYXJyYXksIDEpO1xuICAgICAqIC8vID0+ICdiJ1xuICAgICAqXG4gICAgICogXy5udGgoYXJyYXksIC0yKTtcbiAgICAgKiAvLyA9PiAnYyc7XG4gICAgICovXG4gICAgZnVuY3Rpb24gbnRoKGFycmF5LCBuKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkgPyBiYXNlTnRoKGFycmF5LCB0b0ludGVnZXIobikpIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGdpdmVuIHZhbHVlcyBmcm9tIGBhcnJheWAgdXNpbmdcbiAgICAgKiBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICAgICAqIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8ud2l0aG91dGAsIHRoaXMgbWV0aG9kIG11dGF0ZXMgYGFycmF5YC4gVXNlIGBfLnJlbW92ZWBcbiAgICAgKiB0byByZW1vdmUgZWxlbWVudHMgZnJvbSBhbiBhcnJheSBieSBwcmVkaWNhdGUuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW3ZhbHVlc10gVGhlIHZhbHVlcyB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsnYScsICdiJywgJ2MnLCAnYScsICdiJywgJ2MnXTtcbiAgICAgKlxuICAgICAqIF8ucHVsbChhcnJheSwgJ2EnLCAnYycpO1xuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbJ2InLCAnYiddXG4gICAgICovXG4gICAgdmFyIHB1bGwgPSBiYXNlUmVzdChwdWxsQWxsKTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ucHVsbGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBhbiBhcnJheSBvZiB2YWx1ZXMgdG8gcmVtb3ZlLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5kaWZmZXJlbmNlYCwgdGhpcyBtZXRob2QgbXV0YXRlcyBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byByZW1vdmUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsnYScsICdiJywgJ2MnLCAnYScsICdiJywgJ2MnXTtcbiAgICAgKlxuICAgICAqIF8ucHVsbEFsbChhcnJheSwgWydhJywgJ2MnXSk7XG4gICAgICogY29uc29sZS5sb2coYXJyYXkpO1xuICAgICAqIC8vID0+IFsnYicsICdiJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwdWxsQWxsKGFycmF5LCB2YWx1ZXMpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoICYmIHZhbHVlcyAmJiB2YWx1ZXMubGVuZ3RoKVxuICAgICAgICA/IGJhc2VQdWxsQWxsKGFycmF5LCB2YWx1ZXMpXG4gICAgICAgIDogYXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5wdWxsQWxsYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWAgd2hpY2ggaXNcbiAgICAgKiBpbnZva2VkIGZvciBlYWNoIGVsZW1lbnQgb2YgYGFycmF5YCBhbmQgYHZhbHVlc2AgdG8gZ2VuZXJhdGUgdGhlIGNyaXRlcmlvblxuICAgICAqIGJ5IHdoaWNoIHRoZXkncmUgY29tcGFyZWQuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5kaWZmZXJlbmNlQnlgLCB0aGlzIG1ldGhvZCBtdXRhdGVzIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIHJlbW92ZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFt7ICd4JzogMSB9LCB7ICd4JzogMiB9LCB7ICd4JzogMyB9LCB7ICd4JzogMSB9XTtcbiAgICAgKlxuICAgICAqIF8ucHVsbEFsbEJ5KGFycmF5LCBbeyAneCc6IDEgfSwgeyAneCc6IDMgfV0sICd4Jyk7XG4gICAgICogY29uc29sZS5sb2coYXJyYXkpO1xuICAgICAqIC8vID0+IFt7ICd4JzogMiB9XVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHB1bGxBbGxCeShhcnJheSwgdmFsdWVzLCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGggJiYgdmFsdWVzICYmIHZhbHVlcy5sZW5ndGgpXG4gICAgICAgID8gYmFzZVB1bGxBbGwoYXJyYXksIHZhbHVlcywgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpKVxuICAgICAgICA6IGFycmF5O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ucHVsbEFsbGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgY29tcGFyYXRvcmAgd2hpY2hcbiAgICAgKiBpcyBpbnZva2VkIHRvIGNvbXBhcmUgZWxlbWVudHMgb2YgYGFycmF5YCB0byBgdmFsdWVzYC4gVGhlIGNvbXBhcmF0b3IgaXNcbiAgICAgKiBpbnZva2VkIHdpdGggdHdvIGFyZ3VtZW50czogKGFyclZhbCwgb3RoVmFsKS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgYF8uZGlmZmVyZW5jZVdpdGhgLCB0aGlzIG1ldGhvZCBtdXRhdGVzIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC42LjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIHJlbW92ZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gW3sgJ3gnOiAxLCAneSc6IDIgfSwgeyAneCc6IDMsICd5JzogNCB9LCB7ICd4JzogNSwgJ3knOiA2IH1dO1xuICAgICAqXG4gICAgICogXy5wdWxsQWxsV2l0aChhcnJheSwgW3sgJ3gnOiAzLCAneSc6IDQgfV0sIF8uaXNFcXVhbCk7XG4gICAgICogY29uc29sZS5sb2coYXJyYXkpO1xuICAgICAqIC8vID0+IFt7ICd4JzogMSwgJ3knOiAyIH0sIHsgJ3gnOiA1LCAneSc6IDYgfV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwdWxsQWxsV2l0aChhcnJheSwgdmFsdWVzLCBjb21wYXJhdG9yKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aCAmJiB2YWx1ZXMgJiYgdmFsdWVzLmxlbmd0aClcbiAgICAgICAgPyBiYXNlUHVsbEFsbChhcnJheSwgdmFsdWVzLCB1bmRlZmluZWQsIGNvbXBhcmF0b3IpXG4gICAgICAgIDogYXJyYXk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBlbGVtZW50cyBmcm9tIGBhcnJheWAgY29ycmVzcG9uZGluZyB0byBgaW5kZXhlc2AgYW5kIHJldHVybnMgYW5cbiAgICAgKiBhcnJheSBvZiByZW1vdmVkIGVsZW1lbnRzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5hdGAsIHRoaXMgbWV0aG9kIG11dGF0ZXMgYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHsuLi4obnVtYmVyfG51bWJlcltdKX0gW2luZGV4ZXNdIFRoZSBpbmRleGVzIG9mIGVsZW1lbnRzIHRvIHJlbW92ZS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiByZW1vdmVkIGVsZW1lbnRzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbJ2EnLCAnYicsICdjJywgJ2QnXTtcbiAgICAgKiB2YXIgcHVsbGVkID0gXy5wdWxsQXQoYXJyYXksIFsxLCAzXSk7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWydhJywgJ2MnXVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2cocHVsbGVkKTtcbiAgICAgKiAvLyA9PiBbJ2InLCAnZCddXG4gICAgICovXG4gICAgdmFyIHB1bGxBdCA9IGZsYXRSZXN0KGZ1bmN0aW9uKGFycmF5LCBpbmRleGVzKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGgsXG4gICAgICAgICAgcmVzdWx0ID0gYmFzZUF0KGFycmF5LCBpbmRleGVzKTtcblxuICAgICAgYmFzZVB1bGxBdChhcnJheSwgYXJyYXlNYXAoaW5kZXhlcywgZnVuY3Rpb24oaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIGlzSW5kZXgoaW5kZXgsIGxlbmd0aCkgPyAraW5kZXggOiBpbmRleDtcbiAgICAgIH0pLnNvcnQoY29tcGFyZUFzY2VuZGluZykpO1xuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhbGwgZWxlbWVudHMgZnJvbSBgYXJyYXlgIHRoYXQgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yXG4gICAgICogYW5kIHJldHVybnMgYW4gYXJyYXkgb2YgdGhlIHJlbW92ZWQgZWxlbWVudHMuIFRoZSBwcmVkaWNhdGUgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4LCBhcnJheSkuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVW5saWtlIGBfLmZpbHRlcmAsIHRoaXMgbWV0aG9kIG11dGF0ZXMgYGFycmF5YC4gVXNlIGBfLnB1bGxgXG4gICAgICogdG8gcHVsbCBlbGVtZW50cyBmcm9tIGFuIGFycmF5IGJ5IHZhbHVlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgcmVtb3ZlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWzEsIDIsIDMsIDRdO1xuICAgICAqIHZhciBldmVucyA9IF8ucmVtb3ZlKGFycmF5LCBmdW5jdGlvbihuKSB7XG4gICAgICogICByZXR1cm4gbiAlIDIgPT0gMDtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbMSwgM11cbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKGV2ZW5zKTtcbiAgICAgKiAvLyA9PiBbMiwgNF1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZW1vdmUoYXJyYXksIHByZWRpY2F0ZSkge1xuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgaWYgKCEoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKSkge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgaW5kZXhlcyA9IFtdLFxuICAgICAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICAgICAgcHJlZGljYXRlID0gZ2V0SXRlcmF0ZWUocHJlZGljYXRlLCAzKTtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICAgICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgICBpbmRleGVzLnB1c2goaW5kZXgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBiYXNlUHVsbEF0KGFycmF5LCBpbmRleGVzKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV2ZXJzZXMgYGFycmF5YCBzbyB0aGF0IHRoZSBmaXJzdCBlbGVtZW50IGJlY29tZXMgdGhlIGxhc3QsIHRoZSBzZWNvbmRcbiAgICAgKiBlbGVtZW50IGJlY29tZXMgdGhlIHNlY29uZCB0byBsYXN0LCBhbmQgc28gb24uXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgYXJyYXlgIGFuZCBpcyBiYXNlZCBvblxuICAgICAqIFtgQXJyYXkjcmV2ZXJzZWBdKGh0dHBzOi8vbWRuLmlvL0FycmF5L3JldmVyc2UpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWzEsIDIsIDNdO1xuICAgICAqXG4gICAgICogXy5yZXZlcnNlKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbMywgMiwgMV1cbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbMywgMiwgMV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZXZlcnNlKGFycmF5KSB7XG4gICAgICByZXR1cm4gYXJyYXkgPT0gbnVsbCA/IGFycmF5IDogbmF0aXZlUmV2ZXJzZS5jYWxsKGFycmF5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2xpY2Ugb2YgYGFycmF5YCBmcm9tIGBzdGFydGAgdXAgdG8sIGJ1dCBub3QgaW5jbHVkaW5nLCBgZW5kYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyB1c2VkIGluc3RlYWQgb2ZcbiAgICAgKiBbYEFycmF5I3NsaWNlYF0oaHR0cHM6Ly9tZG4uaW8vQXJyYXkvc2xpY2UpIHRvIGVuc3VyZSBkZW5zZSBhcnJheXMgYXJlXG4gICAgICogcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2xpY2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtlbmQ9YXJyYXkubGVuZ3RoXSBUaGUgZW5kIHBvc2l0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzbGljZShhcnJheSwgc3RhcnQsIGVuZCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgaWYgKGVuZCAmJiB0eXBlb2YgZW5kICE9ICdudW1iZXInICYmIGlzSXRlcmF0ZWVDYWxsKGFycmF5LCBzdGFydCwgZW5kKSkge1xuICAgICAgICBzdGFydCA9IDA7XG4gICAgICAgIGVuZCA9IGxlbmd0aDtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBzdGFydCA9IHN0YXJ0ID09IG51bGwgPyAwIDogdG9JbnRlZ2VyKHN0YXJ0KTtcbiAgICAgICAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW5ndGggOiB0b0ludGVnZXIoZW5kKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlU2xpY2UoYXJyYXksIHN0YXJ0LCBlbmQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVzZXMgYSBiaW5hcnkgc2VhcmNoIHRvIGRldGVybWluZSB0aGUgbG93ZXN0IGluZGV4IGF0IHdoaWNoIGB2YWx1ZWBcbiAgICAgKiBzaG91bGQgYmUgaW5zZXJ0ZWQgaW50byBgYXJyYXlgIGluIG9yZGVyIHRvIG1haW50YWluIGl0cyBzb3J0IG9yZGVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIHNvcnRlZCBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGV2YWx1YXRlLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWAgc2hvdWxkIGJlIGluc2VydGVkXG4gICAgICogIGludG8gYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zb3J0ZWRJbmRleChbMzAsIDUwXSwgNDApO1xuICAgICAqIC8vID0+IDFcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzb3J0ZWRJbmRleChhcnJheSwgdmFsdWUpIHtcbiAgICAgIHJldHVybiBiYXNlU29ydGVkSW5kZXgoYXJyYXksIHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnNvcnRlZEluZGV4YCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWBcbiAgICAgKiB3aGljaCBpcyBpbnZva2VkIGZvciBgdmFsdWVgIGFuZCBlYWNoIGVsZW1lbnQgb2YgYGFycmF5YCB0byBjb21wdXRlIHRoZWlyXG4gICAgICogc29ydCByYW5raW5nLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBzb3J0ZWQgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBldmFsdWF0ZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAgICAgKiAgaW50byBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFt7ICd4JzogNCB9LCB7ICd4JzogNSB9XTtcbiAgICAgKlxuICAgICAqIF8uc29ydGVkSW5kZXhCeShvYmplY3RzLCB7ICd4JzogNCB9LCBmdW5jdGlvbihvKSB7IHJldHVybiBvLng7IH0pO1xuICAgICAqIC8vID0+IDBcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uc29ydGVkSW5kZXhCeShvYmplY3RzLCB7ICd4JzogNCB9LCAneCcpO1xuICAgICAqIC8vID0+IDBcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzb3J0ZWRJbmRleEJ5KGFycmF5LCB2YWx1ZSwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiBiYXNlU29ydGVkSW5kZXhCeShhcnJheSwgdmFsdWUsIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5pbmRleE9mYCBleGNlcHQgdGhhdCBpdCBwZXJmb3JtcyBhIGJpbmFyeVxuICAgICAqIHNlYXJjaCBvbiBhIHNvcnRlZCBgYXJyYXlgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNvcnRlZEluZGV4T2YoWzQsIDUsIDUsIDUsIDZdLCA1KTtcbiAgICAgKiAvLyA9PiAxXG4gICAgICovXG4gICAgZnVuY3Rpb24gc29ydGVkSW5kZXhPZihhcnJheSwgdmFsdWUpIHtcbiAgICAgIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgIGlmIChsZW5ndGgpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gYmFzZVNvcnRlZEluZGV4KGFycmF5LCB2YWx1ZSk7XG4gICAgICAgIGlmIChpbmRleCA8IGxlbmd0aCAmJiBlcShhcnJheVtpbmRleF0sIHZhbHVlKSkge1xuICAgICAgICAgIHJldHVybiBpbmRleDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uc29ydGVkSW5kZXhgIGV4Y2VwdCB0aGF0IGl0IHJldHVybnMgdGhlIGhpZ2hlc3RcbiAgICAgKiBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZCBpbnRvIGBhcnJheWAgaW4gb3JkZXIgdG9cbiAgICAgKiBtYWludGFpbiBpdHMgc29ydCBvcmRlci5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBzb3J0ZWQgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBldmFsdWF0ZS5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBhdCB3aGljaCBgdmFsdWVgIHNob3VsZCBiZSBpbnNlcnRlZFxuICAgICAqICBpbnRvIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc29ydGVkTGFzdEluZGV4KFs0LCA1LCA1LCA1LCA2XSwgNSk7XG4gICAgICogLy8gPT4gNFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNvcnRlZExhc3RJbmRleChhcnJheSwgdmFsdWUpIHtcbiAgICAgIHJldHVybiBiYXNlU29ydGVkSW5kZXgoYXJyYXksIHZhbHVlLCB0cnVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnNvcnRlZExhc3RJbmRleGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgXG4gICAgICogd2hpY2ggaXMgaW52b2tlZCBmb3IgYHZhbHVlYCBhbmQgZWFjaCBlbGVtZW50IG9mIGBhcnJheWAgdG8gY29tcHV0ZSB0aGVpclxuICAgICAqIHNvcnQgcmFua2luZy4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgc29ydGVkIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWAgc2hvdWxkIGJlIGluc2VydGVkXG4gICAgICogIGludG8gYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAneCc6IDQgfSwgeyAneCc6IDUgfV07XG4gICAgICpcbiAgICAgKiBfLnNvcnRlZExhc3RJbmRleEJ5KG9iamVjdHMsIHsgJ3gnOiA0IH0sIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8ueDsgfSk7XG4gICAgICogLy8gPT4gMVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5zb3J0ZWRMYXN0SW5kZXhCeShvYmplY3RzLCB7ICd4JzogNCB9LCAneCcpO1xuICAgICAqIC8vID0+IDFcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzb3J0ZWRMYXN0SW5kZXhCeShhcnJheSwgdmFsdWUsIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gYmFzZVNvcnRlZEluZGV4QnkoYXJyYXksIHZhbHVlLCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMiksIHRydWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ubGFzdEluZGV4T2ZgIGV4Y2VwdCB0aGF0IGl0IHBlcmZvcm1zIGEgYmluYXJ5XG4gICAgICogc2VhcmNoIG9uIGEgc29ydGVkIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc29ydGVkTGFzdEluZGV4T2YoWzQsIDUsIDUsIDUsIDZdLCA1KTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICovXG4gICAgZnVuY3Rpb24gc29ydGVkTGFzdEluZGV4T2YoYXJyYXksIHZhbHVlKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICBpZiAobGVuZ3RoKSB7XG4gICAgICAgIHZhciBpbmRleCA9IGJhc2VTb3J0ZWRJbmRleChhcnJheSwgdmFsdWUsIHRydWUpIC0gMTtcbiAgICAgICAgaWYgKGVxKGFycmF5W2luZGV4XSwgdmFsdWUpKSB7XG4gICAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gLTE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy51bmlxYCBleGNlcHQgdGhhdCBpdCdzIGRlc2lnbmVkIGFuZCBvcHRpbWl6ZWRcbiAgICAgKiBmb3Igc29ydGVkIGFycmF5cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGR1cGxpY2F0ZSBmcmVlIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNvcnRlZFVuaXEoWzEsIDEsIDJdKTtcbiAgICAgKiAvLyA9PiBbMSwgMl1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzb3J0ZWRVbmlxKGFycmF5KSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlU29ydGVkVW5pcShhcnJheSlcbiAgICAgICAgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnVuaXFCeWAgZXhjZXB0IHRoYXQgaXQncyBkZXNpZ25lZCBhbmQgb3B0aW1pemVkXG4gICAgICogZm9yIHNvcnRlZCBhcnJheXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWVdIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGR1cGxpY2F0ZSBmcmVlIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnNvcnRlZFVuaXFCeShbMS4xLCAxLjIsIDIuMywgMi40XSwgTWF0aC5mbG9vcik7XG4gICAgICogLy8gPT4gWzEuMSwgMi4zXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNvcnRlZFVuaXFCeShhcnJheSwgaXRlcmF0ZWUpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKVxuICAgICAgICA/IGJhc2VTb3J0ZWRVbmlxKGFycmF5LCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMikpXG4gICAgICAgIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBhbGwgYnV0IHRoZSBmaXJzdCBlbGVtZW50IG9mIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRhaWwoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiBbMiwgM11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0YWlsKGFycmF5KSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gICAgICByZXR1cm4gbGVuZ3RoID8gYmFzZVNsaWNlKGFycmF5LCAxLCBsZW5ndGgpIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNsaWNlIG9mIGBhcnJheWAgd2l0aCBgbmAgZWxlbWVudHMgdGFrZW4gZnJvbSB0aGUgYmVnaW5uaW5nLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbj0xXSBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRvIHRha2UuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udGFrZShbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IFsxXVxuICAgICAqXG4gICAgICogXy50YWtlKFsxLCAyLCAzXSwgMik7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICpcbiAgICAgKiBfLnRha2UoWzEsIDIsIDNdLCA1KTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKlxuICAgICAqIF8udGFrZShbMSwgMiwgM10sIDApO1xuICAgICAqIC8vID0+IFtdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdGFrZShhcnJheSwgbiwgZ3VhcmQpIHtcbiAgICAgIGlmICghKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgbiA9IChndWFyZCB8fCBuID09PSB1bmRlZmluZWQpID8gMSA6IHRvSW50ZWdlcihuKTtcbiAgICAgIHJldHVybiBiYXNlU2xpY2UoYXJyYXksIDAsIG4gPCAwID8gMCA6IG4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIHdpdGggYG5gIGVsZW1lbnRzIHRha2VuIGZyb20gdGhlIGVuZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW249MV0gVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byB0YWtlLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRha2VSaWdodChbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IFszXVxuICAgICAqXG4gICAgICogXy50YWtlUmlnaHQoWzEsIDIsIDNdLCAyKTtcbiAgICAgKiAvLyA9PiBbMiwgM11cbiAgICAgKlxuICAgICAqIF8udGFrZVJpZ2h0KFsxLCAyLCAzXSwgNSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiBfLnRha2VSaWdodChbMSwgMiwgM10sIDApO1xuICAgICAqIC8vID0+IFtdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdGFrZVJpZ2h0KGFycmF5LCBuLCBndWFyZCkge1xuICAgICAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgbiA9IChndWFyZCB8fCBuID09PSB1bmRlZmluZWQpID8gMSA6IHRvSW50ZWdlcihuKTtcbiAgICAgIG4gPSBsZW5ndGggLSBuO1xuICAgICAgcmV0dXJuIGJhc2VTbGljZShhcnJheSwgbiA8IDAgPyAwIDogbiwgbGVuZ3RoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2xpY2Ugb2YgYGFycmF5YCB3aXRoIGVsZW1lbnRzIHRha2VuIGZyb20gdGhlIGVuZC4gRWxlbWVudHMgYXJlXG4gICAgICogdGFrZW4gdW50aWwgYHByZWRpY2F0ZWAgcmV0dXJucyBmYWxzZXkuIFRoZSBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoXG4gICAgICogdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4LCBhcnJheSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgc2xpY2Ugb2YgYGFycmF5YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy50YWtlUmlnaHRXaGlsZSh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gIW8uYWN0aXZlOyB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnLCAncGViYmxlcyddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8udGFrZVJpZ2h0V2hpbGUodXNlcnMsIHsgJ3VzZXInOiAncGViYmxlcycsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8udGFrZVJpZ2h0V2hpbGUodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnLCAncGViYmxlcyddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnRha2VSaWdodFdoaWxlKHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gW11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0YWtlUmlnaHRXaGlsZShhcnJheSwgcHJlZGljYXRlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlV2hpbGUoYXJyYXksIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyksIGZhbHNlLCB0cnVlKVxuICAgICAgICA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzbGljZSBvZiBgYXJyYXlgIHdpdGggZWxlbWVudHMgdGFrZW4gZnJvbSB0aGUgYmVnaW5uaW5nLiBFbGVtZW50c1xuICAgICAqIGFyZSB0YWtlbiB1bnRpbCBgcHJlZGljYXRlYCByZXR1cm5zIGZhbHNleS4gVGhlIHByZWRpY2F0ZSBpcyBpbnZva2VkIHdpdGhcbiAgICAgKiB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXgsIGFycmF5KS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IHRydWUgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLnRha2VXaGlsZSh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gIW8uYWN0aXZlOyB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leScsICdmcmVkJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy50YWtlV2hpbGUodXNlcnMsIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FjdGl2ZSc6IGZhbHNlIH0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsnYmFybmV5J11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnRha2VXaGlsZSh1c2VycywgWydhY3RpdmUnLCBmYWxzZV0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFsnYmFybmV5JywgJ2ZyZWQnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy50YWtlV2hpbGUodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiBbXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRha2VXaGlsZShhcnJheSwgcHJlZGljYXRlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlV2hpbGUoYXJyYXksIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMykpXG4gICAgICAgIDogW107XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB1bmlxdWUgdmFsdWVzLCBpbiBvcmRlciwgZnJvbSBhbGwgZ2l2ZW4gYXJyYXlzIHVzaW5nXG4gICAgICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIGluc3BlY3QuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tYmluZWQgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnVuaW9uKFsyXSwgWzEsIDJdKTtcbiAgICAgKiAvLyA9PiBbMiwgMV1cbiAgICAgKi9cbiAgICB2YXIgdW5pb24gPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgICAgIHJldHVybiBiYXNlVW5pcShiYXNlRmxhdHRlbihhcnJheXMsIDEsIGlzQXJyYXlMaWtlT2JqZWN0LCB0cnVlKSk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnVuaW9uYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWAgd2hpY2ggaXNcbiAgICAgKiBpbnZva2VkIGZvciBlYWNoIGVsZW1lbnQgb2YgZWFjaCBgYXJyYXlzYCB0byBnZW5lcmF0ZSB0aGUgY3JpdGVyaW9uIGJ5XG4gICAgICogd2hpY2ggdW5pcXVlbmVzcyBpcyBjb21wdXRlZC4gUmVzdWx0IHZhbHVlcyBhcmUgY2hvc2VuIGZyb20gdGhlIGZpcnN0XG4gICAgICogYXJyYXkgaW4gd2hpY2ggdGhlIHZhbHVlIG9jY3Vycy4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6XG4gICAgICogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tYmluZWQgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnVuaW9uQnkoWzIuMV0sIFsxLjIsIDIuM10sIE1hdGguZmxvb3IpO1xuICAgICAqIC8vID0+IFsyLjEsIDEuMl1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8udW5pb25CeShbeyAneCc6IDEgfV0sIFt7ICd4JzogMiB9LCB7ICd4JzogMSB9XSwgJ3gnKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDEgfSwgeyAneCc6IDIgfV1cbiAgICAgKi9cbiAgICB2YXIgdW5pb25CeSA9IGJhc2VSZXN0KGZ1bmN0aW9uKGFycmF5cykge1xuICAgICAgdmFyIGl0ZXJhdGVlID0gbGFzdChhcnJheXMpO1xuICAgICAgaWYgKGlzQXJyYXlMaWtlT2JqZWN0KGl0ZXJhdGVlKSkge1xuICAgICAgICBpdGVyYXRlZSA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlVW5pcShiYXNlRmxhdHRlbihhcnJheXMsIDEsIGlzQXJyYXlMaWtlT2JqZWN0LCB0cnVlKSwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8udW5pb25gIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGNvbXBhcmF0b3JgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCB0byBjb21wYXJlIGVsZW1lbnRzIG9mIGBhcnJheXNgLiBSZXN1bHQgdmFsdWVzIGFyZSBjaG9zZW4gZnJvbVxuICAgICAqIHRoZSBmaXJzdCBhcnJheSBpbiB3aGljaCB0aGUgdmFsdWUgb2NjdXJzLiBUaGUgY29tcGFyYXRvciBpcyBpbnZva2VkXG4gICAgICogd2l0aCB0d28gYXJndW1lbnRzOiAoYXJyVmFsLCBvdGhWYWwpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHsuLi5BcnJheX0gW2FycmF5c10gVGhlIGFycmF5cyB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjb21wYXJhdG9yXSBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGNvbWJpbmVkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAneCc6IDEsICd5JzogMiB9LCB7ICd4JzogMiwgJ3knOiAxIH1dO1xuICAgICAqIHZhciBvdGhlcnMgPSBbeyAneCc6IDEsICd5JzogMSB9LCB7ICd4JzogMSwgJ3knOiAyIH1dO1xuICAgICAqXG4gICAgICogXy51bmlvbldpdGgob2JqZWN0cywgb3RoZXJzLCBfLmlzRXF1YWwpO1xuICAgICAqIC8vID0+IFt7ICd4JzogMSwgJ3knOiAyIH0sIHsgJ3gnOiAyLCAneSc6IDEgfSwgeyAneCc6IDEsICd5JzogMSB9XVxuICAgICAqL1xuICAgIHZhciB1bmlvbldpdGggPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgICAgIHZhciBjb21wYXJhdG9yID0gbGFzdChhcnJheXMpO1xuICAgICAgY29tcGFyYXRvciA9IHR5cGVvZiBjb21wYXJhdG9yID09ICdmdW5jdGlvbicgPyBjb21wYXJhdG9yIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIGJhc2VVbmlxKGJhc2VGbGF0dGVuKGFycmF5cywgMSwgaXNBcnJheUxpa2VPYmplY3QsIHRydWUpLCB1bmRlZmluZWQsIGNvbXBhcmF0b3IpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGR1cGxpY2F0ZS1mcmVlIHZlcnNpb24gb2YgYW4gYXJyYXksIHVzaW5nXG4gICAgICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGluIHdoaWNoIG9ubHkgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgZWFjaCBlbGVtZW50XG4gICAgICogaXMga2VwdC4gVGhlIG9yZGVyIG9mIHJlc3VsdCB2YWx1ZXMgaXMgZGV0ZXJtaW5lZCBieSB0aGUgb3JkZXIgdGhleSBvY2N1clxuICAgICAqIGluIHRoZSBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGR1cGxpY2F0ZSBmcmVlIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnVuaXEoWzIsIDEsIDJdKTtcbiAgICAgKiAvLyA9PiBbMiwgMV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1bmlxKGFycmF5KSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkgPyBiYXNlVW5pcShhcnJheSkgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnVuaXFgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYCB3aGljaCBpc1xuICAgICAqIGludm9rZWQgZm9yIGVhY2ggZWxlbWVudCBpbiBgYXJyYXlgIHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb24gYnkgd2hpY2hcbiAgICAgKiB1bmlxdWVuZXNzIGlzIGNvbXB1dGVkLiBUaGUgb3JkZXIgb2YgcmVzdWx0IHZhbHVlcyBpcyBkZXRlcm1pbmVkIGJ5IHRoZVxuICAgICAqIG9yZGVyIHRoZXkgb2NjdXIgaW4gdGhlIGFycmF5LiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDpcbiAgICAgKiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGR1cGxpY2F0ZSBmcmVlIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnVuaXFCeShbMi4xLCAxLjIsIDIuM10sIE1hdGguZmxvb3IpO1xuICAgICAqIC8vID0+IFsyLjEsIDEuMl1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8udW5pcUJ5KFt7ICd4JzogMSB9LCB7ICd4JzogMiB9LCB7ICd4JzogMSB9XSwgJ3gnKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDEgfSwgeyAneCc6IDIgfV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1bmlxQnkoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aCkgPyBiYXNlVW5pcShhcnJheSwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpKSA6IFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8udW5pcWAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgY29tcGFyYXRvcmAgd2hpY2hcbiAgICAgKiBpcyBpbnZva2VkIHRvIGNvbXBhcmUgZWxlbWVudHMgb2YgYGFycmF5YC4gVGhlIG9yZGVyIG9mIHJlc3VsdCB2YWx1ZXMgaXNcbiAgICAgKiBkZXRlcm1pbmVkIGJ5IHRoZSBvcmRlciB0aGV5IG9jY3VyIGluIHRoZSBhcnJheS5UaGUgY29tcGFyYXRvciBpcyBpbnZva2VkXG4gICAgICogd2l0aCB0d28gYXJndW1lbnRzOiAoYXJyVmFsLCBvdGhWYWwpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmF0b3JdIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZHVwbGljYXRlIGZyZWUgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ3gnOiAxLCAneSc6IDIgfSwgeyAneCc6IDIsICd5JzogMSB9LCB7ICd4JzogMSwgJ3knOiAyIH1dO1xuICAgICAqXG4gICAgICogXy51bmlxV2l0aChvYmplY3RzLCBfLmlzRXF1YWwpO1xuICAgICAqIC8vID0+IFt7ICd4JzogMSwgJ3knOiAyIH0sIHsgJ3gnOiAyLCAneSc6IDEgfV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1bmlxV2l0aChhcnJheSwgY29tcGFyYXRvcikge1xuICAgICAgY29tcGFyYXRvciA9IHR5cGVvZiBjb21wYXJhdG9yID09ICdmdW5jdGlvbicgPyBjb21wYXJhdG9yIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpID8gYmFzZVVuaXEoYXJyYXksIHVuZGVmaW5lZCwgY29tcGFyYXRvcikgOiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnppcGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBhbiBhcnJheSBvZiBncm91cGVkXG4gICAgICogZWxlbWVudHMgYW5kIGNyZWF0ZXMgYW4gYXJyYXkgcmVncm91cGluZyB0aGUgZWxlbWVudHMgdG8gdGhlaXIgcHJlLXppcFxuICAgICAqIGNvbmZpZ3VyYXRpb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMS4yLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgb2YgZ3JvdXBlZCBlbGVtZW50cyB0byBwcm9jZXNzLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHJlZ3JvdXBlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHppcHBlZCA9IF8uemlwKFsnYScsICdiJ10sIFsxLCAyXSwgW3RydWUsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gW1snYScsIDEsIHRydWVdLCBbJ2InLCAyLCBmYWxzZV1dXG4gICAgICpcbiAgICAgKiBfLnVuemlwKHppcHBlZCk7XG4gICAgICogLy8gPT4gW1snYScsICdiJ10sIFsxLCAyXSwgW3RydWUsIGZhbHNlXV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1bnppcChhcnJheSkge1xuICAgICAgaWYgKCEoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKSkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICB2YXIgbGVuZ3RoID0gMDtcbiAgICAgIGFycmF5ID0gYXJyYXlGaWx0ZXIoYXJyYXksIGZ1bmN0aW9uKGdyb3VwKSB7XG4gICAgICAgIGlmIChpc0FycmF5TGlrZU9iamVjdChncm91cCkpIHtcbiAgICAgICAgICBsZW5ndGggPSBuYXRpdmVNYXgoZ3JvdXAubGVuZ3RoLCBsZW5ndGgpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBiYXNlVGltZXMobGVuZ3RoLCBmdW5jdGlvbihpbmRleCkge1xuICAgICAgICByZXR1cm4gYXJyYXlNYXAoYXJyYXksIGJhc2VQcm9wZXJ0eShpbmRleCkpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy51bnppcGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHRvIHNwZWNpZnlcbiAgICAgKiBob3cgcmVncm91cGVkIHZhbHVlcyBzaG91bGQgYmUgY29tYmluZWQuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggdGhlXG4gICAgICogZWxlbWVudHMgb2YgZWFjaCBncm91cDogKC4uLmdyb3VwKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjguMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSBvZiBncm91cGVkIGVsZW1lbnRzIHRvIHByb2Nlc3MuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiB0byBjb21iaW5lXG4gICAgICogIHJlZ3JvdXBlZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgcmVncm91cGVkIGVsZW1lbnRzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgemlwcGVkID0gXy56aXAoWzEsIDJdLCBbMTAsIDIwXSwgWzEwMCwgMjAwXSk7XG4gICAgICogLy8gPT4gW1sxLCAxMCwgMTAwXSwgWzIsIDIwLCAyMDBdXVxuICAgICAqXG4gICAgICogXy51bnppcFdpdGgoemlwcGVkLCBfLmFkZCk7XG4gICAgICogLy8gPT4gWzMsIDMwLCAzMDBdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW56aXBXaXRoKGFycmF5LCBpdGVyYXRlZSkge1xuICAgICAgaWYgKCEoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKSkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICB2YXIgcmVzdWx0ID0gdW56aXAoYXJyYXkpO1xuICAgICAgaWYgKGl0ZXJhdGVlID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhcnJheU1hcChyZXN1bHQsIGZ1bmN0aW9uKGdyb3VwKSB7XG4gICAgICAgIHJldHVybiBhcHBseShpdGVyYXRlZSwgdW5kZWZpbmVkLCBncm91cCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IGV4Y2x1ZGluZyBhbGwgZ2l2ZW4gdmFsdWVzIHVzaW5nXG4gICAgICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVW5saWtlIGBfLnB1bGxgLCB0aGlzIG1ldGhvZCByZXR1cm5zIGEgbmV3IGFycmF5LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHsuLi4qfSBbdmFsdWVzXSBUaGUgdmFsdWVzIHRvIGV4Y2x1ZGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZmlsdGVyZWQgdmFsdWVzLlxuICAgICAqIEBzZWUgXy5kaWZmZXJlbmNlLCBfLnhvclxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLndpdGhvdXQoWzIsIDEsIDIsIDNdLCAxLCAyKTtcbiAgICAgKiAvLyA9PiBbM11cbiAgICAgKi9cbiAgICB2YXIgd2l0aG91dCA9IGJhc2VSZXN0KGZ1bmN0aW9uKGFycmF5LCB2YWx1ZXMpIHtcbiAgICAgIHJldHVybiBpc0FycmF5TGlrZU9iamVjdChhcnJheSlcbiAgICAgICAgPyBiYXNlRGlmZmVyZW5jZShhcnJheSwgdmFsdWVzKVxuICAgICAgICA6IFtdO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiB1bmlxdWUgdmFsdWVzIHRoYXQgaXMgdGhlXG4gICAgICogW3N5bW1ldHJpYyBkaWZmZXJlbmNlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TeW1tZXRyaWNfZGlmZmVyZW5jZSlcbiAgICAgKiBvZiB0aGUgZ2l2ZW4gYXJyYXlzLiBUaGUgb3JkZXIgb2YgcmVzdWx0IHZhbHVlcyBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBvcmRlclxuICAgICAqIHRoZXkgb2NjdXIgaW4gdGhlIGFycmF5cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjQuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBmaWx0ZXJlZCB2YWx1ZXMuXG4gICAgICogQHNlZSBfLmRpZmZlcmVuY2UsIF8ud2l0aG91dFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnhvcihbMiwgMV0sIFsyLCAzXSk7XG4gICAgICogLy8gPT4gWzEsIDNdXG4gICAgICovXG4gICAgdmFyIHhvciA9IGJhc2VSZXN0KGZ1bmN0aW9uKGFycmF5cykge1xuICAgICAgcmV0dXJuIGJhc2VYb3IoYXJyYXlGaWx0ZXIoYXJyYXlzLCBpc0FycmF5TGlrZU9iamVjdCkpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy54b3JgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYCB3aGljaCBpc1xuICAgICAqIGludm9rZWQgZm9yIGVhY2ggZWxlbWVudCBvZiBlYWNoIGBhcnJheXNgIHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb24gYnlcbiAgICAgKiB3aGljaCBieSB3aGljaCB0aGV5J3JlIGNvbXBhcmVkLiBUaGUgb3JkZXIgb2YgcmVzdWx0IHZhbHVlcyBpcyBkZXRlcm1pbmVkXG4gICAgICogYnkgdGhlIG9yZGVyIHRoZXkgb2NjdXIgaW4gdGhlIGFycmF5cy4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmVcbiAgICAgKiBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZmlsdGVyZWQgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnhvckJ5KFsyLjEsIDEuMl0sIFsyLjMsIDMuNF0sIE1hdGguZmxvb3IpO1xuICAgICAqIC8vID0+IFsxLjIsIDMuNF1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ueG9yQnkoW3sgJ3gnOiAxIH1dLCBbeyAneCc6IDIgfSwgeyAneCc6IDEgfV0sICd4Jyk7XG4gICAgICogLy8gPT4gW3sgJ3gnOiAyIH1dXG4gICAgICovXG4gICAgdmFyIHhvckJ5ID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgaXRlcmF0ZWUgPSBsYXN0KGFycmF5cyk7XG4gICAgICBpZiAoaXNBcnJheUxpa2VPYmplY3QoaXRlcmF0ZWUpKSB7XG4gICAgICAgIGl0ZXJhdGVlID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VYb3IoYXJyYXlGaWx0ZXIoYXJyYXlzLCBpc0FycmF5TGlrZU9iamVjdCksIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnhvcmAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgY29tcGFyYXRvcmAgd2hpY2ggaXNcbiAgICAgKiBpbnZva2VkIHRvIGNvbXBhcmUgZWxlbWVudHMgb2YgYGFycmF5c2AuIFRoZSBvcmRlciBvZiByZXN1bHQgdmFsdWVzIGlzXG4gICAgICogZGV0ZXJtaW5lZCBieSB0aGUgb3JkZXIgdGhleSBvY2N1ciBpbiB0aGUgYXJyYXlzLiBUaGUgY29tcGFyYXRvciBpcyBpbnZva2VkXG4gICAgICogd2l0aCB0d28gYXJndW1lbnRzOiAoYXJyVmFsLCBvdGhWYWwpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IEFycmF5XG4gICAgICogQHBhcmFtIHsuLi5BcnJheX0gW2FycmF5c10gVGhlIGFycmF5cyB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjb21wYXJhdG9yXSBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGZpbHRlcmVkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAneCc6IDEsICd5JzogMiB9LCB7ICd4JzogMiwgJ3knOiAxIH1dO1xuICAgICAqIHZhciBvdGhlcnMgPSBbeyAneCc6IDEsICd5JzogMSB9LCB7ICd4JzogMSwgJ3knOiAyIH1dO1xuICAgICAqXG4gICAgICogXy54b3JXaXRoKG9iamVjdHMsIG90aGVycywgXy5pc0VxdWFsKTtcbiAgICAgKiAvLyA9PiBbeyAneCc6IDIsICd5JzogMSB9LCB7ICd4JzogMSwgJ3knOiAxIH1dXG4gICAgICovXG4gICAgdmFyIHhvcldpdGggPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgICAgIHZhciBjb21wYXJhdG9yID0gbGFzdChhcnJheXMpO1xuICAgICAgY29tcGFyYXRvciA9IHR5cGVvZiBjb21wYXJhdG9yID09ICdmdW5jdGlvbicgPyBjb21wYXJhdG9yIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIGJhc2VYb3IoYXJyYXlGaWx0ZXIoYXJyYXlzLCBpc0FycmF5TGlrZU9iamVjdCksIHVuZGVmaW5lZCwgY29tcGFyYXRvcik7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIGdyb3VwZWQgZWxlbWVudHMsIHRoZSBmaXJzdCBvZiB3aGljaCBjb250YWlucyB0aGVcbiAgICAgKiBmaXJzdCBlbGVtZW50cyBvZiB0aGUgZ2l2ZW4gYXJyYXlzLCB0aGUgc2Vjb25kIG9mIHdoaWNoIGNvbnRhaW5zIHRoZVxuICAgICAqIHNlY29uZCBlbGVtZW50cyBvZiB0aGUgZ2l2ZW4gYXJyYXlzLCBhbmQgc28gb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQXJyYXlcbiAgICAgKiBAcGFyYW0gey4uLkFycmF5fSBbYXJyYXlzXSBUaGUgYXJyYXlzIHRvIHByb2Nlc3MuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZ3JvdXBlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy56aXAoWydhJywgJ2InXSwgWzEsIDJdLCBbdHJ1ZSwgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBbWydhJywgMSwgdHJ1ZV0sIFsnYicsIDIsIGZhbHNlXV1cbiAgICAgKi9cbiAgICB2YXIgemlwID0gYmFzZVJlc3QodW56aXApO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5mcm9tUGFpcnNgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgdHdvIGFycmF5cyxcbiAgICAgKiBvbmUgb2YgcHJvcGVydHkgaWRlbnRpZmllcnMgYW5kIG9uZSBvZiBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjQuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtwcm9wcz1bXV0gVGhlIHByb3BlcnR5IGlkZW50aWZpZXJzLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFt2YWx1ZXM9W11dIFRoZSBwcm9wZXJ0eSB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy56aXBPYmplY3QoWydhJywgJ2InXSwgWzEsIDJdKTtcbiAgICAgKiAvLyA9PiB7ICdhJzogMSwgJ2InOiAyIH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB6aXBPYmplY3QocHJvcHMsIHZhbHVlcykge1xuICAgICAgcmV0dXJuIGJhc2VaaXBPYmplY3QocHJvcHMgfHwgW10sIHZhbHVlcyB8fCBbXSwgYXNzaWduVmFsdWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uemlwT2JqZWN0YCBleGNlcHQgdGhhdCBpdCBzdXBwb3J0cyBwcm9wZXJ0eSBwYXRocy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjEuMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFtwcm9wcz1bXV0gVGhlIHByb3BlcnR5IGlkZW50aWZpZXJzLlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IFt2YWx1ZXM9W11dIFRoZSBwcm9wZXJ0eSB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy56aXBPYmplY3REZWVwKFsnYS5iWzBdLmMnLCAnYS5iWzFdLmQnXSwgWzEsIDJdKTtcbiAgICAgKiAvLyA9PiB7ICdhJzogeyAnYic6IFt7ICdjJzogMSB9LCB7ICdkJzogMiB9XSB9IH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB6aXBPYmplY3REZWVwKHByb3BzLCB2YWx1ZXMpIHtcbiAgICAgIHJldHVybiBiYXNlWmlwT2JqZWN0KHByb3BzIHx8IFtdLCB2YWx1ZXMgfHwgW10sIGJhc2VTZXQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uemlwYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBpdGVyYXRlZWAgdG8gc3BlY2lmeVxuICAgICAqIGhvdyBncm91cGVkIHZhbHVlcyBzaG91bGQgYmUgY29tYmluZWQuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggdGhlXG4gICAgICogZWxlbWVudHMgb2YgZWFjaCBncm91cDogKC4uLmdyb3VwKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjguMFxuICAgICAqIEBjYXRlZ29yeSBBcnJheVxuICAgICAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gcHJvY2Vzcy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIHRvIGNvbWJpbmVcbiAgICAgKiAgZ3JvdXBlZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgZ3JvdXBlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy56aXBXaXRoKFsxLCAyXSwgWzEwLCAyMF0sIFsxMDAsIDIwMF0sIGZ1bmN0aW9uKGEsIGIsIGMpIHtcbiAgICAgKiAgIHJldHVybiBhICsgYiArIGM7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gWzExMSwgMjIyXVxuICAgICAqL1xuICAgIHZhciB6aXBXaXRoID0gYmFzZVJlc3QoZnVuY3Rpb24oYXJyYXlzKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gYXJyYXlzLmxlbmd0aCxcbiAgICAgICAgICBpdGVyYXRlZSA9IGxlbmd0aCA+IDEgPyBhcnJheXNbbGVuZ3RoIC0gMV0gOiB1bmRlZmluZWQ7XG5cbiAgICAgIGl0ZXJhdGVlID0gdHlwZW9mIGl0ZXJhdGVlID09ICdmdW5jdGlvbicgPyAoYXJyYXlzLnBvcCgpLCBpdGVyYXRlZSkgOiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gdW56aXBXaXRoKGFycmF5cywgaXRlcmF0ZWUpO1xuICAgIH0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2UgdGhhdCB3cmFwcyBgdmFsdWVgIHdpdGggZXhwbGljaXQgbWV0aG9kXG4gICAgICogY2hhaW4gc2VxdWVuY2VzIGVuYWJsZWQuIFRoZSByZXN1bHQgb2Ygc3VjaCBzZXF1ZW5jZXMgbXVzdCBiZSB1bndyYXBwZWRcbiAgICAgKiB3aXRoIGBfI3ZhbHVlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAxLjMuMFxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICAnYWdlJzogMzYgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhZ2UnOiA0MCB9LFxuICAgICAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FnZSc6IDEgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiB2YXIgeW91bmdlc3QgPSBfXG4gICAgICogICAuY2hhaW4odXNlcnMpXG4gICAgICogICAuc29ydEJ5KCdhZ2UnKVxuICAgICAqICAgLm1hcChmdW5jdGlvbihvKSB7XG4gICAgICogICAgIHJldHVybiBvLnVzZXIgKyAnIGlzICcgKyBvLmFnZTtcbiAgICAgKiAgIH0pXG4gICAgICogICAuaGVhZCgpXG4gICAgICogICAudmFsdWUoKTtcbiAgICAgKiAvLyA9PiAncGViYmxlcyBpcyAxJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNoYWluKHZhbHVlKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbG9kYXNoKHZhbHVlKTtcbiAgICAgIHJlc3VsdC5fX2NoYWluX18gPSB0cnVlO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpbnZva2VzIGBpbnRlcmNlcHRvcmAgYW5kIHJldHVybnMgYHZhbHVlYC4gVGhlIGludGVyY2VwdG9yXG4gICAgICogaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDsgKHZhbHVlKS4gVGhlIHB1cnBvc2Ugb2YgdGhpcyBtZXRob2QgaXMgdG9cbiAgICAgKiBcInRhcCBpbnRvXCIgYSBtZXRob2QgY2hhaW4gc2VxdWVuY2UgaW4gb3JkZXIgdG8gbW9kaWZ5IGludGVybWVkaWF0ZSByZXN1bHRzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IFNlcVxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb3ZpZGUgdG8gYGludGVyY2VwdG9yYC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBpbnRlcmNlcHRvciBUaGUgZnVuY3Rpb24gdG8gaW52b2tlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIGB2YWx1ZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8oWzEsIDIsIDNdKVxuICAgICAqICAudGFwKGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgICogICAgLy8gTXV0YXRlIGlucHV0IGFycmF5LlxuICAgICAqICAgIGFycmF5LnBvcCgpO1xuICAgICAqICB9KVxuICAgICAqICAucmV2ZXJzZSgpXG4gICAgICogIC52YWx1ZSgpO1xuICAgICAqIC8vID0+IFsyLCAxXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRhcCh2YWx1ZSwgaW50ZXJjZXB0b3IpIHtcbiAgICAgIGludGVyY2VwdG9yKHZhbHVlKTtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnRhcGAgZXhjZXB0IHRoYXQgaXQgcmV0dXJucyB0aGUgcmVzdWx0IG9mIGBpbnRlcmNlcHRvcmAuXG4gICAgICogVGhlIHB1cnBvc2Ugb2YgdGhpcyBtZXRob2QgaXMgdG8gXCJwYXNzIHRocnVcIiB2YWx1ZXMgcmVwbGFjaW5nIGludGVybWVkaWF0ZVxuICAgICAqIHJlc3VsdHMgaW4gYSBtZXRob2QgY2hhaW4gc2VxdWVuY2UuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvdmlkZSB0byBgaW50ZXJjZXB0b3JgLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGludGVyY2VwdG9yIFRoZSBmdW5jdGlvbiB0byBpbnZva2UuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc3VsdCBvZiBgaW50ZXJjZXB0b3JgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfKCcgIGFiYyAgJylcbiAgICAgKiAgLmNoYWluKClcbiAgICAgKiAgLnRyaW0oKVxuICAgICAqICAudGhydShmdW5jdGlvbih2YWx1ZSkge1xuICAgICAqICAgIHJldHVybiBbdmFsdWVdO1xuICAgICAqICB9KVxuICAgICAqICAudmFsdWUoKTtcbiAgICAgKiAvLyA9PiBbJ2FiYyddXG4gICAgICovXG4gICAgZnVuY3Rpb24gdGhydSh2YWx1ZSwgaW50ZXJjZXB0b3IpIHtcbiAgICAgIHJldHVybiBpbnRlcmNlcHRvcih2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgdGhlIHdyYXBwZXIgdmVyc2lvbiBvZiBgXy5hdGAuXG4gICAgICpcbiAgICAgKiBAbmFtZSBhdFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMC4wXG4gICAgICogQGNhdGVnb3J5IFNlcVxuICAgICAqIEBwYXJhbSB7Li4uKHN0cmluZ3xzdHJpbmdbXSl9IFtwYXRoc10gVGhlIHByb3BlcnR5IHBhdGhzIHRvIHBpY2suXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogW3sgJ2InOiB7ICdjJzogMyB9IH0sIDRdIH07XG4gICAgICpcbiAgICAgKiBfKG9iamVjdCkuYXQoWydhWzBdLmIuYycsICdhWzFdJ10pLnZhbHVlKCk7XG4gICAgICogLy8gPT4gWzMsIDRdXG4gICAgICovXG4gICAgdmFyIHdyYXBwZXJBdCA9IGZsYXRSZXN0KGZ1bmN0aW9uKHBhdGhzKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gcGF0aHMubGVuZ3RoLFxuICAgICAgICAgIHN0YXJ0ID0gbGVuZ3RoID8gcGF0aHNbMF0gOiAwLFxuICAgICAgICAgIHZhbHVlID0gdGhpcy5fX3dyYXBwZWRfXyxcbiAgICAgICAgICBpbnRlcmNlcHRvciA9IGZ1bmN0aW9uKG9iamVjdCkgeyByZXR1cm4gYmFzZUF0KG9iamVjdCwgcGF0aHMpOyB9O1xuXG4gICAgICBpZiAobGVuZ3RoID4gMSB8fCB0aGlzLl9fYWN0aW9uc19fLmxlbmd0aCB8fFxuICAgICAgICAgICEodmFsdWUgaW5zdGFuY2VvZiBMYXp5V3JhcHBlcikgfHwgIWlzSW5kZXgoc3RhcnQpKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRocnUoaW50ZXJjZXB0b3IpO1xuICAgICAgfVxuICAgICAgdmFsdWUgPSB2YWx1ZS5zbGljZShzdGFydCwgK3N0YXJ0ICsgKGxlbmd0aCA/IDEgOiAwKSk7XG4gICAgICB2YWx1ZS5fX2FjdGlvbnNfXy5wdXNoKHtcbiAgICAgICAgJ2Z1bmMnOiB0aHJ1LFxuICAgICAgICAnYXJncyc6IFtpbnRlcmNlcHRvcl0sXG4gICAgICAgICd0aGlzQXJnJzogdW5kZWZpbmVkXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBuZXcgTG9kYXNoV3JhcHBlcih2YWx1ZSwgdGhpcy5fX2NoYWluX18pLnRocnUoZnVuY3Rpb24oYXJyYXkpIHtcbiAgICAgICAgaWYgKGxlbmd0aCAmJiAhYXJyYXkubGVuZ3RoKSB7XG4gICAgICAgICAgYXJyYXkucHVzaCh1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhcnJheTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2Ugd2l0aCBleHBsaWNpdCBtZXRob2QgY2hhaW4gc2VxdWVuY2VzIGVuYWJsZWQuXG4gICAgICpcbiAgICAgKiBAbmFtZSBjaGFpblxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IFNlcVxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDAgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiAvLyBBIHNlcXVlbmNlIHdpdGhvdXQgZXhwbGljaXQgY2hhaW5pbmcuXG4gICAgICogXyh1c2VycykuaGVhZCgpO1xuICAgICAqIC8vID0+IHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM2IH1cbiAgICAgKlxuICAgICAqIC8vIEEgc2VxdWVuY2Ugd2l0aCBleHBsaWNpdCBjaGFpbmluZy5cbiAgICAgKiBfKHVzZXJzKVxuICAgICAqICAgLmNoYWluKClcbiAgICAgKiAgIC5oZWFkKClcbiAgICAgKiAgIC5waWNrKCd1c2VyJylcbiAgICAgKiAgIC52YWx1ZSgpO1xuICAgICAqIC8vID0+IHsgJ3VzZXInOiAnYmFybmV5JyB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlckNoYWluKCkge1xuICAgICAgcmV0dXJuIGNoYWluKHRoaXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4ZWN1dGVzIHRoZSBjaGFpbiBzZXF1ZW5jZSBhbmQgcmV0dXJucyB0aGUgd3JhcHBlZCByZXN1bHQuXG4gICAgICpcbiAgICAgKiBAbmFtZSBjb21taXRcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjIuMFxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgYGxvZGFzaGAgd3JhcHBlciBpbnN0YW5jZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWzEsIDJdO1xuICAgICAqIHZhciB3cmFwcGVkID0gXyhhcnJheSkucHVzaCgzKTtcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbMSwgMl1cbiAgICAgKlxuICAgICAqIHdyYXBwZWQgPSB3cmFwcGVkLmNvbW1pdCgpO1xuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKlxuICAgICAqIHdyYXBwZWQubGFzdCgpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKGFycmF5KTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB3cmFwcGVyQ29tbWl0KCkge1xuICAgICAgcmV0dXJuIG5ldyBMb2Rhc2hXcmFwcGVyKHRoaXMudmFsdWUoKSwgdGhpcy5fX2NoYWluX18pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIG5leHQgdmFsdWUgb24gYSB3cmFwcGVkIG9iamVjdCBmb2xsb3dpbmcgdGhlXG4gICAgICogW2l0ZXJhdG9yIHByb3RvY29sXShodHRwczovL21kbi5pby9pdGVyYXRpb25fcHJvdG9jb2xzI2l0ZXJhdG9yKS5cbiAgICAgKlxuICAgICAqIEBuYW1lIG5leHRcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXh0IGl0ZXJhdG9yIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgd3JhcHBlZCA9IF8oWzEsIDJdKTtcbiAgICAgKlxuICAgICAqIHdyYXBwZWQubmV4dCgpO1xuICAgICAqIC8vID0+IHsgJ2RvbmUnOiBmYWxzZSwgJ3ZhbHVlJzogMSB9XG4gICAgICpcbiAgICAgKiB3cmFwcGVkLm5leHQoKTtcbiAgICAgKiAvLyA9PiB7ICdkb25lJzogZmFsc2UsICd2YWx1ZSc6IDIgfVxuICAgICAqXG4gICAgICogd3JhcHBlZC5uZXh0KCk7XG4gICAgICogLy8gPT4geyAnZG9uZSc6IHRydWUsICd2YWx1ZSc6IHVuZGVmaW5lZCB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlck5leHQoKSB7XG4gICAgICBpZiAodGhpcy5fX3ZhbHVlc19fID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5fX3ZhbHVlc19fID0gdG9BcnJheSh0aGlzLnZhbHVlKCkpO1xuICAgICAgfVxuICAgICAgdmFyIGRvbmUgPSB0aGlzLl9faW5kZXhfXyA+PSB0aGlzLl9fdmFsdWVzX18ubGVuZ3RoLFxuICAgICAgICAgIHZhbHVlID0gZG9uZSA/IHVuZGVmaW5lZCA6IHRoaXMuX192YWx1ZXNfX1t0aGlzLl9faW5kZXhfXysrXTtcblxuICAgICAgcmV0dXJuIHsgJ2RvbmUnOiBkb25lLCAndmFsdWUnOiB2YWx1ZSB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVuYWJsZXMgdGhlIHdyYXBwZXIgdG8gYmUgaXRlcmFibGUuXG4gICAgICpcbiAgICAgKiBAbmFtZSBTeW1ib2wuaXRlcmF0b3JcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSB3cmFwcGVyIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHdyYXBwZWQgPSBfKFsxLCAyXSk7XG4gICAgICpcbiAgICAgKiB3cmFwcGVkW1N5bWJvbC5pdGVyYXRvcl0oKSA9PT0gd3JhcHBlZDtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBBcnJheS5mcm9tKHdyYXBwZWQpO1xuICAgICAqIC8vID0+IFsxLCAyXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXBwZXJUb0l0ZXJhdG9yKCkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGNsb25lIG9mIHRoZSBjaGFpbiBzZXF1ZW5jZSBwbGFudGluZyBgdmFsdWVgIGFzIHRoZSB3cmFwcGVkIHZhbHVlLlxuICAgICAqXG4gICAgICogQG5hbWUgcGxhbnRcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjIuMFxuICAgICAqIEBjYXRlZ29yeSBTZXFcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwbGFudC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgYGxvZGFzaGAgd3JhcHBlciBpbnN0YW5jZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gc3F1YXJlKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICogbjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiB2YXIgd3JhcHBlZCA9IF8oWzEsIDJdKS5tYXAoc3F1YXJlKTtcbiAgICAgKiB2YXIgb3RoZXIgPSB3cmFwcGVkLnBsYW50KFszLCA0XSk7XG4gICAgICpcbiAgICAgKiBvdGhlci52YWx1ZSgpO1xuICAgICAqIC8vID0+IFs5LCAxNl1cbiAgICAgKlxuICAgICAqIHdyYXBwZWQudmFsdWUoKTtcbiAgICAgKiAvLyA9PiBbMSwgNF1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB3cmFwcGVyUGxhbnQodmFsdWUpIHtcbiAgICAgIHZhciByZXN1bHQsXG4gICAgICAgICAgcGFyZW50ID0gdGhpcztcblxuICAgICAgd2hpbGUgKHBhcmVudCBpbnN0YW5jZW9mIGJhc2VMb2Rhc2gpIHtcbiAgICAgICAgdmFyIGNsb25lID0gd3JhcHBlckNsb25lKHBhcmVudCk7XG4gICAgICAgIGNsb25lLl9faW5kZXhfXyA9IDA7XG4gICAgICAgIGNsb25lLl9fdmFsdWVzX18gPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICBwcmV2aW91cy5fX3dyYXBwZWRfXyA9IGNsb25lO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc3VsdCA9IGNsb25lO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwcmV2aW91cyA9IGNsb25lO1xuICAgICAgICBwYXJlbnQgPSBwYXJlbnQuX193cmFwcGVkX187XG4gICAgICB9XG4gICAgICBwcmV2aW91cy5fX3dyYXBwZWRfXyA9IHZhbHVlO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyB0aGUgd3JhcHBlciB2ZXJzaW9uIG9mIGBfLnJldmVyc2VgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgdGhlIHdyYXBwZWQgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAbmFtZSByZXZlcnNlXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGBsb2Rhc2hgIHdyYXBwZXIgaW5zdGFuY2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyLCAzXTtcbiAgICAgKlxuICAgICAqIF8oYXJyYXkpLnJldmVyc2UoKS52YWx1ZSgpXG4gICAgICogLy8gPT4gWzMsIDIsIDFdXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhhcnJheSk7XG4gICAgICogLy8gPT4gWzMsIDIsIDFdXG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlclJldmVyc2UoKSB7XG4gICAgICB2YXIgdmFsdWUgPSB0aGlzLl9fd3JhcHBlZF9fO1xuICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTGF6eVdyYXBwZXIpIHtcbiAgICAgICAgdmFyIHdyYXBwZWQgPSB2YWx1ZTtcbiAgICAgICAgaWYgKHRoaXMuX19hY3Rpb25zX18ubGVuZ3RoKSB7XG4gICAgICAgICAgd3JhcHBlZCA9IG5ldyBMYXp5V3JhcHBlcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICB3cmFwcGVkID0gd3JhcHBlZC5yZXZlcnNlKCk7XG4gICAgICAgIHdyYXBwZWQuX19hY3Rpb25zX18ucHVzaCh7XG4gICAgICAgICAgJ2Z1bmMnOiB0aHJ1LFxuICAgICAgICAgICdhcmdzJzogW3JldmVyc2VdLFxuICAgICAgICAgICd0aGlzQXJnJzogdW5kZWZpbmVkXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbmV3IExvZGFzaFdyYXBwZXIod3JhcHBlZCwgdGhpcy5fX2NoYWluX18pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMudGhydShyZXZlcnNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyB0aGUgY2hhaW4gc2VxdWVuY2UgdG8gcmVzb2x2ZSB0aGUgdW53cmFwcGVkIHZhbHVlLlxuICAgICAqXG4gICAgICogQG5hbWUgdmFsdWVcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBhbGlhcyB0b0pTT04sIHZhbHVlT2ZcbiAgICAgKiBAY2F0ZWdvcnkgU2VxXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc29sdmVkIHVud3JhcHBlZCB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXyhbMSwgMiwgM10pLnZhbHVlKCk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gd3JhcHBlclZhbHVlKCkge1xuICAgICAgcmV0dXJuIGJhc2VXcmFwcGVyVmFsdWUodGhpcy5fX3dyYXBwZWRfXywgdGhpcy5fX2FjdGlvbnNfXyk7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBvYmplY3QgY29tcG9zZWQgb2Yga2V5cyBnZW5lcmF0ZWQgZnJvbSB0aGUgcmVzdWx0cyBvZiBydW5uaW5nXG4gICAgICogZWFjaCBlbGVtZW50IG9mIGBjb2xsZWN0aW9uYCB0aHJ1IGBpdGVyYXRlZWAuIFRoZSBjb3JyZXNwb25kaW5nIHZhbHVlIG9mXG4gICAgICogZWFjaCBrZXkgaXMgdGhlIG51bWJlciBvZiB0aW1lcyB0aGUga2V5IHdhcyByZXR1cm5lZCBieSBgaXRlcmF0ZWVgLiBUaGVcbiAgICAgKiBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuNS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSB0byB0cmFuc2Zvcm0ga2V5cy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjb21wb3NlZCBhZ2dyZWdhdGUgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmNvdW50QnkoWzYuMSwgNC4yLCA2LjNdLCBNYXRoLmZsb29yKTtcbiAgICAgKiAvLyA9PiB7ICc0JzogMSwgJzYnOiAyIH1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uY291bnRCeShbJ29uZScsICd0d28nLCAndGhyZWUnXSwgJ2xlbmd0aCcpO1xuICAgICAqIC8vID0+IHsgJzMnOiAyLCAnNSc6IDEgfVxuICAgICAqL1xuICAgIHZhciBjb3VudEJ5ID0gY3JlYXRlQWdncmVnYXRvcihmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3VsdCwga2V5KSkge1xuICAgICAgICArK3Jlc3VsdFtrZXldO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYmFzZUFzc2lnblZhbHVlKHJlc3VsdCwga2V5LCAxKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgcHJlZGljYXRlYCByZXR1cm5zIHRydXRoeSBmb3IgKiphbGwqKiBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAuXG4gICAgICogSXRlcmF0aW9uIGlzIHN0b3BwZWQgb25jZSBgcHJlZGljYXRlYCByZXR1cm5zIGZhbHNleS4gVGhlIHByZWRpY2F0ZSBpc1xuICAgICAqIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCByZXR1cm5zIGB0cnVlYCBmb3JcbiAgICAgKiBbZW1wdHkgY29sbGVjdGlvbnNdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0VtcHR5X3NldCkgYmVjYXVzZVxuICAgICAqIFtldmVyeXRoaW5nIGlzIHRydWVdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1ZhY3VvdXNfdHJ1dGgpIG9mXG4gICAgICogZWxlbWVudHMgb2YgZW1wdHkgY29sbGVjdGlvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYWxsIGVsZW1lbnRzIHBhc3MgdGhlIHByZWRpY2F0ZSBjaGVjayxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmV2ZXJ5KFt0cnVlLCAxLCBudWxsLCAneWVzJ10sIEJvb2xlYW4pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmV2ZXJ5KHVzZXJzLCB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZXZlcnkodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmV2ZXJ5KHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBldmVyeShjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGd1YXJkKSB7XG4gICAgICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheUV2ZXJ5IDogYmFzZUV2ZXJ5O1xuICAgICAgaWYgKGd1YXJkICYmIGlzSXRlcmF0ZWVDYWxsKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZ3VhcmQpKSB7XG4gICAgICAgIHByZWRpY2F0ZSA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gLCByZXR1cm5pbmcgYW4gYXJyYXkgb2YgYWxsIGVsZW1lbnRzXG4gICAgICogYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yLiBUaGUgcHJlZGljYXRlIGlzIGludm9rZWQgd2l0aCB0aHJlZVxuICAgICAqIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVubGlrZSBgXy5yZW1vdmVgLCB0aGlzIG1ldGhvZCByZXR1cm5zIGEgbmV3IGFycmF5LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICAgICAqIEBzZWUgXy5yZWplY3RcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5maWx0ZXIodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuICFvLmFjdGl2ZTsgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maWx0ZXIodXNlcnMsIHsgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maWx0ZXIodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maWx0ZXIodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmlsdGVyKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSkge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlGaWx0ZXIgOiBiYXNlRmlsdGVyO1xuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgZ2V0SXRlcmF0ZWUocHJlZGljYXRlLCAzKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAsIHJldHVybmluZyB0aGUgZmlyc3QgZWxlbWVudFxuICAgICAqIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvci4gVGhlIHByZWRpY2F0ZSBpcyBpbnZva2VkIHdpdGggdGhyZWVcbiAgICAgKiBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9MF0gVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXRjaGVkIGVsZW1lbnQsIGVsc2UgYHVuZGVmaW5lZGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWdlJzogMSwgICdhY3RpdmUnOiB0cnVlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5maW5kKHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLmFnZSA8IDQwOyB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3QgZm9yICdiYXJuZXknXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZCh1c2VycywgeyAnYWdlJzogMSwgJ2FjdGl2ZSc6IHRydWUgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0IGZvciAncGViYmxlcydcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmQodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBvYmplY3QgZm9yICdmcmVkJ1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kKHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gb2JqZWN0IGZvciAnYmFybmV5J1xuICAgICAqL1xuICAgIHZhciBmaW5kID0gY3JlYXRlRmluZChmaW5kSW5kZXgpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5maW5kYCBleGNlcHQgdGhhdCBpdCBpdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mXG4gICAgICogYGNvbGxlY3Rpb25gIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjAuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9Y29sbGVjdGlvbi5sZW5ndGgtMV0gVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXRjaGVkIGVsZW1lbnQsIGVsc2UgYHVuZGVmaW5lZGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZmluZExhc3QoWzEsIDIsIDMsIDRdLCBmdW5jdGlvbihuKSB7XG4gICAgICogICByZXR1cm4gbiAlIDIgPT0gMTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICovXG4gICAgdmFyIGZpbmRMYXN0ID0gY3JlYXRlRmluZChmaW5kTGFzdEluZGV4KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmbGF0dGVuZWQgYXJyYXkgb2YgdmFsdWVzIGJ5IHJ1bm5pbmcgZWFjaCBlbGVtZW50IGluIGBjb2xsZWN0aW9uYFxuICAgICAqIHRocnUgYGl0ZXJhdGVlYCBhbmQgZmxhdHRlbmluZyB0aGUgbWFwcGVkIHJlc3VsdHMuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkXG4gICAgICogd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gZHVwbGljYXRlKG4pIHtcbiAgICAgKiAgIHJldHVybiBbbiwgbl07XG4gICAgICogfVxuICAgICAqXG4gICAgICogXy5mbGF0TWFwKFsxLCAyXSwgZHVwbGljYXRlKTtcbiAgICAgKiAvLyA9PiBbMSwgMSwgMiwgMl1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmbGF0TWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gYmFzZUZsYXR0ZW4obWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSwgMSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5mbGF0TWFwYCBleGNlcHQgdGhhdCBpdCByZWN1cnNpdmVseSBmbGF0dGVucyB0aGVcbiAgICAgKiBtYXBwZWQgcmVzdWx0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjcuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gZHVwbGljYXRlKG4pIHtcbiAgICAgKiAgIHJldHVybiBbW1tuLCBuXV1dO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIF8uZmxhdE1hcERlZXAoWzEsIDJdLCBkdXBsaWNhdGUpO1xuICAgICAqIC8vID0+IFsxLCAxLCAyLCAyXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZsYXRNYXBEZWVwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gYmFzZUZsYXR0ZW4obWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSwgSU5GSU5JVFkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZmxhdE1hcGAgZXhjZXB0IHRoYXQgaXQgcmVjdXJzaXZlbHkgZmxhdHRlbnMgdGhlXG4gICAgICogbWFwcGVkIHJlc3VsdHMgdXAgdG8gYGRlcHRoYCB0aW1lcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjcuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbZGVwdGg9MV0gVGhlIG1heGltdW0gcmVjdXJzaW9uIGRlcHRoLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZsYXR0ZW5lZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gZHVwbGljYXRlKG4pIHtcbiAgICAgKiAgIHJldHVybiBbW1tuLCBuXV1dO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIF8uZmxhdE1hcERlcHRoKFsxLCAyXSwgZHVwbGljYXRlLCAyKTtcbiAgICAgKiAvLyA9PiBbWzEsIDFdLCBbMiwgMl1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmxhdE1hcERlcHRoKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCBkZXB0aCkge1xuICAgICAgZGVwdGggPSBkZXB0aCA9PT0gdW5kZWZpbmVkID8gMSA6IHRvSW50ZWdlcihkZXB0aCk7XG4gICAgICByZXR1cm4gYmFzZUZsYXR0ZW4obWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSwgZGVwdGgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gIGFuZCBpbnZva2VzIGBpdGVyYXRlZWAgZm9yIGVhY2ggZWxlbWVudC5cbiAgICAgKiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICAgICAqIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBBcyB3aXRoIG90aGVyIFwiQ29sbGVjdGlvbnNcIiBtZXRob2RzLCBvYmplY3RzIHdpdGggYSBcImxlbmd0aFwiXG4gICAgICogcHJvcGVydHkgYXJlIGl0ZXJhdGVkIGxpa2UgYXJyYXlzLiBUbyBhdm9pZCB0aGlzIGJlaGF2aW9yIHVzZSBgXy5mb3JJbmBcbiAgICAgKiBvciBgXy5mb3JPd25gIGZvciBvYmplY3QgaXRlcmF0aW9uLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGFsaWFzIGVhY2hcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSBSZXR1cm5zIGBjb2xsZWN0aW9uYC5cbiAgICAgKiBAc2VlIF8uZm9yRWFjaFJpZ2h0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZm9yRWFjaChbMSwgMl0sIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICogICBjb25zb2xlLmxvZyh2YWx1ZSk7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gTG9ncyBgMWAgdGhlbiBgMmAuXG4gICAgICpcbiAgICAgKiBfLmZvckVhY2goeyAnYSc6IDEsICdiJzogMiB9LCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICogICBjb25zb2xlLmxvZyhrZXkpO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IExvZ3MgJ2EnIHRoZW4gJ2InIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZvckVhY2goY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5RWFjaCA6IGJhc2VFYWNoO1xuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmZvckVhY2hgIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2ZcbiAgICAgKiBgY29sbGVjdGlvbmAgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGFsaWFzIGVhY2hSaWdodFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R9IFJldHVybnMgYGNvbGxlY3Rpb25gLlxuICAgICAqIEBzZWUgXy5mb3JFYWNoXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZm9yRWFjaFJpZ2h0KFsxLCAyXSwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKHZhbHVlKTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiBMb2dzIGAyYCB0aGVuIGAxYC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmb3JFYWNoUmlnaHQoY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5RWFjaFJpZ2h0IDogYmFzZUVhY2hSaWdodDtcbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAzKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBvYmplY3QgY29tcG9zZWQgb2Yga2V5cyBnZW5lcmF0ZWQgZnJvbSB0aGUgcmVzdWx0cyBvZiBydW5uaW5nXG4gICAgICogZWFjaCBlbGVtZW50IG9mIGBjb2xsZWN0aW9uYCB0aHJ1IGBpdGVyYXRlZWAuIFRoZSBvcmRlciBvZiBncm91cGVkIHZhbHVlc1xuICAgICAqIGlzIGRldGVybWluZWQgYnkgdGhlIG9yZGVyIHRoZXkgb2NjdXIgaW4gYGNvbGxlY3Rpb25gLiBUaGUgY29ycmVzcG9uZGluZ1xuICAgICAqIHZhbHVlIG9mIGVhY2gga2V5IGlzIGFuIGFycmF5IG9mIGVsZW1lbnRzIHJlc3BvbnNpYmxlIGZvciBnZW5lcmF0aW5nIHRoZVxuICAgICAqIGtleS4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIHRvIHRyYW5zZm9ybSBrZXlzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNvbXBvc2VkIGFnZ3JlZ2F0ZSBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZ3JvdXBCeShbNi4xLCA0LjIsIDYuM10sIE1hdGguZmxvb3IpO1xuICAgICAqIC8vID0+IHsgJzQnOiBbNC4yXSwgJzYnOiBbNi4xLCA2LjNdIH1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZ3JvdXBCeShbJ29uZScsICd0d28nLCAndGhyZWUnXSwgJ2xlbmd0aCcpO1xuICAgICAqIC8vID0+IHsgJzMnOiBbJ29uZScsICd0d28nXSwgJzUnOiBbJ3RocmVlJ10gfVxuICAgICAqL1xuICAgIHZhciBncm91cEJ5ID0gY3JlYXRlQWdncmVnYXRvcihmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3VsdCwga2V5KSkge1xuICAgICAgICByZXN1bHRba2V5XS5wdXNoKHZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJhc2VBc3NpZ25WYWx1ZShyZXN1bHQsIGtleSwgW3ZhbHVlXSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBpbiBgY29sbGVjdGlvbmAuIElmIGBjb2xsZWN0aW9uYCBpcyBhIHN0cmluZywgaXQnc1xuICAgICAqIGNoZWNrZWQgZm9yIGEgc3Vic3RyaW5nIG9mIGB2YWx1ZWAsIG90aGVyd2lzZVxuICAgICAqIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gICAgICogaXMgdXNlZCBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuIElmIGBmcm9tSW5kZXhgIGlzIG5lZ2F0aXZlLCBpdCdzIHVzZWQgYXNcbiAgICAgKiB0aGUgb2Zmc2V0IGZyb20gdGhlIGVuZCBvZiBgY29sbGVjdGlvbmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtmcm9tSW5kZXg9MF0gVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLnJlZHVjZWAuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pbmNsdWRlcyhbMSwgMiwgM10sIDEpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaW5jbHVkZXMoWzEsIDIsIDNdLCAxLCAyKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pbmNsdWRlcyh7ICdhJzogMSwgJ2InOiAyIH0sIDEpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaW5jbHVkZXMoJ2FiY2QnLCAnYmMnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5jbHVkZXMoY29sbGVjdGlvbiwgdmFsdWUsIGZyb21JbmRleCwgZ3VhcmQpIHtcbiAgICAgIGNvbGxlY3Rpb24gPSBpc0FycmF5TGlrZShjb2xsZWN0aW9uKSA/IGNvbGxlY3Rpb24gOiB2YWx1ZXMoY29sbGVjdGlvbik7XG4gICAgICBmcm9tSW5kZXggPSAoZnJvbUluZGV4ICYmICFndWFyZCkgPyB0b0ludGVnZXIoZnJvbUluZGV4KSA6IDA7XG5cbiAgICAgIHZhciBsZW5ndGggPSBjb2xsZWN0aW9uLmxlbmd0aDtcbiAgICAgIGlmIChmcm9tSW5kZXggPCAwKSB7XG4gICAgICAgIGZyb21JbmRleCA9IG5hdGl2ZU1heChsZW5ndGggKyBmcm9tSW5kZXgsIDApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGlzU3RyaW5nKGNvbGxlY3Rpb24pXG4gICAgICAgID8gKGZyb21JbmRleCA8PSBsZW5ndGggJiYgY29sbGVjdGlvbi5pbmRleE9mKHZhbHVlLCBmcm9tSW5kZXgpID4gLTEpXG4gICAgICAgIDogKCEhbGVuZ3RoICYmIGJhc2VJbmRleE9mKGNvbGxlY3Rpb24sIHZhbHVlLCBmcm9tSW5kZXgpID4gLTEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEludm9rZXMgdGhlIG1ldGhvZCBhdCBgcGF0aGAgb2YgZWFjaCBlbGVtZW50IGluIGBjb2xsZWN0aW9uYCwgcmV0dXJuaW5nXG4gICAgICogYW4gYXJyYXkgb2YgdGhlIHJlc3VsdHMgb2YgZWFjaCBpbnZva2VkIG1ldGhvZC4gQW55IGFkZGl0aW9uYWwgYXJndW1lbnRzXG4gICAgICogYXJlIHByb3ZpZGVkIHRvIGVhY2ggaW52b2tlZCBtZXRob2QuIElmIGBwYXRoYCBpcyBhIGZ1bmN0aW9uLCBpdCdzIGludm9rZWRcbiAgICAgKiBmb3IsIGFuZCBgdGhpc2AgYm91bmQgdG8sIGVhY2ggZWxlbWVudCBpbiBgY29sbGVjdGlvbmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0FycmF5fEZ1bmN0aW9ufHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgbWV0aG9kIHRvIGludm9rZSBvclxuICAgICAqICB0aGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW2FyZ3NdIFRoZSBhcmd1bWVudHMgdG8gaW52b2tlIGVhY2ggbWV0aG9kIHdpdGguXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiByZXN1bHRzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmludm9rZU1hcChbWzUsIDEsIDddLCBbMywgMiwgMV1dLCAnc29ydCcpO1xuICAgICAqIC8vID0+IFtbMSwgNSwgN10sIFsxLCAyLCAzXV1cbiAgICAgKlxuICAgICAqIF8uaW52b2tlTWFwKFsxMjMsIDQ1Nl0sIFN0cmluZy5wcm90b3R5cGUuc3BsaXQsICcnKTtcbiAgICAgKiAvLyA9PiBbWycxJywgJzInLCAnMyddLCBbJzQnLCAnNScsICc2J11dXG4gICAgICovXG4gICAgdmFyIGludm9rZU1hcCA9IGJhc2VSZXN0KGZ1bmN0aW9uKGNvbGxlY3Rpb24sIHBhdGgsIGFyZ3MpIHtcbiAgICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICAgIGlzRnVuYyA9IHR5cGVvZiBwYXRoID09ICdmdW5jdGlvbicsXG4gICAgICAgICAgcmVzdWx0ID0gaXNBcnJheUxpa2UoY29sbGVjdGlvbikgPyBBcnJheShjb2xsZWN0aW9uLmxlbmd0aCkgOiBbXTtcblxuICAgICAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgcmVzdWx0WysraW5kZXhdID0gaXNGdW5jID8gYXBwbHkocGF0aCwgdmFsdWUsIGFyZ3MpIDogYmFzZUludm9rZSh2YWx1ZSwgcGF0aCwgYXJncyk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCBjb21wb3NlZCBvZiBrZXlzIGdlbmVyYXRlZCBmcm9tIHRoZSByZXN1bHRzIG9mIHJ1bm5pbmdcbiAgICAgKiBlYWNoIGVsZW1lbnQgb2YgYGNvbGxlY3Rpb25gIHRocnUgYGl0ZXJhdGVlYC4gVGhlIGNvcnJlc3BvbmRpbmcgdmFsdWUgb2ZcbiAgICAgKiBlYWNoIGtleSBpcyB0aGUgbGFzdCBlbGVtZW50IHJlc3BvbnNpYmxlIGZvciBnZW5lcmF0aW5nIHRoZSBrZXkuIFRoZVxuICAgICAqIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIHRvIHRyYW5zZm9ybSBrZXlzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNvbXBvc2VkIGFnZ3JlZ2F0ZSBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFtcbiAgICAgKiAgIHsgJ2Rpcic6ICdsZWZ0JywgJ2NvZGUnOiA5NyB9LFxuICAgICAqICAgeyAnZGlyJzogJ3JpZ2h0JywgJ2NvZGUnOiAxMDAgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLmtleUJ5KGFycmF5LCBmdW5jdGlvbihvKSB7XG4gICAgICogICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShvLmNvZGUpO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IHsgJ2EnOiB7ICdkaXInOiAnbGVmdCcsICdjb2RlJzogOTcgfSwgJ2QnOiB7ICdkaXInOiAncmlnaHQnLCAnY29kZSc6IDEwMCB9IH1cbiAgICAgKlxuICAgICAqIF8ua2V5QnkoYXJyYXksICdkaXInKTtcbiAgICAgKiAvLyA9PiB7ICdsZWZ0JzogeyAnZGlyJzogJ2xlZnQnLCAnY29kZSc6IDk3IH0sICdyaWdodCc6IHsgJ2Rpcic6ICdyaWdodCcsICdjb2RlJzogMTAwIH0gfVxuICAgICAqL1xuICAgIHZhciBrZXlCeSA9IGNyZWF0ZUFnZ3JlZ2F0b3IoZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgICBiYXNlQXNzaWduVmFsdWUocmVzdWx0LCBrZXksIHZhbHVlKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdmFsdWVzIGJ5IHJ1bm5pbmcgZWFjaCBlbGVtZW50IGluIGBjb2xsZWN0aW9uYCB0aHJ1XG4gICAgICogYGl0ZXJhdGVlYC4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6XG4gICAgICogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICAgICAqXG4gICAgICogTWFueSBsb2Rhc2ggbWV0aG9kcyBhcmUgZ3VhcmRlZCB0byB3b3JrIGFzIGl0ZXJhdGVlcyBmb3IgbWV0aG9kcyBsaWtlXG4gICAgICogYF8uZXZlcnlgLCBgXy5maWx0ZXJgLCBgXy5tYXBgLCBgXy5tYXBWYWx1ZXNgLCBgXy5yZWplY3RgLCBhbmQgYF8uc29tZWAuXG4gICAgICpcbiAgICAgKiBUaGUgZ3VhcmRlZCBtZXRob2RzIGFyZTpcbiAgICAgKiBgYXJ5YCwgYGNodW5rYCwgYGN1cnJ5YCwgYGN1cnJ5UmlnaHRgLCBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZXZlcnlgLFxuICAgICAqIGBmaWxsYCwgYGludmVydGAsIGBwYXJzZUludGAsIGByYW5kb21gLCBgcmFuZ2VgLCBgcmFuZ2VSaWdodGAsIGByZXBlYXRgLFxuICAgICAqIGBzYW1wbGVTaXplYCwgYHNsaWNlYCwgYHNvbWVgLCBgc29ydEJ5YCwgYHNwbGl0YCwgYHRha2VgLCBgdGFrZVJpZ2h0YCxcbiAgICAgKiBgdGVtcGxhdGVgLCBgdHJpbWAsIGB0cmltRW5kYCwgYHRyaW1TdGFydGAsIGFuZCBgd29yZHNgXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIHNxdWFyZShuKSB7XG4gICAgICogICByZXR1cm4gbiAqIG47XG4gICAgICogfVxuICAgICAqXG4gICAgICogXy5tYXAoWzQsIDhdLCBzcXVhcmUpO1xuICAgICAqIC8vID0+IFsxNiwgNjRdXG4gICAgICpcbiAgICAgKiBfLm1hcCh7ICdhJzogNCwgJ2InOiA4IH0sIHNxdWFyZSk7XG4gICAgICogLy8gPT4gWzE2LCA2NF0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IFtcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JyB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJyB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ubWFwKHVzZXJzLCAndXNlcicpO1xuICAgICAqIC8vID0+IFsnYmFybmV5JywgJ2ZyZWQnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlNYXAgOiBiYXNlTWFwO1xuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnNvcnRCeWAgZXhjZXB0IHRoYXQgaXQgYWxsb3dzIHNwZWNpZnlpbmcgdGhlIHNvcnRcbiAgICAgKiBvcmRlcnMgb2YgdGhlIGl0ZXJhdGVlcyB0byBzb3J0IGJ5LiBJZiBgb3JkZXJzYCBpcyB1bnNwZWNpZmllZCwgYWxsIHZhbHVlc1xuICAgICAqIGFyZSBzb3J0ZWQgaW4gYXNjZW5kaW5nIG9yZGVyLiBPdGhlcndpc2UsIHNwZWNpZnkgYW4gb3JkZXIgb2YgXCJkZXNjXCIgZm9yXG4gICAgICogZGVzY2VuZGluZyBvciBcImFzY1wiIGZvciBhc2NlbmRpbmcgc29ydCBvcmRlciBvZiBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7QXJyYXlbXXxGdW5jdGlvbltdfE9iamVjdFtdfHN0cmluZ1tdfSBbaXRlcmF0ZWVzPVtfLmlkZW50aXR5XV1cbiAgICAgKiAgVGhlIGl0ZXJhdGVlcyB0byBzb3J0IGJ5LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nW119IFtvcmRlcnNdIFRoZSBzb3J0IG9yZGVycyBvZiBgaXRlcmF0ZWVzYC5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5yZWR1Y2VgLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IHNvcnRlZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDggfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM0IH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCB9LFxuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiAvLyBTb3J0IGJ5IGB1c2VyYCBpbiBhc2NlbmRpbmcgb3JkZXIgYW5kIGJ5IGBhZ2VgIGluIGRlc2NlbmRpbmcgb3JkZXIuXG4gICAgICogXy5vcmRlckJ5KHVzZXJzLCBbJ3VzZXInLCAnYWdlJ10sIFsnYXNjJywgJ2Rlc2MnXSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgW1snYmFybmV5JywgMzZdLCBbJ2Jhcm5leScsIDM0XSwgWydmcmVkJywgNDhdLCBbJ2ZyZWQnLCA0MF1dXG4gICAgICovXG4gICAgZnVuY3Rpb24gb3JkZXJCeShjb2xsZWN0aW9uLCBpdGVyYXRlZXMsIG9yZGVycywgZ3VhcmQpIHtcbiAgICAgIGlmIChjb2xsZWN0aW9uID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgaWYgKCFpc0FycmF5KGl0ZXJhdGVlcykpIHtcbiAgICAgICAgaXRlcmF0ZWVzID0gaXRlcmF0ZWVzID09IG51bGwgPyBbXSA6IFtpdGVyYXRlZXNdO1xuICAgICAgfVxuICAgICAgb3JkZXJzID0gZ3VhcmQgPyB1bmRlZmluZWQgOiBvcmRlcnM7XG4gICAgICBpZiAoIWlzQXJyYXkob3JkZXJzKSkge1xuICAgICAgICBvcmRlcnMgPSBvcmRlcnMgPT0gbnVsbCA/IFtdIDogW29yZGVyc107XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZU9yZGVyQnkoY29sbGVjdGlvbiwgaXRlcmF0ZWVzLCBvcmRlcnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgZWxlbWVudHMgc3BsaXQgaW50byB0d28gZ3JvdXBzLCB0aGUgZmlyc3Qgb2Ygd2hpY2hcbiAgICAgKiBjb250YWlucyBlbGVtZW50cyBgcHJlZGljYXRlYCByZXR1cm5zIHRydXRoeSBmb3IsIHRoZSBzZWNvbmQgb2Ygd2hpY2hcbiAgICAgKiBjb250YWlucyBlbGVtZW50cyBgcHJlZGljYXRlYCByZXR1cm5zIGZhbHNleSBmb3IuIFRoZSBwcmVkaWNhdGUgaXNcbiAgICAgKiBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgZ3JvdXBlZCBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FnZSc6IDM2LCAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IHRydWUgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAncGViYmxlcycsICdhZ2UnOiAxLCAgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5wYXJ0aXRpb24odXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8uYWN0aXZlOyB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbWydmcmVkJ10sIFsnYmFybmV5JywgJ3BlYmJsZXMnXV1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5wYXJ0aXRpb24odXNlcnMsIHsgJ2FnZSc6IDEsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbWydwZWJibGVzJ10sIFsnYmFybmV5JywgJ2ZyZWQnXV1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLnBhcnRpdGlvbih1c2VycywgWydhY3RpdmUnLCBmYWxzZV0pO1xuICAgICAqIC8vID0+IG9iamVjdHMgZm9yIFtbJ2Jhcm5leScsICdwZWJibGVzJ10sIFsnZnJlZCddXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5wYXJ0aXRpb24odXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbWydmcmVkJ10sIFsnYmFybmV5JywgJ3BlYmJsZXMnXV1cbiAgICAgKi9cbiAgICB2YXIgcGFydGl0aW9uID0gY3JlYXRlQWdncmVnYXRvcihmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgIHJlc3VsdFtrZXkgPyAwIDogMV0ucHVzaCh2YWx1ZSk7XG4gICAgfSwgZnVuY3Rpb24oKSB7IHJldHVybiBbW10sIFtdXTsgfSk7XG5cbiAgICAvKipcbiAgICAgKiBSZWR1Y2VzIGBjb2xsZWN0aW9uYCB0byBhIHZhbHVlIHdoaWNoIGlzIHRoZSBhY2N1bXVsYXRlZCByZXN1bHQgb2YgcnVubmluZ1xuICAgICAqIGVhY2ggZWxlbWVudCBpbiBgY29sbGVjdGlvbmAgdGhydSBgaXRlcmF0ZWVgLCB3aGVyZSBlYWNoIHN1Y2Nlc3NpdmVcbiAgICAgKiBpbnZvY2F0aW9uIGlzIHN1cHBsaWVkIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIHByZXZpb3VzLiBJZiBgYWNjdW11bGF0b3JgXG4gICAgICogaXMgbm90IGdpdmVuLCB0aGUgZmlyc3QgZWxlbWVudCBvZiBgY29sbGVjdGlvbmAgaXMgdXNlZCBhcyB0aGUgaW5pdGlhbFxuICAgICAqIHZhbHVlLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIGZvdXIgYXJndW1lbnRzOlxuICAgICAqIChhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gICAgICpcbiAgICAgKiBNYW55IGxvZGFzaCBtZXRob2RzIGFyZSBndWFyZGVkIHRvIHdvcmsgYXMgaXRlcmF0ZWVzIGZvciBtZXRob2RzIGxpa2VcbiAgICAgKiBgXy5yZWR1Y2VgLCBgXy5yZWR1Y2VSaWdodGAsIGFuZCBgXy50cmFuc2Zvcm1gLlxuICAgICAqXG4gICAgICogVGhlIGd1YXJkZWQgbWV0aG9kcyBhcmU6XG4gICAgICogYGFzc2lnbmAsIGBkZWZhdWx0c2AsIGBkZWZhdWx0c0RlZXBgLCBgaW5jbHVkZXNgLCBgbWVyZ2VgLCBgb3JkZXJCeWAsXG4gICAgICogYW5kIGBzb3J0QnlgXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcGFyYW0geyp9IFthY2N1bXVsYXRvcl0gVGhlIGluaXRpYWwgdmFsdWUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHZhbHVlLlxuICAgICAqIEBzZWUgXy5yZWR1Y2VSaWdodFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnJlZHVjZShbMSwgMl0sIGZ1bmN0aW9uKHN1bSwgbikge1xuICAgICAqICAgcmV0dXJuIHN1bSArIG47XG4gICAgICogfSwgMCk7XG4gICAgICogLy8gPT4gM1xuICAgICAqXG4gICAgICogXy5yZWR1Y2UoeyAnYSc6IDEsICdiJzogMiwgJ2MnOiAxIH0sIGZ1bmN0aW9uKHJlc3VsdCwgdmFsdWUsIGtleSkge1xuICAgICAqICAgKHJlc3VsdFt2YWx1ZV0gfHwgKHJlc3VsdFt2YWx1ZV0gPSBbXSkpLnB1c2goa2V5KTtcbiAgICAgKiAgIHJldHVybiByZXN1bHQ7XG4gICAgICogfSwge30pO1xuICAgICAqIC8vID0+IHsgJzEnOiBbJ2EnLCAnYyddLCAnMic6IFsnYiddIH0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZWR1Y2UoY29sbGVjdGlvbiwgaXRlcmF0ZWUsIGFjY3VtdWxhdG9yKSB7XG4gICAgICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheVJlZHVjZSA6IGJhc2VSZWR1Y2UsXG4gICAgICAgICAgaW5pdEFjY3VtID0gYXJndW1lbnRzLmxlbmd0aCA8IDM7XG5cbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCA0KSwgYWNjdW11bGF0b3IsIGluaXRBY2N1bSwgYmFzZUVhY2gpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ucmVkdWNlYCBleGNlcHQgdGhhdCBpdCBpdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mXG4gICAgICogYGNvbGxlY3Rpb25gIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gICAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Kn0gW2FjY3VtdWxhdG9yXSBUaGUgaW5pdGlhbCB2YWx1ZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgYWNjdW11bGF0ZWQgdmFsdWUuXG4gICAgICogQHNlZSBfLnJlZHVjZVxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYXJyYXkgPSBbWzAsIDFdLCBbMiwgM10sIFs0LCA1XV07XG4gICAgICpcbiAgICAgKiBfLnJlZHVjZVJpZ2h0KGFycmF5LCBmdW5jdGlvbihmbGF0dGVuZWQsIG90aGVyKSB7XG4gICAgICogICByZXR1cm4gZmxhdHRlbmVkLmNvbmNhdChvdGhlcik7XG4gICAgICogfSwgW10pO1xuICAgICAqIC8vID0+IFs0LCA1LCAyLCAzLCAwLCAxXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJlZHVjZVJpZ2h0KGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCBhY2N1bXVsYXRvcikge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlSZWR1Y2VSaWdodCA6IGJhc2VSZWR1Y2UsXG4gICAgICAgICAgaW5pdEFjY3VtID0gYXJndW1lbnRzLmxlbmd0aCA8IDM7XG5cbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCA0KSwgYWNjdW11bGF0b3IsIGluaXRBY2N1bSwgYmFzZUVhY2hSaWdodCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLmZpbHRlcmA7IHRoaXMgbWV0aG9kIHJldHVybnMgdGhlIGVsZW1lbnRzIG9mIGBjb2xsZWN0aW9uYFxuICAgICAqIHRoYXQgYHByZWRpY2F0ZWAgZG9lcyAqKm5vdCoqIHJldHVybiB0cnV0aHkgZm9yLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICAgICAqIEBzZWUgXy5maWx0ZXJcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiBmYWxzZSB9LFxuICAgICAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDAsICdhY3RpdmUnOiB0cnVlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5yZWplY3QodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuICFvLmFjdGl2ZTsgfSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJ11cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5yZWplY3QodXNlcnMsIHsgJ2FnZSc6IDQwLCAnYWN0aXZlJzogdHJ1ZSB9KTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5yZWplY3QodXNlcnMsIFsnYWN0aXZlJywgZmFsc2VdKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnXVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5yZWplY3QodXNlcnMsICdhY3RpdmUnKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbJ2Jhcm5leSddXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmVqZWN0KGNvbGxlY3Rpb24sIHByZWRpY2F0ZSkge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlGaWx0ZXIgOiBiYXNlRmlsdGVyO1xuICAgICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgbmVnYXRlKGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMykpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGEgcmFuZG9tIGVsZW1lbnQgZnJvbSBgY29sbGVjdGlvbmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNhbXBsZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmFuZG9tIGVsZW1lbnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc2FtcGxlKFsxLCAyLCAzLCA0XSk7XG4gICAgICogLy8gPT4gMlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNhbXBsZShjb2xsZWN0aW9uKSB7XG4gICAgICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheVNhbXBsZSA6IGJhc2VTYW1wbGU7XG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGBuYCByYW5kb20gZWxlbWVudHMgYXQgdW5pcXVlIGtleXMgZnJvbSBgY29sbGVjdGlvbmAgdXAgdG8gdGhlXG4gICAgICogc2l6ZSBvZiBgY29sbGVjdGlvbmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNhbXBsZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW249MV0gVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byBzYW1wbGUuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHJhbmRvbSBlbGVtZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zYW1wbGVTaXplKFsxLCAyLCAzXSwgMik7XG4gICAgICogLy8gPT4gWzMsIDFdXG4gICAgICpcbiAgICAgKiBfLnNhbXBsZVNpemUoWzEsIDIsIDNdLCA0KTtcbiAgICAgKiAvLyA9PiBbMiwgMywgMV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzYW1wbGVTaXplKGNvbGxlY3Rpb24sIG4sIGd1YXJkKSB7XG4gICAgICBpZiAoKGd1YXJkID8gaXNJdGVyYXRlZUNhbGwoY29sbGVjdGlvbiwgbiwgZ3VhcmQpIDogbiA9PT0gdW5kZWZpbmVkKSkge1xuICAgICAgICBuID0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG4gPSB0b0ludGVnZXIobik7XG4gICAgICB9XG4gICAgICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheVNhbXBsZVNpemUgOiBiYXNlU2FtcGxlU2l6ZTtcbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIG4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2Ygc2h1ZmZsZWQgdmFsdWVzLCB1c2luZyBhIHZlcnNpb24gb2YgdGhlXG4gICAgICogW0Zpc2hlci1ZYXRlcyBzaHVmZmxlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9GaXNoZXItWWF0ZXNfc2h1ZmZsZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNodWZmbGUuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgc2h1ZmZsZWQgYXJyYXkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc2h1ZmZsZShbMSwgMiwgMywgNF0pO1xuICAgICAqIC8vID0+IFs0LCAxLCAzLCAyXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNodWZmbGUoY29sbGVjdGlvbikge1xuICAgICAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlTaHVmZmxlIDogYmFzZVNodWZmbGU7XG4gICAgICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBzaXplIG9mIGBjb2xsZWN0aW9uYCBieSByZXR1cm5pbmcgaXRzIGxlbmd0aCBmb3IgYXJyYXktbGlrZVxuICAgICAqIHZhbHVlcyBvciB0aGUgbnVtYmVyIG9mIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0aWVzIGZvciBvYmplY3RzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBjb2xsZWN0aW9uIHNpemUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc2l6ZShbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8uc2l6ZSh7ICdhJzogMSwgJ2InOiAyIH0pO1xuICAgICAqIC8vID0+IDJcbiAgICAgKlxuICAgICAqIF8uc2l6ZSgncGViYmxlcycpO1xuICAgICAqIC8vID0+IDdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzaXplKGNvbGxlY3Rpb24pIHtcbiAgICAgIGlmIChjb2xsZWN0aW9uID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICBpZiAoaXNBcnJheUxpa2UoY29sbGVjdGlvbikpIHtcbiAgICAgICAgcmV0dXJuIGlzU3RyaW5nKGNvbGxlY3Rpb24pID8gc3RyaW5nU2l6ZShjb2xsZWN0aW9uKSA6IGNvbGxlY3Rpb24ubGVuZ3RoO1xuICAgICAgfVxuICAgICAgdmFyIHRhZyA9IGdldFRhZyhjb2xsZWN0aW9uKTtcbiAgICAgIGlmICh0YWcgPT0gbWFwVGFnIHx8IHRhZyA9PSBzZXRUYWcpIHtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb24uc2l6ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlS2V5cyhjb2xsZWN0aW9uKS5sZW5ndGg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvciAqKmFueSoqIGVsZW1lbnQgb2YgYGNvbGxlY3Rpb25gLlxuICAgICAqIEl0ZXJhdGlvbiBpcyBzdG9wcGVkIG9uY2UgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkuIFRoZSBwcmVkaWNhdGUgaXNcbiAgICAgKiBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICAgICAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW55IGVsZW1lbnQgcGFzc2VzIHRoZSBwcmVkaWNhdGUgY2hlY2ssXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zb21lKFtudWxsLCAwLCAneWVzJywgZmFsc2VdLCBCb29sZWFuKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhY3RpdmUnOiBmYWxzZSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5zb21lKHVzZXJzLCB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uc29tZSh1c2VycywgWydhY3RpdmUnLCBmYWxzZV0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uc29tZSh1c2VycywgJ2FjdGl2ZScpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzb21lKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZ3VhcmQpIHtcbiAgICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5U29tZSA6IGJhc2VTb21lO1xuICAgICAgaWYgKGd1YXJkICYmIGlzSXRlcmF0ZWVDYWxsKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZ3VhcmQpKSB7XG4gICAgICAgIHByZWRpY2F0ZSA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgZWxlbWVudHMsIHNvcnRlZCBpbiBhc2NlbmRpbmcgb3JkZXIgYnkgdGhlIHJlc3VsdHMgb2ZcbiAgICAgKiBydW5uaW5nIGVhY2ggZWxlbWVudCBpbiBhIGNvbGxlY3Rpb24gdGhydSBlYWNoIGl0ZXJhdGVlLiBUaGlzIG1ldGhvZFxuICAgICAqIHBlcmZvcm1zIGEgc3RhYmxlIHNvcnQsIHRoYXQgaXMsIGl0IHByZXNlcnZlcyB0aGUgb3JpZ2luYWwgc29ydCBvcmRlciBvZlxuICAgICAqIGVxdWFsIGVsZW1lbnRzLiBUaGUgaXRlcmF0ZWVzIGFyZSBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHsuLi4oRnVuY3Rpb258RnVuY3Rpb25bXSl9IFtpdGVyYXRlZXM9W18uaWRlbnRpdHldXVxuICAgICAqICBUaGUgaXRlcmF0ZWVzIHRvIHNvcnQgYnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgc29ydGVkIGFycmF5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSBbXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0OCB9LFxuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYgfSxcbiAgICAgKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgJ2FnZSc6IDQwIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNCB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8uc29ydEJ5KHVzZXJzLCBbZnVuY3Rpb24obykgeyByZXR1cm4gby51c2VyOyB9XSk7XG4gICAgICogLy8gPT4gb2JqZWN0cyBmb3IgW1snYmFybmV5JywgMzZdLCBbJ2Jhcm5leScsIDM0XSwgWydmcmVkJywgNDhdLCBbJ2ZyZWQnLCA0MF1dXG4gICAgICpcbiAgICAgKiBfLnNvcnRCeSh1c2VycywgWyd1c2VyJywgJ2FnZSddKTtcbiAgICAgKiAvLyA9PiBvYmplY3RzIGZvciBbWydiYXJuZXknLCAzNF0sIFsnYmFybmV5JywgMzZdLCBbJ2ZyZWQnLCA0MF0sIFsnZnJlZCcsIDQ4XV1cbiAgICAgKi9cbiAgICB2YXIgc29ydEJ5ID0gYmFzZVJlc3QoZnVuY3Rpb24oY29sbGVjdGlvbiwgaXRlcmF0ZWVzKSB7XG4gICAgICBpZiAoY29sbGVjdGlvbiA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIHZhciBsZW5ndGggPSBpdGVyYXRlZXMubGVuZ3RoO1xuICAgICAgaWYgKGxlbmd0aCA+IDEgJiYgaXNJdGVyYXRlZUNhbGwoY29sbGVjdGlvbiwgaXRlcmF0ZWVzWzBdLCBpdGVyYXRlZXNbMV0pKSB7XG4gICAgICAgIGl0ZXJhdGVlcyA9IFtdO1xuICAgICAgfSBlbHNlIGlmIChsZW5ndGggPiAyICYmIGlzSXRlcmF0ZWVDYWxsKGl0ZXJhdGVlc1swXSwgaXRlcmF0ZWVzWzFdLCBpdGVyYXRlZXNbMl0pKSB7XG4gICAgICAgIGl0ZXJhdGVlcyA9IFtpdGVyYXRlZXNbMF1dO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJhc2VPcmRlckJ5KGNvbGxlY3Rpb24sIGJhc2VGbGF0dGVuKGl0ZXJhdGVlcywgMSksIFtdKTtcbiAgICB9KTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHRpbWVzdGFtcCBvZiB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0aGF0IGhhdmUgZWxhcHNlZCBzaW5jZVxuICAgICAqIHRoZSBVbml4IGVwb2NoICgxIEphbnVhcnkgMTk3MCAwMDowMDowMCBVVEMpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuNC4wXG4gICAgICogQGNhdGVnb3J5IERhdGVcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSB0aW1lc3RhbXAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZGVmZXIoZnVuY3Rpb24oc3RhbXApIHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKF8ubm93KCkgLSBzdGFtcCk7XG4gICAgICogfSwgXy5ub3coKSk7XG4gICAgICogLy8gPT4gTG9ncyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBpdCB0b29rIGZvciB0aGUgZGVmZXJyZWQgaW52b2NhdGlvbi5cbiAgICAgKi9cbiAgICB2YXIgbm93ID0gY3R4Tm93IHx8IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHJvb3QuRGF0ZS5ub3coKTtcbiAgICB9O1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLmJlZm9yZWA7IHRoaXMgbWV0aG9kIGNyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXNcbiAgICAgKiBgZnVuY2Agb25jZSBpdCdzIGNhbGxlZCBgbmAgb3IgbW9yZSB0aW1lcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgY2FsbHMgYmVmb3JlIGBmdW5jYCBpcyBpbnZva2VkLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJlc3RyaWN0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHJlc3RyaWN0ZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBzYXZlcyA9IFsncHJvZmlsZScsICdzZXR0aW5ncyddO1xuICAgICAqXG4gICAgICogdmFyIGRvbmUgPSBfLmFmdGVyKHNhdmVzLmxlbmd0aCwgZnVuY3Rpb24oKSB7XG4gICAgICogICBjb25zb2xlLmxvZygnZG9uZSBzYXZpbmchJyk7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBfLmZvckVhY2goc2F2ZXMsIGZ1bmN0aW9uKHR5cGUpIHtcbiAgICAgKiAgIGFzeW5jU2F2ZSh7ICd0eXBlJzogdHlwZSwgJ2NvbXBsZXRlJzogZG9uZSB9KTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiBMb2dzICdkb25lIHNhdmluZyEnIGFmdGVyIHRoZSB0d28gYXN5bmMgc2F2ZXMgaGF2ZSBjb21wbGV0ZWQuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYWZ0ZXIobiwgZnVuYykge1xuICAgICAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgbiA9IHRvSW50ZWdlcihuKTtcbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKC0tbiA8IDEpIHtcbiAgICAgICAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgLCB3aXRoIHVwIHRvIGBuYCBhcmd1bWVudHMsXG4gICAgICogaWdub3JpbmcgYW55IGFkZGl0aW9uYWwgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY2FwIGFyZ3VtZW50cyBmb3IuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtuPWZ1bmMubGVuZ3RoXSBUaGUgYXJpdHkgY2FwLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY2FwcGVkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLm1hcChbJzYnLCAnOCcsICcxMCddLCBfLmFyeShwYXJzZUludCwgMSkpO1xuICAgICAqIC8vID0+IFs2LCA4LCAxMF1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhcnkoZnVuYywgbiwgZ3VhcmQpIHtcbiAgICAgIG4gPSBndWFyZCA/IHVuZGVmaW5lZCA6IG47XG4gICAgICBuID0gKGZ1bmMgJiYgbiA9PSBudWxsKSA/IGZ1bmMubGVuZ3RoIDogbjtcbiAgICAgIHJldHVybiBjcmVhdGVXcmFwKGZ1bmMsIFdSQVBfQVJZX0ZMQUcsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2AsIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIGFuZCBhcmd1bWVudHNcbiAgICAgKiBvZiB0aGUgY3JlYXRlZCBmdW5jdGlvbiwgd2hpbGUgaXQncyBjYWxsZWQgbGVzcyB0aGFuIGBuYCB0aW1lcy4gU3Vic2VxdWVudFxuICAgICAqIGNhbGxzIHRvIHRoZSBjcmVhdGVkIGZ1bmN0aW9uIHJldHVybiB0aGUgcmVzdWx0IG9mIHRoZSBsYXN0IGBmdW5jYCBpbnZvY2F0aW9uLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiBjYWxscyBhdCB3aGljaCBgZnVuY2AgaXMgbm8gbG9uZ2VyIGludm9rZWQuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcmVzdHJpY3QuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgcmVzdHJpY3RlZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogalF1ZXJ5KGVsZW1lbnQpLm9uKCdjbGljaycsIF8uYmVmb3JlKDUsIGFkZENvbnRhY3RUb0xpc3QpKTtcbiAgICAgKiAvLyA9PiBBbGxvd3MgYWRkaW5nIHVwIHRvIDQgY29udGFjdHMgdG8gdGhlIGxpc3QuXG4gICAgICovXG4gICAgZnVuY3Rpb24gYmVmb3JlKG4sIGZ1bmMpIHtcbiAgICAgIHZhciByZXN1bHQ7XG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICBuID0gdG9JbnRlZ2VyKG4pO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAoLS1uID4gMCkge1xuICAgICAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobiA8PSAxKSB7XG4gICAgICAgICAgZnVuYyA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiBgdGhpc0FyZ2BcbiAgICAgKiBhbmQgYHBhcnRpYWxzYCBwcmVwZW5kZWQgdG8gdGhlIGFyZ3VtZW50cyBpdCByZWNlaXZlcy5cbiAgICAgKlxuICAgICAqIFRoZSBgXy5iaW5kLnBsYWNlaG9sZGVyYCB2YWx1ZSwgd2hpY2ggZGVmYXVsdHMgdG8gYF9gIGluIG1vbm9saXRoaWMgYnVpbGRzLFxuICAgICAqIG1heSBiZSB1c2VkIGFzIGEgcGxhY2Vob2xkZXIgZm9yIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBVbmxpa2UgbmF0aXZlIGBGdW5jdGlvbiNiaW5kYCwgdGhpcyBtZXRob2QgZG9lc24ndCBzZXQgdGhlIFwibGVuZ3RoXCJcbiAgICAgKiBwcm9wZXJ0eSBvZiBib3VuZCBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBiaW5kLlxuICAgICAqIEBwYXJhbSB7Kn0gdGhpc0FyZyBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJvdW5kIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBncmVldChncmVldGluZywgcHVuY3R1YXRpb24pIHtcbiAgICAgKiAgIHJldHVybiBncmVldGluZyArICcgJyArIHRoaXMudXNlciArIHB1bmN0dWF0aW9uO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICd1c2VyJzogJ2ZyZWQnIH07XG4gICAgICpcbiAgICAgKiB2YXIgYm91bmQgPSBfLmJpbmQoZ3JlZXQsIG9iamVjdCwgJ2hpJyk7XG4gICAgICogYm91bmQoJyEnKTtcbiAgICAgKiAvLyA9PiAnaGkgZnJlZCEnXG4gICAgICpcbiAgICAgKiAvLyBCb3VuZCB3aXRoIHBsYWNlaG9sZGVycy5cbiAgICAgKiB2YXIgYm91bmQgPSBfLmJpbmQoZ3JlZXQsIG9iamVjdCwgXywgJyEnKTtcbiAgICAgKiBib3VuZCgnaGknKTtcbiAgICAgKiAvLyA9PiAnaGkgZnJlZCEnXG4gICAgICovXG4gICAgdmFyIGJpbmQgPSBiYXNlUmVzdChmdW5jdGlvbihmdW5jLCB0aGlzQXJnLCBwYXJ0aWFscykge1xuICAgICAgdmFyIGJpdG1hc2sgPSBXUkFQX0JJTkRfRkxBRztcbiAgICAgIGlmIChwYXJ0aWFscy5sZW5ndGgpIHtcbiAgICAgICAgdmFyIGhvbGRlcnMgPSByZXBsYWNlSG9sZGVycyhwYXJ0aWFscywgZ2V0SG9sZGVyKGJpbmQpKTtcbiAgICAgICAgYml0bWFzayB8PSBXUkFQX1BBUlRJQUxfRkxBRztcbiAgICAgIH1cbiAgICAgIHJldHVybiBjcmVhdGVXcmFwKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgdGhlIG1ldGhvZCBhdCBgb2JqZWN0W2tleV1gIHdpdGggYHBhcnRpYWxzYFxuICAgICAqIHByZXBlbmRlZCB0byB0aGUgYXJndW1lbnRzIGl0IHJlY2VpdmVzLlxuICAgICAqXG4gICAgICogVGhpcyBtZXRob2QgZGlmZmVycyBmcm9tIGBfLmJpbmRgIGJ5IGFsbG93aW5nIGJvdW5kIGZ1bmN0aW9ucyB0byByZWZlcmVuY2VcbiAgICAgKiBtZXRob2RzIHRoYXQgbWF5IGJlIHJlZGVmaW5lZCBvciBkb24ndCB5ZXQgZXhpc3QuIFNlZVxuICAgICAqIFtQZXRlciBNaWNoYXV4J3MgYXJ0aWNsZV0oaHR0cDovL3BldGVyLm1pY2hhdXguY2EvYXJ0aWNsZXMvbGF6eS1mdW5jdGlvbi1kZWZpbml0aW9uLXBhdHRlcm4pXG4gICAgICogZm9yIG1vcmUgZGV0YWlscy5cbiAgICAgKlxuICAgICAqIFRoZSBgXy5iaW5kS2V5LnBsYWNlaG9sZGVyYCB2YWx1ZSwgd2hpY2ggZGVmYXVsdHMgdG8gYF9gIGluIG1vbm9saXRoaWNcbiAgICAgKiBidWlsZHMsIG1heSBiZSB1c2VkIGFzIGEgcGxhY2Vob2xkZXIgZm9yIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEwLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW52b2tlIHRoZSBtZXRob2Qgb24uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBtZXRob2QuXG4gICAgICogQHBhcmFtIHsuLi4qfSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gYmUgcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7XG4gICAgICogICAndXNlcic6ICdmcmVkJyxcbiAgICAgKiAgICdncmVldCc6IGZ1bmN0aW9uKGdyZWV0aW5nLCBwdW5jdHVhdGlvbikge1xuICAgICAqICAgICByZXR1cm4gZ3JlZXRpbmcgKyAnICcgKyB0aGlzLnVzZXIgKyBwdW5jdHVhdGlvbjtcbiAgICAgKiAgIH1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogdmFyIGJvdW5kID0gXy5iaW5kS2V5KG9iamVjdCwgJ2dyZWV0JywgJ2hpJyk7XG4gICAgICogYm91bmQoJyEnKTtcbiAgICAgKiAvLyA9PiAnaGkgZnJlZCEnXG4gICAgICpcbiAgICAgKiBvYmplY3QuZ3JlZXQgPSBmdW5jdGlvbihncmVldGluZywgcHVuY3R1YXRpb24pIHtcbiAgICAgKiAgIHJldHVybiBncmVldGluZyArICd5YSAnICsgdGhpcy51c2VyICsgcHVuY3R1YXRpb247XG4gICAgICogfTtcbiAgICAgKlxuICAgICAqIGJvdW5kKCchJyk7XG4gICAgICogLy8gPT4gJ2hpeWEgZnJlZCEnXG4gICAgICpcbiAgICAgKiAvLyBCb3VuZCB3aXRoIHBsYWNlaG9sZGVycy5cbiAgICAgKiB2YXIgYm91bmQgPSBfLmJpbmRLZXkob2JqZWN0LCAnZ3JlZXQnLCBfLCAnIScpO1xuICAgICAqIGJvdW5kKCdoaScpO1xuICAgICAqIC8vID0+ICdoaXlhIGZyZWQhJ1xuICAgICAqL1xuICAgIHZhciBiaW5kS2V5ID0gYmFzZVJlc3QoZnVuY3Rpb24ob2JqZWN0LCBrZXksIHBhcnRpYWxzKSB7XG4gICAgICB2YXIgYml0bWFzayA9IFdSQVBfQklORF9GTEFHIHwgV1JBUF9CSU5EX0tFWV9GTEFHO1xuICAgICAgaWYgKHBhcnRpYWxzLmxlbmd0aCkge1xuICAgICAgICB2YXIgaG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKHBhcnRpYWxzLCBnZXRIb2xkZXIoYmluZEtleSkpO1xuICAgICAgICBiaXRtYXNrIHw9IFdSQVBfUEFSVElBTF9GTEFHO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNyZWF0ZVdyYXAoa2V5LCBiaXRtYXNrLCBvYmplY3QsIHBhcnRpYWxzLCBob2xkZXJzKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGFjY2VwdHMgYXJndW1lbnRzIG9mIGBmdW5jYCBhbmQgZWl0aGVyIGludm9rZXNcbiAgICAgKiBgZnVuY2AgcmV0dXJuaW5nIGl0cyByZXN1bHQsIGlmIGF0IGxlYXN0IGBhcml0eWAgbnVtYmVyIG9mIGFyZ3VtZW50cyBoYXZlXG4gICAgICogYmVlbiBwcm92aWRlZCwgb3IgcmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgYWNjZXB0cyB0aGUgcmVtYWluaW5nIGBmdW5jYFxuICAgICAqIGFyZ3VtZW50cywgYW5kIHNvIG9uLiBUaGUgYXJpdHkgb2YgYGZ1bmNgIG1heSBiZSBzcGVjaWZpZWQgaWYgYGZ1bmMubGVuZ3RoYFxuICAgICAqIGlzIG5vdCBzdWZmaWNpZW50LlxuICAgICAqXG4gICAgICogVGhlIGBfLmN1cnJ5LnBsYWNlaG9sZGVyYCB2YWx1ZSwgd2hpY2ggZGVmYXVsdHMgdG8gYF9gIGluIG1vbm9saXRoaWMgYnVpbGRzLFxuICAgICAqIG1heSBiZSB1c2VkIGFzIGEgcGxhY2Vob2xkZXIgZm9yIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBkb2Vzbid0IHNldCB0aGUgXCJsZW5ndGhcIiBwcm9wZXJ0eSBvZiBjdXJyaWVkIGZ1bmN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjAuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGN1cnJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJpdHk9ZnVuYy5sZW5ndGhdIFRoZSBhcml0eSBvZiBgZnVuY2AuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjdXJyaWVkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgYWJjID0gZnVuY3Rpb24oYSwgYiwgYykge1xuICAgICAqICAgcmV0dXJuIFthLCBiLCBjXTtcbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogdmFyIGN1cnJpZWQgPSBfLmN1cnJ5KGFiYyk7XG4gICAgICpcbiAgICAgKiBjdXJyaWVkKDEpKDIpKDMpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqXG4gICAgICogY3VycmllZCgxLCAyKSgzKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKlxuICAgICAqIGN1cnJpZWQoMSwgMiwgMyk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiAvLyBDdXJyaWVkIHdpdGggcGxhY2Vob2xkZXJzLlxuICAgICAqIGN1cnJpZWQoMSkoXywgMykoMik7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICovXG4gICAgZnVuY3Rpb24gY3VycnkoZnVuYywgYXJpdHksIGd1YXJkKSB7XG4gICAgICBhcml0eSA9IGd1YXJkID8gdW5kZWZpbmVkIDogYXJpdHk7XG4gICAgICB2YXIgcmVzdWx0ID0gY3JlYXRlV3JhcChmdW5jLCBXUkFQX0NVUlJZX0ZMQUcsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBhcml0eSk7XG4gICAgICByZXN1bHQucGxhY2Vob2xkZXIgPSBjdXJyeS5wbGFjZWhvbGRlcjtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5jdXJyeWAgZXhjZXB0IHRoYXQgYXJndW1lbnRzIGFyZSBhcHBsaWVkIHRvIGBmdW5jYFxuICAgICAqIGluIHRoZSBtYW5uZXIgb2YgYF8ucGFydGlhbFJpZ2h0YCBpbnN0ZWFkIG9mIGBfLnBhcnRpYWxgLlxuICAgICAqXG4gICAgICogVGhlIGBfLmN1cnJ5UmlnaHQucGxhY2Vob2xkZXJgIHZhbHVlLCB3aGljaCBkZWZhdWx0cyB0byBgX2AgaW4gbW9ub2xpdGhpY1xuICAgICAqIGJ1aWxkcywgbWF5IGJlIHVzZWQgYXMgYSBwbGFjZWhvbGRlciBmb3IgcHJvdmlkZWQgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGRvZXNuJ3Qgc2V0IHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IG9mIGN1cnJpZWQgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY3VycnkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFthcml0eT1mdW5jLmxlbmd0aF0gVGhlIGFyaXR5IG9mIGBmdW5jYC5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGN1cnJpZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBhYmMgPSBmdW5jdGlvbihhLCBiLCBjKSB7XG4gICAgICogICByZXR1cm4gW2EsIGIsIGNdO1xuICAgICAqIH07XG4gICAgICpcbiAgICAgKiB2YXIgY3VycmllZCA9IF8uY3VycnlSaWdodChhYmMpO1xuICAgICAqXG4gICAgICogY3VycmllZCgzKSgyKSgxKTtcbiAgICAgKiAvLyA9PiBbMSwgMiwgM11cbiAgICAgKlxuICAgICAqIGN1cnJpZWQoMiwgMykoMSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdXG4gICAgICpcbiAgICAgKiBjdXJyaWVkKDEsIDIsIDMpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqXG4gICAgICogLy8gQ3VycmllZCB3aXRoIHBsYWNlaG9sZGVycy5cbiAgICAgKiBjdXJyaWVkKDMpKDEsIF8pKDIpO1xuICAgICAqIC8vID0+IFsxLCAyLCAzXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGN1cnJ5UmlnaHQoZnVuYywgYXJpdHksIGd1YXJkKSB7XG4gICAgICBhcml0eSA9IGd1YXJkID8gdW5kZWZpbmVkIDogYXJpdHk7XG4gICAgICB2YXIgcmVzdWx0ID0gY3JlYXRlV3JhcChmdW5jLCBXUkFQX0NVUlJZX1JJR0hUX0ZMQUcsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBhcml0eSk7XG4gICAgICByZXN1bHQucGxhY2Vob2xkZXIgPSBjdXJyeVJpZ2h0LnBsYWNlaG9sZGVyO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZGVib3VuY2VkIGZ1bmN0aW9uIHRoYXQgZGVsYXlzIGludm9raW5nIGBmdW5jYCB1bnRpbCBhZnRlciBgd2FpdGBcbiAgICAgKiBtaWxsaXNlY29uZHMgaGF2ZSBlbGFwc2VkIHNpbmNlIHRoZSBsYXN0IHRpbWUgdGhlIGRlYm91bmNlZCBmdW5jdGlvbiB3YXNcbiAgICAgKiBpbnZva2VkLiBUaGUgZGVib3VuY2VkIGZ1bmN0aW9uIGNvbWVzIHdpdGggYSBgY2FuY2VsYCBtZXRob2QgdG8gY2FuY2VsXG4gICAgICogZGVsYXllZCBgZnVuY2AgaW52b2NhdGlvbnMgYW5kIGEgYGZsdXNoYCBtZXRob2QgdG8gaW1tZWRpYXRlbHkgaW52b2tlIHRoZW0uXG4gICAgICogUHJvdmlkZSBgb3B0aW9uc2AgdG8gaW5kaWNhdGUgd2hldGhlciBgZnVuY2Agc2hvdWxkIGJlIGludm9rZWQgb24gdGhlXG4gICAgICogbGVhZGluZyBhbmQvb3IgdHJhaWxpbmcgZWRnZSBvZiB0aGUgYHdhaXRgIHRpbWVvdXQuIFRoZSBgZnVuY2AgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdGhlIGxhc3QgYXJndW1lbnRzIHByb3ZpZGVkIHRvIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb24uIFN1YnNlcXVlbnRcbiAgICAgKiBjYWxscyB0byB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uIHJldHVybiB0aGUgcmVzdWx0IG9mIHRoZSBsYXN0IGBmdW5jYFxuICAgICAqIGludm9jYXRpb24uXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogSWYgYGxlYWRpbmdgIGFuZCBgdHJhaWxpbmdgIG9wdGlvbnMgYXJlIGB0cnVlYCwgYGZ1bmNgIGlzXG4gICAgICogaW52b2tlZCBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dCBvbmx5IGlmIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb25cbiAgICAgKiBpcyBpbnZva2VkIG1vcmUgdGhhbiBvbmNlIGR1cmluZyB0aGUgYHdhaXRgIHRpbWVvdXQuXG4gICAgICpcbiAgICAgKiBJZiBgd2FpdGAgaXMgYDBgIGFuZCBgbGVhZGluZ2AgaXMgYGZhbHNlYCwgYGZ1bmNgIGludm9jYXRpb24gaXMgZGVmZXJyZWRcbiAgICAgKiB1bnRpbCB0byB0aGUgbmV4dCB0aWNrLCBzaW1pbGFyIHRvIGBzZXRUaW1lb3V0YCB3aXRoIGEgdGltZW91dCBvZiBgMGAuXG4gICAgICpcbiAgICAgKiBTZWUgW0RhdmlkIENvcmJhY2hvJ3MgYXJ0aWNsZV0oaHR0cHM6Ly9jc3MtdHJpY2tzLmNvbS9kZWJvdW5jaW5nLXRocm90dGxpbmctZXhwbGFpbmVkLWV4YW1wbGVzLylcbiAgICAgKiBmb3IgZGV0YWlscyBvdmVyIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIGBfLmRlYm91bmNlYCBhbmQgYF8udGhyb3R0bGVgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gZGVib3VuY2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFt3YWl0PTBdIFRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIGRlbGF5LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucz17fV0gVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMubGVhZGluZz1mYWxzZV1cbiAgICAgKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgbGVhZGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5tYXhXYWl0XVxuICAgICAqICBUaGUgbWF4aW11bSB0aW1lIGBmdW5jYCBpcyBhbGxvd2VkIHRvIGJlIGRlbGF5ZWQgYmVmb3JlIGl0J3MgaW52b2tlZC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnRyYWlsaW5nPXRydWVdXG4gICAgICogIFNwZWNpZnkgaW52b2tpbmcgb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZGVib3VuY2VkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiAvLyBBdm9pZCBjb3N0bHkgY2FsY3VsYXRpb25zIHdoaWxlIHRoZSB3aW5kb3cgc2l6ZSBpcyBpbiBmbHV4LlxuICAgICAqIGpRdWVyeSh3aW5kb3cpLm9uKCdyZXNpemUnLCBfLmRlYm91bmNlKGNhbGN1bGF0ZUxheW91dCwgMTUwKSk7XG4gICAgICpcbiAgICAgKiAvLyBJbnZva2UgYHNlbmRNYWlsYCB3aGVuIGNsaWNrZWQsIGRlYm91bmNpbmcgc3Vic2VxdWVudCBjYWxscy5cbiAgICAgKiBqUXVlcnkoZWxlbWVudCkub24oJ2NsaWNrJywgXy5kZWJvdW5jZShzZW5kTWFpbCwgMzAwLCB7XG4gICAgICogICAnbGVhZGluZyc6IHRydWUsXG4gICAgICogICAndHJhaWxpbmcnOiBmYWxzZVxuICAgICAqIH0pKTtcbiAgICAgKlxuICAgICAqIC8vIEVuc3VyZSBgYmF0Y2hMb2dgIGlzIGludm9rZWQgb25jZSBhZnRlciAxIHNlY29uZCBvZiBkZWJvdW5jZWQgY2FsbHMuXG4gICAgICogdmFyIGRlYm91bmNlZCA9IF8uZGVib3VuY2UoYmF0Y2hMb2csIDI1MCwgeyAnbWF4V2FpdCc6IDEwMDAgfSk7XG4gICAgICogdmFyIHNvdXJjZSA9IG5ldyBFdmVudFNvdXJjZSgnL3N0cmVhbScpO1xuICAgICAqIGpRdWVyeShzb3VyY2UpLm9uKCdtZXNzYWdlJywgZGVib3VuY2VkKTtcbiAgICAgKlxuICAgICAqIC8vIENhbmNlbCB0aGUgdHJhaWxpbmcgZGVib3VuY2VkIGludm9jYXRpb24uXG4gICAgICogalF1ZXJ5KHdpbmRvdykub24oJ3BvcHN0YXRlJywgZGVib3VuY2VkLmNhbmNlbCk7XG4gICAgICovXG4gICAgZnVuY3Rpb24gZGVib3VuY2UoZnVuYywgd2FpdCwgb3B0aW9ucykge1xuICAgICAgdmFyIGxhc3RBcmdzLFxuICAgICAgICAgIGxhc3RUaGlzLFxuICAgICAgICAgIG1heFdhaXQsXG4gICAgICAgICAgcmVzdWx0LFxuICAgICAgICAgIHRpbWVySWQsXG4gICAgICAgICAgbGFzdENhbGxUaW1lLFxuICAgICAgICAgIGxhc3RJbnZva2VUaW1lID0gMCxcbiAgICAgICAgICBsZWFkaW5nID0gZmFsc2UsXG4gICAgICAgICAgbWF4aW5nID0gZmFsc2UsXG4gICAgICAgICAgdHJhaWxpbmcgPSB0cnVlO1xuXG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICB3YWl0ID0gdG9OdW1iZXIod2FpdCkgfHwgMDtcbiAgICAgIGlmIChpc09iamVjdChvcHRpb25zKSkge1xuICAgICAgICBsZWFkaW5nID0gISFvcHRpb25zLmxlYWRpbmc7XG4gICAgICAgIG1heGluZyA9ICdtYXhXYWl0JyBpbiBvcHRpb25zO1xuICAgICAgICBtYXhXYWl0ID0gbWF4aW5nID8gbmF0aXZlTWF4KHRvTnVtYmVyKG9wdGlvbnMubWF4V2FpdCkgfHwgMCwgd2FpdCkgOiBtYXhXYWl0O1xuICAgICAgICB0cmFpbGluZyA9ICd0cmFpbGluZycgaW4gb3B0aW9ucyA/ICEhb3B0aW9ucy50cmFpbGluZyA6IHRyYWlsaW5nO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBpbnZva2VGdW5jKHRpbWUpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBsYXN0QXJncyxcbiAgICAgICAgICAgIHRoaXNBcmcgPSBsYXN0VGhpcztcblxuICAgICAgICBsYXN0QXJncyA9IGxhc3RUaGlzID0gdW5kZWZpbmVkO1xuICAgICAgICBsYXN0SW52b2tlVGltZSA9IHRpbWU7XG4gICAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkodGhpc0FyZywgYXJncyk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGxlYWRpbmdFZGdlKHRpbWUpIHtcbiAgICAgICAgLy8gUmVzZXQgYW55IGBtYXhXYWl0YCB0aW1lci5cbiAgICAgICAgbGFzdEludm9rZVRpbWUgPSB0aW1lO1xuICAgICAgICAvLyBTdGFydCB0aGUgdGltZXIgZm9yIHRoZSB0cmFpbGluZyBlZGdlLlxuICAgICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHdhaXQpO1xuICAgICAgICAvLyBJbnZva2UgdGhlIGxlYWRpbmcgZWRnZS5cbiAgICAgICAgcmV0dXJuIGxlYWRpbmcgPyBpbnZva2VGdW5jKHRpbWUpIDogcmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiByZW1haW5pbmdXYWl0KHRpbWUpIHtcbiAgICAgICAgdmFyIHRpbWVTaW5jZUxhc3RDYWxsID0gdGltZSAtIGxhc3RDYWxsVGltZSxcbiAgICAgICAgICAgIHRpbWVTaW5jZUxhc3RJbnZva2UgPSB0aW1lIC0gbGFzdEludm9rZVRpbWUsXG4gICAgICAgICAgICB0aW1lV2FpdGluZyA9IHdhaXQgLSB0aW1lU2luY2VMYXN0Q2FsbDtcblxuICAgICAgICByZXR1cm4gbWF4aW5nXG4gICAgICAgICAgPyBuYXRpdmVNaW4odGltZVdhaXRpbmcsIG1heFdhaXQgLSB0aW1lU2luY2VMYXN0SW52b2tlKVxuICAgICAgICAgIDogdGltZVdhaXRpbmc7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIHNob3VsZEludm9rZSh0aW1lKSB7XG4gICAgICAgIHZhciB0aW1lU2luY2VMYXN0Q2FsbCA9IHRpbWUgLSBsYXN0Q2FsbFRpbWUsXG4gICAgICAgICAgICB0aW1lU2luY2VMYXN0SW52b2tlID0gdGltZSAtIGxhc3RJbnZva2VUaW1lO1xuXG4gICAgICAgIC8vIEVpdGhlciB0aGlzIGlzIHRoZSBmaXJzdCBjYWxsLCBhY3Rpdml0eSBoYXMgc3RvcHBlZCBhbmQgd2UncmUgYXQgdGhlXG4gICAgICAgIC8vIHRyYWlsaW5nIGVkZ2UsIHRoZSBzeXN0ZW0gdGltZSBoYXMgZ29uZSBiYWNrd2FyZHMgYW5kIHdlJ3JlIHRyZWF0aW5nXG4gICAgICAgIC8vIGl0IGFzIHRoZSB0cmFpbGluZyBlZGdlLCBvciB3ZSd2ZSBoaXQgdGhlIGBtYXhXYWl0YCBsaW1pdC5cbiAgICAgICAgcmV0dXJuIChsYXN0Q2FsbFRpbWUgPT09IHVuZGVmaW5lZCB8fCAodGltZVNpbmNlTGFzdENhbGwgPj0gd2FpdCkgfHxcbiAgICAgICAgICAodGltZVNpbmNlTGFzdENhbGwgPCAwKSB8fCAobWF4aW5nICYmIHRpbWVTaW5jZUxhc3RJbnZva2UgPj0gbWF4V2FpdCkpO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiB0aW1lckV4cGlyZWQoKSB7XG4gICAgICAgIHZhciB0aW1lID0gbm93KCk7XG4gICAgICAgIGlmIChzaG91bGRJbnZva2UodGltZSkpIHtcbiAgICAgICAgICByZXR1cm4gdHJhaWxpbmdFZGdlKHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJlc3RhcnQgdGhlIHRpbWVyLlxuICAgICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHJlbWFpbmluZ1dhaXQodGltZSkpO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiB0cmFpbGluZ0VkZ2UodGltZSkge1xuICAgICAgICB0aW1lcklkID0gdW5kZWZpbmVkO1xuXG4gICAgICAgIC8vIE9ubHkgaW52b2tlIGlmIHdlIGhhdmUgYGxhc3RBcmdzYCB3aGljaCBtZWFucyBgZnVuY2AgaGFzIGJlZW5cbiAgICAgICAgLy8gZGVib3VuY2VkIGF0IGxlYXN0IG9uY2UuXG4gICAgICAgIGlmICh0cmFpbGluZyAmJiBsYXN0QXJncykge1xuICAgICAgICAgIHJldHVybiBpbnZva2VGdW5jKHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGxhc3RBcmdzID0gbGFzdFRoaXMgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGNhbmNlbCgpIHtcbiAgICAgICAgaWYgKHRpbWVySWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lcklkKTtcbiAgICAgICAgfVxuICAgICAgICBsYXN0SW52b2tlVGltZSA9IDA7XG4gICAgICAgIGxhc3RBcmdzID0gbGFzdENhbGxUaW1lID0gbGFzdFRoaXMgPSB0aW1lcklkID0gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBmbHVzaCgpIHtcbiAgICAgICAgcmV0dXJuIHRpbWVySWQgPT09IHVuZGVmaW5lZCA/IHJlc3VsdCA6IHRyYWlsaW5nRWRnZShub3coKSk7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGRlYm91bmNlZCgpIHtcbiAgICAgICAgdmFyIHRpbWUgPSBub3coKSxcbiAgICAgICAgICAgIGlzSW52b2tpbmcgPSBzaG91bGRJbnZva2UodGltZSk7XG5cbiAgICAgICAgbGFzdEFyZ3MgPSBhcmd1bWVudHM7XG4gICAgICAgIGxhc3RUaGlzID0gdGhpcztcbiAgICAgICAgbGFzdENhbGxUaW1lID0gdGltZTtcblxuICAgICAgICBpZiAoaXNJbnZva2luZykge1xuICAgICAgICAgIGlmICh0aW1lcklkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBsZWFkaW5nRWRnZShsYXN0Q2FsbFRpbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAobWF4aW5nKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgaW52b2NhdGlvbnMgaW4gYSB0aWdodCBsb29wLlxuICAgICAgICAgICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCB3YWl0KTtcbiAgICAgICAgICAgIHJldHVybiBpbnZva2VGdW5jKGxhc3RDYWxsVGltZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aW1lcklkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHdhaXQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgICBkZWJvdW5jZWQuY2FuY2VsID0gY2FuY2VsO1xuICAgICAgZGVib3VuY2VkLmZsdXNoID0gZmx1c2g7XG4gICAgICByZXR1cm4gZGVib3VuY2VkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlZmVycyBpbnZva2luZyB0aGUgYGZ1bmNgIHVudGlsIHRoZSBjdXJyZW50IGNhbGwgc3RhY2sgaGFzIGNsZWFyZWQuIEFueVxuICAgICAqIGFkZGl0aW9uYWwgYXJndW1lbnRzIGFyZSBwcm92aWRlZCB0byBgZnVuY2Agd2hlbiBpdCdzIGludm9rZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBkZWZlci5cbiAgICAgKiBAcGFyYW0gey4uLip9IFthcmdzXSBUaGUgYXJndW1lbnRzIHRvIGludm9rZSBgZnVuY2Agd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSB0aW1lciBpZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWZlcihmdW5jdGlvbih0ZXh0KSB7XG4gICAgICogICBjb25zb2xlLmxvZyh0ZXh0KTtcbiAgICAgKiB9LCAnZGVmZXJyZWQnKTtcbiAgICAgKiAvLyA9PiBMb2dzICdkZWZlcnJlZCcgYWZ0ZXIgb25lIG1pbGxpc2Vjb25kLlxuICAgICAqL1xuICAgIHZhciBkZWZlciA9IGJhc2VSZXN0KGZ1bmN0aW9uKGZ1bmMsIGFyZ3MpIHtcbiAgICAgIHJldHVybiBiYXNlRGVsYXkoZnVuYywgMSwgYXJncyk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBJbnZva2VzIGBmdW5jYCBhZnRlciBgd2FpdGAgbWlsbGlzZWNvbmRzLiBBbnkgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlXG4gICAgICogcHJvdmlkZWQgdG8gYGZ1bmNgIHdoZW4gaXQncyBpbnZva2VkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gZGVsYXkuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHdhaXQgVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gZGVsYXkgaW52b2NhdGlvbi5cbiAgICAgKiBAcGFyYW0gey4uLip9IFthcmdzXSBUaGUgYXJndW1lbnRzIHRvIGludm9rZSBgZnVuY2Agd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSB0aW1lciBpZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWxheShmdW5jdGlvbih0ZXh0KSB7XG4gICAgICogICBjb25zb2xlLmxvZyh0ZXh0KTtcbiAgICAgKiB9LCAxMDAwLCAnbGF0ZXInKTtcbiAgICAgKiAvLyA9PiBMb2dzICdsYXRlcicgYWZ0ZXIgb25lIHNlY29uZC5cbiAgICAgKi9cbiAgICB2YXIgZGVsYXkgPSBiYXNlUmVzdChmdW5jdGlvbihmdW5jLCB3YWl0LCBhcmdzKSB7XG4gICAgICByZXR1cm4gYmFzZURlbGF5KGZ1bmMsIHRvTnVtYmVyKHdhaXQpIHx8IDAsIGFyZ3MpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCBhcmd1bWVudHMgcmV2ZXJzZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBmbGlwIGFyZ3VtZW50cyBmb3IuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmxpcHBlZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGZsaXBwZWQgPSBfLmZsaXAoZnVuY3Rpb24oKSB7XG4gICAgICogICByZXR1cm4gXy50b0FycmF5KGFyZ3VtZW50cyk7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBmbGlwcGVkKCdhJywgJ2InLCAnYycsICdkJyk7XG4gICAgICogLy8gPT4gWydkJywgJ2MnLCAnYicsICdhJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmbGlwKGZ1bmMpIHtcbiAgICAgIHJldHVybiBjcmVhdGVXcmFwKGZ1bmMsIFdSQVBfRkxJUF9GTEFHKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBtZW1vaXplcyB0aGUgcmVzdWx0IG9mIGBmdW5jYC4gSWYgYHJlc29sdmVyYCBpc1xuICAgICAqIHByb3ZpZGVkLCBpdCBkZXRlcm1pbmVzIHRoZSBjYWNoZSBrZXkgZm9yIHN0b3JpbmcgdGhlIHJlc3VsdCBiYXNlZCBvbiB0aGVcbiAgICAgKiBhcmd1bWVudHMgcHJvdmlkZWQgdG8gdGhlIG1lbW9pemVkIGZ1bmN0aW9uLiBCeSBkZWZhdWx0LCB0aGUgZmlyc3QgYXJndW1lbnRcbiAgICAgKiBwcm92aWRlZCB0byB0aGUgbWVtb2l6ZWQgZnVuY3Rpb24gaXMgdXNlZCBhcyB0aGUgbWFwIGNhY2hlIGtleS4gVGhlIGBmdW5jYFxuICAgICAqIGlzIGludm9rZWQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgdGhlIG1lbW9pemVkIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoZSBjYWNoZSBpcyBleHBvc2VkIGFzIHRoZSBgY2FjaGVgIHByb3BlcnR5IG9uIHRoZSBtZW1vaXplZFxuICAgICAqIGZ1bmN0aW9uLiBJdHMgY3JlYXRpb24gbWF5IGJlIGN1c3RvbWl6ZWQgYnkgcmVwbGFjaW5nIHRoZSBgXy5tZW1vaXplLkNhY2hlYFxuICAgICAqIGNvbnN0cnVjdG9yIHdpdGggb25lIHdob3NlIGluc3RhbmNlcyBpbXBsZW1lbnQgdGhlXG4gICAgICogW2BNYXBgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1wcm9wZXJ0aWVzLW9mLXRoZS1tYXAtcHJvdG90eXBlLW9iamVjdClcbiAgICAgKiBtZXRob2QgaW50ZXJmYWNlIG9mIGBjbGVhcmAsIGBkZWxldGVgLCBgZ2V0YCwgYGhhc2AsIGFuZCBgc2V0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGhhdmUgaXRzIG91dHB1dCBtZW1vaXplZC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcmVzb2x2ZXJdIFRoZSBmdW5jdGlvbiB0byByZXNvbHZlIHRoZSBjYWNoZSBrZXkuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgbWVtb2l6ZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSwgJ2InOiAyIH07XG4gICAgICogdmFyIG90aGVyID0geyAnYyc6IDMsICdkJzogNCB9O1xuICAgICAqXG4gICAgICogdmFyIHZhbHVlcyA9IF8ubWVtb2l6ZShfLnZhbHVlcyk7XG4gICAgICogdmFsdWVzKG9iamVjdCk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICpcbiAgICAgKiB2YWx1ZXMob3RoZXIpO1xuICAgICAqIC8vID0+IFszLCA0XVxuICAgICAqXG4gICAgICogb2JqZWN0LmEgPSAyO1xuICAgICAqIHZhbHVlcyhvYmplY3QpO1xuICAgICAqIC8vID0+IFsxLCAyXVxuICAgICAqXG4gICAgICogLy8gTW9kaWZ5IHRoZSByZXN1bHQgY2FjaGUuXG4gICAgICogdmFsdWVzLmNhY2hlLnNldChvYmplY3QsIFsnYScsICdiJ10pO1xuICAgICAqIHZhbHVlcyhvYmplY3QpO1xuICAgICAqIC8vID0+IFsnYScsICdiJ11cbiAgICAgKlxuICAgICAqIC8vIFJlcGxhY2UgYF8ubWVtb2l6ZS5DYWNoZWAuXG4gICAgICogXy5tZW1vaXplLkNhY2hlID0gV2Vha01hcDtcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtZW1vaXplKGZ1bmMsIHJlc29sdmVyKSB7XG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJyB8fCAocmVzb2x2ZXIgIT0gbnVsbCAmJiB0eXBlb2YgcmVzb2x2ZXIgIT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgdmFyIG1lbW9pemVkID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICAgICAga2V5ID0gcmVzb2x2ZXIgPyByZXNvbHZlci5hcHBseSh0aGlzLCBhcmdzKSA6IGFyZ3NbMF0sXG4gICAgICAgICAgICBjYWNoZSA9IG1lbW9pemVkLmNhY2hlO1xuXG4gICAgICAgIGlmIChjYWNoZS5oYXMoa2V5KSkge1xuICAgICAgICAgIHJldHVybiBjYWNoZS5nZXQoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcmVzdWx0ID0gZnVuYy5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgbWVtb2l6ZWQuY2FjaGUgPSBjYWNoZS5zZXQoa2V5LCByZXN1bHQpIHx8IGNhY2hlO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfTtcbiAgICAgIG1lbW9pemVkLmNhY2hlID0gbmV3IChtZW1vaXplLkNhY2hlIHx8IE1hcENhY2hlKTtcbiAgICAgIHJldHVybiBtZW1vaXplZDtcbiAgICB9XG5cbiAgICAvLyBFeHBvc2UgYE1hcENhY2hlYC5cbiAgICBtZW1vaXplLkNhY2hlID0gTWFwQ2FjaGU7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBuZWdhdGVzIHRoZSByZXN1bHQgb2YgdGhlIHByZWRpY2F0ZSBgZnVuY2AuIFRoZVxuICAgICAqIGBmdW5jYCBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBhbmQgYXJndW1lbnRzIG9mIHRoZVxuICAgICAqIGNyZWF0ZWQgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIHByZWRpY2F0ZSB0byBuZWdhdGUuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgbmVnYXRlZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gaXNFdmVuKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICUgMiA9PSAwO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIF8uZmlsdGVyKFsxLCAyLCAzLCA0LCA1LCA2XSwgXy5uZWdhdGUoaXNFdmVuKSk7XG4gICAgICogLy8gPT4gWzEsIDMsIDVdXG4gICAgICovXG4gICAgZnVuY3Rpb24gbmVnYXRlKHByZWRpY2F0ZSkge1xuICAgICAgaWYgKHR5cGVvZiBwcmVkaWNhdGUgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgICBzd2l0Y2ggKGFyZ3MubGVuZ3RoKSB7XG4gICAgICAgICAgY2FzZSAwOiByZXR1cm4gIXByZWRpY2F0ZS5jYWxsKHRoaXMpO1xuICAgICAgICAgIGNhc2UgMTogcmV0dXJuICFwcmVkaWNhdGUuY2FsbCh0aGlzLCBhcmdzWzBdKTtcbiAgICAgICAgICBjYXNlIDI6IHJldHVybiAhcHJlZGljYXRlLmNhbGwodGhpcywgYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgICAgICAgY2FzZSAzOiByZXR1cm4gIXByZWRpY2F0ZS5jYWxsKHRoaXMsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhcHJlZGljYXRlLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpcyByZXN0cmljdGVkIHRvIGludm9raW5nIGBmdW5jYCBvbmNlLiBSZXBlYXQgY2FsbHNcbiAgICAgKiB0byB0aGUgZnVuY3Rpb24gcmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZmlyc3QgaW52b2NhdGlvbi4gVGhlIGBmdW5jYCBpc1xuICAgICAqIGludm9rZWQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgYW5kIGFyZ3VtZW50cyBvZiB0aGUgY3JlYXRlZCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJlc3RyaWN0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHJlc3RyaWN0ZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBpbml0aWFsaXplID0gXy5vbmNlKGNyZWF0ZUFwcGxpY2F0aW9uKTtcbiAgICAgKiBpbml0aWFsaXplKCk7XG4gICAgICogaW5pdGlhbGl6ZSgpO1xuICAgICAqIC8vID0+IGBjcmVhdGVBcHBsaWNhdGlvbmAgaXMgaW52b2tlZCBvbmNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gb25jZShmdW5jKSB7XG4gICAgICByZXR1cm4gYmVmb3JlKDIsIGZ1bmMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggaXRzIGFyZ3VtZW50cyB0cmFuc2Zvcm1lZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gICAgICogQHBhcmFtIHsuLi4oRnVuY3Rpb258RnVuY3Rpb25bXSl9IFt0cmFuc2Zvcm1zPVtfLmlkZW50aXR5XV1cbiAgICAgKiAgVGhlIGFyZ3VtZW50IHRyYW5zZm9ybXMuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIGRvdWJsZWQobikge1xuICAgICAqICAgcmV0dXJuIG4gKiAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIHNxdWFyZShuKSB7XG4gICAgICogICByZXR1cm4gbiAqIG47XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIGZ1bmMgPSBfLm92ZXJBcmdzKGZ1bmN0aW9uKHgsIHkpIHtcbiAgICAgKiAgIHJldHVybiBbeCwgeV07XG4gICAgICogfSwgW3NxdWFyZSwgZG91YmxlZF0pO1xuICAgICAqXG4gICAgICogZnVuYyg5LCAzKTtcbiAgICAgKiAvLyA9PiBbODEsIDZdXG4gICAgICpcbiAgICAgKiBmdW5jKDEwLCA1KTtcbiAgICAgKiAvLyA9PiBbMTAwLCAxMF1cbiAgICAgKi9cbiAgICB2YXIgb3ZlckFyZ3MgPSBjYXN0UmVzdChmdW5jdGlvbihmdW5jLCB0cmFuc2Zvcm1zKSB7XG4gICAgICB0cmFuc2Zvcm1zID0gKHRyYW5zZm9ybXMubGVuZ3RoID09IDEgJiYgaXNBcnJheSh0cmFuc2Zvcm1zWzBdKSlcbiAgICAgICAgPyBhcnJheU1hcCh0cmFuc2Zvcm1zWzBdLCBiYXNlVW5hcnkoZ2V0SXRlcmF0ZWUoKSkpXG4gICAgICAgIDogYXJyYXlNYXAoYmFzZUZsYXR0ZW4odHJhbnNmb3JtcywgMSksIGJhc2VVbmFyeShnZXRJdGVyYXRlZSgpKSk7XG5cbiAgICAgIHZhciBmdW5jc0xlbmd0aCA9IHRyYW5zZm9ybXMubGVuZ3RoO1xuICAgICAgcmV0dXJuIGJhc2VSZXN0KGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgICAgICBsZW5ndGggPSBuYXRpdmVNaW4oYXJncy5sZW5ndGgsIGZ1bmNzTGVuZ3RoKTtcblxuICAgICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgIGFyZ3NbaW5kZXhdID0gdHJhbnNmb3Jtc1tpbmRleF0uY2FsbCh0aGlzLCBhcmdzW2luZGV4XSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFwcGx5KGZ1bmMsIHRoaXMsIGFyZ3MpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIGBwYXJ0aWFsc2AgcHJlcGVuZGVkIHRvIHRoZVxuICAgICAqIGFyZ3VtZW50cyBpdCByZWNlaXZlcy4gVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5iaW5kYCBleGNlcHQgaXQgZG9lcyAqKm5vdCoqXG4gICAgICogYWx0ZXIgdGhlIGB0aGlzYCBiaW5kaW5nLlxuICAgICAqXG4gICAgICogVGhlIGBfLnBhcnRpYWwucGxhY2Vob2xkZXJgIHZhbHVlLCB3aGljaCBkZWZhdWx0cyB0byBgX2AgaW4gbW9ub2xpdGhpY1xuICAgICAqIGJ1aWxkcywgbWF5IGJlIHVzZWQgYXMgYSBwbGFjZWhvbGRlciBmb3IgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGRvZXNuJ3Qgc2V0IHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IG9mIHBhcnRpYWxseVxuICAgICAqIGFwcGxpZWQgZnVuY3Rpb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMi4wXG4gICAgICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcGFydGlhbGx5IGFwcGx5IGFyZ3VtZW50cyB0by5cbiAgICAgKiBAcGFyYW0gey4uLip9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBiZSBwYXJ0aWFsbHkgYXBwbGllZC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBwYXJ0aWFsbHkgYXBwbGllZCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gZ3JlZXQoZ3JlZXRpbmcsIG5hbWUpIHtcbiAgICAgKiAgIHJldHVybiBncmVldGluZyArICcgJyArIG5hbWU7XG4gICAgICogfVxuICAgICAqXG4gICAgICogdmFyIHNheUhlbGxvVG8gPSBfLnBhcnRpYWwoZ3JlZXQsICdoZWxsbycpO1xuICAgICAqIHNheUhlbGxvVG8oJ2ZyZWQnKTtcbiAgICAgKiAvLyA9PiAnaGVsbG8gZnJlZCdcbiAgICAgKlxuICAgICAqIC8vIFBhcnRpYWxseSBhcHBsaWVkIHdpdGggcGxhY2Vob2xkZXJzLlxuICAgICAqIHZhciBncmVldEZyZWQgPSBfLnBhcnRpYWwoZ3JlZXQsIF8sICdmcmVkJyk7XG4gICAgICogZ3JlZXRGcmVkKCdoaScpO1xuICAgICAqIC8vID0+ICdoaSBmcmVkJ1xuICAgICAqL1xuICAgIHZhciBwYXJ0aWFsID0gYmFzZVJlc3QoZnVuY3Rpb24oZnVuYywgcGFydGlhbHMpIHtcbiAgICAgIHZhciBob2xkZXJzID0gcmVwbGFjZUhvbGRlcnMocGFydGlhbHMsIGdldEhvbGRlcihwYXJ0aWFsKSk7XG4gICAgICByZXR1cm4gY3JlYXRlV3JhcChmdW5jLCBXUkFQX1BBUlRJQUxfRkxBRywgdW5kZWZpbmVkLCBwYXJ0aWFscywgaG9sZGVycyk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnBhcnRpYWxgIGV4Y2VwdCB0aGF0IHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50c1xuICAgICAqIGFyZSBhcHBlbmRlZCB0byB0aGUgYXJndW1lbnRzIGl0IHJlY2VpdmVzLlxuICAgICAqXG4gICAgICogVGhlIGBfLnBhcnRpYWxSaWdodC5wbGFjZWhvbGRlcmAgdmFsdWUsIHdoaWNoIGRlZmF1bHRzIHRvIGBfYCBpbiBtb25vbGl0aGljXG4gICAgICogYnVpbGRzLCBtYXkgYmUgdXNlZCBhcyBhIHBsYWNlaG9sZGVyIGZvciBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgZG9lc24ndCBzZXQgdGhlIFwibGVuZ3RoXCIgcHJvcGVydHkgb2YgcGFydGlhbGx5XG4gICAgICogYXBwbGllZCBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMS4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBwYXJ0aWFsbHkgYXBwbHkgYXJndW1lbnRzIHRvLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHBhcnRpYWxseSBhcHBsaWVkIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBncmVldChncmVldGluZywgbmFtZSkge1xuICAgICAqICAgcmV0dXJuIGdyZWV0aW5nICsgJyAnICsgbmFtZTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiB2YXIgZ3JlZXRGcmVkID0gXy5wYXJ0aWFsUmlnaHQoZ3JlZXQsICdmcmVkJyk7XG4gICAgICogZ3JlZXRGcmVkKCdoaScpO1xuICAgICAqIC8vID0+ICdoaSBmcmVkJ1xuICAgICAqXG4gICAgICogLy8gUGFydGlhbGx5IGFwcGxpZWQgd2l0aCBwbGFjZWhvbGRlcnMuXG4gICAgICogdmFyIHNheUhlbGxvVG8gPSBfLnBhcnRpYWxSaWdodChncmVldCwgJ2hlbGxvJywgXyk7XG4gICAgICogc2F5SGVsbG9UbygnZnJlZCcpO1xuICAgICAqIC8vID0+ICdoZWxsbyBmcmVkJ1xuICAgICAqL1xuICAgIHZhciBwYXJ0aWFsUmlnaHQgPSBiYXNlUmVzdChmdW5jdGlvbihmdW5jLCBwYXJ0aWFscykge1xuICAgICAgdmFyIGhvbGRlcnMgPSByZXBsYWNlSG9sZGVycyhwYXJ0aWFscywgZ2V0SG9sZGVyKHBhcnRpYWxSaWdodCkpO1xuICAgICAgcmV0dXJuIGNyZWF0ZVdyYXAoZnVuYywgV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcsIHVuZGVmaW5lZCwgcGFydGlhbHMsIGhvbGRlcnMpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCBhcmd1bWVudHMgYXJyYW5nZWQgYWNjb3JkaW5nXG4gICAgICogdG8gdGhlIHNwZWNpZmllZCBgaW5kZXhlc2Agd2hlcmUgdGhlIGFyZ3VtZW50IHZhbHVlIGF0IHRoZSBmaXJzdCBpbmRleCBpc1xuICAgICAqIHByb3ZpZGVkIGFzIHRoZSBmaXJzdCBhcmd1bWVudCwgdGhlIGFyZ3VtZW50IHZhbHVlIGF0IHRoZSBzZWNvbmQgaW5kZXggaXNcbiAgICAgKiBwcm92aWRlZCBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50LCBhbmQgc28gb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byByZWFycmFuZ2UgYXJndW1lbnRzIGZvci5cbiAgICAgKiBAcGFyYW0gey4uLihudW1iZXJ8bnVtYmVyW10pfSBpbmRleGVzIFRoZSBhcnJhbmdlZCBhcmd1bWVudCBpbmRleGVzLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgcmVhcmdlZCA9IF8ucmVhcmcoZnVuY3Rpb24oYSwgYiwgYykge1xuICAgICAqICAgcmV0dXJuIFthLCBiLCBjXTtcbiAgICAgKiB9LCBbMiwgMCwgMV0pO1xuICAgICAqXG4gICAgICogcmVhcmdlZCgnYicsICdjJywgJ2EnKVxuICAgICAqIC8vID0+IFsnYScsICdiJywgJ2MnXVxuICAgICAqL1xuICAgIHZhciByZWFyZyA9IGZsYXRSZXN0KGZ1bmN0aW9uKGZ1bmMsIGluZGV4ZXMpIHtcbiAgICAgIHJldHVybiBjcmVhdGVXcmFwKGZ1bmMsIFdSQVBfUkVBUkdfRkxBRywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgaW5kZXhlcyk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGVcbiAgICAgKiBjcmVhdGVkIGZ1bmN0aW9uIGFuZCBhcmd1bWVudHMgZnJvbSBgc3RhcnRgIGFuZCBiZXlvbmQgcHJvdmlkZWQgYXNcbiAgICAgKiBhbiBhcnJheS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvbiB0aGVcbiAgICAgKiBbcmVzdCBwYXJhbWV0ZXJdKGh0dHBzOi8vbWRuLmlvL3Jlc3RfcGFyYW1ldGVycykuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhcHBseSBhIHJlc3QgcGFyYW1ldGVyIHRvLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9ZnVuYy5sZW5ndGgtMV0gVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIHRoZSByZXN0IHBhcmFtZXRlci5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHNheSA9IF8ucmVzdChmdW5jdGlvbih3aGF0LCBuYW1lcykge1xuICAgICAqICAgcmV0dXJuIHdoYXQgKyAnICcgKyBfLmluaXRpYWwobmFtZXMpLmpvaW4oJywgJykgK1xuICAgICAqICAgICAoXy5zaXplKG5hbWVzKSA+IDEgPyAnLCAmICcgOiAnJykgKyBfLmxhc3QobmFtZXMpO1xuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogc2F5KCdoZWxsbycsICdmcmVkJywgJ2Jhcm5leScsICdwZWJibGVzJyk7XG4gICAgICogLy8gPT4gJ2hlbGxvIGZyZWQsIGJhcm5leSwgJiBwZWJibGVzJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJlc3QoZnVuYywgc3RhcnQpIHtcbiAgICAgIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgICAgIH1cbiAgICAgIHN0YXJ0ID0gc3RhcnQgPT09IHVuZGVmaW5lZCA/IHN0YXJ0IDogdG9JbnRlZ2VyKHN0YXJ0KTtcbiAgICAgIHJldHVybiBiYXNlUmVzdChmdW5jLCBzdGFydCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgdGhlXG4gICAgICogY3JlYXRlIGZ1bmN0aW9uIGFuZCBhbiBhcnJheSBvZiBhcmd1bWVudHMgbXVjaCBsaWtlXG4gICAgICogW2BGdW5jdGlvbiNhcHBseWBdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1mdW5jdGlvbi5wcm90b3R5cGUuYXBwbHkpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uIHRoZVxuICAgICAqIFtzcHJlYWQgb3BlcmF0b3JdKGh0dHBzOi8vbWRuLmlvL3NwcmVhZF9vcGVyYXRvcikuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4yLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBzcHJlYWQgYXJndW1lbnRzIG92ZXIuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24gb2YgdGhlIHNwcmVhZC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHNheSA9IF8uc3ByZWFkKGZ1bmN0aW9uKHdobywgd2hhdCkge1xuICAgICAqICAgcmV0dXJuIHdobyArICcgc2F5cyAnICsgd2hhdDtcbiAgICAgKiB9KTtcbiAgICAgKlxuICAgICAqIHNheShbJ2ZyZWQnLCAnaGVsbG8nXSk7XG4gICAgICogLy8gPT4gJ2ZyZWQgc2F5cyBoZWxsbydcbiAgICAgKlxuICAgICAqIHZhciBudW1iZXJzID0gUHJvbWlzZS5hbGwoW1xuICAgICAqICAgUHJvbWlzZS5yZXNvbHZlKDQwKSxcbiAgICAgKiAgIFByb21pc2UucmVzb2x2ZSgzNilcbiAgICAgKiBdKTtcbiAgICAgKlxuICAgICAqIG51bWJlcnMudGhlbihfLnNwcmVhZChmdW5jdGlvbih4LCB5KSB7XG4gICAgICogICByZXR1cm4geCArIHk7XG4gICAgICogfSkpO1xuICAgICAqIC8vID0+IGEgUHJvbWlzZSBvZiA3NlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHNwcmVhZChmdW5jLCBzdGFydCkge1xuICAgICAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgfVxuICAgICAgc3RhcnQgPSBzdGFydCA9PSBudWxsID8gMCA6IG5hdGl2ZU1heCh0b0ludGVnZXIoc3RhcnQpLCAwKTtcbiAgICAgIHJldHVybiBiYXNlUmVzdChmdW5jdGlvbihhcmdzKSB7XG4gICAgICAgIHZhciBhcnJheSA9IGFyZ3Nbc3RhcnRdLFxuICAgICAgICAgICAgb3RoZXJBcmdzID0gY2FzdFNsaWNlKGFyZ3MsIDAsIHN0YXJ0KTtcblxuICAgICAgICBpZiAoYXJyYXkpIHtcbiAgICAgICAgICBhcnJheVB1c2gob3RoZXJBcmdzLCBhcnJheSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFwcGx5KGZ1bmMsIHRoaXMsIG90aGVyQXJncyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgdGhyb3R0bGVkIGZ1bmN0aW9uIHRoYXQgb25seSBpbnZva2VzIGBmdW5jYCBhdCBtb3N0IG9uY2UgcGVyXG4gICAgICogZXZlcnkgYHdhaXRgIG1pbGxpc2Vjb25kcy4gVGhlIHRocm90dGxlZCBmdW5jdGlvbiBjb21lcyB3aXRoIGEgYGNhbmNlbGBcbiAgICAgKiBtZXRob2QgdG8gY2FuY2VsIGRlbGF5ZWQgYGZ1bmNgIGludm9jYXRpb25zIGFuZCBhIGBmbHVzaGAgbWV0aG9kIHRvXG4gICAgICogaW1tZWRpYXRlbHkgaW52b2tlIHRoZW0uIFByb3ZpZGUgYG9wdGlvbnNgIHRvIGluZGljYXRlIHdoZXRoZXIgYGZ1bmNgXG4gICAgICogc2hvdWxkIGJlIGludm9rZWQgb24gdGhlIGxlYWRpbmcgYW5kL29yIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIGB3YWl0YFxuICAgICAqIHRpbWVvdXQuIFRoZSBgZnVuY2AgaXMgaW52b2tlZCB3aXRoIHRoZSBsYXN0IGFyZ3VtZW50cyBwcm92aWRlZCB0byB0aGVcbiAgICAgKiB0aHJvdHRsZWQgZnVuY3Rpb24uIFN1YnNlcXVlbnQgY2FsbHMgdG8gdGhlIHRocm90dGxlZCBmdW5jdGlvbiByZXR1cm4gdGhlXG4gICAgICogcmVzdWx0IG9mIHRoZSBsYXN0IGBmdW5jYCBpbnZvY2F0aW9uLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIElmIGBsZWFkaW5nYCBhbmQgYHRyYWlsaW5nYCBvcHRpb25zIGFyZSBgdHJ1ZWAsIGBmdW5jYCBpc1xuICAgICAqIGludm9rZWQgb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQgb25seSBpZiB0aGUgdGhyb3R0bGVkIGZ1bmN0aW9uXG4gICAgICogaXMgaW52b2tlZCBtb3JlIHRoYW4gb25jZSBkdXJpbmcgdGhlIGB3YWl0YCB0aW1lb3V0LlxuICAgICAqXG4gICAgICogSWYgYHdhaXRgIGlzIGAwYCBhbmQgYGxlYWRpbmdgIGlzIGBmYWxzZWAsIGBmdW5jYCBpbnZvY2F0aW9uIGlzIGRlZmVycmVkXG4gICAgICogdW50aWwgdG8gdGhlIG5leHQgdGljaywgc2ltaWxhciB0byBgc2V0VGltZW91dGAgd2l0aCBhIHRpbWVvdXQgb2YgYDBgLlxuICAgICAqXG4gICAgICogU2VlIFtEYXZpZCBDb3JiYWNobydzIGFydGljbGVdKGh0dHBzOi8vY3NzLXRyaWNrcy5jb20vZGVib3VuY2luZy10aHJvdHRsaW5nLWV4cGxhaW5lZC1leGFtcGxlcy8pXG4gICAgICogZm9yIGRldGFpbHMgb3ZlciB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiBgXy50aHJvdHRsZWAgYW5kIGBfLmRlYm91bmNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHRocm90dGxlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbd2FpdD0wXSBUaGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byB0aHJvdHRsZSBpbnZvY2F0aW9ucyB0by5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmxlYWRpbmc9dHJ1ZV1cbiAgICAgKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgbGVhZGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMudHJhaWxpbmc9dHJ1ZV1cbiAgICAgKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB0aHJvdHRsZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIC8vIEF2b2lkIGV4Y2Vzc2l2ZWx5IHVwZGF0aW5nIHRoZSBwb3NpdGlvbiB3aGlsZSBzY3JvbGxpbmcuXG4gICAgICogalF1ZXJ5KHdpbmRvdykub24oJ3Njcm9sbCcsIF8udGhyb3R0bGUodXBkYXRlUG9zaXRpb24sIDEwMCkpO1xuICAgICAqXG4gICAgICogLy8gSW52b2tlIGByZW5ld1Rva2VuYCB3aGVuIHRoZSBjbGljayBldmVudCBpcyBmaXJlZCwgYnV0IG5vdCBtb3JlIHRoYW4gb25jZSBldmVyeSA1IG1pbnV0ZXMuXG4gICAgICogdmFyIHRocm90dGxlZCA9IF8udGhyb3R0bGUocmVuZXdUb2tlbiwgMzAwMDAwLCB7ICd0cmFpbGluZyc6IGZhbHNlIH0pO1xuICAgICAqIGpRdWVyeShlbGVtZW50KS5vbignY2xpY2snLCB0aHJvdHRsZWQpO1xuICAgICAqXG4gICAgICogLy8gQ2FuY2VsIHRoZSB0cmFpbGluZyB0aHJvdHRsZWQgaW52b2NhdGlvbi5cbiAgICAgKiBqUXVlcnkod2luZG93KS5vbigncG9wc3RhdGUnLCB0aHJvdHRsZWQuY2FuY2VsKTtcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0aHJvdHRsZShmdW5jLCB3YWl0LCBvcHRpb25zKSB7XG4gICAgICB2YXIgbGVhZGluZyA9IHRydWUsXG4gICAgICAgICAgdHJhaWxpbmcgPSB0cnVlO1xuXG4gICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICAgICAgbGVhZGluZyA9ICdsZWFkaW5nJyBpbiBvcHRpb25zID8gISFvcHRpb25zLmxlYWRpbmcgOiBsZWFkaW5nO1xuICAgICAgICB0cmFpbGluZyA9ICd0cmFpbGluZycgaW4gb3B0aW9ucyA/ICEhb3B0aW9ucy50cmFpbGluZyA6IHRyYWlsaW5nO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRlYm91bmNlKGZ1bmMsIHdhaXQsIHtcbiAgICAgICAgJ2xlYWRpbmcnOiBsZWFkaW5nLFxuICAgICAgICAnbWF4V2FpdCc6IHdhaXQsXG4gICAgICAgICd0cmFpbGluZyc6IHRyYWlsaW5nXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBhY2NlcHRzIHVwIHRvIG9uZSBhcmd1bWVudCwgaWdub3JpbmcgYW55XG4gICAgICogYWRkaXRpb25hbCBhcmd1bWVudHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjYXAgYXJndW1lbnRzIGZvci5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjYXBwZWQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubWFwKFsnNicsICc4JywgJzEwJ10sIF8udW5hcnkocGFyc2VJbnQpKTtcbiAgICAgKiAvLyA9PiBbNiwgOCwgMTBdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdW5hcnkoZnVuYykge1xuICAgICAgcmV0dXJuIGFyeShmdW5jLCAxKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBwcm92aWRlcyBgdmFsdWVgIHRvIGB3cmFwcGVyYCBhcyBpdHMgZmlyc3RcbiAgICAgKiBhcmd1bWVudC4gQW55IGFkZGl0aW9uYWwgYXJndW1lbnRzIHByb3ZpZGVkIHRvIHRoZSBmdW5jdGlvbiBhcmUgYXBwZW5kZWRcbiAgICAgKiB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgYHdyYXBwZXJgLiBUaGUgd3JhcHBlciBpcyBpbnZva2VkIHdpdGggdGhlIGB0aGlzYFxuICAgICAqIGJpbmRpbmcgb2YgdGhlIGNyZWF0ZWQgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFt3cmFwcGVyPWlkZW50aXR5XSBUaGUgd3JhcHBlciBmdW5jdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHAgPSBfLndyYXAoXy5lc2NhcGUsIGZ1bmN0aW9uKGZ1bmMsIHRleHQpIHtcbiAgICAgKiAgIHJldHVybiAnPHA+JyArIGZ1bmModGV4dCkgKyAnPC9wPic7XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBwKCdmcmVkLCBiYXJuZXksICYgcGViYmxlcycpO1xuICAgICAqIC8vID0+ICc8cD5mcmVkLCBiYXJuZXksICZhbXA7IHBlYmJsZXM8L3A+J1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHdyYXAodmFsdWUsIHdyYXBwZXIpIHtcbiAgICAgIHJldHVybiBwYXJ0aWFsKGNhc3RGdW5jdGlvbih3cmFwcGVyKSwgdmFsdWUpO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIENhc3RzIGB2YWx1ZWAgYXMgYW4gYXJyYXkgaWYgaXQncyBub3Qgb25lLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgY2FzdCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jYXN0QXJyYXkoMSk7XG4gICAgICogLy8gPT4gWzFdXG4gICAgICpcbiAgICAgKiBfLmNhc3RBcnJheSh7ICdhJzogMSB9KTtcbiAgICAgKiAvLyA9PiBbeyAnYSc6IDEgfV1cbiAgICAgKlxuICAgICAqIF8uY2FzdEFycmF5KCdhYmMnKTtcbiAgICAgKiAvLyA9PiBbJ2FiYyddXG4gICAgICpcbiAgICAgKiBfLmNhc3RBcnJheShudWxsKTtcbiAgICAgKiAvLyA9PiBbbnVsbF1cbiAgICAgKlxuICAgICAqIF8uY2FzdEFycmF5KHVuZGVmaW5lZCk7XG4gICAgICogLy8gPT4gW3VuZGVmaW5lZF1cbiAgICAgKlxuICAgICAqIF8uY2FzdEFycmF5KCk7XG4gICAgICogLy8gPT4gW11cbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsxLCAyLCAzXTtcbiAgICAgKiBjb25zb2xlLmxvZyhfLmNhc3RBcnJheShhcnJheSkgPT09IGFycmF5KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2FzdEFycmF5KCkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIHZhciB2YWx1ZSA9IGFyZ3VtZW50c1swXTtcbiAgICAgIHJldHVybiBpc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW3ZhbHVlXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc2hhbGxvdyBjbG9uZSBvZiBgdmFsdWVgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb24gdGhlXG4gICAgICogW3N0cnVjdHVyZWQgY2xvbmUgYWxnb3JpdGhtXShodHRwczovL21kbi5pby9TdHJ1Y3R1cmVkX2Nsb25lX2FsZ29yaXRobSlcbiAgICAgKiBhbmQgc3VwcG9ydHMgY2xvbmluZyBhcnJheXMsIGFycmF5IGJ1ZmZlcnMsIGJvb2xlYW5zLCBkYXRlIG9iamVjdHMsIG1hcHMsXG4gICAgICogbnVtYmVycywgYE9iamVjdGAgb2JqZWN0cywgcmVnZXhlcywgc2V0cywgc3RyaW5ncywgc3ltYm9scywgYW5kIHR5cGVkXG4gICAgICogYXJyYXlzLiBUaGUgb3duIGVudW1lcmFibGUgcHJvcGVydGllcyBvZiBgYXJndW1lbnRzYCBvYmplY3RzIGFyZSBjbG9uZWRcbiAgICAgKiBhcyBwbGFpbiBvYmplY3RzLiBBbiBlbXB0eSBvYmplY3QgaXMgcmV0dXJuZWQgZm9yIHVuY2xvbmVhYmxlIHZhbHVlcyBzdWNoXG4gICAgICogYXMgZXJyb3Igb2JqZWN0cywgZnVuY3Rpb25zLCBET00gbm9kZXMsIGFuZCBXZWFrTWFwcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2xvbmUuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGNsb25lZCB2YWx1ZS5cbiAgICAgKiBAc2VlIF8uY2xvbmVEZWVwXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ2EnOiAxIH0sIHsgJ2InOiAyIH1dO1xuICAgICAqXG4gICAgICogdmFyIHNoYWxsb3cgPSBfLmNsb25lKG9iamVjdHMpO1xuICAgICAqIGNvbnNvbGUubG9nKHNoYWxsb3dbMF0gPT09IG9iamVjdHNbMF0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGJhc2VDbG9uZSh2YWx1ZSwgQ0xPTkVfU1lNQk9MU19GTEFHKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmNsb25lYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjdXN0b21pemVyYCB3aGljaFxuICAgICAqIGlzIGludm9rZWQgdG8gcHJvZHVjZSB0aGUgY2xvbmVkIHZhbHVlLiBJZiBgY3VzdG9taXplcmAgcmV0dXJucyBgdW5kZWZpbmVkYCxcbiAgICAgKiBjbG9uaW5nIGlzIGhhbmRsZWQgYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgIGlzIGludm9rZWQgd2l0aFxuICAgICAqIHVwIHRvIGZvdXIgYXJndW1lbnRzOyAodmFsdWUgWywgaW5kZXh8a2V5LCBvYmplY3QsIHN0YWNrXSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNsb25lLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNsb25pbmcuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGNsb25lZCB2YWx1ZS5cbiAgICAgKiBAc2VlIF8uY2xvbmVEZWVwV2l0aFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBjdXN0b21pemVyKHZhbHVlKSB7XG4gICAgICogICBpZiAoXy5pc0VsZW1lbnQodmFsdWUpKSB7XG4gICAgICogICAgIHJldHVybiB2YWx1ZS5jbG9uZU5vZGUoZmFsc2UpO1xuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBlbCA9IF8uY2xvbmVXaXRoKGRvY3VtZW50LmJvZHksIGN1c3RvbWl6ZXIpO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2coZWwgPT09IGRvY3VtZW50LmJvZHkpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICogY29uc29sZS5sb2coZWwubm9kZU5hbWUpO1xuICAgICAqIC8vID0+ICdCT0RZJ1xuICAgICAqIGNvbnNvbGUubG9nKGVsLmNoaWxkTm9kZXMubGVuZ3RoKTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2xvbmVXaXRoKHZhbHVlLCBjdXN0b21pemVyKSB7XG4gICAgICBjdXN0b21pemVyID0gdHlwZW9mIGN1c3RvbWl6ZXIgPT0gJ2Z1bmN0aW9uJyA/IGN1c3RvbWl6ZXIgOiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gYmFzZUNsb25lKHZhbHVlLCBDTE9ORV9TWU1CT0xTX0ZMQUcsIGN1c3RvbWl6ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uY2xvbmVgIGV4Y2VwdCB0aGF0IGl0IHJlY3Vyc2l2ZWx5IGNsb25lcyBgdmFsdWVgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byByZWN1cnNpdmVseSBjbG9uZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgZGVlcCBjbG9uZWQgdmFsdWUuXG4gICAgICogQHNlZSBfLmNsb25lXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ2EnOiAxIH0sIHsgJ2InOiAyIH1dO1xuICAgICAqXG4gICAgICogdmFyIGRlZXAgPSBfLmNsb25lRGVlcChvYmplY3RzKTtcbiAgICAgKiBjb25zb2xlLmxvZyhkZWVwWzBdID09PSBvYmplY3RzWzBdKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNsb25lRGVlcCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGJhc2VDbG9uZSh2YWx1ZSwgQ0xPTkVfREVFUF9GTEFHIHwgQ0xPTkVfU1lNQk9MU19GTEFHKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmNsb25lV2l0aGAgZXhjZXB0IHRoYXQgaXQgcmVjdXJzaXZlbHkgY2xvbmVzIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHJlY3Vyc2l2ZWx5IGNsb25lLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNsb25pbmcuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGRlZXAgY2xvbmVkIHZhbHVlLlxuICAgICAqIEBzZWUgXy5jbG9uZVdpdGhcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gY3VzdG9taXplcih2YWx1ZSkge1xuICAgICAqICAgaWYgKF8uaXNFbGVtZW50KHZhbHVlKSkge1xuICAgICAqICAgICByZXR1cm4gdmFsdWUuY2xvbmVOb2RlKHRydWUpO1xuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBlbCA9IF8uY2xvbmVEZWVwV2l0aChkb2N1bWVudC5ib2R5LCBjdXN0b21pemVyKTtcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKGVsID09PSBkb2N1bWVudC5ib2R5KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqIGNvbnNvbGUubG9nKGVsLm5vZGVOYW1lKTtcbiAgICAgKiAvLyA9PiAnQk9EWSdcbiAgICAgKiBjb25zb2xlLmxvZyhlbC5jaGlsZE5vZGVzLmxlbmd0aCk7XG4gICAgICogLy8gPT4gMjBcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbG9uZURlZXBXaXRoKHZhbHVlLCBjdXN0b21pemVyKSB7XG4gICAgICBjdXN0b21pemVyID0gdHlwZW9mIGN1c3RvbWl6ZXIgPT0gJ2Z1bmN0aW9uJyA/IGN1c3RvbWl6ZXIgOiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gYmFzZUNsb25lKHZhbHVlLCBDTE9ORV9ERUVQX0ZMQUcgfCBDTE9ORV9TWU1CT0xTX0ZMQUcsIGN1c3RvbWl6ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgb2JqZWN0YCBjb25mb3JtcyB0byBgc291cmNlYCBieSBpbnZva2luZyB0aGUgcHJlZGljYXRlXG4gICAgICogcHJvcGVydGllcyBvZiBgc291cmNlYCB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIHByb3BlcnR5IHZhbHVlcyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBlcXVpdmFsZW50IHRvIGBfLmNvbmZvcm1zYCB3aGVuIGBzb3VyY2VgIGlzXG4gICAgICogcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xNC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgcHJlZGljYXRlcyB0byBjb25mb3JtIHRvLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgb2JqZWN0YCBjb25mb3JtcywgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogMiB9O1xuICAgICAqXG4gICAgICogXy5jb25mb3Jtc1RvKG9iamVjdCwgeyAnYic6IGZ1bmN0aW9uKG4pIHsgcmV0dXJuIG4gPiAxOyB9IH0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uY29uZm9ybXNUbyhvYmplY3QsIHsgJ2InOiBmdW5jdGlvbihuKSB7IHJldHVybiBuID4gMjsgfSB9KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbmZvcm1zVG8ob2JqZWN0LCBzb3VyY2UpIHtcbiAgICAgIHJldHVybiBzb3VyY2UgPT0gbnVsbCB8fCBiYXNlQ29uZm9ybXNUbyhvYmplY3QsIHNvdXJjZSwga2V5cyhzb3VyY2UpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQZXJmb3JtcyBhXG4gICAgICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAgICAgKiBjb21wYXJpc29uIGJldHdlZW4gdHdvIHZhbHVlcyB0byBkZXRlcm1pbmUgaWYgdGhleSBhcmUgZXF1aXZhbGVudC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSB9O1xuICAgICAqIHZhciBvdGhlciA9IHsgJ2EnOiAxIH07XG4gICAgICpcbiAgICAgKiBfLmVxKG9iamVjdCwgb2JqZWN0KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmVxKG9iamVjdCwgb3RoZXIpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmVxKCdhJywgJ2EnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmVxKCdhJywgT2JqZWN0KCdhJykpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmVxKE5hTiwgTmFOKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gZXEodmFsdWUsIG90aGVyKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IG90aGVyIHx8ICh2YWx1ZSAhPT0gdmFsdWUgJiYgb3RoZXIgIT09IG90aGVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBncmVhdGVyIHRoYW4gYG90aGVyYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjkuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGdyZWF0ZXIgdGhhbiBgb3RoZXJgLFxuICAgICAqICBlbHNlIGBmYWxzZWAuXG4gICAgICogQHNlZSBfLmx0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZ3QoMywgMSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5ndCgzLCAzKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5ndCgxLCAzKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBndCA9IGNyZWF0ZVJlbGF0aW9uYWxPcGVyYXRpb24oYmFzZUd0KTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBgb3RoZXJgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuOS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvXG4gICAgICogIGBvdGhlcmAsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAc2VlIF8ubHRlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZ3RlKDMsIDEpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uZ3RlKDMsIDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uZ3RlKDEsIDMpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgdmFyIGd0ZSA9IGNyZWF0ZVJlbGF0aW9uYWxPcGVyYXRpb24oZnVuY3Rpb24odmFsdWUsIG90aGVyKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPj0gb3RoZXI7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBsaWtlbHkgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBgYXJndW1lbnRzYCBvYmplY3QsXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0FyZ3VtZW50cyhmdW5jdGlvbigpIHsgcmV0dXJuIGFyZ3VtZW50czsgfSgpKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzQXJndW1lbnRzKFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgaXNBcmd1bWVudHMgPSBiYXNlSXNBcmd1bWVudHMoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSkgPyBiYXNlSXNBcmd1bWVudHMgOiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpICYmXG4gICAgICAgICFwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHZhbHVlLCAnY2FsbGVlJyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYW4gYEFycmF5YCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGFycmF5LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheShbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheShkb2N1bWVudC5ib2R5LmNoaWxkcmVuKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5KCdhYmMnKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5KF8ubm9vcCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGFuIGBBcnJheUJ1ZmZlcmAgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMy4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBhcnJheSBidWZmZXIsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5QnVmZmVyKG5ldyBBcnJheUJ1ZmZlcigyKSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5QnVmZmVyKG5ldyBBcnJheSgyKSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgaXNBcnJheUJ1ZmZlciA9IG5vZGVJc0FycmF5QnVmZmVyID8gYmFzZVVuYXJ5KG5vZGVJc0FycmF5QnVmZmVyKSA6IGJhc2VJc0FycmF5QnVmZmVyO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYXJyYXktbGlrZS4gQSB2YWx1ZSBpcyBjb25zaWRlcmVkIGFycmF5LWxpa2UgaWYgaXQnc1xuICAgICAqIG5vdCBhIGZ1bmN0aW9uIGFuZCBoYXMgYSBgdmFsdWUubGVuZ3RoYCB0aGF0J3MgYW4gaW50ZWdlciBncmVhdGVyIHRoYW4gb3JcbiAgICAgKiBlcXVhbCB0byBgMGAgYW5kIGxlc3MgdGhhbiBvciBlcXVhbCB0byBgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheUxpa2UoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXlMaWtlKGRvY3VtZW50LmJvZHkuY2hpbGRyZW4pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheUxpa2UoJ2FiYycpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNBcnJheUxpa2UoXy5ub29wKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzQXJyYXlMaWtlKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgIT0gbnVsbCAmJiBpc0xlbmd0aCh2YWx1ZS5sZW5ndGgpICYmICFpc0Z1bmN0aW9uKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmlzQXJyYXlMaWtlYCBleGNlcHQgdGhhdCBpdCBhbHNvIGNoZWNrcyBpZiBgdmFsdWVgXG4gICAgICogaXMgYW4gb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBhcnJheS1saWtlIG9iamVjdCxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXlMaWtlT2JqZWN0KFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5TGlrZU9iamVjdChkb2N1bWVudC5ib2R5LmNoaWxkcmVuKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzQXJyYXlMaWtlT2JqZWN0KCdhYmMnKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc0FycmF5TGlrZU9iamVjdChfLm5vb3ApO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNBcnJheUxpa2VPYmplY3QodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzQXJyYXlMaWtlKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYm9vbGVhbiBwcmltaXRpdmUgb3Igb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGJvb2xlYW4sIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0Jvb2xlYW4oZmFsc2UpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNCb29sZWFuKG51bGwpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNCb29sZWFuKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IHRydWUgfHwgdmFsdWUgPT09IGZhbHNlIHx8XG4gICAgICAgIChpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IGJvb2xUYWcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgYnVmZmVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMy4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGJ1ZmZlciwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzQnVmZmVyKG5ldyBCdWZmZXIoMikpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNCdWZmZXIobmV3IFVpbnQ4QXJyYXkoMikpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgdmFyIGlzQnVmZmVyID0gbmF0aXZlSXNCdWZmZXIgfHwgc3R1YkZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBEYXRlYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgZGF0ZSBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0RhdGUobmV3IERhdGUpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNEYXRlKCdNb24gQXByaWwgMjMgMjAxMicpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgdmFyIGlzRGF0ZSA9IG5vZGVJc0RhdGUgPyBiYXNlVW5hcnkobm9kZUlzRGF0ZSkgOiBiYXNlSXNEYXRlO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGlrZWx5IGEgRE9NIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgRE9NIGVsZW1lbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0VsZW1lbnQoZG9jdW1lbnQuYm9keSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0VsZW1lbnQoJzxib2R5PicpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNFbGVtZW50KHZhbHVlKSB7XG4gICAgICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiB2YWx1ZS5ub2RlVHlwZSA9PT0gMSAmJiAhaXNQbGFpbk9iamVjdCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYW4gZW1wdHkgb2JqZWN0LCBjb2xsZWN0aW9uLCBtYXAsIG9yIHNldC5cbiAgICAgKlxuICAgICAqIE9iamVjdHMgYXJlIGNvbnNpZGVyZWQgZW1wdHkgaWYgdGhleSBoYXZlIG5vIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZFxuICAgICAqIHByb3BlcnRpZXMuXG4gICAgICpcbiAgICAgKiBBcnJheS1saWtlIHZhbHVlcyBzdWNoIGFzIGBhcmd1bWVudHNgIG9iamVjdHMsIGFycmF5cywgYnVmZmVycywgc3RyaW5ncywgb3JcbiAgICAgKiBqUXVlcnktbGlrZSBjb2xsZWN0aW9ucyBhcmUgY29uc2lkZXJlZCBlbXB0eSBpZiB0aGV5IGhhdmUgYSBgbGVuZ3RoYCBvZiBgMGAuXG4gICAgICogU2ltaWxhcmx5LCBtYXBzIGFuZCBzZXRzIGFyZSBjb25zaWRlcmVkIGVtcHR5IGlmIHRoZXkgaGF2ZSBhIGBzaXplYCBvZiBgMGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGVtcHR5LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNFbXB0eShudWxsKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRW1wdHkodHJ1ZSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc0VtcHR5KDEpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNFbXB0eShbMSwgMiwgM10pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzRW1wdHkoeyAnYSc6IDEgfSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0VtcHR5KHZhbHVlKSB7XG4gICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChpc0FycmF5TGlrZSh2YWx1ZSkgJiZcbiAgICAgICAgICAoaXNBcnJheSh2YWx1ZSkgfHwgdHlwZW9mIHZhbHVlID09ICdzdHJpbmcnIHx8IHR5cGVvZiB2YWx1ZS5zcGxpY2UgPT0gJ2Z1bmN0aW9uJyB8fFxuICAgICAgICAgICAgaXNCdWZmZXIodmFsdWUpIHx8IGlzVHlwZWRBcnJheSh2YWx1ZSkgfHwgaXNBcmd1bWVudHModmFsdWUpKSkge1xuICAgICAgICByZXR1cm4gIXZhbHVlLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIHZhciB0YWcgPSBnZXRUYWcodmFsdWUpO1xuICAgICAgaWYgKHRhZyA9PSBtYXBUYWcgfHwgdGFnID09IHNldFRhZykge1xuICAgICAgICByZXR1cm4gIXZhbHVlLnNpemU7XG4gICAgICB9XG4gICAgICBpZiAoaXNQcm90b3R5cGUodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiAhYmFzZUtleXModmFsdWUpLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGtleSBpbiB2YWx1ZSkge1xuICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwga2V5KSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGVyZm9ybXMgYSBkZWVwIGNvbXBhcmlzb24gYmV0d2VlbiB0d28gdmFsdWVzIHRvIGRldGVybWluZSBpZiB0aGV5IGFyZVxuICAgICAqIGVxdWl2YWxlbnQuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2Qgc3VwcG9ydHMgY29tcGFyaW5nIGFycmF5cywgYXJyYXkgYnVmZmVycywgYm9vbGVhbnMsXG4gICAgICogZGF0ZSBvYmplY3RzLCBlcnJvciBvYmplY3RzLCBtYXBzLCBudW1iZXJzLCBgT2JqZWN0YCBvYmplY3RzLCByZWdleGVzLFxuICAgICAqIHNldHMsIHN0cmluZ3MsIHN5bWJvbHMsIGFuZCB0eXBlZCBhcnJheXMuIGBPYmplY3RgIG9iamVjdHMgYXJlIGNvbXBhcmVkXG4gICAgICogYnkgdGhlaXIgb3duLCBub3QgaW5oZXJpdGVkLCBlbnVtZXJhYmxlIHByb3BlcnRpZXMuIEZ1bmN0aW9ucyBhbmQgRE9NXG4gICAgICogbm9kZXMgYXJlIGNvbXBhcmVkIGJ5IHN0cmljdCBlcXVhbGl0eSwgaS5lLiBgPT09YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSB9O1xuICAgICAqIHZhciBvdGhlciA9IHsgJ2EnOiAxIH07XG4gICAgICpcbiAgICAgKiBfLmlzRXF1YWwob2JqZWN0LCBvdGhlcik7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogb2JqZWN0ID09PSBvdGhlcjtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzRXF1YWwodmFsdWUsIG90aGVyKSB7XG4gICAgICByZXR1cm4gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmlzRXF1YWxgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGN1c3RvbWl6ZXJgIHdoaWNoXG4gICAgICogaXMgaW52b2tlZCB0byBjb21wYXJlIHZhbHVlcy4gSWYgYGN1c3RvbWl6ZXJgIHJldHVybnMgYHVuZGVmaW5lZGAsIGNvbXBhcmlzb25zXG4gICAgICogYXJlIGhhbmRsZWQgYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgIGlzIGludm9rZWQgd2l0aCB1cCB0b1xuICAgICAqIHNpeCBhcmd1bWVudHM6IChvYmpWYWx1ZSwgb3RoVmFsdWUgWywgaW5kZXh8a2V5LCBvYmplY3QsIG90aGVyLCBzdGFja10pLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gaXNHcmVldGluZyh2YWx1ZSkge1xuICAgICAqICAgcmV0dXJuIC9eaCg/Oml8ZWxsbykkLy50ZXN0KHZhbHVlKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBjdXN0b21pemVyKG9ialZhbHVlLCBvdGhWYWx1ZSkge1xuICAgICAqICAgaWYgKGlzR3JlZXRpbmcob2JqVmFsdWUpICYmIGlzR3JlZXRpbmcob3RoVmFsdWUpKSB7XG4gICAgICogICAgIHJldHVybiB0cnVlO1xuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBhcnJheSA9IFsnaGVsbG8nLCAnZ29vZGJ5ZSddO1xuICAgICAqIHZhciBvdGhlciA9IFsnaGknLCAnZ29vZGJ5ZSddO1xuICAgICAqXG4gICAgICogXy5pc0VxdWFsV2l0aChhcnJheSwgb3RoZXIsIGN1c3RvbWl6ZXIpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0VxdWFsV2l0aCh2YWx1ZSwgb3RoZXIsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGN1c3RvbWl6ZXIgPSB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nID8gY3VzdG9taXplciA6IHVuZGVmaW5lZDtcbiAgICAgIHZhciByZXN1bHQgPSBjdXN0b21pemVyID8gY3VzdG9taXplcih2YWx1ZSwgb3RoZXIpIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyLCB1bmRlZmluZWQsIGN1c3RvbWl6ZXIpIDogISFyZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYW4gYEVycm9yYCwgYEV2YWxFcnJvcmAsIGBSYW5nZUVycm9yYCwgYFJlZmVyZW5jZUVycm9yYCxcbiAgICAgKiBgU3ludGF4RXJyb3JgLCBgVHlwZUVycm9yYCwgb3IgYFVSSUVycm9yYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGVycm9yIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzRXJyb3IobmV3IEVycm9yKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRXJyb3IoRXJyb3IpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNFcnJvcih2YWx1ZSkge1xuICAgICAgaWYgKCFpc09iamVjdExpa2UodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHZhciB0YWcgPSBiYXNlR2V0VGFnKHZhbHVlKTtcbiAgICAgIHJldHVybiB0YWcgPT0gZXJyb3JUYWcgfHwgdGFnID09IGRvbUV4Y1RhZyB8fFxuICAgICAgICAodHlwZW9mIHZhbHVlLm1lc3NhZ2UgPT0gJ3N0cmluZycgJiYgdHlwZW9mIHZhbHVlLm5hbWUgPT0gJ3N0cmluZycgJiYgIWlzUGxhaW5PYmplY3QodmFsdWUpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIGZpbml0ZSBwcmltaXRpdmUgbnVtYmVyLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uXG4gICAgICogW2BOdW1iZXIuaXNGaW5pdGVgXShodHRwczovL21kbi5pby9OdW1iZXIvaXNGaW5pdGUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGZpbml0ZSBudW1iZXIsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc0Zpbml0ZSgzKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRmluaXRlKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNGaW5pdGUoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzRmluaXRlKCczJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0Zpbml0ZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJiBuYXRpdmVJc0Zpbml0ZSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBGdW5jdGlvbmAgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGZ1bmN0aW9uLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNGdW5jdGlvbihfKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzRnVuY3Rpb24oL2FiYy8pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNGdW5jdGlvbih2YWx1ZSkge1xuICAgICAgaWYgKCFpc09iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgLy8gVGhlIHVzZSBvZiBgT2JqZWN0I3RvU3RyaW5nYCBhdm9pZHMgaXNzdWVzIHdpdGggdGhlIGB0eXBlb2ZgIG9wZXJhdG9yXG4gICAgICAvLyBpbiBTYWZhcmkgOSB3aGljaCByZXR1cm5zICdvYmplY3QnIGZvciB0eXBlZCBhcnJheXMgYW5kIG90aGVyIGNvbnN0cnVjdG9ycy5cbiAgICAgIHZhciB0YWcgPSBiYXNlR2V0VGFnKHZhbHVlKTtcbiAgICAgIHJldHVybiB0YWcgPT0gZnVuY1RhZyB8fCB0YWcgPT0gZ2VuVGFnIHx8IHRhZyA9PSBhc3luY1RhZyB8fCB0YWcgPT0gcHJveHlUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYW4gaW50ZWdlci5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvblxuICAgICAqIFtgTnVtYmVyLmlzSW50ZWdlcmBdKGh0dHBzOi8vbWRuLmlvL051bWJlci9pc0ludGVnZXIpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBpbnRlZ2VyLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNJbnRlZ2VyKDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNJbnRlZ2VyKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzSW50ZWdlcihJbmZpbml0eSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNJbnRlZ2VyKCczJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0ludGVnZXIodmFsdWUpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgJiYgdmFsdWUgPT0gdG9JbnRlZ2VyKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgbGVuZ3RoLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb25cbiAgICAgKiBbYFRvTGVuZ3RoYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtdG9sZW5ndGgpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGxlbmd0aCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzTGVuZ3RoKDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNMZW5ndGgoTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNMZW5ndGgoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzTGVuZ3RoKCczJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc0xlbmd0aCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJlxuICAgICAgICB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgdGhlXG4gICAgICogW2xhbmd1YWdlIHR5cGVdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1lY21hc2NyaXB0LWxhbmd1YWdlLXR5cGVzKVxuICAgICAqIG9mIGBPYmplY3RgLiAoZS5nLiBhcnJheXMsIGZ1bmN0aW9ucywgb2JqZWN0cywgcmVnZXhlcywgYG5ldyBOdW1iZXIoMClgLCBhbmQgYG5ldyBTdHJpbmcoJycpYClcbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNPYmplY3Qoe30pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNPYmplY3QoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0KF8ubm9vcCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc09iamVjdChudWxsKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgICAgIHJldHVybiB2YWx1ZSAhPSBudWxsICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuIEEgdmFsdWUgaXMgb2JqZWN0LWxpa2UgaWYgaXQncyBub3QgYG51bGxgXG4gICAgICogYW5kIGhhcyBhIGB0eXBlb2ZgIHJlc3VsdCBvZiBcIm9iamVjdFwiLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0TGlrZSh7fSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc09iamVjdExpa2UoWzEsIDIsIDNdKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0TGlrZShfLm5vb3ApO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzT2JqZWN0TGlrZShudWxsKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzT2JqZWN0TGlrZSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgTWFwYCBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4zLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgbWFwLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNNYXAobmV3IE1hcCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc01hcChuZXcgV2Vha01hcCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgaXNNYXAgPSBub2RlSXNNYXAgPyBiYXNlVW5hcnkobm9kZUlzTWFwKSA6IGJhc2VJc01hcDtcblxuICAgIC8qKlxuICAgICAqIFBlcmZvcm1zIGEgcGFydGlhbCBkZWVwIGNvbXBhcmlzb24gYmV0d2VlbiBgb2JqZWN0YCBhbmQgYHNvdXJjZWAgdG9cbiAgICAgKiBkZXRlcm1pbmUgaWYgYG9iamVjdGAgY29udGFpbnMgZXF1aXZhbGVudCBwcm9wZXJ0eSB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgZXF1aXZhbGVudCB0byBgXy5tYXRjaGVzYCB3aGVuIGBzb3VyY2VgIGlzXG4gICAgICogcGFydGlhbGx5IGFwcGxpZWQuXG4gICAgICpcbiAgICAgKiBQYXJ0aWFsIGNvbXBhcmlzb25zIHdpbGwgbWF0Y2ggZW1wdHkgYXJyYXkgYW5kIGVtcHR5IG9iamVjdCBgc291cmNlYFxuICAgICAqIHZhbHVlcyBhZ2FpbnN0IGFueSBhcnJheSBvciBvYmplY3QgdmFsdWUsIHJlc3BlY3RpdmVseS4gU2VlIGBfLmlzRXF1YWxgXG4gICAgICogZm9yIGEgbGlzdCBvZiBzdXBwb3J0ZWQgdmFsdWUgY29tcGFyaXNvbnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBvYmplY3RgIGlzIGEgbWF0Y2gsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxLCAnYic6IDIgfTtcbiAgICAgKlxuICAgICAqIF8uaXNNYXRjaChvYmplY3QsIHsgJ2InOiAyIH0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNNYXRjaChvYmplY3QsIHsgJ2InOiAxIH0pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNNYXRjaChvYmplY3QsIHNvdXJjZSkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PT0gc291cmNlIHx8IGJhc2VJc01hdGNoKG9iamVjdCwgc291cmNlLCBnZXRNYXRjaERhdGEoc291cmNlKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5pc01hdGNoYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjdXN0b21pemVyYCB3aGljaFxuICAgICAqIGlzIGludm9rZWQgdG8gY29tcGFyZSB2YWx1ZXMuIElmIGBjdXN0b21pemVyYCByZXR1cm5zIGB1bmRlZmluZWRgLCBjb21wYXJpc29uc1xuICAgICAqIGFyZSBoYW5kbGVkIGJ5IHRoZSBtZXRob2QgaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYCBpcyBpbnZva2VkIHdpdGggZml2ZVxuICAgICAqIGFyZ3VtZW50czogKG9ialZhbHVlLCBzcmNWYWx1ZSwgaW5kZXh8a2V5LCBvYmplY3QsIHNvdXJjZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaXNvbnMuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBvYmplY3RgIGlzIGEgbWF0Y2gsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gaXNHcmVldGluZyh2YWx1ZSkge1xuICAgICAqICAgcmV0dXJuIC9eaCg/Oml8ZWxsbykkLy50ZXN0KHZhbHVlKTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSkge1xuICAgICAqICAgaWYgKGlzR3JlZXRpbmcob2JqVmFsdWUpICYmIGlzR3JlZXRpbmcoc3JjVmFsdWUpKSB7XG4gICAgICogICAgIHJldHVybiB0cnVlO1xuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdncmVldGluZyc6ICdoZWxsbycgfTtcbiAgICAgKiB2YXIgc291cmNlID0geyAnZ3JlZXRpbmcnOiAnaGknIH07XG4gICAgICpcbiAgICAgKiBfLmlzTWF0Y2hXaXRoKG9iamVjdCwgc291cmNlLCBjdXN0b21pemVyKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNNYXRjaFdpdGgob2JqZWN0LCBzb3VyY2UsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGN1c3RvbWl6ZXIgPSB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nID8gY3VzdG9taXplciA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiBiYXNlSXNNYXRjaChvYmplY3QsIHNvdXJjZSwgZ2V0TWF0Y2hEYXRhKHNvdXJjZSksIGN1c3RvbWl6ZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGBOYU5gLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uXG4gICAgICogW2BOdW1iZXIuaXNOYU5gXShodHRwczovL21kbi5pby9OdW1iZXIvaXNOYU4pIGFuZCBpcyBub3QgdGhlIHNhbWUgYXNcbiAgICAgKiBnbG9iYWwgW2Bpc05hTmBdKGh0dHBzOi8vbWRuLmlvL2lzTmFOKSB3aGljaCByZXR1cm5zIGB0cnVlYCBmb3JcbiAgICAgKiBgdW5kZWZpbmVkYCBhbmQgb3RoZXIgbm9uLW51bWJlciB2YWx1ZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGBOYU5gLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNOYU4oTmFOKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzTmFOKG5ldyBOdW1iZXIoTmFOKSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogaXNOYU4odW5kZWZpbmVkKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzTmFOKHVuZGVmaW5lZCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc05hTih2YWx1ZSkge1xuICAgICAgLy8gQW4gYE5hTmAgcHJpbWl0aXZlIGlzIHRoZSBvbmx5IHZhbHVlIHRoYXQgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi5cbiAgICAgIC8vIFBlcmZvcm0gdGhlIGB0b1N0cmluZ1RhZ2AgY2hlY2sgZmlyc3QgdG8gYXZvaWQgZXJyb3JzIHdpdGggc29tZVxuICAgICAgLy8gQWN0aXZlWCBvYmplY3RzIGluIElFLlxuICAgICAgcmV0dXJuIGlzTnVtYmVyKHZhbHVlKSAmJiB2YWx1ZSAhPSArdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBwcmlzdGluZSBuYXRpdmUgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgY2FuJ3QgcmVsaWFibHkgZGV0ZWN0IG5hdGl2ZSBmdW5jdGlvbnMgaW4gdGhlIHByZXNlbmNlXG4gICAgICogb2YgdGhlIGNvcmUtanMgcGFja2FnZSBiZWNhdXNlIGNvcmUtanMgY2lyY3VtdmVudHMgdGhpcyBraW5kIG9mIGRldGVjdGlvbi5cbiAgICAgKiBEZXNwaXRlIG11bHRpcGxlIHJlcXVlc3RzLCB0aGUgY29yZS1qcyBtYWludGFpbmVyIGhhcyBtYWRlIGl0IGNsZWFyOiBhbnlcbiAgICAgKiBhdHRlbXB0IHRvIGZpeCB0aGUgZGV0ZWN0aW9uIHdpbGwgYmUgb2JzdHJ1Y3RlZC4gQXMgYSByZXN1bHQsIHdlJ3JlIGxlZnRcbiAgICAgKiB3aXRoIGxpdHRsZSBjaG9pY2UgYnV0IHRvIHRocm93IGFuIGVycm9yLiBVbmZvcnR1bmF0ZWx5LCB0aGlzIGFsc28gYWZmZWN0c1xuICAgICAqIHBhY2thZ2VzLCBsaWtlIFtiYWJlbC1wb2x5ZmlsbF0oaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2UvYmFiZWwtcG9seWZpbGwpLFxuICAgICAqIHdoaWNoIHJlbHkgb24gY29yZS1qcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBuYXRpdmUgZnVuY3Rpb24sXG4gICAgICogIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc05hdGl2ZShBcnJheS5wcm90b3R5cGUucHVzaCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc05hdGl2ZShfKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzTmF0aXZlKHZhbHVlKSB7XG4gICAgICBpZiAoaXNNYXNrYWJsZSh2YWx1ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKENPUkVfRVJST1JfVEVYVCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZUlzTmF0aXZlKHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBgbnVsbGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGBudWxsYCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzTnVsbChudWxsKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzTnVsbCh2b2lkIDApO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNOdWxsKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYG51bGxgIG9yIGB1bmRlZmluZWRgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBudWxsaXNoLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNOaWwobnVsbCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc05pbCh2b2lkIDApO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNOaWwoTmFOKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzTmlsKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYE51bWJlcmAgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUbyBleGNsdWRlIGBJbmZpbml0eWAsIGAtSW5maW5pdHlgLCBhbmQgYE5hTmAsIHdoaWNoIGFyZVxuICAgICAqIGNsYXNzaWZpZWQgYXMgbnVtYmVycywgdXNlIHRoZSBgXy5pc0Zpbml0ZWAgbWV0aG9kLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG51bWJlciwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzTnVtYmVyKDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNOdW1iZXIoTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc051bWJlcihJbmZpbml0eSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc051bWJlcignMycpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNOdW1iZXIodmFsdWUpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgfHxcbiAgICAgICAgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gbnVtYmVyVGFnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHBsYWluIG9iamVjdCwgdGhhdCBpcywgYW4gb2JqZWN0IGNyZWF0ZWQgYnkgdGhlXG4gICAgICogYE9iamVjdGAgY29uc3RydWN0b3Igb3Igb25lIHdpdGggYSBgW1tQcm90b3R5cGVdXWAgb2YgYG51bGxgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuOC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHBsYWluIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIF8uaXNQbGFpbk9iamVjdChuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogXy5pc1BsYWluT2JqZWN0KFsxLCAyLCAzXSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaXNQbGFpbk9iamVjdCh7ICd4JzogMCwgJ3knOiAwIH0pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNQbGFpbk9iamVjdChPYmplY3QuY3JlYXRlKG51bGwpKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNQbGFpbk9iamVjdCh2YWx1ZSkge1xuICAgICAgaWYgKCFpc09iamVjdExpa2UodmFsdWUpIHx8IGJhc2VHZXRUYWcodmFsdWUpICE9IG9iamVjdFRhZykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB2YXIgcHJvdG8gPSBnZXRQcm90b3R5cGUodmFsdWUpO1xuICAgICAgaWYgKHByb3RvID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgdmFyIEN0b3IgPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKHByb3RvLCAnY29uc3RydWN0b3InKSAmJiBwcm90by5jb25zdHJ1Y3RvcjtcbiAgICAgIHJldHVybiB0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nICYmIEN0b3IgaW5zdGFuY2VvZiBDdG9yICYmXG4gICAgICAgIGZ1bmNUb1N0cmluZy5jYWxsKEN0b3IpID09IG9iamVjdEN0b3JTdHJpbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBSZWdFeHBgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSByZWdleHAsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc1JlZ0V4cCgvYWJjLyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1JlZ0V4cCgnL2FiYy8nKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBpc1JlZ0V4cCA9IG5vZGVJc1JlZ0V4cCA/IGJhc2VVbmFyeShub2RlSXNSZWdFeHApIDogYmFzZUlzUmVnRXhwO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBzYWZlIGludGVnZXIuIEFuIGludGVnZXIgaXMgc2FmZSBpZiBpdCdzIGFuIElFRUUtNzU0XG4gICAgICogZG91YmxlIHByZWNpc2lvbiBudW1iZXIgd2hpY2ggaXNuJ3QgdGhlIHJlc3VsdCBvZiBhIHJvdW5kZWQgdW5zYWZlIGludGVnZXIuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb25cbiAgICAgKiBbYE51bWJlci5pc1NhZmVJbnRlZ2VyYF0oaHR0cHM6Ly9tZG4uaW8vTnVtYmVyL2lzU2FmZUludGVnZXIpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHNhZmUgaW50ZWdlciwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzU2FmZUludGVnZXIoMyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1NhZmVJbnRlZ2VyKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzU2FmZUludGVnZXIoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmlzU2FmZUludGVnZXIoJzMnKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzU2FmZUludGVnZXIodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc0ludGVnZXIodmFsdWUpICYmIHZhbHVlID49IC1NQVhfU0FGRV9JTlRFR0VSICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTZXRgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjMuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBzZXQsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc1NldChuZXcgU2V0KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmlzU2V0KG5ldyBXZWFrU2V0KTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBpc1NldCA9IG5vZGVJc1NldCA/IGJhc2VVbmFyeShub2RlSXNTZXQpIDogYmFzZUlzU2V0O1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTdHJpbmdgIHByaW1pdGl2ZSBvciBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgc3RyaW5nLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaXNTdHJpbmcoJ2FiYycpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNTdHJpbmcoMSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1N0cmluZyh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJyB8fFxuICAgICAgICAoIWlzQXJyYXkodmFsdWUpICYmIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gc3RyaW5nVGFnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN5bWJvbGAgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBzeW1ib2wsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc1N5bWJvbChTeW1ib2wuaXRlcmF0b3IpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNTeW1ib2woJ2FiYycpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ3N5bWJvbCcgfHxcbiAgICAgICAgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gc3ltYm9sVGFnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgdHlwZWQgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdHlwZWQgYXJyYXksIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5pc1R5cGVkQXJyYXkobmV3IFVpbnQ4QXJyYXkpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaXNUeXBlZEFycmF5KFtdKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBpc1R5cGVkQXJyYXkgPSBub2RlSXNUeXBlZEFycmF5ID8gYmFzZVVuYXJ5KG5vZGVJc1R5cGVkQXJyYXkpIDogYmFzZUlzVHlwZWRBcnJheTtcblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGB1bmRlZmluZWRgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBgdW5kZWZpbmVkYCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzVW5kZWZpbmVkKHZvaWQgMCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1VuZGVmaW5lZChudWxsKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGlzVW5kZWZpbmVkKHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFdlYWtNYXBgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjMuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB3ZWFrIG1hcCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzV2Vha01hcChuZXcgV2Vha01hcCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1dlYWtNYXAobmV3IE1hcCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1dlYWtNYXAodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGdldFRhZyh2YWx1ZSkgPT0gd2Vha01hcFRhZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFdlYWtTZXRgIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjMuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB3ZWFrIHNldCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmlzV2Vha1NldChuZXcgV2Vha1NldCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pc1dlYWtTZXQobmV3IFNldCk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpc1dlYWtTZXQodmFsdWUpIHtcbiAgICAgIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IHdlYWtTZXRUYWc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGVzcyB0aGFuIGBvdGhlcmAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy45LjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gICAgICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBsZXNzIHRoYW4gYG90aGVyYCxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBzZWUgXy5ndFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmx0KDEsIDMpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8ubHQoMywgMyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8ubHQoMywgMSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICB2YXIgbHQgPSBjcmVhdGVSZWxhdGlvbmFsT3BlcmF0aW9uKGJhc2VMdCk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gYG90aGVyYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjkuMFxuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0b1xuICAgICAqICBgb3RoZXJgLCBlbHNlIGBmYWxzZWAuXG4gICAgICogQHNlZSBfLmd0ZVxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmx0ZSgxLCAzKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmx0ZSgzLCAzKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmx0ZSgzLCAxKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqL1xuICAgIHZhciBsdGUgPSBjcmVhdGVSZWxhdGlvbmFsT3BlcmF0aW9uKGZ1bmN0aW9uKHZhbHVlLCBvdGhlcikge1xuICAgICAgcmV0dXJuIHZhbHVlIDw9IG90aGVyO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhbiBhcnJheS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBMYW5nXG4gICAgICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b0FycmF5KHsgJ2EnOiAxLCAnYic6IDIgfSk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICpcbiAgICAgKiBfLnRvQXJyYXkoJ2FiYycpO1xuICAgICAqIC8vID0+IFsnYScsICdiJywgJ2MnXVxuICAgICAqXG4gICAgICogXy50b0FycmF5KDEpO1xuICAgICAqIC8vID0+IFtdXG4gICAgICpcbiAgICAgKiBfLnRvQXJyYXkobnVsbCk7XG4gICAgICogLy8gPT4gW11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b0FycmF5KHZhbHVlKSB7XG4gICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIGlmIChpc0FycmF5TGlrZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGlzU3RyaW5nKHZhbHVlKSA/IHN0cmluZ1RvQXJyYXkodmFsdWUpIDogY29weUFycmF5KHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIGlmIChzeW1JdGVyYXRvciAmJiB2YWx1ZVtzeW1JdGVyYXRvcl0pIHtcbiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yVG9BcnJheSh2YWx1ZVtzeW1JdGVyYXRvcl0oKSk7XG4gICAgICB9XG4gICAgICB2YXIgdGFnID0gZ2V0VGFnKHZhbHVlKSxcbiAgICAgICAgICBmdW5jID0gdGFnID09IG1hcFRhZyA/IG1hcFRvQXJyYXkgOiAodGFnID09IHNldFRhZyA/IHNldFRvQXJyYXkgOiB2YWx1ZXMpO1xuXG4gICAgICByZXR1cm4gZnVuYyh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhIGZpbml0ZSBudW1iZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xMi4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBudW1iZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udG9GaW5pdGUoMy4yKTtcbiAgICAgKiAvLyA9PiAzLjJcbiAgICAgKlxuICAgICAqIF8udG9GaW5pdGUoTnVtYmVyLk1JTl9WQUxVRSk7XG4gICAgICogLy8gPT4gNWUtMzI0XG4gICAgICpcbiAgICAgKiBfLnRvRmluaXRlKEluZmluaXR5KTtcbiAgICAgKiAvLyA9PiAxLjc5NzY5MzEzNDg2MjMxNTdlKzMwOFxuICAgICAqXG4gICAgICogXy50b0Zpbml0ZSgnMy4yJyk7XG4gICAgICogLy8gPT4gMy4yXG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9GaW5pdGUodmFsdWUpIHtcbiAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiAwO1xuICAgICAgfVxuICAgICAgdmFsdWUgPSB0b051bWJlcih2YWx1ZSk7XG4gICAgICBpZiAodmFsdWUgPT09IElORklOSVRZIHx8IHZhbHVlID09PSAtSU5GSU5JVFkpIHtcbiAgICAgICAgdmFyIHNpZ24gPSAodmFsdWUgPCAwID8gLTEgOiAxKTtcbiAgICAgICAgcmV0dXJuIHNpZ24gKiBNQVhfSU5URUdFUjtcbiAgICAgIH1cbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gdmFsdWUgPyB2YWx1ZSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhbiBpbnRlZ2VyLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb25cbiAgICAgKiBbYFRvSW50ZWdlcmBdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy10b2ludGVnZXIpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBpbnRlZ2VyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRvSW50ZWdlcigzLjIpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8udG9JbnRlZ2VyKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IDBcbiAgICAgKlxuICAgICAqIF8udG9JbnRlZ2VyKEluZmluaXR5KTtcbiAgICAgKiAvLyA9PiAxLjc5NzY5MzEzNDg2MjMxNTdlKzMwOFxuICAgICAqXG4gICAgICogXy50b0ludGVnZXIoJzMuMicpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b0ludGVnZXIodmFsdWUpIHtcbiAgICAgIHZhciByZXN1bHQgPSB0b0Zpbml0ZSh2YWx1ZSksXG4gICAgICAgICAgcmVtYWluZGVyID0gcmVzdWx0ICUgMTtcblxuICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gcmVzdWx0ID8gKHJlbWFpbmRlciA/IHJlc3VsdCAtIHJlbWFpbmRlciA6IHJlc3VsdCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYW4gaW50ZWdlciBzdWl0YWJsZSBmb3IgdXNlIGFzIHRoZSBsZW5ndGggb2YgYW5cbiAgICAgKiBhcnJheS1saWtlIG9iamVjdC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvblxuICAgICAqIFtgVG9MZW5ndGhgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy10b2xlbmd0aCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY29udmVydGVkIGludGVnZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udG9MZW5ndGgoMy4yKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiBfLnRvTGVuZ3RoKE51bWJlci5NSU5fVkFMVUUpO1xuICAgICAqIC8vID0+IDBcbiAgICAgKlxuICAgICAqIF8udG9MZW5ndGgoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IDQyOTQ5NjcyOTVcbiAgICAgKlxuICAgICAqIF8udG9MZW5ndGgoJzMuMicpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b0xlbmd0aCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID8gYmFzZUNsYW1wKHRvSW50ZWdlcih2YWx1ZSksIDAsIE1BWF9BUlJBWV9MRU5HVEgpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgbnVtYmVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IExhbmdcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG51bWJlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b051bWJlcigzLjIpO1xuICAgICAqIC8vID0+IDMuMlxuICAgICAqXG4gICAgICogXy50b051bWJlcihOdW1iZXIuTUlOX1ZBTFVFKTtcbiAgICAgKiAvLyA9PiA1ZS0zMjRcbiAgICAgKlxuICAgICAqIF8udG9OdW1iZXIoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IEluZmluaXR5XG4gICAgICpcbiAgICAgKiBfLnRvTnVtYmVyKCczLjInKTtcbiAgICAgKiAvLyA9PiAzLjJcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b051bWJlcih2YWx1ZSkge1xuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICBpZiAoaXNTeW1ib2wodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBOQU47XG4gICAgICB9XG4gICAgICBpZiAoaXNPYmplY3QodmFsdWUpKSB7XG4gICAgICAgIHZhciBvdGhlciA9IHR5cGVvZiB2YWx1ZS52YWx1ZU9mID09ICdmdW5jdGlvbicgPyB2YWx1ZS52YWx1ZU9mKCkgOiB2YWx1ZTtcbiAgICAgICAgdmFsdWUgPSBpc09iamVjdChvdGhlcikgPyAob3RoZXIgKyAnJykgOiBvdGhlcjtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiArdmFsdWU7XG4gICAgICB9XG4gICAgICB2YWx1ZSA9IHZhbHVlLnJlcGxhY2UocmVUcmltLCAnJyk7XG4gICAgICB2YXIgaXNCaW5hcnkgPSByZUlzQmluYXJ5LnRlc3QodmFsdWUpO1xuICAgICAgcmV0dXJuIChpc0JpbmFyeSB8fCByZUlzT2N0YWwudGVzdCh2YWx1ZSkpXG4gICAgICAgID8gZnJlZVBhcnNlSW50KHZhbHVlLnNsaWNlKDIpLCBpc0JpbmFyeSA/IDIgOiA4KVxuICAgICAgICA6IChyZUlzQmFkSGV4LnRlc3QodmFsdWUpID8gTkFOIDogK3ZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgcGxhaW4gb2JqZWN0IGZsYXR0ZW5pbmcgaW5oZXJpdGVkIGVudW1lcmFibGUgc3RyaW5nXG4gICAgICoga2V5ZWQgcHJvcGVydGllcyBvZiBgdmFsdWVgIHRvIG93biBwcm9wZXJ0aWVzIG9mIHRoZSBwbGFpbiBvYmplY3QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY29udmVydGVkIHBsYWluIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy5hc3NpZ24oeyAnYSc6IDEgfSwgbmV3IEZvbyk7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdiJzogMiB9XG4gICAgICpcbiAgICAgKiBfLmFzc2lnbih7ICdhJzogMSB9LCBfLnRvUGxhaW5PYmplY3QobmV3IEZvbykpO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMyB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9QbGFpbk9iamVjdCh2YWx1ZSkge1xuICAgICAgcmV0dXJuIGNvcHlPYmplY3QodmFsdWUsIGtleXNJbih2YWx1ZSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYSBzYWZlIGludGVnZXIuIEEgc2FmZSBpbnRlZ2VyIGNhbiBiZSBjb21wYXJlZCBhbmRcbiAgICAgKiByZXByZXNlbnRlZCBjb3JyZWN0bHkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY29udmVydGVkIGludGVnZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udG9TYWZlSW50ZWdlcigzLjIpO1xuICAgICAqIC8vID0+IDNcbiAgICAgKlxuICAgICAqIF8udG9TYWZlSW50ZWdlcihOdW1iZXIuTUlOX1ZBTFVFKTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICpcbiAgICAgKiBfLnRvU2FmZUludGVnZXIoSW5maW5pdHkpO1xuICAgICAqIC8vID0+IDkwMDcxOTkyNTQ3NDA5OTFcbiAgICAgKlxuICAgICAqIF8udG9TYWZlSW50ZWdlcignMy4yJyk7XG4gICAgICogLy8gPT4gM1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvU2FmZUludGVnZXIodmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZVxuICAgICAgICA/IGJhc2VDbGFtcCh0b0ludGVnZXIodmFsdWUpLCAtTUFYX1NBRkVfSU5URUdFUiwgTUFYX1NBRkVfSU5URUdFUilcbiAgICAgICAgOiAodmFsdWUgPT09IDAgPyB2YWx1ZSA6IDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYSBzdHJpbmcuIEFuIGVtcHR5IHN0cmluZyBpcyByZXR1cm5lZCBmb3IgYG51bGxgXG4gICAgICogYW5kIGB1bmRlZmluZWRgIHZhbHVlcy4gVGhlIHNpZ24gb2YgYC0wYCBpcyBwcmVzZXJ2ZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTGFuZ1xuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgY29udmVydGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b1N0cmluZyhudWxsKTtcbiAgICAgKiAvLyA9PiAnJ1xuICAgICAqXG4gICAgICogXy50b1N0cmluZygtMCk7XG4gICAgICogLy8gPT4gJy0wJ1xuICAgICAqXG4gICAgICogXy50b1N0cmluZyhbMSwgMiwgM10pO1xuICAgICAqIC8vID0+ICcxLDIsMydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0b1N0cmluZyh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlID09IG51bGwgPyAnJyA6IGJhc2VUb1N0cmluZyh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQXNzaWducyBvd24gZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllcyBvZiBzb3VyY2Ugb2JqZWN0cyB0byB0aGVcbiAgICAgKiBkZXN0aW5hdGlvbiBvYmplY3QuIFNvdXJjZSBvYmplY3RzIGFyZSBhcHBsaWVkIGZyb20gbGVmdCB0byByaWdodC5cbiAgICAgKiBTdWJzZXF1ZW50IHNvdXJjZXMgb3ZlcndyaXRlIHByb3BlcnR5IGFzc2lnbm1lbnRzIG9mIHByZXZpb3VzIHNvdXJjZXMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YCBhbmQgaXMgbG9vc2VseSBiYXNlZCBvblxuICAgICAqIFtgT2JqZWN0LmFzc2lnbmBdKGh0dHBzOi8vbWRuLmlvL09iamVjdC9hc3NpZ24pLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuMTAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi5PYmplY3R9IFtzb3VyY2VzXSBUaGUgc291cmNlIG9iamVjdHMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAc2VlIF8uYXNzaWduSW5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBCYXIoKSB7XG4gICAgICogICB0aGlzLmMgPSAzO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYiA9IDI7XG4gICAgICogQmFyLnByb3RvdHlwZS5kID0gNDtcbiAgICAgKlxuICAgICAqIF8uYXNzaWduKHsgJ2EnOiAwIH0sIG5ldyBGb28sIG5ldyBCYXIpO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYyc6IDMgfVxuICAgICAqL1xuICAgIHZhciBhc3NpZ24gPSBjcmVhdGVBc3NpZ25lcihmdW5jdGlvbihvYmplY3QsIHNvdXJjZSkge1xuICAgICAgaWYgKGlzUHJvdG90eXBlKHNvdXJjZSkgfHwgaXNBcnJheUxpa2Uoc291cmNlKSkge1xuICAgICAgICBjb3B5T2JqZWN0KHNvdXJjZSwga2V5cyhzb3VyY2UpLCBvYmplY3QpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7XG4gICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkge1xuICAgICAgICAgIGFzc2lnblZhbHVlKG9iamVjdCwga2V5LCBzb3VyY2Vba2V5XSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uYXNzaWduYCBleGNlcHQgdGhhdCBpdCBpdGVyYXRlcyBvdmVyIG93biBhbmRcbiAgICAgKiBpbmhlcml0ZWQgc291cmNlIHByb3BlcnRpZXMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBhbGlhcyBleHRlbmRcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uT2JqZWN0fSBbc291cmNlc10gVGhlIHNvdXJjZSBvYmplY3RzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQHNlZSBfLmFzc2lnblxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEJhcigpIHtcbiAgICAgKiAgIHRoaXMuYyA9IDM7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5iID0gMjtcbiAgICAgKiBCYXIucHJvdG90eXBlLmQgPSA0O1xuICAgICAqXG4gICAgICogXy5hc3NpZ25Jbih7ICdhJzogMCB9LCBuZXcgRm9vLCBuZXcgQmFyKTtcbiAgICAgKiAvLyA9PiB7ICdhJzogMSwgJ2InOiAyLCAnYyc6IDMsICdkJzogNCB9XG4gICAgICovXG4gICAgdmFyIGFzc2lnbkluID0gY3JlYXRlQXNzaWduZXIoZnVuY3Rpb24ob2JqZWN0LCBzb3VyY2UpIHtcbiAgICAgIGNvcHlPYmplY3Qoc291cmNlLCBrZXlzSW4oc291cmNlKSwgb2JqZWN0KTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uYXNzaWduSW5gIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGN1c3RvbWl6ZXJgXG4gICAgICogd2hpY2ggaXMgaW52b2tlZCB0byBwcm9kdWNlIHRoZSBhc3NpZ25lZCB2YWx1ZXMuIElmIGBjdXN0b21pemVyYCByZXR1cm5zXG4gICAgICogYHVuZGVmaW5lZGAsIGFzc2lnbm1lbnQgaXMgaGFuZGxlZCBieSB0aGUgbWV0aG9kIGluc3RlYWQuIFRoZSBgY3VzdG9taXplcmBcbiAgICAgKiBpcyBpbnZva2VkIHdpdGggZml2ZSBhcmd1bWVudHM6IChvYmpWYWx1ZSwgc3JjVmFsdWUsIGtleSwgb2JqZWN0LCBzb3VyY2UpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAYWxpYXMgZXh0ZW5kV2l0aFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi5PYmplY3R9IHNvdXJjZXMgVGhlIHNvdXJjZSBvYmplY3RzLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGFzc2lnbmVkIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBzZWUgXy5hc3NpZ25XaXRoXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIGN1c3RvbWl6ZXIob2JqVmFsdWUsIHNyY1ZhbHVlKSB7XG4gICAgICogICByZXR1cm4gXy5pc1VuZGVmaW5lZChvYmpWYWx1ZSkgPyBzcmNWYWx1ZSA6IG9ialZhbHVlO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIHZhciBkZWZhdWx0cyA9IF8ucGFydGlhbFJpZ2h0KF8uYXNzaWduSW5XaXRoLCBjdXN0b21pemVyKTtcbiAgICAgKlxuICAgICAqIGRlZmF1bHRzKHsgJ2EnOiAxIH0sIHsgJ2InOiAyIH0sIHsgJ2EnOiAzIH0pO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYic6IDIgfVxuICAgICAqL1xuICAgIHZhciBhc3NpZ25JbldpdGggPSBjcmVhdGVBc3NpZ25lcihmdW5jdGlvbihvYmplY3QsIHNvdXJjZSwgc3JjSW5kZXgsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGNvcHlPYmplY3Qoc291cmNlLCBrZXlzSW4oc291cmNlKSwgb2JqZWN0LCBjdXN0b21pemVyKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uYXNzaWduYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjdXN0b21pemVyYFxuICAgICAqIHdoaWNoIGlzIGludm9rZWQgdG8gcHJvZHVjZSB0aGUgYXNzaWduZWQgdmFsdWVzLiBJZiBgY3VzdG9taXplcmAgcmV0dXJuc1xuICAgICAqIGB1bmRlZmluZWRgLCBhc3NpZ25tZW50IGlzIGhhbmRsZWQgYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgXG4gICAgICogaXMgaW52b2tlZCB3aXRoIGZpdmUgYXJndW1lbnRzOiAob2JqVmFsdWUsIHNyY1ZhbHVlLCBrZXksIG9iamVjdCwgc291cmNlKS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gey4uLk9iamVjdH0gc291cmNlcyBUaGUgc291cmNlIG9iamVjdHMuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgYXNzaWduZWQgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQHNlZSBfLmFzc2lnbkluV2l0aFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSkge1xuICAgICAqICAgcmV0dXJuIF8uaXNVbmRlZmluZWQob2JqVmFsdWUpID8gc3JjVmFsdWUgOiBvYmpWYWx1ZTtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiB2YXIgZGVmYXVsdHMgPSBfLnBhcnRpYWxSaWdodChfLmFzc2lnbldpdGgsIGN1c3RvbWl6ZXIpO1xuICAgICAqXG4gICAgICogZGVmYXVsdHMoeyAnYSc6IDEgfSwgeyAnYic6IDIgfSwgeyAnYSc6IDMgfSk7XG4gICAgICogLy8gPT4geyAnYSc6IDEsICdiJzogMiB9XG4gICAgICovXG4gICAgdmFyIGFzc2lnbldpdGggPSBjcmVhdGVBc3NpZ25lcihmdW5jdGlvbihvYmplY3QsIHNvdXJjZSwgc3JjSW5kZXgsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGNvcHlPYmplY3Qoc291cmNlLCBrZXlzKHNvdXJjZSksIG9iamVjdCwgY3VzdG9taXplcik7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIHZhbHVlcyBjb3JyZXNwb25kaW5nIHRvIGBwYXRoc2Agb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMS4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0gey4uLihzdHJpbmd8c3RyaW5nW10pfSBbcGF0aHNdIFRoZSBwcm9wZXJ0eSBwYXRocyB0byBwaWNrLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcGlja2VkIHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiBbeyAnYic6IHsgJ2MnOiAzIH0gfSwgNF0gfTtcbiAgICAgKlxuICAgICAqIF8uYXQob2JqZWN0LCBbJ2FbMF0uYi5jJywgJ2FbMV0nXSk7XG4gICAgICogLy8gPT4gWzMsIDRdXG4gICAgICovXG4gICAgdmFyIGF0ID0gZmxhdFJlc3QoYmFzZUF0KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gb2JqZWN0IHRoYXQgaW5oZXJpdHMgZnJvbSB0aGUgYHByb3RvdHlwZWAgb2JqZWN0LiBJZiBhXG4gICAgICogYHByb3BlcnRpZXNgIG9iamVjdCBpcyBnaXZlbiwgaXRzIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0aWVzXG4gICAgICogYXJlIGFzc2lnbmVkIHRvIHRoZSBjcmVhdGVkIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjMuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcHJvdG90eXBlIFRoZSBvYmplY3QgdG8gaW5oZXJpdCBmcm9tLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbcHJvcGVydGllc10gVGhlIHByb3BlcnRpZXMgdG8gYXNzaWduIHRvIHRoZSBvYmplY3QuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gU2hhcGUoKSB7XG4gICAgICogICB0aGlzLnggPSAwO1xuICAgICAqICAgdGhpcy55ID0gMDtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBDaXJjbGUoKSB7XG4gICAgICogICBTaGFwZS5jYWxsKHRoaXMpO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIENpcmNsZS5wcm90b3R5cGUgPSBfLmNyZWF0ZShTaGFwZS5wcm90b3R5cGUsIHtcbiAgICAgKiAgICdjb25zdHJ1Y3Rvcic6IENpcmNsZVxuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogdmFyIGNpcmNsZSA9IG5ldyBDaXJjbGU7XG4gICAgICogY2lyY2xlIGluc3RhbmNlb2YgQ2lyY2xlO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIGNpcmNsZSBpbnN0YW5jZW9mIFNoYXBlO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjcmVhdGUocHJvdG90eXBlLCBwcm9wZXJ0aWVzKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gYmFzZUNyZWF0ZShwcm90b3R5cGUpO1xuICAgICAgcmV0dXJuIHByb3BlcnRpZXMgPT0gbnVsbCA/IHJlc3VsdCA6IGJhc2VBc3NpZ24ocmVzdWx0LCBwcm9wZXJ0aWVzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBc3NpZ25zIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnRpZXMgb2Ygc291cmNlXG4gICAgICogb2JqZWN0cyB0byB0aGUgZGVzdGluYXRpb24gb2JqZWN0IGZvciBhbGwgZGVzdGluYXRpb24gcHJvcGVydGllcyB0aGF0XG4gICAgICogcmVzb2x2ZSB0byBgdW5kZWZpbmVkYC4gU291cmNlIG9iamVjdHMgYXJlIGFwcGxpZWQgZnJvbSBsZWZ0IHRvIHJpZ2h0LlxuICAgICAqIE9uY2UgYSBwcm9wZXJ0eSBpcyBzZXQsIGFkZGl0aW9uYWwgdmFsdWVzIG9mIHRoZSBzYW1lIHByb3BlcnR5IGFyZSBpZ25vcmVkLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uT2JqZWN0fSBbc291cmNlc10gVGhlIHNvdXJjZSBvYmplY3RzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQHNlZSBfLmRlZmF1bHRzRGVlcFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmRlZmF1bHRzKHsgJ2EnOiAxIH0sIHsgJ2InOiAyIH0sIHsgJ2EnOiAzIH0pO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYic6IDIgfVxuICAgICAqL1xuICAgIHZhciBkZWZhdWx0cyA9IGJhc2VSZXN0KGZ1bmN0aW9uKG9iamVjdCwgc291cmNlcykge1xuICAgICAgb2JqZWN0ID0gT2JqZWN0KG9iamVjdCk7XG5cbiAgICAgIHZhciBpbmRleCA9IC0xO1xuICAgICAgdmFyIGxlbmd0aCA9IHNvdXJjZXMubGVuZ3RoO1xuICAgICAgdmFyIGd1YXJkID0gbGVuZ3RoID4gMiA/IHNvdXJjZXNbMl0gOiB1bmRlZmluZWQ7XG5cbiAgICAgIGlmIChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbChzb3VyY2VzWzBdLCBzb3VyY2VzWzFdLCBndWFyZCkpIHtcbiAgICAgICAgbGVuZ3RoID0gMTtcbiAgICAgIH1cblxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHNvdXJjZSA9IHNvdXJjZXNbaW5kZXhdO1xuICAgICAgICB2YXIgcHJvcHMgPSBrZXlzSW4oc291cmNlKTtcbiAgICAgICAgdmFyIHByb3BzSW5kZXggPSAtMTtcbiAgICAgICAgdmFyIHByb3BzTGVuZ3RoID0gcHJvcHMubGVuZ3RoO1xuXG4gICAgICAgIHdoaWxlICgrK3Byb3BzSW5kZXggPCBwcm9wc0xlbmd0aCkge1xuICAgICAgICAgIHZhciBrZXkgPSBwcm9wc1twcm9wc0luZGV4XTtcbiAgICAgICAgICB2YXIgdmFsdWUgPSBvYmplY3Rba2V5XTtcblxuICAgICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgICAgIChlcSh2YWx1ZSwgb2JqZWN0UHJvdG9ba2V5XSkgJiYgIWhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSkge1xuICAgICAgICAgICAgb2JqZWN0W2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZGVmYXVsdHNgIGV4Y2VwdCB0aGF0IGl0IHJlY3Vyc2l2ZWx5IGFzc2lnbnNcbiAgICAgKiBkZWZhdWx0IHByb3BlcnRpZXMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjEwLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uT2JqZWN0fSBbc291cmNlc10gVGhlIHNvdXJjZSBvYmplY3RzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQHNlZSBfLmRlZmF1bHRzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZGVmYXVsdHNEZWVwKHsgJ2EnOiB7ICdiJzogMiB9IH0sIHsgJ2EnOiB7ICdiJzogMSwgJ2MnOiAzIH0gfSk7XG4gICAgICogLy8gPT4geyAnYSc6IHsgJ2InOiAyLCAnYyc6IDMgfSB9XG4gICAgICovXG4gICAgdmFyIGRlZmF1bHRzRGVlcCA9IGJhc2VSZXN0KGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgIGFyZ3MucHVzaCh1bmRlZmluZWQsIGN1c3RvbURlZmF1bHRzTWVyZ2UpO1xuICAgICAgcmV0dXJuIGFwcGx5KG1lcmdlV2l0aCwgdW5kZWZpbmVkLCBhcmdzKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZmluZGAgZXhjZXB0IHRoYXQgaXQgcmV0dXJucyB0aGUga2V5IG9mIHRoZSBmaXJzdFxuICAgICAqIGVsZW1lbnQgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yIGluc3RlYWQgb2YgdGhlIGVsZW1lbnQgaXRzZWxmLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDEuMS4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfHVuZGVmaW5lZH0gUmV0dXJucyB0aGUga2V5IG9mIHRoZSBtYXRjaGVkIGVsZW1lbnQsXG4gICAgICogIGVsc2UgYHVuZGVmaW5lZGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IHtcbiAgICAgKiAgICdiYXJuZXknOiAgeyAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICAnZnJlZCc6ICAgIHsgJ2FnZSc6IDQwLCAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgICdwZWJibGVzJzogeyAnYWdlJzogMSwgICdhY3RpdmUnOiB0cnVlIH1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogXy5maW5kS2V5KHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLmFnZSA8IDQwOyB9KTtcbiAgICAgKiAvLyA9PiAnYmFybmV5JyAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmRLZXkodXNlcnMsIHsgJ2FnZSc6IDEsICdhY3RpdmUnOiB0cnVlIH0pO1xuICAgICAqIC8vID0+ICdwZWJibGVzJ1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uZmluZEtleSh1c2VycywgWydhY3RpdmUnLCBmYWxzZV0pO1xuICAgICAqIC8vID0+ICdmcmVkJ1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maW5kS2V5KHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gJ2Jhcm5leSdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmaW5kS2V5KG9iamVjdCwgcHJlZGljYXRlKSB7XG4gICAgICByZXR1cm4gYmFzZUZpbmRLZXkob2JqZWN0LCBnZXRJdGVyYXRlZShwcmVkaWNhdGUsIDMpLCBiYXNlRm9yT3duKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmZpbmRLZXlgIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2ZcbiAgICAgKiBhIGNvbGxlY3Rpb24gaW4gdGhlIG9wcG9zaXRlIG9yZGVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfHVuZGVmaW5lZH0gUmV0dXJucyB0aGUga2V5IG9mIHRoZSBtYXRjaGVkIGVsZW1lbnQsXG4gICAgICogIGVsc2UgYHVuZGVmaW5lZGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB1c2VycyA9IHtcbiAgICAgKiAgICdiYXJuZXknOiAgeyAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICAnZnJlZCc6ICAgIHsgJ2FnZSc6IDQwLCAnYWN0aXZlJzogZmFsc2UgfSxcbiAgICAgKiAgICdwZWJibGVzJzogeyAnYWdlJzogMSwgICdhY3RpdmUnOiB0cnVlIH1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogXy5maW5kTGFzdEtleSh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gby5hZ2UgPCA0MDsgfSk7XG4gICAgICogLy8gPT4gcmV0dXJucyAncGViYmxlcycgYXNzdW1pbmcgYF8uZmluZEtleWAgcmV0dXJucyAnYmFybmV5J1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmRMYXN0S2V5KHVzZXJzLCB7ICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IHRydWUgfSk7XG4gICAgICogLy8gPT4gJ2Jhcm5leSdcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmRMYXN0S2V5KHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gICAgICogLy8gPT4gJ2ZyZWQnXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbmRMYXN0S2V5KHVzZXJzLCAnYWN0aXZlJyk7XG4gICAgICogLy8gPT4gJ3BlYmJsZXMnXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmluZExhc3RLZXkob2JqZWN0LCBwcmVkaWNhdGUpIHtcbiAgICAgIHJldHVybiBiYXNlRmluZEtleShvYmplY3QsIGdldEl0ZXJhdGVlKHByZWRpY2F0ZSwgMyksIGJhc2VGb3JPd25SaWdodCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSXRlcmF0ZXMgb3ZlciBvd24gYW5kIGluaGVyaXRlZCBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0aWVzIG9mIGFuXG4gICAgICogb2JqZWN0IGFuZCBpbnZva2VzIGBpdGVyYXRlZWAgZm9yIGVhY2ggcHJvcGVydHkuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkXG4gICAgICogd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwga2V5LCBvYmplY3QpLiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXRcbiAgICAgKiBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjMuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQHNlZSBfLmZvckluUmlnaHRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8uZm9ySW4obmV3IEZvbywgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAqICAgY29uc29sZS5sb2coa2V5KTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiBMb2dzICdhJywgJ2InLCB0aGVuICdjJyAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmb3JJbihvYmplY3QsIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGxcbiAgICAgICAgPyBvYmplY3RcbiAgICAgICAgOiBiYXNlRm9yKG9iamVjdCwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDMpLCBrZXlzSW4pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZm9ySW5gIGV4Y2VwdCB0aGF0IGl0IGl0ZXJhdGVzIG92ZXIgcHJvcGVydGllcyBvZlxuICAgICAqIGBvYmplY3RgIGluIHRoZSBvcHBvc2l0ZSBvcmRlci5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAyLjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQHNlZSBfLmZvckluXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLmZvckluUmlnaHQobmV3IEZvbywgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAqICAgY29uc29sZS5sb2coa2V5KTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiBMb2dzICdjJywgJ2InLCB0aGVuICdhJyBhc3N1bWluZyBgXy5mb3JJbmAgbG9ncyAnYScsICdiJywgdGhlbiAnYycuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZm9ySW5SaWdodChvYmplY3QsIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGxcbiAgICAgICAgPyBvYmplY3RcbiAgICAgICAgOiBiYXNlRm9yUmlnaHQob2JqZWN0LCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMyksIGtleXNJbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSXRlcmF0ZXMgb3ZlciBvd24gZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllcyBvZiBhbiBvYmplY3QgYW5kXG4gICAgICogaW52b2tlcyBgaXRlcmF0ZWVgIGZvciBlYWNoIHByb3BlcnR5LiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIHRocmVlXG4gICAgICogYXJndW1lbnRzOiAodmFsdWUsIGtleSwgb2JqZWN0KS4gSXRlcmF0ZWUgZnVuY3Rpb25zIG1heSBleGl0IGl0ZXJhdGlvblxuICAgICAqIGVhcmx5IGJ5IGV4cGxpY2l0bHkgcmV0dXJuaW5nIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC4zLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBzZWUgXy5mb3JPd25SaWdodFxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy5mb3JPd24obmV3IEZvbywgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAqICAgY29uc29sZS5sb2coa2V5KTtcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiBMb2dzICdhJyB0aGVuICdiJyAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmb3JPd24ob2JqZWN0LCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIG9iamVjdCAmJiBiYXNlRm9yT3duKG9iamVjdCwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDMpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmZvck93bmAgZXhjZXB0IHRoYXQgaXQgaXRlcmF0ZXMgb3ZlciBwcm9wZXJ0aWVzIG9mXG4gICAgICogYG9iamVjdGAgaW4gdGhlIG9wcG9zaXRlIG9yZGVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAc2VlIF8uZm9yT3duXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLmZvck93blJpZ2h0KG5ldyBGb28sIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgKiAgIGNvbnNvbGUubG9nKGtleSk7XG4gICAgICogfSk7XG4gICAgICogLy8gPT4gTG9ncyAnYicgdGhlbiAnYScgYXNzdW1pbmcgYF8uZm9yT3duYCBsb2dzICdhJyB0aGVuICdiJy5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmb3JPd25SaWdodChvYmplY3QsIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ICYmIGJhc2VGb3JPd25SaWdodChvYmplY3QsIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAzKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBmdW5jdGlvbiBwcm9wZXJ0eSBuYW1lcyBmcm9tIG93biBlbnVtZXJhYmxlIHByb3BlcnRpZXNcbiAgICAgKiBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW5zcGVjdC5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGZ1bmN0aW9uIG5hbWVzLlxuICAgICAqIEBzZWUgXy5mdW5jdGlvbnNJblxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSBfLmNvbnN0YW50KCdhJyk7XG4gICAgICogICB0aGlzLmIgPSBfLmNvbnN0YW50KCdiJyk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gXy5jb25zdGFudCgnYycpO1xuICAgICAqXG4gICAgICogXy5mdW5jdGlvbnMobmV3IEZvbyk7XG4gICAgICogLy8gPT4gWydhJywgJ2InXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZ1bmN0aW9ucyhvYmplY3QpIHtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IFtdIDogYmFzZUZ1bmN0aW9ucyhvYmplY3QsIGtleXMob2JqZWN0KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBmdW5jdGlvbiBwcm9wZXJ0eSBuYW1lcyBmcm9tIG93biBhbmQgaW5oZXJpdGVkXG4gICAgICogZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgZnVuY3Rpb24gbmFtZXMuXG4gICAgICogQHNlZSBfLmZ1bmN0aW9uc1xuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSBfLmNvbnN0YW50KCdhJyk7XG4gICAgICogICB0aGlzLmIgPSBfLmNvbnN0YW50KCdiJyk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gXy5jb25zdGFudCgnYycpO1xuICAgICAqXG4gICAgICogXy5mdW5jdGlvbnNJbihuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBbJ2EnLCAnYicsICdjJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBmdW5jdGlvbnNJbihvYmplY3QpIHtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IFtdIDogYmFzZUZ1bmN0aW9ucyhvYmplY3QsIGtleXNJbihvYmplY3QpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSB2YWx1ZSBhdCBgcGF0aGAgb2YgYG9iamVjdGAuIElmIHRoZSByZXNvbHZlZCB2YWx1ZSBpc1xuICAgICAqIGB1bmRlZmluZWRgLCB0aGUgYGRlZmF1bHRWYWx1ZWAgaXMgcmV0dXJuZWQgaW4gaXRzIHBsYWNlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuNy4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gW2RlZmF1bHRWYWx1ZV0gVGhlIHZhbHVlIHJldHVybmVkIGZvciBgdW5kZWZpbmVkYCByZXNvbHZlZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc29sdmVkIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYyc6IDMgfSB9XSB9O1xuICAgICAqXG4gICAgICogXy5nZXQob2JqZWN0LCAnYVswXS5iLmMnKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiBfLmdldChvYmplY3QsIFsnYScsICcwJywgJ2InLCAnYyddKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiBfLmdldChvYmplY3QsICdhLmIuYycsICdkZWZhdWx0Jyk7XG4gICAgICogLy8gPT4gJ2RlZmF1bHQnXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0KG9iamVjdCwgcGF0aCwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBiYXNlR2V0KG9iamVjdCwgcGF0aCk7XG4gICAgICByZXR1cm4gcmVzdWx0ID09PSB1bmRlZmluZWQgPyBkZWZhdWx0VmFsdWUgOiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBwYXRoYCBpcyBhIGRpcmVjdCBwcm9wZXJ0eSBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBwYXRoYCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiB7ICdiJzogMiB9IH07XG4gICAgICogdmFyIG90aGVyID0gXy5jcmVhdGUoeyAnYSc6IF8uY3JlYXRlKHsgJ2InOiAyIH0pIH0pO1xuICAgICAqXG4gICAgICogXy5oYXMob2JqZWN0LCAnYScpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaGFzKG9iamVjdCwgJ2EuYicpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaGFzKG9iamVjdCwgWydhJywgJ2InXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5oYXMob3RoZXIsICdhJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBoYXMob2JqZWN0LCBwYXRoKSB7XG4gICAgICByZXR1cm4gb2JqZWN0ICE9IG51bGwgJiYgaGFzUGF0aChvYmplY3QsIHBhdGgsIGJhc2VIYXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBgcGF0aGAgaXMgYSBkaXJlY3Qgb3IgaW5oZXJpdGVkIHByb3BlcnR5IG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHBhdGhgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0gXy5jcmVhdGUoeyAnYSc6IF8uY3JlYXRlKHsgJ2InOiAyIH0pIH0pO1xuICAgICAqXG4gICAgICogXy5oYXNJbihvYmplY3QsICdhJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5oYXNJbihvYmplY3QsICdhLmInKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmhhc0luKG9iamVjdCwgWydhJywgJ2InXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5oYXNJbihvYmplY3QsICdiJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBoYXNJbihvYmplY3QsIHBhdGgpIHtcbiAgICAgIHJldHVybiBvYmplY3QgIT0gbnVsbCAmJiBoYXNQYXRoKG9iamVjdCwgcGF0aCwgYmFzZUhhc0luKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCBjb21wb3NlZCBvZiB0aGUgaW52ZXJ0ZWQga2V5cyBhbmQgdmFsdWVzIG9mIGBvYmplY3RgLlxuICAgICAqIElmIGBvYmplY3RgIGNvbnRhaW5zIGR1cGxpY2F0ZSB2YWx1ZXMsIHN1YnNlcXVlbnQgdmFsdWVzIG92ZXJ3cml0ZVxuICAgICAqIHByb3BlcnR5IGFzc2lnbm1lbnRzIG9mIHByZXZpb3VzIHZhbHVlcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjcuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW52ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBpbnZlcnRlZCBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSwgJ2InOiAyLCAnYyc6IDEgfTtcbiAgICAgKlxuICAgICAqIF8uaW52ZXJ0KG9iamVjdCk7XG4gICAgICogLy8gPT4geyAnMSc6ICdjJywgJzInOiAnYicgfVxuICAgICAqL1xuICAgIHZhciBpbnZlcnQgPSBjcmVhdGVJbnZlcnRlcihmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgIGlmICh2YWx1ZSAhPSBudWxsICYmXG4gICAgICAgICAgdHlwZW9mIHZhbHVlLnRvU3RyaW5nICE9ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdmFsdWUgPSBuYXRpdmVPYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgICAgIH1cblxuICAgICAgcmVzdWx0W3ZhbHVlXSA9IGtleTtcbiAgICB9LCBjb25zdGFudChpZGVudGl0eSkpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5pbnZlcnRgIGV4Y2VwdCB0aGF0IHRoZSBpbnZlcnRlZCBvYmplY3QgaXMgZ2VuZXJhdGVkXG4gICAgICogZnJvbSB0aGUgcmVzdWx0cyBvZiBydW5uaW5nIGVhY2ggZWxlbWVudCBvZiBgb2JqZWN0YCB0aHJ1IGBpdGVyYXRlZWAuIFRoZVxuICAgICAqIGNvcnJlc3BvbmRpbmcgaW52ZXJ0ZWQgdmFsdWUgb2YgZWFjaCBpbnZlcnRlZCBrZXkgaXMgYW4gYXJyYXkgb2Yga2V5c1xuICAgICAqIHJlc3BvbnNpYmxlIGZvciBnZW5lcmF0aW5nIHRoZSBpbnZlcnRlZCB2YWx1ZS4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWRcbiAgICAgKiB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjEuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaW52ZXJ0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgaW52ZXJ0ZWQgb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogMiwgJ2MnOiAxIH07XG4gICAgICpcbiAgICAgKiBfLmludmVydEJ5KG9iamVjdCk7XG4gICAgICogLy8gPT4geyAnMSc6IFsnYScsICdjJ10sICcyJzogWydiJ10gfVxuICAgICAqXG4gICAgICogXy5pbnZlcnRCeShvYmplY3QsIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICogICByZXR1cm4gJ2dyb3VwJyArIHZhbHVlO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IHsgJ2dyb3VwMSc6IFsnYScsICdjJ10sICdncm91cDInOiBbJ2InXSB9XG4gICAgICovXG4gICAgdmFyIGludmVydEJ5ID0gY3JlYXRlSW52ZXJ0ZXIoZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgICBpZiAodmFsdWUgIT0gbnVsbCAmJlxuICAgICAgICAgIHR5cGVvZiB2YWx1ZS50b1N0cmluZyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHZhbHVlID0gbmF0aXZlT2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3VsdCwgdmFsdWUpKSB7XG4gICAgICAgIHJlc3VsdFt2YWx1ZV0ucHVzaChrZXkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0W3ZhbHVlXSA9IFtrZXldO1xuICAgICAgfVxuICAgIH0sIGdldEl0ZXJhdGVlKTtcblxuICAgIC8qKlxuICAgICAqIEludm9rZXMgdGhlIG1ldGhvZCBhdCBgcGF0aGAgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBtZXRob2QgdG8gaW52b2tlLlxuICAgICAqIEBwYXJhbSB7Li4uKn0gW2FyZ3NdIFRoZSBhcmd1bWVudHMgdG8gaW52b2tlIHRoZSBtZXRob2Qgd2l0aC5cbiAgICAgKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSBpbnZva2VkIG1ldGhvZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiBbeyAnYic6IHsgJ2MnOiBbMSwgMiwgMywgNF0gfSB9XSB9O1xuICAgICAqXG4gICAgICogXy5pbnZva2Uob2JqZWN0LCAnYVswXS5iLmMuc2xpY2UnLCAxLCAzKTtcbiAgICAgKiAvLyA9PiBbMiwgM11cbiAgICAgKi9cbiAgICB2YXIgaW52b2tlID0gYmFzZVJlc3QoYmFzZUludm9rZSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBOb24tb2JqZWN0IHZhbHVlcyBhcmUgY29lcmNlZCB0byBvYmplY3RzLiBTZWUgdGhlXG4gICAgICogW0VTIHNwZWNdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLW9iamVjdC5rZXlzKVxuICAgICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLmtleXMobmV3IEZvbyk7XG4gICAgICogLy8gPT4gWydhJywgJ2InXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqXG4gICAgICogXy5rZXlzKCdoaScpO1xuICAgICAqIC8vID0+IFsnMCcsICcxJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBrZXlzKG9iamVjdCkge1xuICAgICAgcmV0dXJuIGlzQXJyYXlMaWtlKG9iamVjdCkgPyBhcnJheUxpa2VLZXlzKG9iamVjdCkgOiBiYXNlS2V5cyhvYmplY3QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8ua2V5c0luKG5ldyBGb28pO1xuICAgICAqIC8vID0+IFsnYScsICdiJywgJ2MnXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGtleXNJbihvYmplY3QpIHtcbiAgICAgIHJldHVybiBpc0FycmF5TGlrZShvYmplY3QpID8gYXJyYXlMaWtlS2V5cyhvYmplY3QsIHRydWUpIDogYmFzZUtleXNJbihvYmplY3QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoZSBvcHBvc2l0ZSBvZiBgXy5tYXBWYWx1ZXNgOyB0aGlzIG1ldGhvZCBjcmVhdGVzIGFuIG9iamVjdCB3aXRoIHRoZVxuICAgICAqIHNhbWUgdmFsdWVzIGFzIGBvYmplY3RgIGFuZCBrZXlzIGdlbmVyYXRlZCBieSBydW5uaW5nIGVhY2ggb3duIGVudW1lcmFibGVcbiAgICAgKiBzdHJpbmcga2V5ZWQgcHJvcGVydHkgb2YgYG9iamVjdGAgdGhydSBgaXRlcmF0ZWVgLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZFxuICAgICAqIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGtleSwgb2JqZWN0KS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjguMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgb2JqZWN0LlxuICAgICAqIEBzZWUgXy5tYXBWYWx1ZXNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5tYXBLZXlzKHsgJ2EnOiAxLCAnYic6IDIgfSwgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAqICAgcmV0dXJuIGtleSArIHZhbHVlO1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+IHsgJ2ExJzogMSwgJ2IyJzogMiB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gbWFwS2V5cyhvYmplY3QsIGl0ZXJhdGVlKSB7XG4gICAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgICBpdGVyYXRlZSA9IGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAzKTtcblxuICAgICAgYmFzZUZvck93bihvYmplY3QsIGZ1bmN0aW9uKHZhbHVlLCBrZXksIG9iamVjdCkge1xuICAgICAgICBiYXNlQXNzaWduVmFsdWUocmVzdWx0LCBpdGVyYXRlZSh2YWx1ZSwga2V5LCBvYmplY3QpLCB2YWx1ZSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBvYmplY3Qgd2l0aCB0aGUgc2FtZSBrZXlzIGFzIGBvYmplY3RgIGFuZCB2YWx1ZXMgZ2VuZXJhdGVkXG4gICAgICogYnkgcnVubmluZyBlYWNoIG93biBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0eSBvZiBgb2JqZWN0YCB0aHJ1XG4gICAgICogYGl0ZXJhdGVlYC4gVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6XG4gICAgICogKHZhbHVlLCBrZXksIG9iamVjdCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi40LjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIG9iamVjdC5cbiAgICAgKiBAc2VlIF8ubWFwS2V5c1xuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgdXNlcnMgPSB7XG4gICAgICogICAnZnJlZCc6ICAgIHsgJ3VzZXInOiAnZnJlZCcsICAgICdhZ2UnOiA0MCB9LFxuICAgICAqICAgJ3BlYmJsZXMnOiB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWdlJzogMSB9XG4gICAgICogfTtcbiAgICAgKlxuICAgICAqIF8ubWFwVmFsdWVzKHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLmFnZTsgfSk7XG4gICAgICogLy8gPT4geyAnZnJlZCc6IDQwLCAncGViYmxlcyc6IDEgfSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5tYXBWYWx1ZXModXNlcnMsICdhZ2UnKTtcbiAgICAgKiAvLyA9PiB7ICdmcmVkJzogNDAsICdwZWJibGVzJzogMSB9IChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWFwVmFsdWVzKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICAgIGl0ZXJhdGVlID0gZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDMpO1xuXG4gICAgICBiYXNlRm9yT3duKG9iamVjdCwgZnVuY3Rpb24odmFsdWUsIGtleSwgb2JqZWN0KSB7XG4gICAgICAgIGJhc2VBc3NpZ25WYWx1ZShyZXN1bHQsIGtleSwgaXRlcmF0ZWUodmFsdWUsIGtleSwgb2JqZWN0KSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5hc3NpZ25gIGV4Y2VwdCB0aGF0IGl0IHJlY3Vyc2l2ZWx5IG1lcmdlcyBvd24gYW5kXG4gICAgICogaW5oZXJpdGVkIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnRpZXMgb2Ygc291cmNlIG9iamVjdHMgaW50byB0aGVcbiAgICAgKiBkZXN0aW5hdGlvbiBvYmplY3QuIFNvdXJjZSBwcm9wZXJ0aWVzIHRoYXQgcmVzb2x2ZSB0byBgdW5kZWZpbmVkYCBhcmVcbiAgICAgKiBza2lwcGVkIGlmIGEgZGVzdGluYXRpb24gdmFsdWUgZXhpc3RzLiBBcnJheSBhbmQgcGxhaW4gb2JqZWN0IHByb3BlcnRpZXNcbiAgICAgKiBhcmUgbWVyZ2VkIHJlY3Vyc2l2ZWx5LiBPdGhlciBvYmplY3RzIGFuZCB2YWx1ZSB0eXBlcyBhcmUgb3ZlcnJpZGRlbiBieVxuICAgICAqIGFzc2lnbm1lbnQuIFNvdXJjZSBvYmplY3RzIGFyZSBhcHBsaWVkIGZyb20gbGVmdCB0byByaWdodC4gU3Vic2VxdWVudFxuICAgICAqIHNvdXJjZXMgb3ZlcndyaXRlIHByb3BlcnR5IGFzc2lnbm1lbnRzIG9mIHByZXZpb3VzIHNvdXJjZXMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgbXV0YXRlcyBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAwLjUuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHsuLi5PYmplY3R9IFtzb3VyY2VzXSBUaGUgc291cmNlIG9iamVjdHMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHtcbiAgICAgKiAgICdhJzogW3sgJ2InOiAyIH0sIHsgJ2QnOiA0IH1dXG4gICAgICogfTtcbiAgICAgKlxuICAgICAqIHZhciBvdGhlciA9IHtcbiAgICAgKiAgICdhJzogW3sgJ2MnOiAzIH0sIHsgJ2UnOiA1IH1dXG4gICAgICogfTtcbiAgICAgKlxuICAgICAqIF8ubWVyZ2Uob2JqZWN0LCBvdGhlcik7XG4gICAgICogLy8gPT4geyAnYSc6IFt7ICdiJzogMiwgJ2MnOiAzIH0sIHsgJ2QnOiA0LCAnZSc6IDUgfV0gfVxuICAgICAqL1xuICAgIHZhciBtZXJnZSA9IGNyZWF0ZUFzc2lnbmVyKGZ1bmN0aW9uKG9iamVjdCwgc291cmNlLCBzcmNJbmRleCkge1xuICAgICAgYmFzZU1lcmdlKG9iamVjdCwgc291cmNlLCBzcmNJbmRleCk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLm1lcmdlYCBleGNlcHQgdGhhdCBpdCBhY2NlcHRzIGBjdXN0b21pemVyYCB3aGljaFxuICAgICAqIGlzIGludm9rZWQgdG8gcHJvZHVjZSB0aGUgbWVyZ2VkIHZhbHVlcyBvZiB0aGUgZGVzdGluYXRpb24gYW5kIHNvdXJjZVxuICAgICAqIHByb3BlcnRpZXMuIElmIGBjdXN0b21pemVyYCByZXR1cm5zIGB1bmRlZmluZWRgLCBtZXJnaW5nIGlzIGhhbmRsZWQgYnkgdGhlXG4gICAgICogbWV0aG9kIGluc3RlYWQuIFRoZSBgY3VzdG9taXplcmAgaXMgaW52b2tlZCB3aXRoIHNpeCBhcmd1bWVudHM6XG4gICAgICogKG9ialZhbHVlLCBzcmNWYWx1ZSwga2V5LCBvYmplY3QsIHNvdXJjZSwgc3RhY2spLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uT2JqZWN0fSBzb3VyY2VzIFRoZSBzb3VyY2Ugb2JqZWN0cy5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjdXN0b21pemVyIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgYXNzaWduZWQgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIGN1c3RvbWl6ZXIob2JqVmFsdWUsIHNyY1ZhbHVlKSB7XG4gICAgICogICBpZiAoXy5pc0FycmF5KG9ialZhbHVlKSkge1xuICAgICAqICAgICByZXR1cm4gb2JqVmFsdWUuY29uY2F0KHNyY1ZhbHVlKTtcbiAgICAgKiAgIH1cbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFsxXSwgJ2InOiBbMl0gfTtcbiAgICAgKiB2YXIgb3RoZXIgPSB7ICdhJzogWzNdLCAnYic6IFs0XSB9O1xuICAgICAqXG4gICAgICogXy5tZXJnZVdpdGgob2JqZWN0LCBvdGhlciwgY3VzdG9taXplcik7XG4gICAgICogLy8gPT4geyAnYSc6IFsxLCAzXSwgJ2InOiBbMiwgNF0gfVxuICAgICAqL1xuICAgIHZhciBtZXJnZVdpdGggPSBjcmVhdGVBc3NpZ25lcihmdW5jdGlvbihvYmplY3QsIHNvdXJjZSwgc3JjSW5kZXgsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGJhc2VNZXJnZShvYmplY3QsIHNvdXJjZSwgc3JjSW5kZXgsIGN1c3RvbWl6ZXIpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLnBpY2tgOyB0aGlzIG1ldGhvZCBjcmVhdGVzIGFuIG9iamVjdCBjb21wb3NlZCBvZiB0aGVcbiAgICAgKiBvd24gYW5kIGluaGVyaXRlZCBlbnVtZXJhYmxlIHByb3BlcnR5IHBhdGhzIG9mIGBvYmplY3RgIHRoYXQgYXJlIG5vdCBvbWl0dGVkLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGNvbnNpZGVyYWJseSBzbG93ZXIgdGhhbiBgXy5waWNrYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBzb3VyY2Ugb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uKHN0cmluZ3xzdHJpbmdbXSl9IFtwYXRoc10gVGhlIHByb3BlcnR5IHBhdGhzIHRvIG9taXQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxLCAnYic6ICcyJywgJ2MnOiAzIH07XG4gICAgICpcbiAgICAgKiBfLm9taXQob2JqZWN0LCBbJ2EnLCAnYyddKTtcbiAgICAgKiAvLyA9PiB7ICdiJzogJzInIH1cbiAgICAgKi9cbiAgICB2YXIgb21pdCA9IGZsYXRSZXN0KGZ1bmN0aW9uKG9iamVjdCwgcGF0aHMpIHtcbiAgICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuICAgICAgdmFyIGlzRGVlcCA9IGZhbHNlO1xuICAgICAgcGF0aHMgPSBhcnJheU1hcChwYXRocywgZnVuY3Rpb24ocGF0aCkge1xuICAgICAgICBwYXRoID0gY2FzdFBhdGgocGF0aCwgb2JqZWN0KTtcbiAgICAgICAgaXNEZWVwIHx8IChpc0RlZXAgPSBwYXRoLmxlbmd0aCA+IDEpO1xuICAgICAgICByZXR1cm4gcGF0aDtcbiAgICAgIH0pO1xuICAgICAgY29weU9iamVjdChvYmplY3QsIGdldEFsbEtleXNJbihvYmplY3QpLCByZXN1bHQpO1xuICAgICAgaWYgKGlzRGVlcCkge1xuICAgICAgICByZXN1bHQgPSBiYXNlQ2xvbmUocmVzdWx0LCBDTE9ORV9ERUVQX0ZMQUcgfCBDTE9ORV9GTEFUX0ZMQUcgfCBDTE9ORV9TWU1CT0xTX0ZMQUcsIGN1c3RvbU9taXRDbG9uZSk7XG4gICAgICB9XG4gICAgICB2YXIgbGVuZ3RoID0gcGF0aHMubGVuZ3RoO1xuICAgICAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgICAgIGJhc2VVbnNldChyZXN1bHQsIHBhdGhzW2xlbmd0aF0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBvcHBvc2l0ZSBvZiBgXy5waWNrQnlgOyB0aGlzIG1ldGhvZCBjcmVhdGVzIGFuIG9iamVjdCBjb21wb3NlZCBvZlxuICAgICAqIHRoZSBvd24gYW5kIGluaGVyaXRlZCBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0aWVzIG9mIGBvYmplY3RgIHRoYXRcbiAgICAgKiBgcHJlZGljYXRlYCBkb2Vzbid0IHJldHVybiB0cnV0aHkgZm9yLiBUaGUgcHJlZGljYXRlIGlzIGludm9rZWQgd2l0aCB0d29cbiAgICAgKiBhcmd1bWVudHM6ICh2YWx1ZSwga2V5KS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBzb3VyY2Ugb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIHByb3BlcnR5LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSwgJ2InOiAnMicsICdjJzogMyB9O1xuICAgICAqXG4gICAgICogXy5vbWl0Qnkob2JqZWN0LCBfLmlzTnVtYmVyKTtcbiAgICAgKiAvLyA9PiB7ICdiJzogJzInIH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBvbWl0Qnkob2JqZWN0LCBwcmVkaWNhdGUpIHtcbiAgICAgIHJldHVybiBwaWNrQnkob2JqZWN0LCBuZWdhdGUoZ2V0SXRlcmF0ZWUocHJlZGljYXRlKSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mIHRoZSBwaWNrZWQgYG9iamVjdGAgcHJvcGVydGllcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBzb3VyY2Ugb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7Li4uKHN0cmluZ3xzdHJpbmdbXSl9IFtwYXRoc10gVGhlIHByb3BlcnR5IHBhdGhzIHRvIHBpY2suXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxLCAnYic6ICcyJywgJ2MnOiAzIH07XG4gICAgICpcbiAgICAgKiBfLnBpY2sob2JqZWN0LCBbJ2EnLCAnYyddKTtcbiAgICAgKiAvLyA9PiB7ICdhJzogMSwgJ2MnOiAzIH1cbiAgICAgKi9cbiAgICB2YXIgcGljayA9IGZsYXRSZXN0KGZ1bmN0aW9uKG9iamVjdCwgcGF0aHMpIHtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHt9IDogYmFzZVBpY2sob2JqZWN0LCBwYXRocyk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCBjb21wb3NlZCBvZiB0aGUgYG9iamVjdGAgcHJvcGVydGllcyBgcHJlZGljYXRlYCByZXR1cm5zXG4gICAgICogdHJ1dGh5IGZvci4gVGhlIHByZWRpY2F0ZSBpcyBpbnZva2VkIHdpdGggdHdvIGFyZ3VtZW50czogKHZhbHVlLCBrZXkpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIHNvdXJjZSBvYmplY3QuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3ByZWRpY2F0ZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgcHJvcGVydHkuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxLCAnYic6ICcyJywgJ2MnOiAzIH07XG4gICAgICpcbiAgICAgKiBfLnBpY2tCeShvYmplY3QsIF8uaXNOdW1iZXIpO1xuICAgICAqIC8vID0+IHsgJ2EnOiAxLCAnYyc6IDMgfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHBpY2tCeShvYmplY3QsIHByZWRpY2F0ZSkge1xuICAgICAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICAgIH1cbiAgICAgIHZhciBwcm9wcyA9IGFycmF5TWFwKGdldEFsbEtleXNJbihvYmplY3QpLCBmdW5jdGlvbihwcm9wKSB7XG4gICAgICAgIHJldHVybiBbcHJvcF07XG4gICAgICB9KTtcbiAgICAgIHByZWRpY2F0ZSA9IGdldEl0ZXJhdGVlKHByZWRpY2F0ZSk7XG4gICAgICByZXR1cm4gYmFzZVBpY2tCeShvYmplY3QsIHByb3BzLCBmdW5jdGlvbih2YWx1ZSwgcGF0aCkge1xuICAgICAgICByZXR1cm4gcHJlZGljYXRlKHZhbHVlLCBwYXRoWzBdKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZ2V0YCBleGNlcHQgdGhhdCBpZiB0aGUgcmVzb2x2ZWQgdmFsdWUgaXMgYVxuICAgICAqIGZ1bmN0aW9uIGl0J3MgaW52b2tlZCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiBpdHMgcGFyZW50IG9iamVjdCBhbmRcbiAgICAgKiBpdHMgcmVzdWx0IGlzIHJldHVybmVkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gcmVzb2x2ZS5cbiAgICAgKiBAcGFyYW0geyp9IFtkZWZhdWx0VmFsdWVdIFRoZSB2YWx1ZSByZXR1cm5lZCBmb3IgYHVuZGVmaW5lZGAgcmVzb2x2ZWQgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiBbeyAnYic6IHsgJ2MxJzogMywgJ2MyJzogXy5jb25zdGFudCg0KSB9IH1dIH07XG4gICAgICpcbiAgICAgKiBfLnJlc3VsdChvYmplY3QsICdhWzBdLmIuYzEnKTtcbiAgICAgKiAvLyA9PiAzXG4gICAgICpcbiAgICAgKiBfLnJlc3VsdChvYmplY3QsICdhWzBdLmIuYzInKTtcbiAgICAgKiAvLyA9PiA0XG4gICAgICpcbiAgICAgKiBfLnJlc3VsdChvYmplY3QsICdhWzBdLmIuYzMnLCAnZGVmYXVsdCcpO1xuICAgICAqIC8vID0+ICdkZWZhdWx0J1xuICAgICAqXG4gICAgICogXy5yZXN1bHQob2JqZWN0LCAnYVswXS5iLmMzJywgXy5jb25zdGFudCgnZGVmYXVsdCcpKTtcbiAgICAgKiAvLyA9PiAnZGVmYXVsdCdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZXN1bHQob2JqZWN0LCBwYXRoLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgIHBhdGggPSBjYXN0UGF0aChwYXRoLCBvYmplY3QpO1xuXG4gICAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgICBsZW5ndGggPSBwYXRoLmxlbmd0aDtcblxuICAgICAgLy8gRW5zdXJlIHRoZSBsb29wIGlzIGVudGVyZWQgd2hlbiBwYXRoIGlzIGVtcHR5LlxuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgbGVuZ3RoID0gMTtcbiAgICAgICAgb2JqZWN0ID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3RbdG9LZXkocGF0aFtpbmRleF0pXTtcbiAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBpbmRleCA9IGxlbmd0aDtcbiAgICAgICAgICB2YWx1ZSA9IGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBvYmplY3QgPSBpc0Z1bmN0aW9uKHZhbHVlKSA/IHZhbHVlLmNhbGwob2JqZWN0KSA6IHZhbHVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSB2YWx1ZSBhdCBgcGF0aGAgb2YgYG9iamVjdGAuIElmIGEgcG9ydGlvbiBvZiBgcGF0aGAgZG9lc24ndCBleGlzdCxcbiAgICAgKiBpdCdzIGNyZWF0ZWQuIEFycmF5cyBhcmUgY3JlYXRlZCBmb3IgbWlzc2luZyBpbmRleCBwcm9wZXJ0aWVzIHdoaWxlIG9iamVjdHNcbiAgICAgKiBhcmUgY3JlYXRlZCBmb3IgYWxsIG90aGVyIG1pc3NpbmcgcHJvcGVydGllcy4gVXNlIGBfLnNldFdpdGhgIHRvIGN1c3RvbWl6ZVxuICAgICAqIGBwYXRoYCBjcmVhdGlvbi5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuNy4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIHNldC5cbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHsgJ2EnOiBbeyAnYic6IHsgJ2MnOiAzIH0gfV0gfTtcbiAgICAgKlxuICAgICAqIF8uc2V0KG9iamVjdCwgJ2FbMF0uYi5jJywgNCk7XG4gICAgICogY29uc29sZS5sb2cob2JqZWN0LmFbMF0uYi5jKTtcbiAgICAgKiAvLyA9PiA0XG4gICAgICpcbiAgICAgKiBfLnNldChvYmplY3QsIFsneCcsICcwJywgJ3knLCAneiddLCA1KTtcbiAgICAgKiBjb25zb2xlLmxvZyhvYmplY3QueFswXS55LnopO1xuICAgICAqIC8vID0+IDVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzZXQob2JqZWN0LCBwYXRoLCB2YWx1ZSkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gb2JqZWN0IDogYmFzZVNldChvYmplY3QsIHBhdGgsIHZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnNldGAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgY3VzdG9taXplcmAgd2hpY2ggaXNcbiAgICAgKiBpbnZva2VkIHRvIHByb2R1Y2UgdGhlIG9iamVjdHMgb2YgYHBhdGhgLiAgSWYgYGN1c3RvbWl6ZXJgIHJldHVybnMgYHVuZGVmaW5lZGBcbiAgICAgKiBwYXRoIGNyZWF0aW9uIGlzIGhhbmRsZWQgYnkgdGhlIG1ldGhvZCBpbnN0ZWFkLiBUaGUgYGN1c3RvbWl6ZXJgIGlzIGludm9rZWRcbiAgICAgKiB3aXRoIHRocmVlIGFyZ3VtZW50czogKG5zVmFsdWUsIGtleSwgbnNPYmplY3QpLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gc2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHNldC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBhc3NpZ25lZCB2YWx1ZXMuXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdCA9IHt9O1xuICAgICAqXG4gICAgICogXy5zZXRXaXRoKG9iamVjdCwgJ1swXVsxXScsICdhJywgT2JqZWN0KTtcbiAgICAgKiAvLyA9PiB7ICcwJzogeyAnMSc6ICdhJyB9IH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzZXRXaXRoKG9iamVjdCwgcGF0aCwgdmFsdWUsIGN1c3RvbWl6ZXIpIHtcbiAgICAgIGN1c3RvbWl6ZXIgPSB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nID8gY3VzdG9taXplciA6IHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IG9iamVjdCA6IGJhc2VTZXQob2JqZWN0LCBwYXRoLCB2YWx1ZSwgY3VzdG9taXplcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBhcnJheSBvZiBvd24gZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQtdmFsdWUgcGFpcnMgZm9yIGBvYmplY3RgXG4gICAgICogd2hpY2ggY2FuIGJlIGNvbnN1bWVkIGJ5IGBfLmZyb21QYWlyc2AuIElmIGBvYmplY3RgIGlzIGEgbWFwIG9yIHNldCwgaXRzXG4gICAgICogZW50cmllcyBhcmUgcmV0dXJuZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAYWxpYXMgZW50cmllc1xuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBrZXktdmFsdWUgcGFpcnMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLnRvUGFpcnMobmV3IEZvbyk7XG4gICAgICogLy8gPT4gW1snYScsIDFdLCBbJ2InLCAyXV0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKi9cbiAgICB2YXIgdG9QYWlycyA9IGNyZWF0ZVRvUGFpcnMoa2V5cyk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgc3RyaW5nIGtleWVkLXZhbHVlIHBhaXJzXG4gICAgICogZm9yIGBvYmplY3RgIHdoaWNoIGNhbiBiZSBjb25zdW1lZCBieSBgXy5mcm9tUGFpcnNgLiBJZiBgb2JqZWN0YCBpcyBhIG1hcFxuICAgICAqIG9yIHNldCwgaXRzIGVudHJpZXMgYXJlIHJldHVybmVkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGFsaWFzIGVudHJpZXNJblxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBrZXktdmFsdWUgcGFpcnMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIGZ1bmN0aW9uIEZvbygpIHtcbiAgICAgKiAgIHRoaXMuYSA9IDE7XG4gICAgICogICB0aGlzLmIgPSAyO1xuICAgICAqIH1cbiAgICAgKlxuICAgICAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gICAgICpcbiAgICAgKiBfLnRvUGFpcnNJbihuZXcgRm9vKTtcbiAgICAgKiAvLyA9PiBbWydhJywgMV0sIFsnYicsIDJdLCBbJ2MnLCAzXV0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAgICAgKi9cbiAgICB2YXIgdG9QYWlyc0luID0gY3JlYXRlVG9QYWlycyhrZXlzSW4pO1xuXG4gICAgLyoqXG4gICAgICogQW4gYWx0ZXJuYXRpdmUgdG8gYF8ucmVkdWNlYDsgdGhpcyBtZXRob2QgdHJhbnNmb3JtcyBgb2JqZWN0YCB0byBhIG5ld1xuICAgICAqIGBhY2N1bXVsYXRvcmAgb2JqZWN0IHdoaWNoIGlzIHRoZSByZXN1bHQgb2YgcnVubmluZyBlYWNoIG9mIGl0cyBvd25cbiAgICAgKiBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0aWVzIHRocnUgYGl0ZXJhdGVlYCwgd2l0aCBlYWNoIGludm9jYXRpb25cbiAgICAgKiBwb3RlbnRpYWxseSBtdXRhdGluZyB0aGUgYGFjY3VtdWxhdG9yYCBvYmplY3QuIElmIGBhY2N1bXVsYXRvcmAgaXMgbm90XG4gICAgICogcHJvdmlkZWQsIGEgbmV3IG9iamVjdCB3aXRoIHRoZSBzYW1lIGBbW1Byb3RvdHlwZV1dYCB3aWxsIGJlIHVzZWQuIFRoZVxuICAgICAqIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBmb3VyIGFyZ3VtZW50czogKGFjY3VtdWxhdG9yLCB2YWx1ZSwga2V5LCBvYmplY3QpLlxuICAgICAqIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAxLjMuMFxuICAgICAqIEBjYXRlZ29yeSBPYmplY3RcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEBwYXJhbSB7Kn0gW2FjY3VtdWxhdG9yXSBUaGUgY3VzdG9tIGFjY3VtdWxhdG9yIHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBhY2N1bXVsYXRlZCB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50cmFuc2Zvcm0oWzIsIDMsIDRdLCBmdW5jdGlvbihyZXN1bHQsIG4pIHtcbiAgICAgKiAgIHJlc3VsdC5wdXNoKG4gKj0gbik7XG4gICAgICogICByZXR1cm4gbiAlIDIgPT0gMDtcbiAgICAgKiB9LCBbXSk7XG4gICAgICogLy8gPT4gWzQsIDldXG4gICAgICpcbiAgICAgKiBfLnRyYW5zZm9ybSh7ICdhJzogMSwgJ2InOiAyLCAnYyc6IDEgfSwgZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgICogICAocmVzdWx0W3ZhbHVlXSB8fCAocmVzdWx0W3ZhbHVlXSA9IFtdKSkucHVzaChrZXkpO1xuICAgICAqIH0sIHt9KTtcbiAgICAgKiAvLyA9PiB7ICcxJzogWydhJywgJ2MnXSwgJzInOiBbJ2InXSB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gdHJhbnNmb3JtKG9iamVjdCwgaXRlcmF0ZWUsIGFjY3VtdWxhdG9yKSB7XG4gICAgICB2YXIgaXNBcnIgPSBpc0FycmF5KG9iamVjdCksXG4gICAgICAgICAgaXNBcnJMaWtlID0gaXNBcnIgfHwgaXNCdWZmZXIob2JqZWN0KSB8fCBpc1R5cGVkQXJyYXkob2JqZWN0KTtcblxuICAgICAgaXRlcmF0ZWUgPSBnZXRJdGVyYXRlZShpdGVyYXRlZSwgNCk7XG4gICAgICBpZiAoYWNjdW11bGF0b3IgPT0gbnVsbCkge1xuICAgICAgICB2YXIgQ3RvciA9IG9iamVjdCAmJiBvYmplY3QuY29uc3RydWN0b3I7XG4gICAgICAgIGlmIChpc0Fyckxpa2UpIHtcbiAgICAgICAgICBhY2N1bXVsYXRvciA9IGlzQXJyID8gbmV3IEN0b3IgOiBbXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc09iamVjdChvYmplY3QpKSB7XG4gICAgICAgICAgYWNjdW11bGF0b3IgPSBpc0Z1bmN0aW9uKEN0b3IpID8gYmFzZUNyZWF0ZShnZXRQcm90b3R5cGUob2JqZWN0KSkgOiB7fTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBhY2N1bXVsYXRvciA9IHt9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAoaXNBcnJMaWtlID8gYXJyYXlFYWNoIDogYmFzZUZvck93bikob2JqZWN0LCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIG9iamVjdCkge1xuICAgICAgICByZXR1cm4gaXRlcmF0ZWUoYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleCwgb2JqZWN0KTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgdGhlIHByb3BlcnR5IGF0IGBwYXRoYCBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIHVuc2V0LlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvcGVydHkgaXMgZGVsZXRlZCwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0geyAnYSc6IFt7ICdiJzogeyAnYyc6IDcgfSB9XSB9O1xuICAgICAqIF8udW5zZXQob2JqZWN0LCAnYVswXS5iLmMnKTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhvYmplY3QpO1xuICAgICAqIC8vID0+IHsgJ2EnOiBbeyAnYic6IHt9IH1dIH07XG4gICAgICpcbiAgICAgKiBfLnVuc2V0KG9iamVjdCwgWydhJywgJzAnLCAnYicsICdjJ10pO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKG9iamVjdCk7XG4gICAgICogLy8gPT4geyAnYSc6IFt7ICdiJzoge30gfV0gfTtcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1bnNldChvYmplY3QsIHBhdGgpIHtcbiAgICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHRydWUgOiBiYXNlVW5zZXQob2JqZWN0LCBwYXRoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLnNldGAgZXhjZXB0IHRoYXQgYWNjZXB0cyBgdXBkYXRlcmAgdG8gcHJvZHVjZSB0aGVcbiAgICAgKiB2YWx1ZSB0byBzZXQuIFVzZSBgXy51cGRhdGVXaXRoYCB0byBjdXN0b21pemUgYHBhdGhgIGNyZWF0aW9uLiBUaGUgYHVwZGF0ZXJgXG4gICAgICogaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNi4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIHNldC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB1cGRhdGVyIFRoZSBmdW5jdGlvbiB0byBwcm9kdWNlIHRoZSB1cGRhdGVkIHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogW3sgJ2InOiB7ICdjJzogMyB9IH1dIH07XG4gICAgICpcbiAgICAgKiBfLnVwZGF0ZShvYmplY3QsICdhWzBdLmIuYycsIGZ1bmN0aW9uKG4pIHsgcmV0dXJuIG4gKiBuOyB9KTtcbiAgICAgKiBjb25zb2xlLmxvZyhvYmplY3QuYVswXS5iLmMpO1xuICAgICAqIC8vID0+IDlcbiAgICAgKlxuICAgICAqIF8udXBkYXRlKG9iamVjdCwgJ3hbMF0ueS56JywgZnVuY3Rpb24obikgeyByZXR1cm4gbiA/IG4gKyAxIDogMDsgfSk7XG4gICAgICogY29uc29sZS5sb2cob2JqZWN0LnhbMF0ueS56KTtcbiAgICAgKiAvLyA9PiAwXG4gICAgICovXG4gICAgZnVuY3Rpb24gdXBkYXRlKG9iamVjdCwgcGF0aCwgdXBkYXRlcikge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gb2JqZWN0IDogYmFzZVVwZGF0ZShvYmplY3QsIHBhdGgsIGNhc3RGdW5jdGlvbih1cGRhdGVyKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy51cGRhdGVgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGN1c3RvbWl6ZXJgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCB0byBwcm9kdWNlIHRoZSBvYmplY3RzIG9mIGBwYXRoYC4gIElmIGBjdXN0b21pemVyYCByZXR1cm5zIGB1bmRlZmluZWRgXG4gICAgICogcGF0aCBjcmVhdGlvbiBpcyBoYW5kbGVkIGJ5IHRoZSBtZXRob2QgaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYCBpcyBpbnZva2VkXG4gICAgICogd2l0aCB0aHJlZSBhcmd1bWVudHM6IChuc1ZhbHVlLCBrZXksIG5zT2JqZWN0KS5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNi4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIHNldC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB1cGRhdGVyIFRoZSBmdW5jdGlvbiB0byBwcm9kdWNlIHRoZSB1cGRhdGVkIHZhbHVlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGFzc2lnbmVkIHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0ID0ge307XG4gICAgICpcbiAgICAgKiBfLnVwZGF0ZVdpdGgob2JqZWN0LCAnWzBdWzFdJywgXy5jb25zdGFudCgnYScpLCBPYmplY3QpO1xuICAgICAqIC8vID0+IHsgJzAnOiB7ICcxJzogJ2EnIH0gfVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVwZGF0ZVdpdGgob2JqZWN0LCBwYXRoLCB1cGRhdGVyLCBjdXN0b21pemVyKSB7XG4gICAgICBjdXN0b21pemVyID0gdHlwZW9mIGN1c3RvbWl6ZXIgPT0gJ2Z1bmN0aW9uJyA/IGN1c3RvbWl6ZXIgOiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyBvYmplY3QgOiBiYXNlVXBkYXRlKG9iamVjdCwgcGF0aCwgY2FzdEZ1bmN0aW9uKHVwZGF0ZXIpLCBjdXN0b21pemVyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydHkgdmFsdWVzIG9mIGBvYmplY3RgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgT2JqZWN0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgdmFsdWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBmdW5jdGlvbiBGb28oKSB7XG4gICAgICogICB0aGlzLmEgPSAxO1xuICAgICAqICAgdGhpcy5iID0gMjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICAgICAqXG4gICAgICogXy52YWx1ZXMobmV3IEZvbyk7XG4gICAgICogLy8gPT4gWzEsIDJdIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICpcbiAgICAgKiBfLnZhbHVlcygnaGknKTtcbiAgICAgKiAvLyA9PiBbJ2gnLCAnaSddXG4gICAgICovXG4gICAgZnVuY3Rpb24gdmFsdWVzKG9iamVjdCkge1xuICAgICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gW10gOiBiYXNlVmFsdWVzKG9iamVjdCwga2V5cyhvYmplY3QpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gYW5kIGluaGVyaXRlZCBlbnVtZXJhYmxlIHN0cmluZyBrZXllZCBwcm9wZXJ0eVxuICAgICAqIHZhbHVlcyBvZiBgb2JqZWN0YC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBOb24tb2JqZWN0IHZhbHVlcyBhcmUgY29lcmNlZCB0byBvYmplY3RzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IE9iamVjdFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IHZhbHVlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gRm9vKCkge1xuICAgICAqICAgdGhpcy5hID0gMTtcbiAgICAgKiAgIHRoaXMuYiA9IDI7XG4gICAgICogfVxuICAgICAqXG4gICAgICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAgICAgKlxuICAgICAqIF8udmFsdWVzSW4obmV3IEZvbyk7XG4gICAgICogLy8gPT4gWzEsIDIsIDNdIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gICAgICovXG4gICAgZnVuY3Rpb24gdmFsdWVzSW4ob2JqZWN0KSB7XG4gICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyBbXSA6IGJhc2VWYWx1ZXMob2JqZWN0LCBrZXlzSW4ob2JqZWN0KSk7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ2xhbXBzIGBudW1iZXJgIHdpdGhpbiB0aGUgaW5jbHVzaXZlIGBsb3dlcmAgYW5kIGB1cHBlcmAgYm91bmRzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IE51bWJlclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXIgVGhlIG51bWJlciB0byBjbGFtcC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xvd2VyXSBUaGUgbG93ZXIgYm91bmQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHVwcGVyIFRoZSB1cHBlciBib3VuZC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBjbGFtcGVkIG51bWJlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jbGFtcCgtMTAsIC01LCA1KTtcbiAgICAgKiAvLyA9PiAtNVxuICAgICAqXG4gICAgICogXy5jbGFtcCgxMCwgLTUsIDUpO1xuICAgICAqIC8vID0+IDVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBjbGFtcChudW1iZXIsIGxvd2VyLCB1cHBlcikge1xuICAgICAgaWYgKHVwcGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdXBwZXIgPSBsb3dlcjtcbiAgICAgICAgbG93ZXIgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBpZiAodXBwZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB1cHBlciA9IHRvTnVtYmVyKHVwcGVyKTtcbiAgICAgICAgdXBwZXIgPSB1cHBlciA9PT0gdXBwZXIgPyB1cHBlciA6IDA7XG4gICAgICB9XG4gICAgICBpZiAobG93ZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBsb3dlciA9IHRvTnVtYmVyKGxvd2VyKTtcbiAgICAgICAgbG93ZXIgPSBsb3dlciA9PT0gbG93ZXIgPyBsb3dlciA6IDA7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZUNsYW1wKHRvTnVtYmVyKG51bWJlciksIGxvd2VyLCB1cHBlcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGBuYCBpcyBiZXR3ZWVuIGBzdGFydGAgYW5kIHVwIHRvLCBidXQgbm90IGluY2x1ZGluZywgYGVuZGAuIElmXG4gICAgICogYGVuZGAgaXMgbm90IHNwZWNpZmllZCwgaXQncyBzZXQgdG8gYHN0YXJ0YCB3aXRoIGBzdGFydGAgdGhlbiBzZXQgdG8gYDBgLlxuICAgICAqIElmIGBzdGFydGAgaXMgZ3JlYXRlciB0aGFuIGBlbmRgIHRoZSBwYXJhbXMgYXJlIHN3YXBwZWQgdG8gc3VwcG9ydFxuICAgICAqIG5lZ2F0aXZlIHJhbmdlcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjMuMFxuICAgICAqIEBjYXRlZ29yeSBOdW1iZXJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbnVtYmVyIFRoZSBudW1iZXIgdG8gY2hlY2suXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgb2YgdGhlIHJhbmdlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgVGhlIGVuZCBvZiB0aGUgcmFuZ2UuXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBudW1iZXJgIGlzIGluIHRoZSByYW5nZSwgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBzZWUgXy5yYW5nZSwgXy5yYW5nZVJpZ2h0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uaW5SYW5nZSgzLCAyLCA0KTtcbiAgICAgKiAvLyA9PiB0cnVlXG4gICAgICpcbiAgICAgKiBfLmluUmFuZ2UoNCwgOCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5pblJhbmdlKDQsIDIpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmluUmFuZ2UoMiwgMik7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uaW5SYW5nZSgxLjIsIDIpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uaW5SYW5nZSg1LjIsIDQpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLmluUmFuZ2UoLTMsIC0yLCAtNik7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGluUmFuZ2UobnVtYmVyLCBzdGFydCwgZW5kKSB7XG4gICAgICBzdGFydCA9IHRvRmluaXRlKHN0YXJ0KTtcbiAgICAgIGlmIChlbmQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBlbmQgPSBzdGFydDtcbiAgICAgICAgc3RhcnQgPSAwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZW5kID0gdG9GaW5pdGUoZW5kKTtcbiAgICAgIH1cbiAgICAgIG51bWJlciA9IHRvTnVtYmVyKG51bWJlcik7XG4gICAgICByZXR1cm4gYmFzZUluUmFuZ2UobnVtYmVyLCBzdGFydCwgZW5kKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcm9kdWNlcyBhIHJhbmRvbSBudW1iZXIgYmV0d2VlbiB0aGUgaW5jbHVzaXZlIGBsb3dlcmAgYW5kIGB1cHBlcmAgYm91bmRzLlxuICAgICAqIElmIG9ubHkgb25lIGFyZ3VtZW50IGlzIHByb3ZpZGVkIGEgbnVtYmVyIGJldHdlZW4gYDBgIGFuZCB0aGUgZ2l2ZW4gbnVtYmVyXG4gICAgICogaXMgcmV0dXJuZWQuIElmIGBmbG9hdGluZ2AgaXMgYHRydWVgLCBvciBlaXRoZXIgYGxvd2VyYCBvciBgdXBwZXJgIGFyZVxuICAgICAqIGZsb2F0cywgYSBmbG9hdGluZy1wb2ludCBudW1iZXIgaXMgcmV0dXJuZWQgaW5zdGVhZCBvZiBhbiBpbnRlZ2VyLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIEphdmFTY3JpcHQgZm9sbG93cyB0aGUgSUVFRS03NTQgc3RhbmRhcmQgZm9yIHJlc29sdmluZ1xuICAgICAqIGZsb2F0aW5nLXBvaW50IHZhbHVlcyB3aGljaCBjYW4gcHJvZHVjZSB1bmV4cGVjdGVkIHJlc3VsdHMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMC43LjBcbiAgICAgKiBAY2F0ZWdvcnkgTnVtYmVyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsb3dlcj0wXSBUaGUgbG93ZXIgYm91bmQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFt1cHBlcj0xXSBUaGUgdXBwZXIgYm91bmQuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbZmxvYXRpbmddIFNwZWNpZnkgcmV0dXJuaW5nIGEgZmxvYXRpbmctcG9pbnQgbnVtYmVyLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHJhbmRvbSBudW1iZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucmFuZG9tKDAsIDUpO1xuICAgICAqIC8vID0+IGFuIGludGVnZXIgYmV0d2VlbiAwIGFuZCA1XG4gICAgICpcbiAgICAgKiBfLnJhbmRvbSg1KTtcbiAgICAgKiAvLyA9PiBhbHNvIGFuIGludGVnZXIgYmV0d2VlbiAwIGFuZCA1XG4gICAgICpcbiAgICAgKiBfLnJhbmRvbSg1LCB0cnVlKTtcbiAgICAgKiAvLyA9PiBhIGZsb2F0aW5nLXBvaW50IG51bWJlciBiZXR3ZWVuIDAgYW5kIDVcbiAgICAgKlxuICAgICAqIF8ucmFuZG9tKDEuMiwgNS4yKTtcbiAgICAgKiAvLyA9PiBhIGZsb2F0aW5nLXBvaW50IG51bWJlciBiZXR3ZWVuIDEuMiBhbmQgNS4yXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmFuZG9tKGxvd2VyLCB1cHBlciwgZmxvYXRpbmcpIHtcbiAgICAgIGlmIChmbG9hdGluZyAmJiB0eXBlb2YgZmxvYXRpbmcgIT0gJ2Jvb2xlYW4nICYmIGlzSXRlcmF0ZWVDYWxsKGxvd2VyLCB1cHBlciwgZmxvYXRpbmcpKSB7XG4gICAgICAgIHVwcGVyID0gZmxvYXRpbmcgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBpZiAoZmxvYXRpbmcgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIHVwcGVyID09ICdib29sZWFuJykge1xuICAgICAgICAgIGZsb2F0aW5nID0gdXBwZXI7XG4gICAgICAgICAgdXBwZXIgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIGxvd2VyID09ICdib29sZWFuJykge1xuICAgICAgICAgIGZsb2F0aW5nID0gbG93ZXI7XG4gICAgICAgICAgbG93ZXIgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChsb3dlciA9PT0gdW5kZWZpbmVkICYmIHVwcGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbG93ZXIgPSAwO1xuICAgICAgICB1cHBlciA9IDE7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgbG93ZXIgPSB0b0Zpbml0ZShsb3dlcik7XG4gICAgICAgIGlmICh1cHBlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdXBwZXIgPSBsb3dlcjtcbiAgICAgICAgICBsb3dlciA9IDA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdXBwZXIgPSB0b0Zpbml0ZSh1cHBlcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChsb3dlciA+IHVwcGVyKSB7XG4gICAgICAgIHZhciB0ZW1wID0gbG93ZXI7XG4gICAgICAgIGxvd2VyID0gdXBwZXI7XG4gICAgICAgIHVwcGVyID0gdGVtcDtcbiAgICAgIH1cbiAgICAgIGlmIChmbG9hdGluZyB8fCBsb3dlciAlIDEgfHwgdXBwZXIgJSAxKSB7XG4gICAgICAgIHZhciByYW5kID0gbmF0aXZlUmFuZG9tKCk7XG4gICAgICAgIHJldHVybiBuYXRpdmVNaW4obG93ZXIgKyAocmFuZCAqICh1cHBlciAtIGxvd2VyICsgZnJlZVBhcnNlRmxvYXQoJzFlLScgKyAoKHJhbmQgKyAnJykubGVuZ3RoIC0gMSkpKSksIHVwcGVyKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBiYXNlUmFuZG9tKGxvd2VyLCB1cHBlcik7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHN0cmluZ2AgdG8gW2NhbWVsIGNhc2VdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NhbWVsQ2FzZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBjYW1lbCBjYXNlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uY2FtZWxDYXNlKCdGb28gQmFyJyk7XG4gICAgICogLy8gPT4gJ2Zvb0JhcidcbiAgICAgKlxuICAgICAqIF8uY2FtZWxDYXNlKCctLWZvby1iYXItLScpO1xuICAgICAqIC8vID0+ICdmb29CYXInXG4gICAgICpcbiAgICAgKiBfLmNhbWVsQ2FzZSgnX19GT09fQkFSX18nKTtcbiAgICAgKiAvLyA9PiAnZm9vQmFyJ1xuICAgICAqL1xuICAgIHZhciBjYW1lbENhc2UgPSBjcmVhdGVDb21wb3VuZGVyKGZ1bmN0aW9uKHJlc3VsdCwgd29yZCwgaW5kZXgpIHtcbiAgICAgIHdvcmQgPSB3b3JkLnRvTG93ZXJDYXNlKCk7XG4gICAgICByZXR1cm4gcmVzdWx0ICsgKGluZGV4ID8gY2FwaXRhbGl6ZSh3b3JkKSA6IHdvcmQpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiBgc3RyaW5nYCB0byB1cHBlciBjYXNlIGFuZCB0aGUgcmVtYWluaW5nXG4gICAgICogdG8gbG93ZXIgY2FzZS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjYXBpdGFsaXplLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGNhcGl0YWxpemVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5jYXBpdGFsaXplKCdGUkVEJyk7XG4gICAgICogLy8gPT4gJ0ZyZWQnXG4gICAgICovXG4gICAgZnVuY3Rpb24gY2FwaXRhbGl6ZShzdHJpbmcpIHtcbiAgICAgIHJldHVybiB1cHBlckZpcnN0KHRvU3RyaW5nKHN0cmluZykudG9Mb3dlckNhc2UoKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVidXJycyBgc3RyaW5nYCBieSBjb252ZXJ0aW5nXG4gICAgICogW0xhdGluLTEgU3VwcGxlbWVudF0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGF0aW4tMV9TdXBwbGVtZW50XyhVbmljb2RlX2Jsb2NrKSNDaGFyYWN0ZXJfdGFibGUpXG4gICAgICogYW5kIFtMYXRpbiBFeHRlbmRlZC1BXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MYXRpbl9FeHRlbmRlZC1BKVxuICAgICAqIGxldHRlcnMgdG8gYmFzaWMgTGF0aW4gbGV0dGVycyBhbmQgcmVtb3ZpbmdcbiAgICAgKiBbY29tYmluaW5nIGRpYWNyaXRpY2FsIG1hcmtzXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db21iaW5pbmdfRGlhY3JpdGljYWxfTWFya3MpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGRlYnVyci5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBkZWJ1cnJlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZGVidXJyKCdkw6lqw6AgdnUnKTtcbiAgICAgKiAvLyA9PiAnZGVqYSB2dSdcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBkZWJ1cnIoc3RyaW5nKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgcmV0dXJuIHN0cmluZyAmJiBzdHJpbmcucmVwbGFjZShyZUxhdGluLCBkZWJ1cnJMZXR0ZXIpLnJlcGxhY2UocmVDb21ib01hcmssICcnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHN0cmluZ2AgZW5kcyB3aXRoIHRoZSBnaXZlbiB0YXJnZXQgc3RyaW5nLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt0YXJnZXRdIFRoZSBzdHJpbmcgdG8gc2VhcmNoIGZvci5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3Bvc2l0aW9uPXN0cmluZy5sZW5ndGhdIFRoZSBwb3NpdGlvbiB0byBzZWFyY2ggdXAgdG8uXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBzdHJpbmdgIGVuZHMgd2l0aCBgdGFyZ2V0YCxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmVuZHNXaXRoKCdhYmMnLCAnYycpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIF8uZW5kc1dpdGgoJ2FiYycsICdiJyk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKlxuICAgICAqIF8uZW5kc1dpdGgoJ2FiYycsICdiJywgMik7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGVuZHNXaXRoKHN0cmluZywgdGFyZ2V0LCBwb3NpdGlvbikge1xuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIHRhcmdldCA9IGJhc2VUb1N0cmluZyh0YXJnZXQpO1xuXG4gICAgICB2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aDtcbiAgICAgIHBvc2l0aW9uID0gcG9zaXRpb24gPT09IHVuZGVmaW5lZFxuICAgICAgICA/IGxlbmd0aFxuICAgICAgICA6IGJhc2VDbGFtcCh0b0ludGVnZXIocG9zaXRpb24pLCAwLCBsZW5ndGgpO1xuXG4gICAgICB2YXIgZW5kID0gcG9zaXRpb247XG4gICAgICBwb3NpdGlvbiAtPSB0YXJnZXQubGVuZ3RoO1xuICAgICAgcmV0dXJuIHBvc2l0aW9uID49IDAgJiYgc3RyaW5nLnNsaWNlKHBvc2l0aW9uLCBlbmQpID09IHRhcmdldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyB0aGUgY2hhcmFjdGVycyBcIiZcIiwgXCI8XCIsIFwiPlwiLCAnXCInLCBhbmQgXCInXCIgaW4gYHN0cmluZ2AgdG8gdGhlaXJcbiAgICAgKiBjb3JyZXNwb25kaW5nIEhUTUwgZW50aXRpZXMuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogTm8gb3RoZXIgY2hhcmFjdGVycyBhcmUgZXNjYXBlZC4gVG8gZXNjYXBlIGFkZGl0aW9uYWxcbiAgICAgKiBjaGFyYWN0ZXJzIHVzZSBhIHRoaXJkLXBhcnR5IGxpYnJhcnkgbGlrZSBbX2hlX10oaHR0cHM6Ly9tdGhzLmJlL2hlKS5cbiAgICAgKlxuICAgICAqIFRob3VnaCB0aGUgXCI+XCIgY2hhcmFjdGVyIGlzIGVzY2FwZWQgZm9yIHN5bW1ldHJ5LCBjaGFyYWN0ZXJzIGxpa2VcbiAgICAgKiBcIj5cIiBhbmQgXCIvXCIgZG9uJ3QgbmVlZCBlc2NhcGluZyBpbiBIVE1MIGFuZCBoYXZlIG5vIHNwZWNpYWwgbWVhbmluZ1xuICAgICAqIHVubGVzcyB0aGV5J3JlIHBhcnQgb2YgYSB0YWcgb3IgdW5xdW90ZWQgYXR0cmlidXRlIHZhbHVlLiBTZWVcbiAgICAgKiBbTWF0aGlhcyBCeW5lbnMncyBhcnRpY2xlXShodHRwczovL21hdGhpYXNieW5lbnMuYmUvbm90ZXMvYW1iaWd1b3VzLWFtcGVyc2FuZHMpXG4gICAgICogKHVuZGVyIFwic2VtaS1yZWxhdGVkIGZ1biBmYWN0XCIpIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICpcbiAgICAgKiBXaGVuIHdvcmtpbmcgd2l0aCBIVE1MIHlvdSBzaG91bGQgYWx3YXlzXG4gICAgICogW3F1b3RlIGF0dHJpYnV0ZSB2YWx1ZXNdKGh0dHA6Ly93b25rby5jb20vcG9zdC9odG1sLWVzY2FwaW5nKSB0byByZWR1Y2VcbiAgICAgKiBYU1MgdmVjdG9ycy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBlc2NhcGUuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgZXNjYXBlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZXNjYXBlKCdmcmVkLCBiYXJuZXksICYgcGViYmxlcycpO1xuICAgICAqIC8vID0+ICdmcmVkLCBiYXJuZXksICZhbXA7IHBlYmJsZXMnXG4gICAgICovXG4gICAgZnVuY3Rpb24gZXNjYXBlKHN0cmluZykge1xuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIHJldHVybiAoc3RyaW5nICYmIHJlSGFzVW5lc2NhcGVkSHRtbC50ZXN0KHN0cmluZykpXG4gICAgICAgID8gc3RyaW5nLnJlcGxhY2UocmVVbmVzY2FwZWRIdG1sLCBlc2NhcGVIdG1sQ2hhcilcbiAgICAgICAgOiBzdHJpbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXNjYXBlcyB0aGUgYFJlZ0V4cGAgc3BlY2lhbCBjaGFyYWN0ZXJzIFwiXlwiLCBcIiRcIiwgXCJcXFwiLCBcIi5cIiwgXCIqXCIsIFwiK1wiLFxuICAgICAqIFwiP1wiLCBcIihcIiwgXCIpXCIsIFwiW1wiLCBcIl1cIiwgXCJ7XCIsIFwifVwiLCBhbmQgXCJ8XCIgaW4gYHN0cmluZ2AuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gZXNjYXBlLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGVzY2FwZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmVzY2FwZVJlZ0V4cCgnW2xvZGFzaF0oaHR0cHM6Ly9sb2Rhc2guY29tLyknKTtcbiAgICAgKiAvLyA9PiAnXFxbbG9kYXNoXFxdXFwoaHR0cHM6Ly9sb2Rhc2hcXC5jb20vXFwpJ1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGVzY2FwZVJlZ0V4cChzdHJpbmcpIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICByZXR1cm4gKHN0cmluZyAmJiByZUhhc1JlZ0V4cENoYXIudGVzdChzdHJpbmcpKVxuICAgICAgICA/IHN0cmluZy5yZXBsYWNlKHJlUmVnRXhwQ2hhciwgJ1xcXFwkJicpXG4gICAgICAgIDogc3RyaW5nO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGBzdHJpbmdgIHRvXG4gICAgICogW2tlYmFiIGNhc2VdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0xldHRlcl9jYXNlI1NwZWNpYWxfY2FzZV9zdHlsZXMpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUga2ViYWIgY2FzZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmtlYmFiQ2FzZSgnRm9vIEJhcicpO1xuICAgICAqIC8vID0+ICdmb28tYmFyJ1xuICAgICAqXG4gICAgICogXy5rZWJhYkNhc2UoJ2Zvb0JhcicpO1xuICAgICAqIC8vID0+ICdmb28tYmFyJ1xuICAgICAqXG4gICAgICogXy5rZWJhYkNhc2UoJ19fRk9PX0JBUl9fJyk7XG4gICAgICogLy8gPT4gJ2Zvby1iYXInXG4gICAgICovXG4gICAgdmFyIGtlYmFiQ2FzZSA9IGNyZWF0ZUNvbXBvdW5kZXIoZnVuY3Rpb24ocmVzdWx0LCB3b3JkLCBpbmRleCkge1xuICAgICAgcmV0dXJuIHJlc3VsdCArIChpbmRleCA/ICctJyA6ICcnKSArIHdvcmQudG9Mb3dlckNhc2UoKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGBzdHJpbmdgLCBhcyBzcGFjZSBzZXBhcmF0ZWQgd29yZHMsIHRvIGxvd2VyIGNhc2UuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBsb3dlciBjYXNlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubG93ZXJDYXNlKCctLUZvby1CYXItLScpO1xuICAgICAqIC8vID0+ICdmb28gYmFyJ1xuICAgICAqXG4gICAgICogXy5sb3dlckNhc2UoJ2Zvb0JhcicpO1xuICAgICAqIC8vID0+ICdmb28gYmFyJ1xuICAgICAqXG4gICAgICogXy5sb3dlckNhc2UoJ19fRk9PX0JBUl9fJyk7XG4gICAgICogLy8gPT4gJ2ZvbyBiYXInXG4gICAgICovXG4gICAgdmFyIGxvd2VyQ2FzZSA9IGNyZWF0ZUNvbXBvdW5kZXIoZnVuY3Rpb24ocmVzdWx0LCB3b3JkLCBpbmRleCkge1xuICAgICAgcmV0dXJuIHJlc3VsdCArIChpbmRleCA/ICcgJyA6ICcnKSArIHdvcmQudG9Mb3dlckNhc2UoKTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIHRoZSBmaXJzdCBjaGFyYWN0ZXIgb2YgYHN0cmluZ2AgdG8gbG93ZXIgY2FzZS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGNvbnZlcnRlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ubG93ZXJGaXJzdCgnRnJlZCcpO1xuICAgICAqIC8vID0+ICdmcmVkJ1xuICAgICAqXG4gICAgICogXy5sb3dlckZpcnN0KCdGUkVEJyk7XG4gICAgICogLy8gPT4gJ2ZSRUQnXG4gICAgICovXG4gICAgdmFyIGxvd2VyRmlyc3QgPSBjcmVhdGVDYXNlRmlyc3QoJ3RvTG93ZXJDYXNlJyk7XG5cbiAgICAvKipcbiAgICAgKiBQYWRzIGBzdHJpbmdgIG9uIHRoZSBsZWZ0IGFuZCByaWdodCBzaWRlcyBpZiBpdCdzIHNob3J0ZXIgdGhhbiBgbGVuZ3RoYC5cbiAgICAgKiBQYWRkaW5nIGNoYXJhY3RlcnMgYXJlIHRydW5jYXRlZCBpZiB0aGV5IGNhbid0IGJlIGV2ZW5seSBkaXZpZGVkIGJ5IGBsZW5ndGhgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHBhZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aD0wXSBUaGUgcGFkZGluZyBsZW5ndGguXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtjaGFycz0nICddIFRoZSBzdHJpbmcgdXNlZCBhcyBwYWRkaW5nLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHBhZGRlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucGFkKCdhYmMnLCA4KTtcbiAgICAgKiAvLyA9PiAnICBhYmMgICAnXG4gICAgICpcbiAgICAgKiBfLnBhZCgnYWJjJywgOCwgJ18tJyk7XG4gICAgICogLy8gPT4gJ18tYWJjXy1fJ1xuICAgICAqXG4gICAgICogXy5wYWQoJ2FiYycsIDMpO1xuICAgICAqIC8vID0+ICdhYmMnXG4gICAgICovXG4gICAgZnVuY3Rpb24gcGFkKHN0cmluZywgbGVuZ3RoLCBjaGFycykge1xuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIGxlbmd0aCA9IHRvSW50ZWdlcihsZW5ndGgpO1xuXG4gICAgICB2YXIgc3RyTGVuZ3RoID0gbGVuZ3RoID8gc3RyaW5nU2l6ZShzdHJpbmcpIDogMDtcbiAgICAgIGlmICghbGVuZ3RoIHx8IHN0ckxlbmd0aCA+PSBsZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZztcbiAgICAgIH1cbiAgICAgIHZhciBtaWQgPSAobGVuZ3RoIC0gc3RyTGVuZ3RoKSAvIDI7XG4gICAgICByZXR1cm4gKFxuICAgICAgICBjcmVhdGVQYWRkaW5nKG5hdGl2ZUZsb29yKG1pZCksIGNoYXJzKSArXG4gICAgICAgIHN0cmluZyArXG4gICAgICAgIGNyZWF0ZVBhZGRpbmcobmF0aXZlQ2VpbChtaWQpLCBjaGFycylcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFkcyBgc3RyaW5nYCBvbiB0aGUgcmlnaHQgc2lkZSBpZiBpdCdzIHNob3J0ZXIgdGhhbiBgbGVuZ3RoYC4gUGFkZGluZ1xuICAgICAqIGNoYXJhY3RlcnMgYXJlIHRydW5jYXRlZCBpZiB0aGV5IGV4Y2VlZCBgbGVuZ3RoYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBwYWQuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGg9MF0gVGhlIHBhZGRpbmcgbGVuZ3RoLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbY2hhcnM9JyAnXSBUaGUgc3RyaW5nIHVzZWQgYXMgcGFkZGluZy5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBwYWRkZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnBhZEVuZCgnYWJjJywgNik7XG4gICAgICogLy8gPT4gJ2FiYyAgICdcbiAgICAgKlxuICAgICAqIF8ucGFkRW5kKCdhYmMnLCA2LCAnXy0nKTtcbiAgICAgKiAvLyA9PiAnYWJjXy1fJ1xuICAgICAqXG4gICAgICogXy5wYWRFbmQoJ2FiYycsIDMpO1xuICAgICAqIC8vID0+ICdhYmMnXG4gICAgICovXG4gICAgZnVuY3Rpb24gcGFkRW5kKHN0cmluZywgbGVuZ3RoLCBjaGFycykge1xuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIGxlbmd0aCA9IHRvSW50ZWdlcihsZW5ndGgpO1xuXG4gICAgICB2YXIgc3RyTGVuZ3RoID0gbGVuZ3RoID8gc3RyaW5nU2l6ZShzdHJpbmcpIDogMDtcbiAgICAgIHJldHVybiAobGVuZ3RoICYmIHN0ckxlbmd0aCA8IGxlbmd0aClcbiAgICAgICAgPyAoc3RyaW5nICsgY3JlYXRlUGFkZGluZyhsZW5ndGggLSBzdHJMZW5ndGgsIGNoYXJzKSlcbiAgICAgICAgOiBzdHJpbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGFkcyBgc3RyaW5nYCBvbiB0aGUgbGVmdCBzaWRlIGlmIGl0J3Mgc2hvcnRlciB0aGFuIGBsZW5ndGhgLiBQYWRkaW5nXG4gICAgICogY2hhcmFjdGVycyBhcmUgdHJ1bmNhdGVkIGlmIHRoZXkgZXhjZWVkIGBsZW5ndGhgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHBhZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aD0wXSBUaGUgcGFkZGluZyBsZW5ndGguXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtjaGFycz0nICddIFRoZSBzdHJpbmcgdXNlZCBhcyBwYWRkaW5nLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHBhZGRlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucGFkU3RhcnQoJ2FiYycsIDYpO1xuICAgICAqIC8vID0+ICcgICBhYmMnXG4gICAgICpcbiAgICAgKiBfLnBhZFN0YXJ0KCdhYmMnLCA2LCAnXy0nKTtcbiAgICAgKiAvLyA9PiAnXy1fYWJjJ1xuICAgICAqXG4gICAgICogXy5wYWRTdGFydCgnYWJjJywgMyk7XG4gICAgICogLy8gPT4gJ2FiYydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwYWRTdGFydChzdHJpbmcsIGxlbmd0aCwgY2hhcnMpIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICBsZW5ndGggPSB0b0ludGVnZXIobGVuZ3RoKTtcblxuICAgICAgdmFyIHN0ckxlbmd0aCA9IGxlbmd0aCA/IHN0cmluZ1NpemUoc3RyaW5nKSA6IDA7XG4gICAgICByZXR1cm4gKGxlbmd0aCAmJiBzdHJMZW5ndGggPCBsZW5ndGgpXG4gICAgICAgID8gKGNyZWF0ZVBhZGRpbmcobGVuZ3RoIC0gc3RyTGVuZ3RoLCBjaGFycykgKyBzdHJpbmcpXG4gICAgICAgIDogc3RyaW5nO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGBzdHJpbmdgIHRvIGFuIGludGVnZXIgb2YgdGhlIHNwZWNpZmllZCByYWRpeC4gSWYgYHJhZGl4YCBpc1xuICAgICAqIGB1bmRlZmluZWRgIG9yIGAwYCwgYSBgcmFkaXhgIG9mIGAxMGAgaXMgdXNlZCB1bmxlc3MgYHZhbHVlYCBpcyBhXG4gICAgICogaGV4YWRlY2ltYWwsIGluIHdoaWNoIGNhc2UgYSBgcmFkaXhgIG9mIGAxNmAgaXMgdXNlZC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBhbGlnbnMgd2l0aCB0aGVcbiAgICAgKiBbRVM1IGltcGxlbWVudGF0aW9uXShodHRwczovL2VzNS5naXRodWIuaW8vI3gxNS4xLjIuMikgb2YgYHBhcnNlSW50YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAxLjEuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3JhZGl4PTEwXSBUaGUgcmFkaXggdG8gaW50ZXJwcmV0IGB2YWx1ZWAgYnkuXG4gICAgICogQHBhcmFtLSB7T2JqZWN0fSBbZ3VhcmRdIEVuYWJsZXMgdXNlIGFzIGFuIGl0ZXJhdGVlIGZvciBtZXRob2RzIGxpa2UgYF8ubWFwYC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgaW50ZWdlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5wYXJzZUludCgnMDgnKTtcbiAgICAgKiAvLyA9PiA4XG4gICAgICpcbiAgICAgKiBfLm1hcChbJzYnLCAnMDgnLCAnMTAnXSwgXy5wYXJzZUludCk7XG4gICAgICogLy8gPT4gWzYsIDgsIDEwXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHBhcnNlSW50KHN0cmluZywgcmFkaXgsIGd1YXJkKSB7XG4gICAgICBpZiAoZ3VhcmQgfHwgcmFkaXggPT0gbnVsbCkge1xuICAgICAgICByYWRpeCA9IDA7XG4gICAgICB9IGVsc2UgaWYgKHJhZGl4KSB7XG4gICAgICAgIHJhZGl4ID0gK3JhZGl4O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5hdGl2ZVBhcnNlSW50KHRvU3RyaW5nKHN0cmluZykucmVwbGFjZShyZVRyaW1TdGFydCwgJycpLCByYWRpeCB8fCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXBlYXRzIHRoZSBnaXZlbiBzdHJpbmcgYG5gIHRpbWVzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHJlcGVhdC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW249MV0gVGhlIG51bWJlciBvZiB0aW1lcyB0byByZXBlYXQgdGhlIHN0cmluZy5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHJlcGVhdGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5yZXBlYXQoJyonLCAzKTtcbiAgICAgKiAvLyA9PiAnKioqJ1xuICAgICAqXG4gICAgICogXy5yZXBlYXQoJ2FiYycsIDIpO1xuICAgICAqIC8vID0+ICdhYmNhYmMnXG4gICAgICpcbiAgICAgKiBfLnJlcGVhdCgnYWJjJywgMCk7XG4gICAgICogLy8gPT4gJydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZXBlYXQoc3RyaW5nLCBuLCBndWFyZCkge1xuICAgICAgaWYgKChndWFyZCA/IGlzSXRlcmF0ZWVDYWxsKHN0cmluZywgbiwgZ3VhcmQpIDogbiA9PT0gdW5kZWZpbmVkKSkge1xuICAgICAgICBuID0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG4gPSB0b0ludGVnZXIobik7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZVJlcGVhdCh0b1N0cmluZyhzdHJpbmcpLCBuKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXBsYWNlcyBtYXRjaGVzIGZvciBgcGF0dGVybmAgaW4gYHN0cmluZ2Agd2l0aCBgcmVwbGFjZW1lbnRgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uXG4gICAgICogW2BTdHJpbmcjcmVwbGFjZWBdKGh0dHBzOi8vbWRuLmlvL1N0cmluZy9yZXBsYWNlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBtb2RpZnkuXG4gICAgICogQHBhcmFtIHtSZWdFeHB8c3RyaW5nfSBwYXR0ZXJuIFRoZSBwYXR0ZXJuIHRvIHJlcGxhY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbnxzdHJpbmd9IHJlcGxhY2VtZW50IFRoZSBtYXRjaCByZXBsYWNlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBtb2RpZmllZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucmVwbGFjZSgnSGkgRnJlZCcsICdGcmVkJywgJ0Jhcm5leScpO1xuICAgICAqIC8vID0+ICdIaSBCYXJuZXknXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmVwbGFjZSgpIHtcbiAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICAgIHN0cmluZyA9IHRvU3RyaW5nKGFyZ3NbMF0pO1xuXG4gICAgICByZXR1cm4gYXJncy5sZW5ndGggPCAzID8gc3RyaW5nIDogc3RyaW5nLnJlcGxhY2UoYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHN0cmluZ2AgdG9cbiAgICAgKiBbc25ha2UgY2FzZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU25ha2VfY2FzZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzbmFrZSBjYXNlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc25ha2VDYXNlKCdGb28gQmFyJyk7XG4gICAgICogLy8gPT4gJ2Zvb19iYXInXG4gICAgICpcbiAgICAgKiBfLnNuYWtlQ2FzZSgnZm9vQmFyJyk7XG4gICAgICogLy8gPT4gJ2Zvb19iYXInXG4gICAgICpcbiAgICAgKiBfLnNuYWtlQ2FzZSgnLS1GT08tQkFSLS0nKTtcbiAgICAgKiAvLyA9PiAnZm9vX2JhcidcbiAgICAgKi9cbiAgICB2YXIgc25ha2VDYXNlID0gY3JlYXRlQ29tcG91bmRlcihmdW5jdGlvbihyZXN1bHQsIHdvcmQsIGluZGV4KSB7XG4gICAgICByZXR1cm4gcmVzdWx0ICsgKGluZGV4ID8gJ18nIDogJycpICsgd29yZC50b0xvd2VyQ2FzZSgpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogU3BsaXRzIGBzdHJpbmdgIGJ5IGBzZXBhcmF0b3JgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uXG4gICAgICogW2BTdHJpbmcjc3BsaXRgXShodHRwczovL21kbi5pby9TdHJpbmcvc3BsaXQpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHNwbGl0LlxuICAgICAqIEBwYXJhbSB7UmVnRXhwfHN0cmluZ30gc2VwYXJhdG9yIFRoZSBzZXBhcmF0b3IgcGF0dGVybiB0byBzcGxpdCBieS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xpbWl0XSBUaGUgbGVuZ3RoIHRvIHRydW5jYXRlIHJlc3VsdHMgdG8uXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzdHJpbmcgc2VnbWVudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc3BsaXQoJ2EtYi1jJywgJy0nLCAyKTtcbiAgICAgKiAvLyA9PiBbJ2EnLCAnYiddXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3BsaXQoc3RyaW5nLCBzZXBhcmF0b3IsIGxpbWl0KSB7XG4gICAgICBpZiAobGltaXQgJiYgdHlwZW9mIGxpbWl0ICE9ICdudW1iZXInICYmIGlzSXRlcmF0ZWVDYWxsKHN0cmluZywgc2VwYXJhdG9yLCBsaW1pdCkpIHtcbiAgICAgICAgc2VwYXJhdG9yID0gbGltaXQgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBsaW1pdCA9IGxpbWl0ID09PSB1bmRlZmluZWQgPyBNQVhfQVJSQVlfTEVOR1RIIDogbGltaXQgPj4+IDA7XG4gICAgICBpZiAoIWxpbWl0KSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICBpZiAoc3RyaW5nICYmIChcbiAgICAgICAgICAgIHR5cGVvZiBzZXBhcmF0b3IgPT0gJ3N0cmluZycgfHxcbiAgICAgICAgICAgIChzZXBhcmF0b3IgIT0gbnVsbCAmJiAhaXNSZWdFeHAoc2VwYXJhdG9yKSlcbiAgICAgICAgICApKSB7XG4gICAgICAgIHNlcGFyYXRvciA9IGJhc2VUb1N0cmluZyhzZXBhcmF0b3IpO1xuICAgICAgICBpZiAoIXNlcGFyYXRvciAmJiBoYXNVbmljb2RlKHN0cmluZykpIHtcbiAgICAgICAgICByZXR1cm4gY2FzdFNsaWNlKHN0cmluZ1RvQXJyYXkoc3RyaW5nKSwgMCwgbGltaXQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gc3RyaW5nLnNwbGl0KHNlcGFyYXRvciwgbGltaXQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGBzdHJpbmdgIHRvXG4gICAgICogW3N0YXJ0IGNhc2VdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0xldHRlcl9jYXNlI1N0eWxpc3RpY19vcl9zcGVjaWFsaXNlZF91c2FnZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4xLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzdGFydCBjYXNlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc3RhcnRDYXNlKCctLWZvby1iYXItLScpO1xuICAgICAqIC8vID0+ICdGb28gQmFyJ1xuICAgICAqXG4gICAgICogXy5zdGFydENhc2UoJ2Zvb0JhcicpO1xuICAgICAqIC8vID0+ICdGb28gQmFyJ1xuICAgICAqXG4gICAgICogXy5zdGFydENhc2UoJ19fRk9PX0JBUl9fJyk7XG4gICAgICogLy8gPT4gJ0ZPTyBCQVInXG4gICAgICovXG4gICAgdmFyIHN0YXJ0Q2FzZSA9IGNyZWF0ZUNvbXBvdW5kZXIoZnVuY3Rpb24ocmVzdWx0LCB3b3JkLCBpbmRleCkge1xuICAgICAgcmV0dXJuIHJlc3VsdCArIChpbmRleCA/ICcgJyA6ICcnKSArIHVwcGVyRmlyc3Qod29yZCk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYHN0cmluZ2Agc3RhcnRzIHdpdGggdGhlIGdpdmVuIHRhcmdldCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gaW5zcGVjdC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3RhcmdldF0gVGhlIHN0cmluZyB0byBzZWFyY2ggZm9yLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbcG9zaXRpb249MF0gVGhlIHBvc2l0aW9uIHRvIHNlYXJjaCBmcm9tLlxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgc3RyaW5nYCBzdGFydHMgd2l0aCBgdGFyZ2V0YCxcbiAgICAgKiAgZWxzZSBgZmFsc2VgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnN0YXJ0c1dpdGgoJ2FiYycsICdhJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogXy5zdGFydHNXaXRoKCdhYmMnLCAnYicpO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICpcbiAgICAgKiBfLnN0YXJ0c1dpdGgoJ2FiYycsICdiJywgMSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN0YXJ0c1dpdGgoc3RyaW5nLCB0YXJnZXQsIHBvc2l0aW9uKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbiA9PSBudWxsXG4gICAgICAgID8gMFxuICAgICAgICA6IGJhc2VDbGFtcCh0b0ludGVnZXIocG9zaXRpb24pLCAwLCBzdHJpbmcubGVuZ3RoKTtcblxuICAgICAgdGFyZ2V0ID0gYmFzZVRvU3RyaW5nKHRhcmdldCk7XG4gICAgICByZXR1cm4gc3RyaW5nLnNsaWNlKHBvc2l0aW9uLCBwb3NpdGlvbiArIHRhcmdldC5sZW5ndGgpID09IHRhcmdldDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY29tcGlsZWQgdGVtcGxhdGUgZnVuY3Rpb24gdGhhdCBjYW4gaW50ZXJwb2xhdGUgZGF0YSBwcm9wZXJ0aWVzXG4gICAgICogaW4gXCJpbnRlcnBvbGF0ZVwiIGRlbGltaXRlcnMsIEhUTUwtZXNjYXBlIGludGVycG9sYXRlZCBkYXRhIHByb3BlcnRpZXMgaW5cbiAgICAgKiBcImVzY2FwZVwiIGRlbGltaXRlcnMsIGFuZCBleGVjdXRlIEphdmFTY3JpcHQgaW4gXCJldmFsdWF0ZVwiIGRlbGltaXRlcnMuIERhdGFcbiAgICAgKiBwcm9wZXJ0aWVzIG1heSBiZSBhY2Nlc3NlZCBhcyBmcmVlIHZhcmlhYmxlcyBpbiB0aGUgdGVtcGxhdGUuIElmIGEgc2V0dGluZ1xuICAgICAqIG9iamVjdCBpcyBnaXZlbiwgaXQgdGFrZXMgcHJlY2VkZW5jZSBvdmVyIGBfLnRlbXBsYXRlU2V0dGluZ3NgIHZhbHVlcy5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBJbiB0aGUgZGV2ZWxvcG1lbnQgYnVpbGQgYF8udGVtcGxhdGVgIHV0aWxpemVzXG4gICAgICogW3NvdXJjZVVSTHNdKGh0dHA6Ly93d3cuaHRtbDVyb2Nrcy5jb20vZW4vdHV0b3JpYWxzL2RldmVsb3BlcnRvb2xzL3NvdXJjZW1hcHMvI3RvYy1zb3VyY2V1cmwpXG4gICAgICogZm9yIGVhc2llciBkZWJ1Z2dpbmcuXG4gICAgICpcbiAgICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBwcmVjb21waWxpbmcgdGVtcGxhdGVzIHNlZVxuICAgICAqIFtsb2Rhc2gncyBjdXN0b20gYnVpbGRzIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vbG9kYXNoLmNvbS9jdXN0b20tYnVpbGRzKS5cbiAgICAgKlxuICAgICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIG9uIENocm9tZSBleHRlbnNpb24gc2FuZGJveGVzIHNlZVxuICAgICAqIFtDaHJvbWUncyBleHRlbnNpb25zIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vZGV2ZWxvcGVyLmNocm9tZS5jb20vZXh0ZW5zaW9ucy9zYW5kYm94aW5nRXZhbCkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgU3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSB0ZW1wbGF0ZSBzdHJpbmcuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zPXt9XSBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtIHtSZWdFeHB9IFtvcHRpb25zLmVzY2FwZT1fLnRlbXBsYXRlU2V0dGluZ3MuZXNjYXBlXVxuICAgICAqICBUaGUgSFRNTCBcImVzY2FwZVwiIGRlbGltaXRlci5cbiAgICAgKiBAcGFyYW0ge1JlZ0V4cH0gW29wdGlvbnMuZXZhbHVhdGU9Xy50ZW1wbGF0ZVNldHRpbmdzLmV2YWx1YXRlXVxuICAgICAqICBUaGUgXCJldmFsdWF0ZVwiIGRlbGltaXRlci5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMuaW1wb3J0cz1fLnRlbXBsYXRlU2V0dGluZ3MuaW1wb3J0c11cbiAgICAgKiAgQW4gb2JqZWN0IHRvIGltcG9ydCBpbnRvIHRoZSB0ZW1wbGF0ZSBhcyBmcmVlIHZhcmlhYmxlcy5cbiAgICAgKiBAcGFyYW0ge1JlZ0V4cH0gW29wdGlvbnMuaW50ZXJwb2xhdGU9Xy50ZW1wbGF0ZVNldHRpbmdzLmludGVycG9sYXRlXVxuICAgICAqICBUaGUgXCJpbnRlcnBvbGF0ZVwiIGRlbGltaXRlci5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW29wdGlvbnMuc291cmNlVVJMPSdsb2Rhc2gudGVtcGxhdGVTb3VyY2VzW25dJ11cbiAgICAgKiAgVGhlIHNvdXJjZVVSTCBvZiB0aGUgY29tcGlsZWQgdGVtcGxhdGUuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLnZhcmlhYmxlPSdvYmonXVxuICAgICAqICBUaGUgZGF0YSBvYmplY3QgdmFyaWFibGUgbmFtZS5cbiAgICAgKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYW4gaXRlcmF0ZWUgZm9yIG1ldGhvZHMgbGlrZSBgXy5tYXBgLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgY29tcGlsZWQgdGVtcGxhdGUgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIC8vIFVzZSB0aGUgXCJpbnRlcnBvbGF0ZVwiIGRlbGltaXRlciB0byBjcmVhdGUgYSBjb21waWxlZCB0ZW1wbGF0ZS5cbiAgICAgKiB2YXIgY29tcGlsZWQgPSBfLnRlbXBsYXRlKCdoZWxsbyA8JT0gdXNlciAlPiEnKTtcbiAgICAgKiBjb21waWxlZCh7ICd1c2VyJzogJ2ZyZWQnIH0pO1xuICAgICAqIC8vID0+ICdoZWxsbyBmcmVkISdcbiAgICAgKlxuICAgICAqIC8vIFVzZSB0aGUgSFRNTCBcImVzY2FwZVwiIGRlbGltaXRlciB0byBlc2NhcGUgZGF0YSBwcm9wZXJ0eSB2YWx1ZXMuXG4gICAgICogdmFyIGNvbXBpbGVkID0gXy50ZW1wbGF0ZSgnPGI+PCUtIHZhbHVlICU+PC9iPicpO1xuICAgICAqIGNvbXBpbGVkKHsgJ3ZhbHVlJzogJzxzY3JpcHQ+JyB9KTtcbiAgICAgKiAvLyA9PiAnPGI+Jmx0O3NjcmlwdCZndDs8L2I+J1xuICAgICAqXG4gICAgICogLy8gVXNlIHRoZSBcImV2YWx1YXRlXCIgZGVsaW1pdGVyIHRvIGV4ZWN1dGUgSmF2YVNjcmlwdCBhbmQgZ2VuZXJhdGUgSFRNTC5cbiAgICAgKiB2YXIgY29tcGlsZWQgPSBfLnRlbXBsYXRlKCc8JSBfLmZvckVhY2godXNlcnMsIGZ1bmN0aW9uKHVzZXIpIHsgJT48bGk+PCUtIHVzZXIgJT48L2xpPjwlIH0pOyAlPicpO1xuICAgICAqIGNvbXBpbGVkKHsgJ3VzZXJzJzogWydmcmVkJywgJ2Jhcm5leSddIH0pO1xuICAgICAqIC8vID0+ICc8bGk+ZnJlZDwvbGk+PGxpPmJhcm5leTwvbGk+J1xuICAgICAqXG4gICAgICogLy8gVXNlIHRoZSBpbnRlcm5hbCBgcHJpbnRgIGZ1bmN0aW9uIGluIFwiZXZhbHVhdGVcIiBkZWxpbWl0ZXJzLlxuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJzwlIHByaW50KFwiaGVsbG8gXCIgKyB1c2VyKTsgJT4hJyk7XG4gICAgICogY29tcGlsZWQoeyAndXNlcic6ICdiYXJuZXknIH0pO1xuICAgICAqIC8vID0+ICdoZWxsbyBiYXJuZXkhJ1xuICAgICAqXG4gICAgICogLy8gVXNlIHRoZSBFUyB0ZW1wbGF0ZSBsaXRlcmFsIGRlbGltaXRlciBhcyBhbiBcImludGVycG9sYXRlXCIgZGVsaW1pdGVyLlxuICAgICAqIC8vIERpc2FibGUgc3VwcG9ydCBieSByZXBsYWNpbmcgdGhlIFwiaW50ZXJwb2xhdGVcIiBkZWxpbWl0ZXIuXG4gICAgICogdmFyIGNvbXBpbGVkID0gXy50ZW1wbGF0ZSgnaGVsbG8gJHsgdXNlciB9IScpO1xuICAgICAqIGNvbXBpbGVkKHsgJ3VzZXInOiAncGViYmxlcycgfSk7XG4gICAgICogLy8gPT4gJ2hlbGxvIHBlYmJsZXMhJ1xuICAgICAqXG4gICAgICogLy8gVXNlIGJhY2tzbGFzaGVzIHRvIHRyZWF0IGRlbGltaXRlcnMgYXMgcGxhaW4gdGV4dC5cbiAgICAgKiB2YXIgY29tcGlsZWQgPSBfLnRlbXBsYXRlKCc8JT0gXCJcXFxcPCUtIHZhbHVlICVcXFxcPlwiICU+Jyk7XG4gICAgICogY29tcGlsZWQoeyAndmFsdWUnOiAnaWdub3JlZCcgfSk7XG4gICAgICogLy8gPT4gJzwlLSB2YWx1ZSAlPidcbiAgICAgKlxuICAgICAqIC8vIFVzZSB0aGUgYGltcG9ydHNgIG9wdGlvbiB0byBpbXBvcnQgYGpRdWVyeWAgYXMgYGpxYC5cbiAgICAgKiB2YXIgdGV4dCA9ICc8JSBqcS5lYWNoKHVzZXJzLCBmdW5jdGlvbih1c2VyKSB7ICU+PGxpPjwlLSB1c2VyICU+PC9saT48JSB9KTsgJT4nO1xuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUodGV4dCwgeyAnaW1wb3J0cyc6IHsgJ2pxJzogalF1ZXJ5IH0gfSk7XG4gICAgICogY29tcGlsZWQoeyAndXNlcnMnOiBbJ2ZyZWQnLCAnYmFybmV5J10gfSk7XG4gICAgICogLy8gPT4gJzxsaT5mcmVkPC9saT48bGk+YmFybmV5PC9saT4nXG4gICAgICpcbiAgICAgKiAvLyBVc2UgdGhlIGBzb3VyY2VVUkxgIG9wdGlvbiB0byBzcGVjaWZ5IGEgY3VzdG9tIHNvdXJjZVVSTCBmb3IgdGhlIHRlbXBsYXRlLlxuICAgICAqIHZhciBjb21waWxlZCA9IF8udGVtcGxhdGUoJ2hlbGxvIDwlPSB1c2VyICU+IScsIHsgJ3NvdXJjZVVSTCc6ICcvYmFzaWMvZ3JlZXRpbmcuanN0JyB9KTtcbiAgICAgKiBjb21waWxlZChkYXRhKTtcbiAgICAgKiAvLyA9PiBGaW5kIHRoZSBzb3VyY2Ugb2YgXCJncmVldGluZy5qc3RcIiB1bmRlciB0aGUgU291cmNlcyB0YWIgb3IgUmVzb3VyY2VzIHBhbmVsIG9mIHRoZSB3ZWIgaW5zcGVjdG9yLlxuICAgICAqXG4gICAgICogLy8gVXNlIHRoZSBgdmFyaWFibGVgIG9wdGlvbiB0byBlbnN1cmUgYSB3aXRoLXN0YXRlbWVudCBpc24ndCB1c2VkIGluIHRoZSBjb21waWxlZCB0ZW1wbGF0ZS5cbiAgICAgKiB2YXIgY29tcGlsZWQgPSBfLnRlbXBsYXRlKCdoaSA8JT0gZGF0YS51c2VyICU+IScsIHsgJ3ZhcmlhYmxlJzogJ2RhdGEnIH0pO1xuICAgICAqIGNvbXBpbGVkLnNvdXJjZTtcbiAgICAgKiAvLyA9PiBmdW5jdGlvbihkYXRhKSB7XG4gICAgICogLy8gICB2YXIgX190LCBfX3AgPSAnJztcbiAgICAgKiAvLyAgIF9fcCArPSAnaGkgJyArICgoX190ID0gKCBkYXRhLnVzZXIgKSkgPT0gbnVsbCA/ICcnIDogX190KSArICchJztcbiAgICAgKiAvLyAgIHJldHVybiBfX3A7XG4gICAgICogLy8gfVxuICAgICAqXG4gICAgICogLy8gVXNlIGN1c3RvbSB0ZW1wbGF0ZSBkZWxpbWl0ZXJzLlxuICAgICAqIF8udGVtcGxhdGVTZXR0aW5ncy5pbnRlcnBvbGF0ZSA9IC97eyhbXFxzXFxTXSs/KX19L2c7XG4gICAgICogdmFyIGNvbXBpbGVkID0gXy50ZW1wbGF0ZSgnaGVsbG8ge3sgdXNlciB9fSEnKTtcbiAgICAgKiBjb21waWxlZCh7ICd1c2VyJzogJ211c3RhY2hlJyB9KTtcbiAgICAgKiAvLyA9PiAnaGVsbG8gbXVzdGFjaGUhJ1xuICAgICAqXG4gICAgICogLy8gVXNlIHRoZSBgc291cmNlYCBwcm9wZXJ0eSB0byBpbmxpbmUgY29tcGlsZWQgdGVtcGxhdGVzIGZvciBtZWFuaW5nZnVsXG4gICAgICogLy8gbGluZSBudW1iZXJzIGluIGVycm9yIG1lc3NhZ2VzIGFuZCBzdGFjayB0cmFjZXMuXG4gICAgICogZnMud3JpdGVGaWxlU3luYyhwYXRoLmpvaW4ocHJvY2Vzcy5jd2QoKSwgJ2pzdC5qcycpLCAnXFxcbiAgICAgKiAgIHZhciBKU1QgPSB7XFxcbiAgICAgKiAgICAgXCJtYWluXCI6ICcgKyBfLnRlbXBsYXRlKG1haW5UZXh0KS5zb3VyY2UgKyAnXFxcbiAgICAgKiAgIH07XFxcbiAgICAgKiAnKTtcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0ZW1wbGF0ZShzdHJpbmcsIG9wdGlvbnMsIGd1YXJkKSB7XG4gICAgICAvLyBCYXNlZCBvbiBKb2huIFJlc2lnJ3MgYHRtcGxgIGltcGxlbWVudGF0aW9uXG4gICAgICAvLyAoaHR0cDovL2Vqb2huLm9yZy9ibG9nL2phdmFzY3JpcHQtbWljcm8tdGVtcGxhdGluZy8pXG4gICAgICAvLyBhbmQgTGF1cmEgRG9rdG9yb3ZhJ3MgZG9ULmpzIChodHRwczovL2dpdGh1Yi5jb20vb2xhZG8vZG9UKS5cbiAgICAgIHZhciBzZXR0aW5ncyA9IGxvZGFzaC50ZW1wbGF0ZVNldHRpbmdzO1xuXG4gICAgICBpZiAoZ3VhcmQgJiYgaXNJdGVyYXRlZUNhbGwoc3RyaW5nLCBvcHRpb25zLCBndWFyZCkpIHtcbiAgICAgICAgb3B0aW9ucyA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICBvcHRpb25zID0gYXNzaWduSW5XaXRoKHt9LCBvcHRpb25zLCBzZXR0aW5ncywgY3VzdG9tRGVmYXVsdHNBc3NpZ25Jbik7XG5cbiAgICAgIHZhciBpbXBvcnRzID0gYXNzaWduSW5XaXRoKHt9LCBvcHRpb25zLmltcG9ydHMsIHNldHRpbmdzLmltcG9ydHMsIGN1c3RvbURlZmF1bHRzQXNzaWduSW4pLFxuICAgICAgICAgIGltcG9ydHNLZXlzID0ga2V5cyhpbXBvcnRzKSxcbiAgICAgICAgICBpbXBvcnRzVmFsdWVzID0gYmFzZVZhbHVlcyhpbXBvcnRzLCBpbXBvcnRzS2V5cyk7XG5cbiAgICAgIHZhciBpc0VzY2FwaW5nLFxuICAgICAgICAgIGlzRXZhbHVhdGluZyxcbiAgICAgICAgICBpbmRleCA9IDAsXG4gICAgICAgICAgaW50ZXJwb2xhdGUgPSBvcHRpb25zLmludGVycG9sYXRlIHx8IHJlTm9NYXRjaCxcbiAgICAgICAgICBzb3VyY2UgPSBcIl9fcCArPSAnXCI7XG5cbiAgICAgIC8vIENvbXBpbGUgdGhlIHJlZ2V4cCB0byBtYXRjaCBlYWNoIGRlbGltaXRlci5cbiAgICAgIHZhciByZURlbGltaXRlcnMgPSBSZWdFeHAoXG4gICAgICAgIChvcHRpb25zLmVzY2FwZSB8fCByZU5vTWF0Y2gpLnNvdXJjZSArICd8JyArXG4gICAgICAgIGludGVycG9sYXRlLnNvdXJjZSArICd8JyArXG4gICAgICAgIChpbnRlcnBvbGF0ZSA9PT0gcmVJbnRlcnBvbGF0ZSA/IHJlRXNUZW1wbGF0ZSA6IHJlTm9NYXRjaCkuc291cmNlICsgJ3wnICtcbiAgICAgICAgKG9wdGlvbnMuZXZhbHVhdGUgfHwgcmVOb01hdGNoKS5zb3VyY2UgKyAnfCQnXG4gICAgICAsICdnJyk7XG5cbiAgICAgIC8vIFVzZSBhIHNvdXJjZVVSTCBmb3IgZWFzaWVyIGRlYnVnZ2luZy5cbiAgICAgIHZhciBzb3VyY2VVUkwgPSAnLy8jIHNvdXJjZVVSTD0nICtcbiAgICAgICAgKCdzb3VyY2VVUkwnIGluIG9wdGlvbnNcbiAgICAgICAgICA/IG9wdGlvbnMuc291cmNlVVJMXG4gICAgICAgICAgOiAoJ2xvZGFzaC50ZW1wbGF0ZVNvdXJjZXNbJyArICgrK3RlbXBsYXRlQ291bnRlcikgKyAnXScpXG4gICAgICAgICkgKyAnXFxuJztcblxuICAgICAgc3RyaW5nLnJlcGxhY2UocmVEZWxpbWl0ZXJzLCBmdW5jdGlvbihtYXRjaCwgZXNjYXBlVmFsdWUsIGludGVycG9sYXRlVmFsdWUsIGVzVGVtcGxhdGVWYWx1ZSwgZXZhbHVhdGVWYWx1ZSwgb2Zmc2V0KSB7XG4gICAgICAgIGludGVycG9sYXRlVmFsdWUgfHwgKGludGVycG9sYXRlVmFsdWUgPSBlc1RlbXBsYXRlVmFsdWUpO1xuXG4gICAgICAgIC8vIEVzY2FwZSBjaGFyYWN0ZXJzIHRoYXQgY2FuJ3QgYmUgaW5jbHVkZWQgaW4gc3RyaW5nIGxpdGVyYWxzLlxuICAgICAgICBzb3VyY2UgKz0gc3RyaW5nLnNsaWNlKGluZGV4LCBvZmZzZXQpLnJlcGxhY2UocmVVbmVzY2FwZWRTdHJpbmcsIGVzY2FwZVN0cmluZ0NoYXIpO1xuXG4gICAgICAgIC8vIFJlcGxhY2UgZGVsaW1pdGVycyB3aXRoIHNuaXBwZXRzLlxuICAgICAgICBpZiAoZXNjYXBlVmFsdWUpIHtcbiAgICAgICAgICBpc0VzY2FwaW5nID0gdHJ1ZTtcbiAgICAgICAgICBzb3VyY2UgKz0gXCInICtcXG5fX2UoXCIgKyBlc2NhcGVWYWx1ZSArIFwiKSArXFxuJ1wiO1xuICAgICAgICB9XG4gICAgICAgIGlmIChldmFsdWF0ZVZhbHVlKSB7XG4gICAgICAgICAgaXNFdmFsdWF0aW5nID0gdHJ1ZTtcbiAgICAgICAgICBzb3VyY2UgKz0gXCInO1xcblwiICsgZXZhbHVhdGVWYWx1ZSArIFwiO1xcbl9fcCArPSAnXCI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGludGVycG9sYXRlVmFsdWUpIHtcbiAgICAgICAgICBzb3VyY2UgKz0gXCInICtcXG4oKF9fdCA9IChcIiArIGludGVycG9sYXRlVmFsdWUgKyBcIikpID09IG51bGwgPyAnJyA6IF9fdCkgK1xcbidcIjtcbiAgICAgICAgfVxuICAgICAgICBpbmRleCA9IG9mZnNldCArIG1hdGNoLmxlbmd0aDtcblxuICAgICAgICAvLyBUaGUgSlMgZW5naW5lIGVtYmVkZGVkIGluIEFkb2JlIHByb2R1Y3RzIG5lZWRzIGBtYXRjaGAgcmV0dXJuZWQgaW5cbiAgICAgICAgLy8gb3JkZXIgdG8gcHJvZHVjZSB0aGUgY29ycmVjdCBgb2Zmc2V0YCB2YWx1ZS5cbiAgICAgICAgcmV0dXJuIG1hdGNoO1xuICAgICAgfSk7XG5cbiAgICAgIHNvdXJjZSArPSBcIic7XFxuXCI7XG5cbiAgICAgIC8vIElmIGB2YXJpYWJsZWAgaXMgbm90IHNwZWNpZmllZCB3cmFwIGEgd2l0aC1zdGF0ZW1lbnQgYXJvdW5kIHRoZSBnZW5lcmF0ZWRcbiAgICAgIC8vIGNvZGUgdG8gYWRkIHRoZSBkYXRhIG9iamVjdCB0byB0aGUgdG9wIG9mIHRoZSBzY29wZSBjaGFpbi5cbiAgICAgIHZhciB2YXJpYWJsZSA9IG9wdGlvbnMudmFyaWFibGU7XG4gICAgICBpZiAoIXZhcmlhYmxlKSB7XG4gICAgICAgIHNvdXJjZSA9ICd3aXRoIChvYmopIHtcXG4nICsgc291cmNlICsgJ1xcbn1cXG4nO1xuICAgICAgfVxuICAgICAgLy8gQ2xlYW51cCBjb2RlIGJ5IHN0cmlwcGluZyBlbXB0eSBzdHJpbmdzLlxuICAgICAgc291cmNlID0gKGlzRXZhbHVhdGluZyA/IHNvdXJjZS5yZXBsYWNlKHJlRW1wdHlTdHJpbmdMZWFkaW5nLCAnJykgOiBzb3VyY2UpXG4gICAgICAgIC5yZXBsYWNlKHJlRW1wdHlTdHJpbmdNaWRkbGUsICckMScpXG4gICAgICAgIC5yZXBsYWNlKHJlRW1wdHlTdHJpbmdUcmFpbGluZywgJyQxOycpO1xuXG4gICAgICAvLyBGcmFtZSBjb2RlIGFzIHRoZSBmdW5jdGlvbiBib2R5LlxuICAgICAgc291cmNlID0gJ2Z1bmN0aW9uKCcgKyAodmFyaWFibGUgfHwgJ29iaicpICsgJykge1xcbicgK1xuICAgICAgICAodmFyaWFibGVcbiAgICAgICAgICA/ICcnXG4gICAgICAgICAgOiAnb2JqIHx8IChvYmogPSB7fSk7XFxuJ1xuICAgICAgICApICtcbiAgICAgICAgXCJ2YXIgX190LCBfX3AgPSAnJ1wiICtcbiAgICAgICAgKGlzRXNjYXBpbmdcbiAgICAgICAgICAgPyAnLCBfX2UgPSBfLmVzY2FwZSdcbiAgICAgICAgICAgOiAnJ1xuICAgICAgICApICtcbiAgICAgICAgKGlzRXZhbHVhdGluZ1xuICAgICAgICAgID8gJywgX19qID0gQXJyYXkucHJvdG90eXBlLmpvaW47XFxuJyArXG4gICAgICAgICAgICBcImZ1bmN0aW9uIHByaW50KCkgeyBfX3AgKz0gX19qLmNhbGwoYXJndW1lbnRzLCAnJykgfVxcblwiXG4gICAgICAgICAgOiAnO1xcbidcbiAgICAgICAgKSArXG4gICAgICAgIHNvdXJjZSArXG4gICAgICAgICdyZXR1cm4gX19wXFxufSc7XG5cbiAgICAgIHZhciByZXN1bHQgPSBhdHRlbXB0KGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb24oaW1wb3J0c0tleXMsIHNvdXJjZVVSTCArICdyZXR1cm4gJyArIHNvdXJjZSlcbiAgICAgICAgICAuYXBwbHkodW5kZWZpbmVkLCBpbXBvcnRzVmFsdWVzKTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBQcm92aWRlIHRoZSBjb21waWxlZCBmdW5jdGlvbidzIHNvdXJjZSBieSBpdHMgYHRvU3RyaW5nYCBtZXRob2Qgb3JcbiAgICAgIC8vIHRoZSBgc291cmNlYCBwcm9wZXJ0eSBhcyBhIGNvbnZlbmllbmNlIGZvciBpbmxpbmluZyBjb21waWxlZCB0ZW1wbGF0ZXMuXG4gICAgICByZXN1bHQuc291cmNlID0gc291cmNlO1xuICAgICAgaWYgKGlzRXJyb3IocmVzdWx0KSkge1xuICAgICAgICB0aHJvdyByZXN1bHQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGBzdHJpbmdgLCBhcyBhIHdob2xlLCB0byBsb3dlciBjYXNlIGp1c3QgbGlrZVxuICAgICAqIFtTdHJpbmcjdG9Mb3dlckNhc2VdKGh0dHBzOi8vbWRuLmlvL3RvTG93ZXJDYXNlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGxvd2VyIGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b0xvd2VyKCctLUZvby1CYXItLScpO1xuICAgICAqIC8vID0+ICctLWZvby1iYXItLSdcbiAgICAgKlxuICAgICAqIF8udG9Mb3dlcignZm9vQmFyJyk7XG4gICAgICogLy8gPT4gJ2Zvb2JhcidcbiAgICAgKlxuICAgICAqIF8udG9Mb3dlcignX19GT09fQkFSX18nKTtcbiAgICAgKiAvLyA9PiAnX19mb29fYmFyX18nXG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9Mb3dlcih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRvU3RyaW5nKHZhbHVlKS50b0xvd2VyQ2FzZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGBzdHJpbmdgLCBhcyBhIHdob2xlLCB0byB1cHBlciBjYXNlIGp1c3QgbGlrZVxuICAgICAqIFtTdHJpbmcjdG9VcHBlckNhc2VdKGh0dHBzOi8vbWRuLmlvL3RvVXBwZXJDYXNlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHVwcGVyIGNhc2VkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b1VwcGVyKCctLWZvby1iYXItLScpO1xuICAgICAqIC8vID0+ICctLUZPTy1CQVItLSdcbiAgICAgKlxuICAgICAqIF8udG9VcHBlcignZm9vQmFyJyk7XG4gICAgICogLy8gPT4gJ0ZPT0JBUidcbiAgICAgKlxuICAgICAqIF8udG9VcHBlcignX19mb29fYmFyX18nKTtcbiAgICAgKiAvLyA9PiAnX19GT09fQkFSX18nXG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9VcHBlcih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHRvU3RyaW5nKHZhbHVlKS50b1VwcGVyQ2FzZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBvciBzcGVjaWZpZWQgY2hhcmFjdGVycyBmcm9tIGBzdHJpbmdgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHRyaW0uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtjaGFycz13aGl0ZXNwYWNlXSBUaGUgY2hhcmFjdGVycyB0byB0cmltLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdHJpbW1lZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udHJpbSgnICBhYmMgICcpO1xuICAgICAqIC8vID0+ICdhYmMnXG4gICAgICpcbiAgICAgKiBfLnRyaW0oJy1fLWFiYy1fLScsICdfLScpO1xuICAgICAqIC8vID0+ICdhYmMnXG4gICAgICpcbiAgICAgKiBfLm1hcChbJyAgZm9vICAnLCAnICBiYXIgICddLCBfLnRyaW0pO1xuICAgICAqIC8vID0+IFsnZm9vJywgJ2JhciddXG4gICAgICovXG4gICAgZnVuY3Rpb24gdHJpbShzdHJpbmcsIGNoYXJzLCBndWFyZCkge1xuICAgICAgc3RyaW5nID0gdG9TdHJpbmcoc3RyaW5nKTtcbiAgICAgIGlmIChzdHJpbmcgJiYgKGd1YXJkIHx8IGNoYXJzID09PSB1bmRlZmluZWQpKSB7XG4gICAgICAgIHJldHVybiBzdHJpbmcucmVwbGFjZShyZVRyaW0sICcnKTtcbiAgICAgIH1cbiAgICAgIGlmICghc3RyaW5nIHx8ICEoY2hhcnMgPSBiYXNlVG9TdHJpbmcoY2hhcnMpKSkge1xuICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgICAgfVxuICAgICAgdmFyIHN0clN5bWJvbHMgPSBzdHJpbmdUb0FycmF5KHN0cmluZyksXG4gICAgICAgICAgY2hyU3ltYm9scyA9IHN0cmluZ1RvQXJyYXkoY2hhcnMpLFxuICAgICAgICAgIHN0YXJ0ID0gY2hhcnNTdGFydEluZGV4KHN0clN5bWJvbHMsIGNoclN5bWJvbHMpLFxuICAgICAgICAgIGVuZCA9IGNoYXJzRW5kSW5kZXgoc3RyU3ltYm9scywgY2hyU3ltYm9scykgKyAxO1xuXG4gICAgICByZXR1cm4gY2FzdFNsaWNlKHN0clN5bWJvbHMsIHN0YXJ0LCBlbmQpLmpvaW4oJycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgdHJhaWxpbmcgd2hpdGVzcGFjZSBvciBzcGVjaWZpZWQgY2hhcmFjdGVycyBmcm9tIGBzdHJpbmdgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHRyaW0uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtjaGFycz13aGl0ZXNwYWNlXSBUaGUgY2hhcmFjdGVycyB0byB0cmltLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdHJpbW1lZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udHJpbUVuZCgnICBhYmMgICcpO1xuICAgICAqIC8vID0+ICcgIGFiYydcbiAgICAgKlxuICAgICAqIF8udHJpbUVuZCgnLV8tYWJjLV8tJywgJ18tJyk7XG4gICAgICogLy8gPT4gJy1fLWFiYydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB0cmltRW5kKHN0cmluZywgY2hhcnMsIGd1YXJkKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgaWYgKHN0cmluZyAmJiAoZ3VhcmQgfHwgY2hhcnMgPT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKHJlVHJpbUVuZCwgJycpO1xuICAgICAgfVxuICAgICAgaWYgKCFzdHJpbmcgfHwgIShjaGFycyA9IGJhc2VUb1N0cmluZyhjaGFycykpKSB7XG4gICAgICAgIHJldHVybiBzdHJpbmc7XG4gICAgICB9XG4gICAgICB2YXIgc3RyU3ltYm9scyA9IHN0cmluZ1RvQXJyYXkoc3RyaW5nKSxcbiAgICAgICAgICBlbmQgPSBjaGFyc0VuZEluZGV4KHN0clN5bWJvbHMsIHN0cmluZ1RvQXJyYXkoY2hhcnMpKSArIDE7XG5cbiAgICAgIHJldHVybiBjYXN0U2xpY2Uoc3RyU3ltYm9scywgMCwgZW5kKS5qb2luKCcnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGxlYWRpbmcgd2hpdGVzcGFjZSBvciBzcGVjaWZpZWQgY2hhcmFjdGVycyBmcm9tIGBzdHJpbmdgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHRyaW0uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtjaGFycz13aGl0ZXNwYWNlXSBUaGUgY2hhcmFjdGVycyB0byB0cmltLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdHJpbW1lZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udHJpbVN0YXJ0KCcgIGFiYyAgJyk7XG4gICAgICogLy8gPT4gJ2FiYyAgJ1xuICAgICAqXG4gICAgICogXy50cmltU3RhcnQoJy1fLWFiYy1fLScsICdfLScpO1xuICAgICAqIC8vID0+ICdhYmMtXy0nXG4gICAgICovXG4gICAgZnVuY3Rpb24gdHJpbVN0YXJ0KHN0cmluZywgY2hhcnMsIGd1YXJkKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgaWYgKHN0cmluZyAmJiAoZ3VhcmQgfHwgY2hhcnMgPT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKHJlVHJpbVN0YXJ0LCAnJyk7XG4gICAgICB9XG4gICAgICBpZiAoIXN0cmluZyB8fCAhKGNoYXJzID0gYmFzZVRvU3RyaW5nKGNoYXJzKSkpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZztcbiAgICAgIH1cbiAgICAgIHZhciBzdHJTeW1ib2xzID0gc3RyaW5nVG9BcnJheShzdHJpbmcpLFxuICAgICAgICAgIHN0YXJ0ID0gY2hhcnNTdGFydEluZGV4KHN0clN5bWJvbHMsIHN0cmluZ1RvQXJyYXkoY2hhcnMpKTtcblxuICAgICAgcmV0dXJuIGNhc3RTbGljZShzdHJTeW1ib2xzLCBzdGFydCkuam9pbignJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVHJ1bmNhdGVzIGBzdHJpbmdgIGlmIGl0J3MgbG9uZ2VyIHRoYW4gdGhlIGdpdmVuIG1heGltdW0gc3RyaW5nIGxlbmd0aC5cbiAgICAgKiBUaGUgbGFzdCBjaGFyYWN0ZXJzIG9mIHRoZSB0cnVuY2F0ZWQgc3RyaW5nIGFyZSByZXBsYWNlZCB3aXRoIHRoZSBvbWlzc2lvblxuICAgICAqIHN0cmluZyB3aGljaCBkZWZhdWx0cyB0byBcIi4uLlwiLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHRydW5jYXRlLlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucz17fV0gVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5sZW5ndGg9MzBdIFRoZSBtYXhpbXVtIHN0cmluZyBsZW5ndGguXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtvcHRpb25zLm9taXNzaW9uPScuLi4nXSBUaGUgc3RyaW5nIHRvIGluZGljYXRlIHRleHQgaXMgb21pdHRlZC5cbiAgICAgKiBAcGFyYW0ge1JlZ0V4cHxzdHJpbmd9IFtvcHRpb25zLnNlcGFyYXRvcl0gVGhlIHNlcGFyYXRvciBwYXR0ZXJuIHRvIHRydW5jYXRlIHRvLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHRydW5jYXRlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udHJ1bmNhdGUoJ2hpLWRpZGRseS1obyB0aGVyZSwgbmVpZ2hib3Jpbm8nKTtcbiAgICAgKiAvLyA9PiAnaGktZGlkZGx5LWhvIHRoZXJlLCBuZWlnaGJvLi4uJ1xuICAgICAqXG4gICAgICogXy50cnVuY2F0ZSgnaGktZGlkZGx5LWhvIHRoZXJlLCBuZWlnaGJvcmlubycsIHtcbiAgICAgKiAgICdsZW5ndGgnOiAyNCxcbiAgICAgKiAgICdzZXBhcmF0b3InOiAnICdcbiAgICAgKiB9KTtcbiAgICAgKiAvLyA9PiAnaGktZGlkZGx5LWhvIHRoZXJlLC4uLidcbiAgICAgKlxuICAgICAqIF8udHJ1bmNhdGUoJ2hpLWRpZGRseS1obyB0aGVyZSwgbmVpZ2hib3Jpbm8nLCB7XG4gICAgICogICAnbGVuZ3RoJzogMjQsXG4gICAgICogICAnc2VwYXJhdG9yJzogLyw/ICsvXG4gICAgICogfSk7XG4gICAgICogLy8gPT4gJ2hpLWRpZGRseS1obyB0aGVyZS4uLidcbiAgICAgKlxuICAgICAqIF8udHJ1bmNhdGUoJ2hpLWRpZGRseS1obyB0aGVyZSwgbmVpZ2hib3Jpbm8nLCB7XG4gICAgICogICAnb21pc3Npb24nOiAnIFsuLi5dJ1xuICAgICAqIH0pO1xuICAgICAqIC8vID0+ICdoaS1kaWRkbHktaG8gdGhlcmUsIG5laWcgWy4uLl0nXG4gICAgICovXG4gICAgZnVuY3Rpb24gdHJ1bmNhdGUoc3RyaW5nLCBvcHRpb25zKSB7XG4gICAgICB2YXIgbGVuZ3RoID0gREVGQVVMVF9UUlVOQ19MRU5HVEgsXG4gICAgICAgICAgb21pc3Npb24gPSBERUZBVUxUX1RSVU5DX09NSVNTSU9OO1xuXG4gICAgICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICAgICAgdmFyIHNlcGFyYXRvciA9ICdzZXBhcmF0b3InIGluIG9wdGlvbnMgPyBvcHRpb25zLnNlcGFyYXRvciA6IHNlcGFyYXRvcjtcbiAgICAgICAgbGVuZ3RoID0gJ2xlbmd0aCcgaW4gb3B0aW9ucyA/IHRvSW50ZWdlcihvcHRpb25zLmxlbmd0aCkgOiBsZW5ndGg7XG4gICAgICAgIG9taXNzaW9uID0gJ29taXNzaW9uJyBpbiBvcHRpb25zID8gYmFzZVRvU3RyaW5nKG9wdGlvbnMub21pc3Npb24pIDogb21pc3Npb247XG4gICAgICB9XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuXG4gICAgICB2YXIgc3RyTGVuZ3RoID0gc3RyaW5nLmxlbmd0aDtcbiAgICAgIGlmIChoYXNVbmljb2RlKHN0cmluZykpIHtcbiAgICAgICAgdmFyIHN0clN5bWJvbHMgPSBzdHJpbmdUb0FycmF5KHN0cmluZyk7XG4gICAgICAgIHN0ckxlbmd0aCA9IHN0clN5bWJvbHMubGVuZ3RoO1xuICAgICAgfVxuICAgICAgaWYgKGxlbmd0aCA+PSBzdHJMZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIHN0cmluZztcbiAgICAgIH1cbiAgICAgIHZhciBlbmQgPSBsZW5ndGggLSBzdHJpbmdTaXplKG9taXNzaW9uKTtcbiAgICAgIGlmIChlbmQgPCAxKSB7XG4gICAgICAgIHJldHVybiBvbWlzc2lvbjtcbiAgICAgIH1cbiAgICAgIHZhciByZXN1bHQgPSBzdHJTeW1ib2xzXG4gICAgICAgID8gY2FzdFNsaWNlKHN0clN5bWJvbHMsIDAsIGVuZCkuam9pbignJylcbiAgICAgICAgOiBzdHJpbmcuc2xpY2UoMCwgZW5kKTtcblxuICAgICAgaWYgKHNlcGFyYXRvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgKyBvbWlzc2lvbjtcbiAgICAgIH1cbiAgICAgIGlmIChzdHJTeW1ib2xzKSB7XG4gICAgICAgIGVuZCArPSAocmVzdWx0Lmxlbmd0aCAtIGVuZCk7XG4gICAgICB9XG4gICAgICBpZiAoaXNSZWdFeHAoc2VwYXJhdG9yKSkge1xuICAgICAgICBpZiAoc3RyaW5nLnNsaWNlKGVuZCkuc2VhcmNoKHNlcGFyYXRvcikpIHtcbiAgICAgICAgICB2YXIgbWF0Y2gsXG4gICAgICAgICAgICAgIHN1YnN0cmluZyA9IHJlc3VsdDtcblxuICAgICAgICAgIGlmICghc2VwYXJhdG9yLmdsb2JhbCkge1xuICAgICAgICAgICAgc2VwYXJhdG9yID0gUmVnRXhwKHNlcGFyYXRvci5zb3VyY2UsIHRvU3RyaW5nKHJlRmxhZ3MuZXhlYyhzZXBhcmF0b3IpKSArICdnJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNlcGFyYXRvci5sYXN0SW5kZXggPSAwO1xuICAgICAgICAgIHdoaWxlICgobWF0Y2ggPSBzZXBhcmF0b3IuZXhlYyhzdWJzdHJpbmcpKSkge1xuICAgICAgICAgICAgdmFyIG5ld0VuZCA9IG1hdGNoLmluZGV4O1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXN1bHQgPSByZXN1bHQuc2xpY2UoMCwgbmV3RW5kID09PSB1bmRlZmluZWQgPyBlbmQgOiBuZXdFbmQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHN0cmluZy5pbmRleE9mKGJhc2VUb1N0cmluZyhzZXBhcmF0b3IpLCBlbmQpICE9IGVuZCkge1xuICAgICAgICB2YXIgaW5kZXggPSByZXN1bHQubGFzdEluZGV4T2Yoc2VwYXJhdG9yKTtcbiAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICByZXN1bHQgPSByZXN1bHQuc2xpY2UoMCwgaW5kZXgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0ICsgb21pc3Npb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGludmVyc2Ugb2YgYF8uZXNjYXBlYDsgdGhpcyBtZXRob2QgY29udmVydHMgdGhlIEhUTUwgZW50aXRpZXNcbiAgICAgKiBgJmFtcDtgLCBgJmx0O2AsIGAmZ3Q7YCwgYCZxdW90O2AsIGFuZCBgJiMzOTtgIGluIGBzdHJpbmdgIHRvXG4gICAgICogdGhlaXIgY29ycmVzcG9uZGluZyBjaGFyYWN0ZXJzLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIE5vIG90aGVyIEhUTUwgZW50aXRpZXMgYXJlIHVuZXNjYXBlZC4gVG8gdW5lc2NhcGUgYWRkaXRpb25hbFxuICAgICAqIEhUTUwgZW50aXRpZXMgdXNlIGEgdGhpcmQtcGFydHkgbGlicmFyeSBsaWtlIFtfaGVfXShodHRwczovL210aHMuYmUvaGUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDAuNi4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIHVuZXNjYXBlLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHVuZXNjYXBlZCBzdHJpbmcuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udW5lc2NhcGUoJ2ZyZWQsIGJhcm5leSwgJmFtcDsgcGViYmxlcycpO1xuICAgICAqIC8vID0+ICdmcmVkLCBiYXJuZXksICYgcGViYmxlcydcbiAgICAgKi9cbiAgICBmdW5jdGlvbiB1bmVzY2FwZShzdHJpbmcpIHtcbiAgICAgIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gICAgICByZXR1cm4gKHN0cmluZyAmJiByZUhhc0VzY2FwZWRIdG1sLnRlc3Qoc3RyaW5nKSlcbiAgICAgICAgPyBzdHJpbmcucmVwbGFjZShyZUVzY2FwZWRIdG1sLCB1bmVzY2FwZUh0bWxDaGFyKVxuICAgICAgICA6IHN0cmluZztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBgc3RyaW5nYCwgYXMgc3BhY2Ugc2VwYXJhdGVkIHdvcmRzLCB0byB1cHBlciBjYXNlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdXBwZXIgY2FzZWQgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnVwcGVyQ2FzZSgnLS1mb28tYmFyJyk7XG4gICAgICogLy8gPT4gJ0ZPTyBCQVInXG4gICAgICpcbiAgICAgKiBfLnVwcGVyQ2FzZSgnZm9vQmFyJyk7XG4gICAgICogLy8gPT4gJ0ZPTyBCQVInXG4gICAgICpcbiAgICAgKiBfLnVwcGVyQ2FzZSgnX19mb29fYmFyX18nKTtcbiAgICAgKiAvLyA9PiAnRk9PIEJBUidcbiAgICAgKi9cbiAgICB2YXIgdXBwZXJDYXNlID0gY3JlYXRlQ29tcG91bmRlcihmdW5jdGlvbihyZXN1bHQsIHdvcmQsIGluZGV4KSB7XG4gICAgICByZXR1cm4gcmVzdWx0ICsgKGluZGV4ID8gJyAnIDogJycpICsgd29yZC50b1VwcGVyQ2FzZSgpO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiBgc3RyaW5nYCB0byB1cHBlciBjYXNlLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFN0cmluZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgY29udmVydGVkIHN0cmluZy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy51cHBlckZpcnN0KCdmcmVkJyk7XG4gICAgICogLy8gPT4gJ0ZyZWQnXG4gICAgICpcbiAgICAgKiBfLnVwcGVyRmlyc3QoJ0ZSRUQnKTtcbiAgICAgKiAvLyA9PiAnRlJFRCdcbiAgICAgKi9cbiAgICB2YXIgdXBwZXJGaXJzdCA9IGNyZWF0ZUNhc2VGaXJzdCgndG9VcHBlckNhc2UnKTtcblxuICAgIC8qKlxuICAgICAqIFNwbGl0cyBgc3RyaW5nYCBpbnRvIGFuIGFycmF5IG9mIGl0cyB3b3Jkcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBTdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBpbnNwZWN0LlxuICAgICAqIEBwYXJhbSB7UmVnRXhwfHN0cmluZ30gW3BhdHRlcm5dIFRoZSBwYXR0ZXJuIHRvIG1hdGNoIHdvcmRzLlxuICAgICAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgbWV0aG9kcyBsaWtlIGBfLm1hcGAuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSB3b3JkcyBvZiBgc3RyaW5nYC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy53b3JkcygnZnJlZCwgYmFybmV5LCAmIHBlYmJsZXMnKTtcbiAgICAgKiAvLyA9PiBbJ2ZyZWQnLCAnYmFybmV5JywgJ3BlYmJsZXMnXVxuICAgICAqXG4gICAgICogXy53b3JkcygnZnJlZCwgYmFybmV5LCAmIHBlYmJsZXMnLCAvW14sIF0rL2cpO1xuICAgICAqIC8vID0+IFsnZnJlZCcsICdiYXJuZXknLCAnJicsICdwZWJibGVzJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiB3b3JkcyhzdHJpbmcsIHBhdHRlcm4sIGd1YXJkKSB7XG4gICAgICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICAgICAgcGF0dGVybiA9IGd1YXJkID8gdW5kZWZpbmVkIDogcGF0dGVybjtcblxuICAgICAgaWYgKHBhdHRlcm4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gaGFzVW5pY29kZVdvcmQoc3RyaW5nKSA/IHVuaWNvZGVXb3JkcyhzdHJpbmcpIDogYXNjaWlXb3JkcyhzdHJpbmcpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHN0cmluZy5tYXRjaChwYXR0ZXJuKSB8fCBbXTtcbiAgICB9XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBBdHRlbXB0cyB0byBpbnZva2UgYGZ1bmNgLCByZXR1cm5pbmcgZWl0aGVyIHRoZSByZXN1bHQgb3IgdGhlIGNhdWdodCBlcnJvclxuICAgICAqIG9iamVjdC4gQW55IGFkZGl0aW9uYWwgYXJndW1lbnRzIGFyZSBwcm92aWRlZCB0byBgZnVuY2Agd2hlbiBpdCdzIGludm9rZWQuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGF0dGVtcHQuXG4gICAgICogQHBhcmFtIHsuLi4qfSBbYXJnc10gVGhlIGFyZ3VtZW50cyB0byBpbnZva2UgYGZ1bmNgIHdpdGguXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGBmdW5jYCByZXN1bHQgb3IgZXJyb3Igb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiAvLyBBdm9pZCB0aHJvd2luZyBlcnJvcnMgZm9yIGludmFsaWQgc2VsZWN0b3JzLlxuICAgICAqIHZhciBlbGVtZW50cyA9IF8uYXR0ZW1wdChmdW5jdGlvbihzZWxlY3Rvcikge1xuICAgICAqICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpO1xuICAgICAqIH0sICc+Xz4nKTtcbiAgICAgKlxuICAgICAqIGlmIChfLmlzRXJyb3IoZWxlbWVudHMpKSB7XG4gICAgICogICBlbGVtZW50cyA9IFtdO1xuICAgICAqIH1cbiAgICAgKi9cbiAgICB2YXIgYXR0ZW1wdCA9IGJhc2VSZXN0KGZ1bmN0aW9uKGZ1bmMsIGFyZ3MpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhcHBseShmdW5jLCB1bmRlZmluZWQsIGFyZ3MpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gaXNFcnJvcihlKSA/IGUgOiBuZXcgRXJyb3IoZSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBCaW5kcyBtZXRob2RzIG9mIGFuIG9iamVjdCB0byB0aGUgb2JqZWN0IGl0c2VsZiwgb3ZlcndyaXRpbmcgdGhlIGV4aXN0aW5nXG4gICAgICogbWV0aG9kLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGRvZXNuJ3Qgc2V0IHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IG9mIGJvdW5kIGZ1bmN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGJpbmQgYW5kIGFzc2lnbiB0aGUgYm91bmQgbWV0aG9kcyB0by5cbiAgICAgKiBAcGFyYW0gey4uLihzdHJpbmd8c3RyaW5nW10pfSBtZXRob2ROYW1lcyBUaGUgb2JqZWN0IG1ldGhvZCBuYW1lcyB0byBiaW5kLlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciB2aWV3ID0ge1xuICAgICAqICAgJ2xhYmVsJzogJ2RvY3MnLFxuICAgICAqICAgJ2NsaWNrJzogZnVuY3Rpb24oKSB7XG4gICAgICogICAgIGNvbnNvbGUubG9nKCdjbGlja2VkICcgKyB0aGlzLmxhYmVsKTtcbiAgICAgKiAgIH1cbiAgICAgKiB9O1xuICAgICAqXG4gICAgICogXy5iaW5kQWxsKHZpZXcsIFsnY2xpY2snXSk7XG4gICAgICogalF1ZXJ5KGVsZW1lbnQpLm9uKCdjbGljaycsIHZpZXcuY2xpY2spO1xuICAgICAqIC8vID0+IExvZ3MgJ2NsaWNrZWQgZG9jcycgd2hlbiBjbGlja2VkLlxuICAgICAqL1xuICAgIHZhciBiaW5kQWxsID0gZmxhdFJlc3QoZnVuY3Rpb24ob2JqZWN0LCBtZXRob2ROYW1lcykge1xuICAgICAgYXJyYXlFYWNoKG1ldGhvZE5hbWVzLCBmdW5jdGlvbihrZXkpIHtcbiAgICAgICAga2V5ID0gdG9LZXkoa2V5KTtcbiAgICAgICAgYmFzZUFzc2lnblZhbHVlKG9iamVjdCwga2V5LCBiaW5kKG9iamVjdFtrZXldLCBvYmplY3QpKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGl0ZXJhdGVzIG92ZXIgYHBhaXJzYCBhbmQgaW52b2tlcyB0aGUgY29ycmVzcG9uZGluZ1xuICAgICAqIGZ1bmN0aW9uIG9mIHRoZSBmaXJzdCBwcmVkaWNhdGUgdG8gcmV0dXJuIHRydXRoeS4gVGhlIHByZWRpY2F0ZS1mdW5jdGlvblxuICAgICAqIHBhaXJzIGFyZSBpbnZva2VkIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIGFuZCBhcmd1bWVudHMgb2YgdGhlIGNyZWF0ZWRcbiAgICAgKiBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtBcnJheX0gcGFpcnMgVGhlIHByZWRpY2F0ZS1mdW5jdGlvbiBwYWlycy5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjb21wb3NpdGUgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBmdW5jID0gXy5jb25kKFtcbiAgICAgKiAgIFtfLm1hdGNoZXMoeyAnYSc6IDEgfSksICAgICAgICAgICBfLmNvbnN0YW50KCdtYXRjaGVzIEEnKV0sXG4gICAgICogICBbXy5jb25mb3Jtcyh7ICdiJzogXy5pc051bWJlciB9KSwgXy5jb25zdGFudCgnbWF0Y2hlcyBCJyldLFxuICAgICAqICAgW18uc3R1YlRydWUsICAgICAgICAgICAgICAgICAgICAgIF8uY29uc3RhbnQoJ25vIG1hdGNoJyldXG4gICAgICogXSk7XG4gICAgICpcbiAgICAgKiBmdW5jKHsgJ2EnOiAxLCAnYic6IDIgfSk7XG4gICAgICogLy8gPT4gJ21hdGNoZXMgQSdcbiAgICAgKlxuICAgICAqIGZ1bmMoeyAnYSc6IDAsICdiJzogMSB9KTtcbiAgICAgKiAvLyA9PiAnbWF0Y2hlcyBCJ1xuICAgICAqXG4gICAgICogZnVuYyh7ICdhJzogJzEnLCAnYic6ICcyJyB9KTtcbiAgICAgKiAvLyA9PiAnbm8gbWF0Y2gnXG4gICAgICovXG4gICAgZnVuY3Rpb24gY29uZChwYWlycykge1xuICAgICAgdmFyIGxlbmd0aCA9IHBhaXJzID09IG51bGwgPyAwIDogcGFpcnMubGVuZ3RoLFxuICAgICAgICAgIHRvSXRlcmF0ZWUgPSBnZXRJdGVyYXRlZSgpO1xuXG4gICAgICBwYWlycyA9ICFsZW5ndGggPyBbXSA6IGFycmF5TWFwKHBhaXJzLCBmdW5jdGlvbihwYWlyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcGFpclsxXSAhPSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbdG9JdGVyYXRlZShwYWlyWzBdKSwgcGFpclsxXV07XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGJhc2VSZXN0KGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gLTE7XG4gICAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgdmFyIHBhaXIgPSBwYWlyc1tpbmRleF07XG4gICAgICAgICAgaWYgKGFwcGx5KHBhaXJbMF0sIHRoaXMsIGFyZ3MpKSB7XG4gICAgICAgICAgICByZXR1cm4gYXBwbHkocGFpclsxXSwgdGhpcywgYXJncyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIHRoZSBwcmVkaWNhdGUgcHJvcGVydGllcyBvZiBgc291cmNlYCB3aXRoXG4gICAgICogdGhlIGNvcnJlc3BvbmRpbmcgcHJvcGVydHkgdmFsdWVzIG9mIGEgZ2l2ZW4gb2JqZWN0LCByZXR1cm5pbmcgYHRydWVgIGlmXG4gICAgICogYWxsIHByZWRpY2F0ZXMgcmV0dXJuIHRydXRoeSwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFRoZSBjcmVhdGVkIGZ1bmN0aW9uIGlzIGVxdWl2YWxlbnQgdG8gYF8uY29uZm9ybXNUb2Agd2l0aFxuICAgICAqIGBzb3VyY2VgIHBhcnRpYWxseSBhcHBsaWVkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgcHJlZGljYXRlcyB0byBjb25mb3JtIHRvLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHNwZWMgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW1xuICAgICAqICAgeyAnYSc6IDIsICdiJzogMSB9LFxuICAgICAqICAgeyAnYSc6IDEsICdiJzogMiB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8uZmlsdGVyKG9iamVjdHMsIF8uY29uZm9ybXMoeyAnYic6IGZ1bmN0aW9uKG4pIHsgcmV0dXJuIG4gPiAxOyB9IH0pKTtcbiAgICAgKiAvLyA9PiBbeyAnYSc6IDEsICdiJzogMiB9XVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbmZvcm1zKHNvdXJjZSkge1xuICAgICAgcmV0dXJuIGJhc2VDb25mb3JtcyhiYXNlQ2xvbmUoc291cmNlLCBDTE9ORV9ERUVQX0ZMQUcpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGB2YWx1ZWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMi40LjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHJldHVybiBmcm9tIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY29uc3RhbnQgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gXy50aW1lcygyLCBfLmNvbnN0YW50KHsgJ2EnOiAxIH0pKTtcbiAgICAgKlxuICAgICAqIGNvbnNvbGUubG9nKG9iamVjdHMpO1xuICAgICAqIC8vID0+IFt7ICdhJzogMSB9LCB7ICdhJzogMSB9XVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2cob2JqZWN0c1swXSA9PT0gb2JqZWN0c1sxXSk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNvbnN0YW50KHZhbHVlKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGB2YWx1ZWAgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgYSBkZWZhdWx0IHZhbHVlIHNob3VsZCBiZSByZXR1cm5lZCBpblxuICAgICAqIGl0cyBwbGFjZS4gVGhlIGBkZWZhdWx0VmFsdWVgIGlzIHJldHVybmVkIGlmIGB2YWx1ZWAgaXMgYE5hTmAsIGBudWxsYCxcbiAgICAgKiBvciBgdW5kZWZpbmVkYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjE0LjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICAgICAqIEBwYXJhbSB7Kn0gZGVmYXVsdFZhbHVlIFRoZSBkZWZhdWx0IHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSByZXNvbHZlZCB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5kZWZhdWx0VG8oMSwgMTApO1xuICAgICAqIC8vID0+IDFcbiAgICAgKlxuICAgICAqIF8uZGVmYXVsdFRvKHVuZGVmaW5lZCwgMTApO1xuICAgICAqIC8vID0+IDEwXG4gICAgICovXG4gICAgZnVuY3Rpb24gZGVmYXVsdFRvKHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgICAgIHJldHVybiAodmFsdWUgPT0gbnVsbCB8fCB2YWx1ZSAhPT0gdmFsdWUpID8gZGVmYXVsdFZhbHVlIDogdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgcmVzdWx0IG9mIGludm9raW5nIHRoZSBnaXZlbiBmdW5jdGlvbnNcbiAgICAgKiB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGUgY3JlYXRlZCBmdW5jdGlvbiwgd2hlcmUgZWFjaCBzdWNjZXNzaXZlXG4gICAgICogaW52b2NhdGlvbiBpcyBzdXBwbGllZCB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBwcmV2aW91cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHsuLi4oRnVuY3Rpb258RnVuY3Rpb25bXSl9IFtmdW5jc10gVGhlIGZ1bmN0aW9ucyB0byBpbnZva2UuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY29tcG9zaXRlIGZ1bmN0aW9uLlxuICAgICAqIEBzZWUgXy5mbG93UmlnaHRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gc3F1YXJlKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICogbjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiB2YXIgYWRkU3F1YXJlID0gXy5mbG93KFtfLmFkZCwgc3F1YXJlXSk7XG4gICAgICogYWRkU3F1YXJlKDEsIDIpO1xuICAgICAqIC8vID0+IDlcbiAgICAgKi9cbiAgICB2YXIgZmxvdyA9IGNyZWF0ZUZsb3coKTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8uZmxvd2AgZXhjZXB0IHRoYXQgaXQgY3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXRcbiAgICAgKiBpbnZva2VzIHRoZSBnaXZlbiBmdW5jdGlvbnMgZnJvbSByaWdodCB0byBsZWZ0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0gey4uLihGdW5jdGlvbnxGdW5jdGlvbltdKX0gW2Z1bmNzXSBUaGUgZnVuY3Rpb25zIHRvIGludm9rZS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjb21wb3NpdGUgZnVuY3Rpb24uXG4gICAgICogQHNlZSBfLmZsb3dcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gc3F1YXJlKG4pIHtcbiAgICAgKiAgIHJldHVybiBuICogbjtcbiAgICAgKiB9XG4gICAgICpcbiAgICAgKiB2YXIgYWRkU3F1YXJlID0gXy5mbG93UmlnaHQoW3NxdWFyZSwgXy5hZGRdKTtcbiAgICAgKiBhZGRTcXVhcmUoMSwgMik7XG4gICAgICogLy8gPT4gOVxuICAgICAqL1xuICAgIHZhciBmbG93UmlnaHQgPSBjcmVhdGVGbG93KHRydWUpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgZmlyc3QgYXJndW1lbnQgaXQgcmVjZWl2ZXMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQHNpbmNlIDAuMS4wXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgQW55IHZhbHVlLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIGB2YWx1ZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3QgPSB7ICdhJzogMSB9O1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2coXy5pZGVudGl0eShvYmplY3QpID09PSBvYmplY3QpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpZGVudGl0eSh2YWx1ZSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggdGhlIGFyZ3VtZW50cyBvZiB0aGUgY3JlYXRlZFxuICAgICAqIGZ1bmN0aW9uLiBJZiBgZnVuY2AgaXMgYSBwcm9wZXJ0eSBuYW1lLCB0aGUgY3JlYXRlZCBmdW5jdGlvbiByZXR1cm5zIHRoZVxuICAgICAqIHByb3BlcnR5IHZhbHVlIGZvciBhIGdpdmVuIGVsZW1lbnQuIElmIGBmdW5jYCBpcyBhbiBhcnJheSBvciBvYmplY3QsIHRoZVxuICAgICAqIGNyZWF0ZWQgZnVuY3Rpb24gcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgY29udGFpbiB0aGUgZXF1aXZhbGVudFxuICAgICAqIHNvdXJjZSBwcm9wZXJ0aWVzLCBvdGhlcndpc2UgaXQgcmV0dXJucyBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0geyp9IFtmdW5jPV8uaWRlbnRpdHldIFRoZSB2YWx1ZSB0byBjb252ZXJ0IHRvIGEgY2FsbGJhY2suXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBjYWxsYmFjay5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIHVzZXJzID0gW1xuICAgICAqICAgeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0sXG4gICAgICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogLy8gVGhlIGBfLm1hdGNoZXNgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAgICAgKiBfLmZpbHRlcih1c2VycywgXy5pdGVyYXRlZSh7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiB0cnVlIH0pKTtcbiAgICAgKiAvLyA9PiBbeyAndXNlcic6ICdiYXJuZXknLCAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH1dXG4gICAgICpcbiAgICAgKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5maWx0ZXIodXNlcnMsIF8uaXRlcmF0ZWUoWyd1c2VyJywgJ2ZyZWQnXSkpO1xuICAgICAqIC8vID0+IFt7ICd1c2VyJzogJ2ZyZWQnLCAnYWdlJzogNDAgfV1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ubWFwKHVzZXJzLCBfLml0ZXJhdGVlKCd1c2VyJykpO1xuICAgICAqIC8vID0+IFsnYmFybmV5JywgJ2ZyZWQnXVxuICAgICAqXG4gICAgICogLy8gQ3JlYXRlIGN1c3RvbSBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICAgICAqIF8uaXRlcmF0ZWUgPSBfLndyYXAoXy5pdGVyYXRlZSwgZnVuY3Rpb24oaXRlcmF0ZWUsIGZ1bmMpIHtcbiAgICAgKiAgIHJldHVybiAhXy5pc1JlZ0V4cChmdW5jKSA/IGl0ZXJhdGVlKGZ1bmMpIDogZnVuY3Rpb24oc3RyaW5nKSB7XG4gICAgICogICAgIHJldHVybiBmdW5jLnRlc3Qoc3RyaW5nKTtcbiAgICAgKiAgIH07XG4gICAgICogfSk7XG4gICAgICpcbiAgICAgKiBfLmZpbHRlcihbJ2FiYycsICdkZWYnXSwgL2VmLyk7XG4gICAgICogLy8gPT4gWydkZWYnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGl0ZXJhdGVlKGZ1bmMpIHtcbiAgICAgIHJldHVybiBiYXNlSXRlcmF0ZWUodHlwZW9mIGZ1bmMgPT0gJ2Z1bmN0aW9uJyA/IGZ1bmMgOiBiYXNlQ2xvbmUoZnVuYywgQ0xPTkVfREVFUF9GTEFHKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcGVyZm9ybXMgYSBwYXJ0aWFsIGRlZXAgY29tcGFyaXNvbiBiZXR3ZWVuIGEgZ2l2ZW5cbiAgICAgKiBvYmplY3QgYW5kIGBzb3VyY2VgLCByZXR1cm5pbmcgYHRydWVgIGlmIHRoZSBnaXZlbiBvYmplY3QgaGFzIGVxdWl2YWxlbnRcbiAgICAgKiBwcm9wZXJ0eSB2YWx1ZXMsIGVsc2UgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqICoqTm90ZToqKiBUaGUgY3JlYXRlZCBmdW5jdGlvbiBpcyBlcXVpdmFsZW50IHRvIGBfLmlzTWF0Y2hgIHdpdGggYHNvdXJjZWBcbiAgICAgKiBwYXJ0aWFsbHkgYXBwbGllZC5cbiAgICAgKlxuICAgICAqIFBhcnRpYWwgY29tcGFyaXNvbnMgd2lsbCBtYXRjaCBlbXB0eSBhcnJheSBhbmQgZW1wdHkgb2JqZWN0IGBzb3VyY2VgXG4gICAgICogdmFsdWVzIGFnYWluc3QgYW55IGFycmF5IG9yIG9iamVjdCB2YWx1ZSwgcmVzcGVjdGl2ZWx5LiBTZWUgYF8uaXNFcXVhbGBcbiAgICAgKiBmb3IgYSBsaXN0IG9mIHN1cHBvcnRlZCB2YWx1ZSBjb21wYXJpc29ucy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIHByb3BlcnR5IHZhbHVlcyB0byBtYXRjaC5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFtcbiAgICAgKiAgIHsgJ2EnOiAxLCAnYic6IDIsICdjJzogMyB9LFxuICAgICAqICAgeyAnYSc6IDQsICdiJzogNSwgJ2MnOiA2IH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5maWx0ZXIob2JqZWN0cywgXy5tYXRjaGVzKHsgJ2EnOiA0LCAnYyc6IDYgfSkpO1xuICAgICAqIC8vID0+IFt7ICdhJzogNCwgJ2InOiA1LCAnYyc6IDYgfV1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXRjaGVzKHNvdXJjZSkge1xuICAgICAgcmV0dXJuIGJhc2VNYXRjaGVzKGJhc2VDbG9uZShzb3VyY2UsIENMT05FX0RFRVBfRkxBRykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHBlcmZvcm1zIGEgcGFydGlhbCBkZWVwIGNvbXBhcmlzb24gYmV0d2VlbiB0aGVcbiAgICAgKiB2YWx1ZSBhdCBgcGF0aGAgb2YgYSBnaXZlbiBvYmplY3QgdG8gYHNyY1ZhbHVlYCwgcmV0dXJuaW5nIGB0cnVlYCBpZiB0aGVcbiAgICAgKiBvYmplY3QgdmFsdWUgaXMgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFBhcnRpYWwgY29tcGFyaXNvbnMgd2lsbCBtYXRjaCBlbXB0eSBhcnJheSBhbmQgZW1wdHkgb2JqZWN0XG4gICAgICogYHNyY1ZhbHVlYCB2YWx1ZXMgYWdhaW5zdCBhbnkgYXJyYXkgb3Igb2JqZWN0IHZhbHVlLCByZXNwZWN0aXZlbHkuIFNlZVxuICAgICAqIGBfLmlzRXF1YWxgIGZvciBhIGxpc3Qgb2Ygc3VwcG9ydGVkIHZhbHVlIGNvbXBhcmlzb25zLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMi4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgICAqIEBwYXJhbSB7Kn0gc3JjVmFsdWUgVGhlIHZhbHVlIHRvIG1hdGNoLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHNwZWMgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW1xuICAgICAqICAgeyAnYSc6IDEsICdiJzogMiwgJ2MnOiAzIH0sXG4gICAgICogICB7ICdhJzogNCwgJ2InOiA1LCAnYyc6IDYgfVxuICAgICAqIF07XG4gICAgICpcbiAgICAgKiBfLmZpbmQob2JqZWN0cywgXy5tYXRjaGVzUHJvcGVydHkoJ2EnLCA0KSk7XG4gICAgICogLy8gPT4geyAnYSc6IDQsICdiJzogNSwgJ2MnOiA2IH1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXRjaGVzUHJvcGVydHkocGF0aCwgc3JjVmFsdWUpIHtcbiAgICAgIHJldHVybiBiYXNlTWF0Y2hlc1Byb3BlcnR5KHBhdGgsIGJhc2VDbG9uZShzcmNWYWx1ZSwgQ0xPTkVfREVFUF9GTEFHKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyB0aGUgbWV0aG9kIGF0IGBwYXRoYCBvZiBhIGdpdmVuIG9iamVjdC5cbiAgICAgKiBBbnkgYWRkaXRpb25hbCBhcmd1bWVudHMgYXJlIHByb3ZpZGVkIHRvIHRoZSBpbnZva2VkIG1ldGhvZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjcuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIG1ldGhvZCB0byBpbnZva2UuXG4gICAgICogQHBhcmFtIHsuLi4qfSBbYXJnc10gVGhlIGFyZ3VtZW50cyB0byBpbnZva2UgdGhlIG1ldGhvZCB3aXRoLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGludm9rZXIgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW1xuICAgICAqICAgeyAnYSc6IHsgJ2InOiBfLmNvbnN0YW50KDIpIH0gfSxcbiAgICAgKiAgIHsgJ2EnOiB7ICdiJzogXy5jb25zdGFudCgxKSB9IH1cbiAgICAgKiBdO1xuICAgICAqXG4gICAgICogXy5tYXAob2JqZWN0cywgXy5tZXRob2QoJ2EuYicpKTtcbiAgICAgKiAvLyA9PiBbMiwgMV1cbiAgICAgKlxuICAgICAqIF8ubWFwKG9iamVjdHMsIF8ubWV0aG9kKFsnYScsICdiJ10pKTtcbiAgICAgKiAvLyA9PiBbMiwgMV1cbiAgICAgKi9cbiAgICB2YXIgbWV0aG9kID0gYmFzZVJlc3QoZnVuY3Rpb24ocGF0aCwgYXJncykge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgICAgICByZXR1cm4gYmFzZUludm9rZShvYmplY3QsIHBhdGgsIGFyZ3MpO1xuICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBvcHBvc2l0ZSBvZiBgXy5tZXRob2RgOyB0aGlzIG1ldGhvZCBjcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzXG4gICAgICogdGhlIG1ldGhvZCBhdCBhIGdpdmVuIHBhdGggb2YgYG9iamVjdGAuIEFueSBhZGRpdGlvbmFsIGFyZ3VtZW50cyBhcmVcbiAgICAgKiBwcm92aWRlZCB0byB0aGUgaW52b2tlZCBtZXRob2QuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy43LjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0gey4uLip9IFthcmdzXSBUaGUgYXJndW1lbnRzIHRvIGludm9rZSB0aGUgbWV0aG9kIHdpdGguXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgaW52b2tlciBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gXy50aW1lcygzLCBfLmNvbnN0YW50KSxcbiAgICAgKiAgICAgb2JqZWN0ID0geyAnYSc6IGFycmF5LCAnYic6IGFycmF5LCAnYyc6IGFycmF5IH07XG4gICAgICpcbiAgICAgKiBfLm1hcChbJ2FbMl0nLCAnY1swXSddLCBfLm1ldGhvZE9mKG9iamVjdCkpO1xuICAgICAqIC8vID0+IFsyLCAwXVxuICAgICAqXG4gICAgICogXy5tYXAoW1snYScsICcyJ10sIFsnYycsICcwJ11dLCBfLm1ldGhvZE9mKG9iamVjdCkpO1xuICAgICAqIC8vID0+IFsyLCAwXVxuICAgICAqL1xuICAgIHZhciBtZXRob2RPZiA9IGJhc2VSZXN0KGZ1bmN0aW9uKG9iamVjdCwgYXJncykge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKHBhdGgpIHtcbiAgICAgICAgcmV0dXJuIGJhc2VJbnZva2Uob2JqZWN0LCBwYXRoLCBhcmdzKTtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGFsbCBvd24gZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgZnVuY3Rpb24gcHJvcGVydGllcyBvZiBhIHNvdXJjZVxuICAgICAqIG9iamVjdCB0byB0aGUgZGVzdGluYXRpb24gb2JqZWN0LiBJZiBgb2JqZWN0YCBpcyBhIGZ1bmN0aW9uLCB0aGVuIG1ldGhvZHNcbiAgICAgKiBhcmUgYWRkZWQgdG8gaXRzIHByb3RvdHlwZSBhcyB3ZWxsLlxuICAgICAqXG4gICAgICogKipOb3RlOioqIFVzZSBgXy5ydW5JbkNvbnRleHRgIHRvIGNyZWF0ZSBhIHByaXN0aW5lIGBsb2Rhc2hgIGZ1bmN0aW9uIHRvXG4gICAgICogYXZvaWQgY29uZmxpY3RzIGNhdXNlZCBieSBtb2RpZnlpbmcgdGhlIG9yaWdpbmFsLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdH0gW29iamVjdD1sb2Rhc2hdIFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgb2JqZWN0IG9mIGZ1bmN0aW9ucyB0byBhZGQuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zPXt9XSBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5jaGFpbj10cnVlXSBTcGVjaWZ5IHdoZXRoZXIgbWl4aW5zIGFyZSBjaGFpbmFibGUuXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufE9iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogZnVuY3Rpb24gdm93ZWxzKHN0cmluZykge1xuICAgICAqICAgcmV0dXJuIF8uZmlsdGVyKHN0cmluZywgZnVuY3Rpb24odikge1xuICAgICAqICAgICByZXR1cm4gL1thZWlvdV0vaS50ZXN0KHYpO1xuICAgICAqICAgfSk7XG4gICAgICogfVxuICAgICAqXG4gICAgICogXy5taXhpbih7ICd2b3dlbHMnOiB2b3dlbHMgfSk7XG4gICAgICogXy52b3dlbHMoJ2ZyZWQnKTtcbiAgICAgKiAvLyA9PiBbJ2UnXVxuICAgICAqXG4gICAgICogXygnZnJlZCcpLnZvd2VscygpLnZhbHVlKCk7XG4gICAgICogLy8gPT4gWydlJ11cbiAgICAgKlxuICAgICAqIF8ubWl4aW4oeyAndm93ZWxzJzogdm93ZWxzIH0sIHsgJ2NoYWluJzogZmFsc2UgfSk7XG4gICAgICogXygnZnJlZCcpLnZvd2VscygpO1xuICAgICAqIC8vID0+IFsnZSddXG4gICAgICovXG4gICAgZnVuY3Rpb24gbWl4aW4ob2JqZWN0LCBzb3VyY2UsIG9wdGlvbnMpIHtcbiAgICAgIHZhciBwcm9wcyA9IGtleXMoc291cmNlKSxcbiAgICAgICAgICBtZXRob2ROYW1lcyA9IGJhc2VGdW5jdGlvbnMoc291cmNlLCBwcm9wcyk7XG5cbiAgICAgIGlmIChvcHRpb25zID09IG51bGwgJiZcbiAgICAgICAgICAhKGlzT2JqZWN0KHNvdXJjZSkgJiYgKG1ldGhvZE5hbWVzLmxlbmd0aCB8fCAhcHJvcHMubGVuZ3RoKSkpIHtcbiAgICAgICAgb3B0aW9ucyA9IHNvdXJjZTtcbiAgICAgICAgc291cmNlID0gb2JqZWN0O1xuICAgICAgICBvYmplY3QgPSB0aGlzO1xuICAgICAgICBtZXRob2ROYW1lcyA9IGJhc2VGdW5jdGlvbnMoc291cmNlLCBrZXlzKHNvdXJjZSkpO1xuICAgICAgfVxuICAgICAgdmFyIGNoYWluID0gIShpc09iamVjdChvcHRpb25zKSAmJiAnY2hhaW4nIGluIG9wdGlvbnMpIHx8ICEhb3B0aW9ucy5jaGFpbixcbiAgICAgICAgICBpc0Z1bmMgPSBpc0Z1bmN0aW9uKG9iamVjdCk7XG5cbiAgICAgIGFycmF5RWFjaChtZXRob2ROYW1lcywgZnVuY3Rpb24obWV0aG9kTmFtZSkge1xuICAgICAgICB2YXIgZnVuYyA9IHNvdXJjZVttZXRob2ROYW1lXTtcbiAgICAgICAgb2JqZWN0W21ldGhvZE5hbWVdID0gZnVuYztcbiAgICAgICAgaWYgKGlzRnVuYykge1xuICAgICAgICAgIG9iamVjdC5wcm90b3R5cGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHZhciBjaGFpbkFsbCA9IHRoaXMuX19jaGFpbl9fO1xuICAgICAgICAgICAgaWYgKGNoYWluIHx8IGNoYWluQWxsKSB7XG4gICAgICAgICAgICAgIHZhciByZXN1bHQgPSBvYmplY3QodGhpcy5fX3dyYXBwZWRfXyksXG4gICAgICAgICAgICAgICAgICBhY3Rpb25zID0gcmVzdWx0Ll9fYWN0aW9uc19fID0gY29weUFycmF5KHRoaXMuX19hY3Rpb25zX18pO1xuXG4gICAgICAgICAgICAgIGFjdGlvbnMucHVzaCh7ICdmdW5jJzogZnVuYywgJ2FyZ3MnOiBhcmd1bWVudHMsICd0aGlzQXJnJzogb2JqZWN0IH0pO1xuICAgICAgICAgICAgICByZXN1bHQuX19jaGFpbl9fID0gY2hhaW5BbGw7XG4gICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZnVuYy5hcHBseShvYmplY3QsIGFycmF5UHVzaChbdGhpcy52YWx1ZSgpXSwgYXJndW1lbnRzKSk7XG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV2ZXJ0cyB0aGUgYF9gIHZhcmlhYmxlIHRvIGl0cyBwcmV2aW91cyB2YWx1ZSBhbmQgcmV0dXJucyBhIHJlZmVyZW5jZSB0b1xuICAgICAqIHRoZSBgbG9kYXNoYCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBgbG9kYXNoYCBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGxvZGFzaCA9IF8ubm9Db25mbGljdCgpO1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIG5vQ29uZmxpY3QoKSB7XG4gICAgICBpZiAocm9vdC5fID09PSB0aGlzKSB7XG4gICAgICAgIHJvb3QuXyA9IG9sZERhc2g7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIGB1bmRlZmluZWRgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuMy4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50aW1lcygyLCBfLm5vb3ApO1xuICAgICAqIC8vID0+IFt1bmRlZmluZWQsIHVuZGVmaW5lZF1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBub29wKCkge1xuICAgICAgLy8gTm8gb3BlcmF0aW9uIHBlcmZvcm1lZC5cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBnZXRzIHRoZSBhcmd1bWVudCBhdCBpbmRleCBgbmAuIElmIGBuYCBpcyBuZWdhdGl2ZSxcbiAgICAgKiB0aGUgbnRoIGFyZ3VtZW50IGZyb20gdGhlIGVuZCBpcyByZXR1cm5lZC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtuPTBdIFRoZSBpbmRleCBvZiB0aGUgYXJndW1lbnQgdG8gcmV0dXJuLlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHBhc3MtdGhydSBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGZ1bmMgPSBfLm50aEFyZygxKTtcbiAgICAgKiBmdW5jKCdhJywgJ2InLCAnYycsICdkJyk7XG4gICAgICogLy8gPT4gJ2InXG4gICAgICpcbiAgICAgKiB2YXIgZnVuYyA9IF8ubnRoQXJnKC0yKTtcbiAgICAgKiBmdW5jKCdhJywgJ2InLCAnYycsICdkJyk7XG4gICAgICogLy8gPT4gJ2MnXG4gICAgICovXG4gICAgZnVuY3Rpb24gbnRoQXJnKG4pIHtcbiAgICAgIG4gPSB0b0ludGVnZXIobik7XG4gICAgICByZXR1cm4gYmFzZVJlc3QoZnVuY3Rpb24oYXJncykge1xuICAgICAgICByZXR1cm4gYmFzZU50aChhcmdzLCBuKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGl0ZXJhdGVlc2Agd2l0aCB0aGUgYXJndW1lbnRzIGl0IHJlY2VpdmVzXG4gICAgICogYW5kIHJldHVybnMgdGhlaXIgcmVzdWx0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHsuLi4oRnVuY3Rpb258RnVuY3Rpb25bXSl9IFtpdGVyYXRlZXM9W18uaWRlbnRpdHldXVxuICAgICAqICBUaGUgaXRlcmF0ZWVzIHRvIGludm9rZS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGZ1bmMgPSBfLm92ZXIoW01hdGgubWF4LCBNYXRoLm1pbl0pO1xuICAgICAqXG4gICAgICogZnVuYygxLCAyLCAzLCA0KTtcbiAgICAgKiAvLyA9PiBbNCwgMV1cbiAgICAgKi9cbiAgICB2YXIgb3ZlciA9IGNyZWF0ZU92ZXIoYXJyYXlNYXApO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgY2hlY2tzIGlmICoqYWxsKiogb2YgdGhlIGBwcmVkaWNhdGVzYCByZXR1cm5cbiAgICAgKiB0cnV0aHkgd2hlbiBpbnZva2VkIHdpdGggdGhlIGFyZ3VtZW50cyBpdCByZWNlaXZlcy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHsuLi4oRnVuY3Rpb258RnVuY3Rpb25bXSl9IFtwcmVkaWNhdGVzPVtfLmlkZW50aXR5XV1cbiAgICAgKiAgVGhlIHByZWRpY2F0ZXMgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBmdW5jID0gXy5vdmVyRXZlcnkoW0Jvb2xlYW4sIGlzRmluaXRlXSk7XG4gICAgICpcbiAgICAgKiBmdW5jKCcxJyk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogZnVuYyhudWxsKTtcbiAgICAgKiAvLyA9PiBmYWxzZVxuICAgICAqXG4gICAgICogZnVuYyhOYU4pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgdmFyIG92ZXJFdmVyeSA9IGNyZWF0ZU92ZXIoYXJyYXlFdmVyeSk7XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBjaGVja3MgaWYgKiphbnkqKiBvZiB0aGUgYHByZWRpY2F0ZXNgIHJldHVyblxuICAgICAqIHRydXRoeSB3aGVuIGludm9rZWQgd2l0aCB0aGUgYXJndW1lbnRzIGl0IHJlY2VpdmVzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0gey4uLihGdW5jdGlvbnxGdW5jdGlvbltdKX0gW3ByZWRpY2F0ZXM9W18uaWRlbnRpdHldXVxuICAgICAqICBUaGUgcHJlZGljYXRlcyB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGZ1bmMgPSBfLm92ZXJTb21lKFtCb29sZWFuLCBpc0Zpbml0ZV0pO1xuICAgICAqXG4gICAgICogZnVuYygnMScpO1xuICAgICAqIC8vID0+IHRydWVcbiAgICAgKlxuICAgICAqIGZ1bmMobnVsbCk7XG4gICAgICogLy8gPT4gdHJ1ZVxuICAgICAqXG4gICAgICogZnVuYyhOYU4pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgdmFyIG92ZXJTb21lID0gY3JlYXRlT3ZlcihhcnJheVNvbWUpO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgdmFsdWUgYXQgYHBhdGhgIG9mIGEgZ2l2ZW4gb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDIuNC4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGFjY2Vzc29yIGZ1bmN0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFtcbiAgICAgKiAgIHsgJ2EnOiB7ICdiJzogMiB9IH0sXG4gICAgICogICB7ICdhJzogeyAnYic6IDEgfSB9XG4gICAgICogXTtcbiAgICAgKlxuICAgICAqIF8ubWFwKG9iamVjdHMsIF8ucHJvcGVydHkoJ2EuYicpKTtcbiAgICAgKiAvLyA9PiBbMiwgMV1cbiAgICAgKlxuICAgICAqIF8ubWFwKF8uc29ydEJ5KG9iamVjdHMsIF8ucHJvcGVydHkoWydhJywgJ2InXSkpLCAnYS5iJyk7XG4gICAgICogLy8gPT4gWzEsIDJdXG4gICAgICovXG4gICAgZnVuY3Rpb24gcHJvcGVydHkocGF0aCkge1xuICAgICAgcmV0dXJuIGlzS2V5KHBhdGgpID8gYmFzZVByb3BlcnR5KHRvS2V5KHBhdGgpKSA6IGJhc2VQcm9wZXJ0eURlZXAocGF0aCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIG9wcG9zaXRlIG9mIGBfLnByb3BlcnR5YDsgdGhpcyBtZXRob2QgY3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJuc1xuICAgICAqIHRoZSB2YWx1ZSBhdCBhIGdpdmVuIHBhdGggb2YgYG9iamVjdGAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBhY2Nlc3NvciBmdW5jdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5ID0gWzAsIDEsIDJdLFxuICAgICAqICAgICBvYmplY3QgPSB7ICdhJzogYXJyYXksICdiJzogYXJyYXksICdjJzogYXJyYXkgfTtcbiAgICAgKlxuICAgICAqIF8ubWFwKFsnYVsyXScsICdjWzBdJ10sIF8ucHJvcGVydHlPZihvYmplY3QpKTtcbiAgICAgKiAvLyA9PiBbMiwgMF1cbiAgICAgKlxuICAgICAqIF8ubWFwKFtbJ2EnLCAnMiddLCBbJ2MnLCAnMCddXSwgXy5wcm9wZXJ0eU9mKG9iamVjdCkpO1xuICAgICAqIC8vID0+IFsyLCAwXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHByb3BlcnR5T2Yob2JqZWN0KSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24ocGF0aCkge1xuICAgICAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBiYXNlR2V0KG9iamVjdCwgcGF0aCk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgbnVtYmVycyAocG9zaXRpdmUgYW5kL29yIG5lZ2F0aXZlKSBwcm9ncmVzc2luZyBmcm9tXG4gICAgICogYHN0YXJ0YCB1cCB0bywgYnV0IG5vdCBpbmNsdWRpbmcsIGBlbmRgLiBBIHN0ZXAgb2YgYC0xYCBpcyB1c2VkIGlmIGEgbmVnYXRpdmVcbiAgICAgKiBgc3RhcnRgIGlzIHNwZWNpZmllZCB3aXRob3V0IGFuIGBlbmRgIG9yIGBzdGVwYC4gSWYgYGVuZGAgaXMgbm90IHNwZWNpZmllZCxcbiAgICAgKiBpdCdzIHNldCB0byBgc3RhcnRgIHdpdGggYHN0YXJ0YCB0aGVuIHNldCB0byBgMGAuXG4gICAgICpcbiAgICAgKiAqKk5vdGU6KiogSmF2YVNjcmlwdCBmb2xsb3dzIHRoZSBJRUVFLTc1NCBzdGFuZGFyZCBmb3IgcmVzb2x2aW5nXG4gICAgICogZmxvYXRpbmctcG9pbnQgdmFsdWVzIHdoaWNoIGNhbiBwcm9kdWNlIHVuZXhwZWN0ZWQgcmVzdWx0cy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgb2YgdGhlIHJhbmdlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgVGhlIGVuZCBvZiB0aGUgcmFuZ2UuXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGVwPTFdIFRoZSB2YWx1ZSB0byBpbmNyZW1lbnQgb3IgZGVjcmVtZW50IGJ5LlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgcmFuZ2Ugb2YgbnVtYmVycy5cbiAgICAgKiBAc2VlIF8uaW5SYW5nZSwgXy5yYW5nZVJpZ2h0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8ucmFuZ2UoNCk7XG4gICAgICogLy8gPT4gWzAsIDEsIDIsIDNdXG4gICAgICpcbiAgICAgKiBfLnJhbmdlKC00KTtcbiAgICAgKiAvLyA9PiBbMCwgLTEsIC0yLCAtM11cbiAgICAgKlxuICAgICAqIF8ucmFuZ2UoMSwgNSk7XG4gICAgICogLy8gPT4gWzEsIDIsIDMsIDRdXG4gICAgICpcbiAgICAgKiBfLnJhbmdlKDAsIDIwLCA1KTtcbiAgICAgKiAvLyA9PiBbMCwgNSwgMTAsIDE1XVxuICAgICAqXG4gICAgICogXy5yYW5nZSgwLCAtNCwgLTEpO1xuICAgICAqIC8vID0+IFswLCAtMSwgLTIsIC0zXVxuICAgICAqXG4gICAgICogXy5yYW5nZSgxLCA0LCAwKTtcbiAgICAgKiAvLyA9PiBbMSwgMSwgMV1cbiAgICAgKlxuICAgICAqIF8ucmFuZ2UoMCk7XG4gICAgICogLy8gPT4gW11cbiAgICAgKi9cbiAgICB2YXIgcmFuZ2UgPSBjcmVhdGVSYW5nZSgpO1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5yYW5nZWAgZXhjZXB0IHRoYXQgaXQgcG9wdWxhdGVzIHZhbHVlcyBpblxuICAgICAqIGRlc2NlbmRpbmcgb3JkZXIuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9MF0gVGhlIHN0YXJ0IG9mIHRoZSByYW5nZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZW5kIFRoZSBlbmQgb2YgdGhlIHJhbmdlLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbc3RlcD0xXSBUaGUgdmFsdWUgdG8gaW5jcmVtZW50IG9yIGRlY3JlbWVudCBieS5cbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHJhbmdlIG9mIG51bWJlcnMuXG4gICAgICogQHNlZSBfLmluUmFuZ2UsIF8ucmFuZ2VcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5yYW5nZVJpZ2h0KDQpO1xuICAgICAqIC8vID0+IFszLCAyLCAxLCAwXVxuICAgICAqXG4gICAgICogXy5yYW5nZVJpZ2h0KC00KTtcbiAgICAgKiAvLyA9PiBbLTMsIC0yLCAtMSwgMF1cbiAgICAgKlxuICAgICAqIF8ucmFuZ2VSaWdodCgxLCA1KTtcbiAgICAgKiAvLyA9PiBbNCwgMywgMiwgMV1cbiAgICAgKlxuICAgICAqIF8ucmFuZ2VSaWdodCgwLCAyMCwgNSk7XG4gICAgICogLy8gPT4gWzE1LCAxMCwgNSwgMF1cbiAgICAgKlxuICAgICAqIF8ucmFuZ2VSaWdodCgwLCAtNCwgLTEpO1xuICAgICAqIC8vID0+IFstMywgLTIsIC0xLCAwXVxuICAgICAqXG4gICAgICogXy5yYW5nZVJpZ2h0KDEsIDQsIDApO1xuICAgICAqIC8vID0+IFsxLCAxLCAxXVxuICAgICAqXG4gICAgICogXy5yYW5nZVJpZ2h0KDApO1xuICAgICAqIC8vID0+IFtdXG4gICAgICovXG4gICAgdmFyIHJhbmdlUmlnaHQgPSBjcmVhdGVSYW5nZSh0cnVlKTtcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYSBuZXcgZW1wdHkgYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4xMy4wXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBlbXB0eSBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIGFycmF5cyA9IF8udGltZXMoMiwgXy5zdHViQXJyYXkpO1xuICAgICAqXG4gICAgICogY29uc29sZS5sb2coYXJyYXlzKTtcbiAgICAgKiAvLyA9PiBbW10sIFtdXVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2coYXJyYXlzWzBdID09PSBhcnJheXNbMV0pO1xuICAgICAqIC8vID0+IGZhbHNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3R1YkFycmF5KCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYGZhbHNlYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjEzLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGBmYWxzZWAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8udGltZXMoMiwgXy5zdHViRmFsc2UpO1xuICAgICAqIC8vID0+IFtmYWxzZSwgZmFsc2VdXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3R1YkZhbHNlKCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYSBuZXcgZW1wdHkgb2JqZWN0LlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMTMuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IGVtcHR5IG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBfLnRpbWVzKDIsIF8uc3R1Yk9iamVjdCk7XG4gICAgICpcbiAgICAgKiBjb25zb2xlLmxvZyhvYmplY3RzKTtcbiAgICAgKiAvLyA9PiBbe30sIHt9XVxuICAgICAqXG4gICAgICogY29uc29sZS5sb2cob2JqZWN0c1swXSA9PT0gb2JqZWN0c1sxXSk7XG4gICAgICogLy8gPT4gZmFsc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdHViT2JqZWN0KCkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYW4gZW1wdHkgc3RyaW5nLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMTMuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgZW1wdHkgc3RyaW5nLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRpbWVzKDIsIF8uc3R1YlN0cmluZyk7XG4gICAgICogLy8gPT4gWycnLCAnJ11cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdHViU3RyaW5nKCkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYHRydWVgLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuMTMuMFxuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnRpbWVzKDIsIF8uc3R1YlRydWUpO1xuICAgICAqIC8vID0+IFt0cnVlLCB0cnVlXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN0dWJUcnVlKCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW52b2tlcyB0aGUgaXRlcmF0ZWUgYG5gIHRpbWVzLCByZXR1cm5pbmcgYW4gYXJyYXkgb2YgdGhlIHJlc3VsdHMgb2ZcbiAgICAgKiBlYWNoIGludm9jYXRpb24uIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OyAoaW5kZXgpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IFV0aWxcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIGludm9rZSBgaXRlcmF0ZWVgLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICAgICAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcmVzdWx0cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50aW1lcygzLCBTdHJpbmcpO1xuICAgICAqIC8vID0+IFsnMCcsICcxJywgJzInXVxuICAgICAqXG4gICAgICogIF8udGltZXMoNCwgXy5jb25zdGFudCgwKSk7XG4gICAgICogLy8gPT4gWzAsIDAsIDAsIDBdXG4gICAgICovXG4gICAgZnVuY3Rpb24gdGltZXMobiwgaXRlcmF0ZWUpIHtcbiAgICAgIG4gPSB0b0ludGVnZXIobik7XG4gICAgICBpZiAobiA8IDEgfHwgbiA+IE1BWF9TQUZFX0lOVEVHRVIpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgdmFyIGluZGV4ID0gTUFYX0FSUkFZX0xFTkdUSCxcbiAgICAgICAgICBsZW5ndGggPSBuYXRpdmVNaW4obiwgTUFYX0FSUkFZX0xFTkdUSCk7XG5cbiAgICAgIGl0ZXJhdGVlID0gZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUpO1xuICAgICAgbiAtPSBNQVhfQVJSQVlfTEVOR1RIO1xuXG4gICAgICB2YXIgcmVzdWx0ID0gYmFzZVRpbWVzKGxlbmd0aCwgaXRlcmF0ZWUpO1xuICAgICAgd2hpbGUgKCsraW5kZXggPCBuKSB7XG4gICAgICAgIGl0ZXJhdGVlKGluZGV4KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYHZhbHVlYCB0byBhIHByb3BlcnR5IHBhdGggYXJyYXkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgVXRpbFxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgcHJvcGVydHkgcGF0aCBhcnJheS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy50b1BhdGgoJ2EuYi5jJyk7XG4gICAgICogLy8gPT4gWydhJywgJ2InLCAnYyddXG4gICAgICpcbiAgICAgKiBfLnRvUGF0aCgnYVswXS5iLmMnKTtcbiAgICAgKiAvLyA9PiBbJ2EnLCAnMCcsICdiJywgJ2MnXVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvUGF0aCh2YWx1ZSkge1xuICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBhcnJheU1hcCh2YWx1ZSwgdG9LZXkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGlzU3ltYm9sKHZhbHVlKSA/IFt2YWx1ZV0gOiBjb3B5QXJyYXkoc3RyaW5nVG9QYXRoKHRvU3RyaW5nKHZhbHVlKSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlcyBhIHVuaXF1ZSBJRC4gSWYgYHByZWZpeGAgaXMgZ2l2ZW4sIHRoZSBJRCBpcyBhcHBlbmRlZCB0byBpdC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAc2luY2UgMC4xLjBcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBjYXRlZ29yeSBVdGlsXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtwcmVmaXg9JyddIFRoZSB2YWx1ZSB0byBwcmVmaXggdGhlIElEIHdpdGguXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgdW5pcXVlIElELlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnVuaXF1ZUlkKCdjb250YWN0XycpO1xuICAgICAqIC8vID0+ICdjb250YWN0XzEwNCdcbiAgICAgKlxuICAgICAqIF8udW5pcXVlSWQoKTtcbiAgICAgKiAvLyA9PiAnMTA1J1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVuaXF1ZUlkKHByZWZpeCkge1xuICAgICAgdmFyIGlkID0gKytpZENvdW50ZXI7XG4gICAgICByZXR1cm4gdG9TdHJpbmcocHJlZml4KSArIGlkO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIEFkZHMgdHdvIG51bWJlcnMuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgMy40LjBcbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBhdWdlbmQgVGhlIGZpcnN0IG51bWJlciBpbiBhbiBhZGRpdGlvbi5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYWRkZW5kIFRoZSBzZWNvbmQgbnVtYmVyIGluIGFuIGFkZGl0aW9uLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHRvdGFsLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmFkZCg2LCA0KTtcbiAgICAgKiAvLyA9PiAxMFxuICAgICAqL1xuICAgIHZhciBhZGQgPSBjcmVhdGVNYXRoT3BlcmF0aW9uKGZ1bmN0aW9uKGF1Z2VuZCwgYWRkZW5kKSB7XG4gICAgICByZXR1cm4gYXVnZW5kICsgYWRkZW5kO1xuICAgIH0sIDApO1xuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgYG51bWJlcmAgcm91bmRlZCB1cCB0byBgcHJlY2lzaW9uYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjEwLjBcbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXIgVGhlIG51bWJlciB0byByb3VuZCB1cC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3ByZWNpc2lvbj0wXSBUaGUgcHJlY2lzaW9uIHRvIHJvdW5kIHVwIHRvLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHJvdW5kZWQgdXAgbnVtYmVyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLmNlaWwoNC4wMDYpO1xuICAgICAqIC8vID0+IDVcbiAgICAgKlxuICAgICAqIF8uY2VpbCg2LjAwNCwgMik7XG4gICAgICogLy8gPT4gNi4wMVxuICAgICAqXG4gICAgICogXy5jZWlsKDYwNDAsIC0yKTtcbiAgICAgKiAvLyA9PiA2MTAwXG4gICAgICovXG4gICAgdmFyIGNlaWwgPSBjcmVhdGVSb3VuZCgnY2VpbCcpO1xuXG4gICAgLyoqXG4gICAgICogRGl2aWRlIHR3byBudW1iZXJzLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNy4wXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZGl2aWRlbmQgVGhlIGZpcnN0IG51bWJlciBpbiBhIGRpdmlzaW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBkaXZpc29yIFRoZSBzZWNvbmQgbnVtYmVyIGluIGEgZGl2aXNpb24uXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgcXVvdGllbnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZGl2aWRlKDYsIDQpO1xuICAgICAqIC8vID0+IDEuNVxuICAgICAqL1xuICAgIHZhciBkaXZpZGUgPSBjcmVhdGVNYXRoT3BlcmF0aW9uKGZ1bmN0aW9uKGRpdmlkZW5kLCBkaXZpc29yKSB7XG4gICAgICByZXR1cm4gZGl2aWRlbmQgLyBkaXZpc29yO1xuICAgIH0sIDEpO1xuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgYG51bWJlcmAgcm91bmRlZCBkb3duIHRvIGBwcmVjaXNpb25gLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDMuMTAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG51bWJlciBUaGUgbnVtYmVyIHRvIHJvdW5kIGRvd24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtwcmVjaXNpb249MF0gVGhlIHByZWNpc2lvbiB0byByb3VuZCBkb3duIHRvLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHJvdW5kZWQgZG93biBudW1iZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uZmxvb3IoNC4wMDYpO1xuICAgICAqIC8vID0+IDRcbiAgICAgKlxuICAgICAqIF8uZmxvb3IoMC4wNDYsIDIpO1xuICAgICAqIC8vID0+IDAuMDRcbiAgICAgKlxuICAgICAqIF8uZmxvb3IoNDA2MCwgLTIpO1xuICAgICAqIC8vID0+IDQwMDBcbiAgICAgKi9cbiAgICB2YXIgZmxvb3IgPSBjcmVhdGVSb3VuZCgnZmxvb3InKTtcblxuICAgIC8qKlxuICAgICAqIENvbXB1dGVzIHRoZSBtYXhpbXVtIHZhbHVlIG9mIGBhcnJheWAuIElmIGBhcnJheWAgaXMgZW1wdHkgb3IgZmFsc2V5LFxuICAgICAqIGB1bmRlZmluZWRgIGlzIHJldHVybmVkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXhpbXVtIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLm1heChbNCwgMiwgOCwgNl0pO1xuICAgICAqIC8vID0+IDhcbiAgICAgKlxuICAgICAqIF8ubWF4KFtdKTtcbiAgICAgKiAvLyA9PiB1bmRlZmluZWRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtYXgoYXJyYXkpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKVxuICAgICAgICA/IGJhc2VFeHRyZW11bShhcnJheSwgaWRlbnRpdHksIGJhc2VHdClcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5tYXhgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYCB3aGljaCBpc1xuICAgICAqIGludm9rZWQgZm9yIGVhY2ggZWxlbWVudCBpbiBgYXJyYXlgIHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb24gYnkgd2hpY2hcbiAgICAgKiB0aGUgdmFsdWUgaXMgcmFua2VkLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1heGltdW0gdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ24nOiAxIH0sIHsgJ24nOiAyIH1dO1xuICAgICAqXG4gICAgICogXy5tYXhCeShvYmplY3RzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLm47IH0pO1xuICAgICAqIC8vID0+IHsgJ24nOiAyIH1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ubWF4Qnkob2JqZWN0cywgJ24nKTtcbiAgICAgKiAvLyA9PiB7ICduJzogMiB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gbWF4QnkoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlRXh0cmVtdW0oYXJyYXksIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSwgYmFzZUd0KVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb21wdXRlcyB0aGUgbWVhbiBvZiB0aGUgdmFsdWVzIGluIGBhcnJheWAuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgbWVhbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5tZWFuKFs0LCAyLCA4LCA2XSk7XG4gICAgICogLy8gPT4gNVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG1lYW4oYXJyYXkpIHtcbiAgICAgIHJldHVybiBiYXNlTWVhbihhcnJheSwgaWRlbnRpdHkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGxpa2UgYF8ubWVhbmAgZXhjZXB0IHRoYXQgaXQgYWNjZXB0cyBgaXRlcmF0ZWVgIHdoaWNoIGlzXG4gICAgICogaW52b2tlZCBmb3IgZWFjaCBlbGVtZW50IGluIGBhcnJheWAgdG8gZ2VuZXJhdGUgdGhlIHZhbHVlIHRvIGJlIGF2ZXJhZ2VkLlxuICAgICAqIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggb25lIGFyZ3VtZW50OiAodmFsdWUpLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHNpbmNlIDQuNy4wXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBtZWFuLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiB2YXIgb2JqZWN0cyA9IFt7ICduJzogNCB9LCB7ICduJzogMiB9LCB7ICduJzogOCB9LCB7ICduJzogNiB9XTtcbiAgICAgKlxuICAgICAqIF8ubWVhbkJ5KG9iamVjdHMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8ubjsgfSk7XG4gICAgICogLy8gPT4gNVxuICAgICAqXG4gICAgICogLy8gVGhlIGBfLnByb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gICAgICogXy5tZWFuQnkob2JqZWN0cywgJ24nKTtcbiAgICAgKiAvLyA9PiA1XG4gICAgICovXG4gICAgZnVuY3Rpb24gbWVhbkJ5KGFycmF5LCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIGJhc2VNZWFuKGFycmF5LCBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMikpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbXB1dGVzIHRoZSBtaW5pbXVtIHZhbHVlIG9mIGBhcnJheWAuIElmIGBhcnJheWAgaXMgZW1wdHkgb3IgZmFsc2V5LFxuICAgICAqIGB1bmRlZmluZWRgIGlzIHJldHVybmVkLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBzaW5jZSAwLjEuMFxuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQGNhdGVnb3J5IE1hdGhcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICAgICAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtaW5pbXVtIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLm1pbihbNCwgMiwgOCwgNl0pO1xuICAgICAqIC8vID0+IDJcbiAgICAgKlxuICAgICAqIF8ubWluKFtdKTtcbiAgICAgKiAvLyA9PiB1bmRlZmluZWRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBtaW4oYXJyYXkpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKVxuICAgICAgICA/IGJhc2VFeHRyZW11bShhcnJheSwgaWRlbnRpdHksIGJhc2VMdClcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5taW5gIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYCB3aGljaCBpc1xuICAgICAqIGludm9rZWQgZm9yIGVhY2ggZWxlbWVudCBpbiBgYXJyYXlgIHRvIGdlbmVyYXRlIHRoZSBjcml0ZXJpb24gYnkgd2hpY2hcbiAgICAgKiB0aGUgdmFsdWUgaXMgcmFua2VkLiBUaGUgaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1pbmltdW0gdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIHZhciBvYmplY3RzID0gW3sgJ24nOiAxIH0sIHsgJ24nOiAyIH1dO1xuICAgICAqXG4gICAgICogXy5taW5CeShvYmplY3RzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLm47IH0pO1xuICAgICAqIC8vID0+IHsgJ24nOiAxIH1cbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8ubWluQnkob2JqZWN0cywgJ24nKTtcbiAgICAgKiAvLyA9PiB7ICduJzogMSB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gbWluQnkoYXJyYXksIGl0ZXJhdGVlKSB7XG4gICAgICByZXR1cm4gKGFycmF5ICYmIGFycmF5Lmxlbmd0aClcbiAgICAgICAgPyBiYXNlRXh0cmVtdW0oYXJyYXksIGdldEl0ZXJhdGVlKGl0ZXJhdGVlLCAyKSwgYmFzZUx0KVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNdWx0aXBseSB0d28gbnVtYmVycy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjcuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG11bHRpcGxpZXIgVGhlIGZpcnN0IG51bWJlciBpbiBhIG11bHRpcGxpY2F0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBtdWx0aXBsaWNhbmQgVGhlIHNlY29uZCBudW1iZXIgaW4gYSBtdWx0aXBsaWNhdGlvbi5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBwcm9kdWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLm11bHRpcGx5KDYsIDQpO1xuICAgICAqIC8vID0+IDI0XG4gICAgICovXG4gICAgdmFyIG11bHRpcGx5ID0gY3JlYXRlTWF0aE9wZXJhdGlvbihmdW5jdGlvbihtdWx0aXBsaWVyLCBtdWx0aXBsaWNhbmQpIHtcbiAgICAgIHJldHVybiBtdWx0aXBsaWVyICogbXVsdGlwbGljYW5kO1xuICAgIH0sIDEpO1xuXG4gICAgLyoqXG4gICAgICogQ29tcHV0ZXMgYG51bWJlcmAgcm91bmRlZCB0byBgcHJlY2lzaW9uYC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjEwLjBcbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXIgVGhlIG51bWJlciB0byByb3VuZC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW3ByZWNpc2lvbj0wXSBUaGUgcHJlY2lzaW9uIHRvIHJvdW5kIHRvLlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHJvdW5kZWQgbnVtYmVyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICpcbiAgICAgKiBfLnJvdW5kKDQuMDA2KTtcbiAgICAgKiAvLyA9PiA0XG4gICAgICpcbiAgICAgKiBfLnJvdW5kKDQuMDA2LCAyKTtcbiAgICAgKiAvLyA9PiA0LjAxXG4gICAgICpcbiAgICAgKiBfLnJvdW5kKDQwNjAsIC0yKTtcbiAgICAgKiAvLyA9PiA0MTAwXG4gICAgICovXG4gICAgdmFyIHJvdW5kID0gY3JlYXRlUm91bmQoJ3JvdW5kJyk7XG5cbiAgICAvKipcbiAgICAgKiBTdWJ0cmFjdCB0d28gbnVtYmVycy5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSA0LjAuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG1pbnVlbmQgVGhlIGZpcnN0IG51bWJlciBpbiBhIHN1YnRyYWN0aW9uLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzdWJ0cmFoZW5kIFRoZSBzZWNvbmQgbnVtYmVyIGluIGEgc3VidHJhY3Rpb24uXG4gICAgICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgZGlmZmVyZW5jZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogXy5zdWJ0cmFjdCg2LCA0KTtcbiAgICAgKiAvLyA9PiAyXG4gICAgICovXG4gICAgdmFyIHN1YnRyYWN0ID0gY3JlYXRlTWF0aE9wZXJhdGlvbihmdW5jdGlvbihtaW51ZW5kLCBzdWJ0cmFoZW5kKSB7XG4gICAgICByZXR1cm4gbWludWVuZCAtIHN1YnRyYWhlbmQ7XG4gICAgfSwgMCk7XG5cbiAgICAvKipcbiAgICAgKiBDb21wdXRlcyB0aGUgc3VtIG9mIHRoZSB2YWx1ZXMgaW4gYGFycmF5YC5cbiAgICAgKlxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAbWVtYmVyT2YgX1xuICAgICAqIEBzaW5jZSAzLjQuMFxuICAgICAqIEBjYXRlZ29yeSBNYXRoXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBzdW0uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqIF8uc3VtKFs0LCAyLCA4LCA2XSk7XG4gICAgICogLy8gPT4gMjBcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdW0oYXJyYXkpIHtcbiAgICAgIHJldHVybiAoYXJyYXkgJiYgYXJyYXkubGVuZ3RoKVxuICAgICAgICA/IGJhc2VTdW0oYXJyYXksIGlkZW50aXR5KVxuICAgICAgICA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5zdW1gIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYGl0ZXJhdGVlYCB3aGljaCBpc1xuICAgICAqIGludm9rZWQgZm9yIGVhY2ggZWxlbWVudCBpbiBgYXJyYXlgIHRvIGdlbmVyYXRlIHRoZSB2YWx1ZSB0byBiZSBzdW1tZWQuXG4gICAgICogVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCBvbmUgYXJndW1lbnQ6ICh2YWx1ZSkuXG4gICAgICpcbiAgICAgKiBAc3RhdGljXG4gICAgICogQG1lbWJlck9mIF9cbiAgICAgKiBAc2luY2UgNC4wLjBcbiAgICAgKiBAY2F0ZWdvcnkgTWF0aFxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSBpbnZva2VkIHBlciBlbGVtZW50LlxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHN1bS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqXG4gICAgICogdmFyIG9iamVjdHMgPSBbeyAnbic6IDQgfSwgeyAnbic6IDIgfSwgeyAnbic6IDggfSwgeyAnbic6IDYgfV07XG4gICAgICpcbiAgICAgKiBfLnN1bUJ5KG9iamVjdHMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuIG8ubjsgfSk7XG4gICAgICogLy8gPT4gMjBcbiAgICAgKlxuICAgICAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICAgICAqIF8uc3VtQnkob2JqZWN0cywgJ24nKTtcbiAgICAgKiAvLyA9PiAyMFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN1bUJ5KGFycmF5LCBpdGVyYXRlZSkge1xuICAgICAgcmV0dXJuIChhcnJheSAmJiBhcnJheS5sZW5ndGgpXG4gICAgICAgID8gYmFzZVN1bShhcnJheSwgZ2V0SXRlcmF0ZWUoaXRlcmF0ZWUsIDIpKVxuICAgICAgICA6IDA7XG4gICAgfVxuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLy8gQWRkIG1ldGhvZHMgdGhhdCByZXR1cm4gd3JhcHBlZCB2YWx1ZXMgaW4gY2hhaW4gc2VxdWVuY2VzLlxuICAgIGxvZGFzaC5hZnRlciA9IGFmdGVyO1xuICAgIGxvZGFzaC5hcnkgPSBhcnk7XG4gICAgbG9kYXNoLmFzc2lnbiA9IGFzc2lnbjtcbiAgICBsb2Rhc2guYXNzaWduSW4gPSBhc3NpZ25JbjtcbiAgICBsb2Rhc2guYXNzaWduSW5XaXRoID0gYXNzaWduSW5XaXRoO1xuICAgIGxvZGFzaC5hc3NpZ25XaXRoID0gYXNzaWduV2l0aDtcbiAgICBsb2Rhc2guYXQgPSBhdDtcbiAgICBsb2Rhc2guYmVmb3JlID0gYmVmb3JlO1xuICAgIGxvZGFzaC5iaW5kID0gYmluZDtcbiAgICBsb2Rhc2guYmluZEFsbCA9IGJpbmRBbGw7XG4gICAgbG9kYXNoLmJpbmRLZXkgPSBiaW5kS2V5O1xuICAgIGxvZGFzaC5jYXN0QXJyYXkgPSBjYXN0QXJyYXk7XG4gICAgbG9kYXNoLmNoYWluID0gY2hhaW47XG4gICAgbG9kYXNoLmNodW5rID0gY2h1bms7XG4gICAgbG9kYXNoLmNvbXBhY3QgPSBjb21wYWN0O1xuICAgIGxvZGFzaC5jb25jYXQgPSBjb25jYXQ7XG4gICAgbG9kYXNoLmNvbmQgPSBjb25kO1xuICAgIGxvZGFzaC5jb25mb3JtcyA9IGNvbmZvcm1zO1xuICAgIGxvZGFzaC5jb25zdGFudCA9IGNvbnN0YW50O1xuICAgIGxvZGFzaC5jb3VudEJ5ID0gY291bnRCeTtcbiAgICBsb2Rhc2guY3JlYXRlID0gY3JlYXRlO1xuICAgIGxvZGFzaC5jdXJyeSA9IGN1cnJ5O1xuICAgIGxvZGFzaC5jdXJyeVJpZ2h0ID0gY3VycnlSaWdodDtcbiAgICBsb2Rhc2guZGVib3VuY2UgPSBkZWJvdW5jZTtcbiAgICBsb2Rhc2guZGVmYXVsdHMgPSBkZWZhdWx0cztcbiAgICBsb2Rhc2guZGVmYXVsdHNEZWVwID0gZGVmYXVsdHNEZWVwO1xuICAgIGxvZGFzaC5kZWZlciA9IGRlZmVyO1xuICAgIGxvZGFzaC5kZWxheSA9IGRlbGF5O1xuICAgIGxvZGFzaC5kaWZmZXJlbmNlID0gZGlmZmVyZW5jZTtcbiAgICBsb2Rhc2guZGlmZmVyZW5jZUJ5ID0gZGlmZmVyZW5jZUJ5O1xuICAgIGxvZGFzaC5kaWZmZXJlbmNlV2l0aCA9IGRpZmZlcmVuY2VXaXRoO1xuICAgIGxvZGFzaC5kcm9wID0gZHJvcDtcbiAgICBsb2Rhc2guZHJvcFJpZ2h0ID0gZHJvcFJpZ2h0O1xuICAgIGxvZGFzaC5kcm9wUmlnaHRXaGlsZSA9IGRyb3BSaWdodFdoaWxlO1xuICAgIGxvZGFzaC5kcm9wV2hpbGUgPSBkcm9wV2hpbGU7XG4gICAgbG9kYXNoLmZpbGwgPSBmaWxsO1xuICAgIGxvZGFzaC5maWx0ZXIgPSBmaWx0ZXI7XG4gICAgbG9kYXNoLmZsYXRNYXAgPSBmbGF0TWFwO1xuICAgIGxvZGFzaC5mbGF0TWFwRGVlcCA9IGZsYXRNYXBEZWVwO1xuICAgIGxvZGFzaC5mbGF0TWFwRGVwdGggPSBmbGF0TWFwRGVwdGg7XG4gICAgbG9kYXNoLmZsYXR0ZW4gPSBmbGF0dGVuO1xuICAgIGxvZGFzaC5mbGF0dGVuRGVlcCA9IGZsYXR0ZW5EZWVwO1xuICAgIGxvZGFzaC5mbGF0dGVuRGVwdGggPSBmbGF0dGVuRGVwdGg7XG4gICAgbG9kYXNoLmZsaXAgPSBmbGlwO1xuICAgIGxvZGFzaC5mbG93ID0gZmxvdztcbiAgICBsb2Rhc2guZmxvd1JpZ2h0ID0gZmxvd1JpZ2h0O1xuICAgIGxvZGFzaC5mcm9tUGFpcnMgPSBmcm9tUGFpcnM7XG4gICAgbG9kYXNoLmZ1bmN0aW9ucyA9IGZ1bmN0aW9ucztcbiAgICBsb2Rhc2guZnVuY3Rpb25zSW4gPSBmdW5jdGlvbnNJbjtcbiAgICBsb2Rhc2guZ3JvdXBCeSA9IGdyb3VwQnk7XG4gICAgbG9kYXNoLmluaXRpYWwgPSBpbml0aWFsO1xuICAgIGxvZGFzaC5pbnRlcnNlY3Rpb24gPSBpbnRlcnNlY3Rpb247XG4gICAgbG9kYXNoLmludGVyc2VjdGlvbkJ5ID0gaW50ZXJzZWN0aW9uQnk7XG4gICAgbG9kYXNoLmludGVyc2VjdGlvbldpdGggPSBpbnRlcnNlY3Rpb25XaXRoO1xuICAgIGxvZGFzaC5pbnZlcnQgPSBpbnZlcnQ7XG4gICAgbG9kYXNoLmludmVydEJ5ID0gaW52ZXJ0Qnk7XG4gICAgbG9kYXNoLmludm9rZU1hcCA9IGludm9rZU1hcDtcbiAgICBsb2Rhc2guaXRlcmF0ZWUgPSBpdGVyYXRlZTtcbiAgICBsb2Rhc2gua2V5QnkgPSBrZXlCeTtcbiAgICBsb2Rhc2gua2V5cyA9IGtleXM7XG4gICAgbG9kYXNoLmtleXNJbiA9IGtleXNJbjtcbiAgICBsb2Rhc2gubWFwID0gbWFwO1xuICAgIGxvZGFzaC5tYXBLZXlzID0gbWFwS2V5cztcbiAgICBsb2Rhc2gubWFwVmFsdWVzID0gbWFwVmFsdWVzO1xuICAgIGxvZGFzaC5tYXRjaGVzID0gbWF0Y2hlcztcbiAgICBsb2Rhc2gubWF0Y2hlc1Byb3BlcnR5ID0gbWF0Y2hlc1Byb3BlcnR5O1xuICAgIGxvZGFzaC5tZW1vaXplID0gbWVtb2l6ZTtcbiAgICBsb2Rhc2gubWVyZ2UgPSBtZXJnZTtcbiAgICBsb2Rhc2gubWVyZ2VXaXRoID0gbWVyZ2VXaXRoO1xuICAgIGxvZGFzaC5tZXRob2QgPSBtZXRob2Q7XG4gICAgbG9kYXNoLm1ldGhvZE9mID0gbWV0aG9kT2Y7XG4gICAgbG9kYXNoLm1peGluID0gbWl4aW47XG4gICAgbG9kYXNoLm5lZ2F0ZSA9IG5lZ2F0ZTtcbiAgICBsb2Rhc2gubnRoQXJnID0gbnRoQXJnO1xuICAgIGxvZGFzaC5vbWl0ID0gb21pdDtcbiAgICBsb2Rhc2gub21pdEJ5ID0gb21pdEJ5O1xuICAgIGxvZGFzaC5vbmNlID0gb25jZTtcbiAgICBsb2Rhc2gub3JkZXJCeSA9IG9yZGVyQnk7XG4gICAgbG9kYXNoLm92ZXIgPSBvdmVyO1xuICAgIGxvZGFzaC5vdmVyQXJncyA9IG92ZXJBcmdzO1xuICAgIGxvZGFzaC5vdmVyRXZlcnkgPSBvdmVyRXZlcnk7XG4gICAgbG9kYXNoLm92ZXJTb21lID0gb3ZlclNvbWU7XG4gICAgbG9kYXNoLnBhcnRpYWwgPSBwYXJ0aWFsO1xuICAgIGxvZGFzaC5wYXJ0aWFsUmlnaHQgPSBwYXJ0aWFsUmlnaHQ7XG4gICAgbG9kYXNoLnBhcnRpdGlvbiA9IHBhcnRpdGlvbjtcbiAgICBsb2Rhc2gucGljayA9IHBpY2s7XG4gICAgbG9kYXNoLnBpY2tCeSA9IHBpY2tCeTtcbiAgICBsb2Rhc2gucHJvcGVydHkgPSBwcm9wZXJ0eTtcbiAgICBsb2Rhc2gucHJvcGVydHlPZiA9IHByb3BlcnR5T2Y7XG4gICAgbG9kYXNoLnB1bGwgPSBwdWxsO1xuICAgIGxvZGFzaC5wdWxsQWxsID0gcHVsbEFsbDtcbiAgICBsb2Rhc2gucHVsbEFsbEJ5ID0gcHVsbEFsbEJ5O1xuICAgIGxvZGFzaC5wdWxsQWxsV2l0aCA9IHB1bGxBbGxXaXRoO1xuICAgIGxvZGFzaC5wdWxsQXQgPSBwdWxsQXQ7XG4gICAgbG9kYXNoLnJhbmdlID0gcmFuZ2U7XG4gICAgbG9kYXNoLnJhbmdlUmlnaHQgPSByYW5nZVJpZ2h0O1xuICAgIGxvZGFzaC5yZWFyZyA9IHJlYXJnO1xuICAgIGxvZGFzaC5yZWplY3QgPSByZWplY3Q7XG4gICAgbG9kYXNoLnJlbW92ZSA9IHJlbW92ZTtcbiAgICBsb2Rhc2gucmVzdCA9IHJlc3Q7XG4gICAgbG9kYXNoLnJldmVyc2UgPSByZXZlcnNlO1xuICAgIGxvZGFzaC5zYW1wbGVTaXplID0gc2FtcGxlU2l6ZTtcbiAgICBsb2Rhc2guc2V0ID0gc2V0O1xuICAgIGxvZGFzaC5zZXRXaXRoID0gc2V0V2l0aDtcbiAgICBsb2Rhc2guc2h1ZmZsZSA9IHNodWZmbGU7XG4gICAgbG9kYXNoLnNsaWNlID0gc2xpY2U7XG4gICAgbG9kYXNoLnNvcnRCeSA9IHNvcnRCeTtcbiAgICBsb2Rhc2guc29ydGVkVW5pcSA9IHNvcnRlZFVuaXE7XG4gICAgbG9kYXNoLnNvcnRlZFVuaXFCeSA9IHNvcnRlZFVuaXFCeTtcbiAgICBsb2Rhc2guc3BsaXQgPSBzcGxpdDtcbiAgICBsb2Rhc2guc3ByZWFkID0gc3ByZWFkO1xuICAgIGxvZGFzaC50YWlsID0gdGFpbDtcbiAgICBsb2Rhc2gudGFrZSA9IHRha2U7XG4gICAgbG9kYXNoLnRha2VSaWdodCA9IHRha2VSaWdodDtcbiAgICBsb2Rhc2gudGFrZVJpZ2h0V2hpbGUgPSB0YWtlUmlnaHRXaGlsZTtcbiAgICBsb2Rhc2gudGFrZVdoaWxlID0gdGFrZVdoaWxlO1xuICAgIGxvZGFzaC50YXAgPSB0YXA7XG4gICAgbG9kYXNoLnRocm90dGxlID0gdGhyb3R0bGU7XG4gICAgbG9kYXNoLnRocnUgPSB0aHJ1O1xuICAgIGxvZGFzaC50b0FycmF5ID0gdG9BcnJheTtcbiAgICBsb2Rhc2gudG9QYWlycyA9IHRvUGFpcnM7XG4gICAgbG9kYXNoLnRvUGFpcnNJbiA9IHRvUGFpcnNJbjtcbiAgICBsb2Rhc2gudG9QYXRoID0gdG9QYXRoO1xuICAgIGxvZGFzaC50b1BsYWluT2JqZWN0ID0gdG9QbGFpbk9iamVjdDtcbiAgICBsb2Rhc2gudHJhbnNmb3JtID0gdHJhbnNmb3JtO1xuICAgIGxvZGFzaC51bmFyeSA9IHVuYXJ5O1xuICAgIGxvZGFzaC51bmlvbiA9IHVuaW9uO1xuICAgIGxvZGFzaC51bmlvbkJ5ID0gdW5pb25CeTtcbiAgICBsb2Rhc2gudW5pb25XaXRoID0gdW5pb25XaXRoO1xuICAgIGxvZGFzaC51bmlxID0gdW5pcTtcbiAgICBsb2Rhc2gudW5pcUJ5ID0gdW5pcUJ5O1xuICAgIGxvZGFzaC51bmlxV2l0aCA9IHVuaXFXaXRoO1xuICAgIGxvZGFzaC51bnNldCA9IHVuc2V0O1xuICAgIGxvZGFzaC51bnppcCA9IHVuemlwO1xuICAgIGxvZGFzaC51bnppcFdpdGggPSB1bnppcFdpdGg7XG4gICAgbG9kYXNoLnVwZGF0ZSA9IHVwZGF0ZTtcbiAgICBsb2Rhc2gudXBkYXRlV2l0aCA9IHVwZGF0ZVdpdGg7XG4gICAgbG9kYXNoLnZhbHVlcyA9IHZhbHVlcztcbiAgICBsb2Rhc2gudmFsdWVzSW4gPSB2YWx1ZXNJbjtcbiAgICBsb2Rhc2gud2l0aG91dCA9IHdpdGhvdXQ7XG4gICAgbG9kYXNoLndvcmRzID0gd29yZHM7XG4gICAgbG9kYXNoLndyYXAgPSB3cmFwO1xuICAgIGxvZGFzaC54b3IgPSB4b3I7XG4gICAgbG9kYXNoLnhvckJ5ID0geG9yQnk7XG4gICAgbG9kYXNoLnhvcldpdGggPSB4b3JXaXRoO1xuICAgIGxvZGFzaC56aXAgPSB6aXA7XG4gICAgbG9kYXNoLnppcE9iamVjdCA9IHppcE9iamVjdDtcbiAgICBsb2Rhc2guemlwT2JqZWN0RGVlcCA9IHppcE9iamVjdERlZXA7XG4gICAgbG9kYXNoLnppcFdpdGggPSB6aXBXaXRoO1xuXG4gICAgLy8gQWRkIGFsaWFzZXMuXG4gICAgbG9kYXNoLmVudHJpZXMgPSB0b1BhaXJzO1xuICAgIGxvZGFzaC5lbnRyaWVzSW4gPSB0b1BhaXJzSW47XG4gICAgbG9kYXNoLmV4dGVuZCA9IGFzc2lnbkluO1xuICAgIGxvZGFzaC5leHRlbmRXaXRoID0gYXNzaWduSW5XaXRoO1xuXG4gICAgLy8gQWRkIG1ldGhvZHMgdG8gYGxvZGFzaC5wcm90b3R5cGVgLlxuICAgIG1peGluKGxvZGFzaCwgbG9kYXNoKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8vIEFkZCBtZXRob2RzIHRoYXQgcmV0dXJuIHVud3JhcHBlZCB2YWx1ZXMgaW4gY2hhaW4gc2VxdWVuY2VzLlxuICAgIGxvZGFzaC5hZGQgPSBhZGQ7XG4gICAgbG9kYXNoLmF0dGVtcHQgPSBhdHRlbXB0O1xuICAgIGxvZGFzaC5jYW1lbENhc2UgPSBjYW1lbENhc2U7XG4gICAgbG9kYXNoLmNhcGl0YWxpemUgPSBjYXBpdGFsaXplO1xuICAgIGxvZGFzaC5jZWlsID0gY2VpbDtcbiAgICBsb2Rhc2guY2xhbXAgPSBjbGFtcDtcbiAgICBsb2Rhc2guY2xvbmUgPSBjbG9uZTtcbiAgICBsb2Rhc2guY2xvbmVEZWVwID0gY2xvbmVEZWVwO1xuICAgIGxvZGFzaC5jbG9uZURlZXBXaXRoID0gY2xvbmVEZWVwV2l0aDtcbiAgICBsb2Rhc2guY2xvbmVXaXRoID0gY2xvbmVXaXRoO1xuICAgIGxvZGFzaC5jb25mb3Jtc1RvID0gY29uZm9ybXNUbztcbiAgICBsb2Rhc2guZGVidXJyID0gZGVidXJyO1xuICAgIGxvZGFzaC5kZWZhdWx0VG8gPSBkZWZhdWx0VG87XG4gICAgbG9kYXNoLmRpdmlkZSA9IGRpdmlkZTtcbiAgICBsb2Rhc2guZW5kc1dpdGggPSBlbmRzV2l0aDtcbiAgICBsb2Rhc2guZXEgPSBlcTtcbiAgICBsb2Rhc2guZXNjYXBlID0gZXNjYXBlO1xuICAgIGxvZGFzaC5lc2NhcGVSZWdFeHAgPSBlc2NhcGVSZWdFeHA7XG4gICAgbG9kYXNoLmV2ZXJ5ID0gZXZlcnk7XG4gICAgbG9kYXNoLmZpbmQgPSBmaW5kO1xuICAgIGxvZGFzaC5maW5kSW5kZXggPSBmaW5kSW5kZXg7XG4gICAgbG9kYXNoLmZpbmRLZXkgPSBmaW5kS2V5O1xuICAgIGxvZGFzaC5maW5kTGFzdCA9IGZpbmRMYXN0O1xuICAgIGxvZGFzaC5maW5kTGFzdEluZGV4ID0gZmluZExhc3RJbmRleDtcbiAgICBsb2Rhc2guZmluZExhc3RLZXkgPSBmaW5kTGFzdEtleTtcbiAgICBsb2Rhc2guZmxvb3IgPSBmbG9vcjtcbiAgICBsb2Rhc2guZm9yRWFjaCA9IGZvckVhY2g7XG4gICAgbG9kYXNoLmZvckVhY2hSaWdodCA9IGZvckVhY2hSaWdodDtcbiAgICBsb2Rhc2guZm9ySW4gPSBmb3JJbjtcbiAgICBsb2Rhc2guZm9ySW5SaWdodCA9IGZvckluUmlnaHQ7XG4gICAgbG9kYXNoLmZvck93biA9IGZvck93bjtcbiAgICBsb2Rhc2guZm9yT3duUmlnaHQgPSBmb3JPd25SaWdodDtcbiAgICBsb2Rhc2guZ2V0ID0gZ2V0O1xuICAgIGxvZGFzaC5ndCA9IGd0O1xuICAgIGxvZGFzaC5ndGUgPSBndGU7XG4gICAgbG9kYXNoLmhhcyA9IGhhcztcbiAgICBsb2Rhc2guaGFzSW4gPSBoYXNJbjtcbiAgICBsb2Rhc2guaGVhZCA9IGhlYWQ7XG4gICAgbG9kYXNoLmlkZW50aXR5ID0gaWRlbnRpdHk7XG4gICAgbG9kYXNoLmluY2x1ZGVzID0gaW5jbHVkZXM7XG4gICAgbG9kYXNoLmluZGV4T2YgPSBpbmRleE9mO1xuICAgIGxvZGFzaC5pblJhbmdlID0gaW5SYW5nZTtcbiAgICBsb2Rhc2guaW52b2tlID0gaW52b2tlO1xuICAgIGxvZGFzaC5pc0FyZ3VtZW50cyA9IGlzQXJndW1lbnRzO1xuICAgIGxvZGFzaC5pc0FycmF5ID0gaXNBcnJheTtcbiAgICBsb2Rhc2guaXNBcnJheUJ1ZmZlciA9IGlzQXJyYXlCdWZmZXI7XG4gICAgbG9kYXNoLmlzQXJyYXlMaWtlID0gaXNBcnJheUxpa2U7XG4gICAgbG9kYXNoLmlzQXJyYXlMaWtlT2JqZWN0ID0gaXNBcnJheUxpa2VPYmplY3Q7XG4gICAgbG9kYXNoLmlzQm9vbGVhbiA9IGlzQm9vbGVhbjtcbiAgICBsb2Rhc2guaXNCdWZmZXIgPSBpc0J1ZmZlcjtcbiAgICBsb2Rhc2guaXNEYXRlID0gaXNEYXRlO1xuICAgIGxvZGFzaC5pc0VsZW1lbnQgPSBpc0VsZW1lbnQ7XG4gICAgbG9kYXNoLmlzRW1wdHkgPSBpc0VtcHR5O1xuICAgIGxvZGFzaC5pc0VxdWFsID0gaXNFcXVhbDtcbiAgICBsb2Rhc2guaXNFcXVhbFdpdGggPSBpc0VxdWFsV2l0aDtcbiAgICBsb2Rhc2guaXNFcnJvciA9IGlzRXJyb3I7XG4gICAgbG9kYXNoLmlzRmluaXRlID0gaXNGaW5pdGU7XG4gICAgbG9kYXNoLmlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uO1xuICAgIGxvZGFzaC5pc0ludGVnZXIgPSBpc0ludGVnZXI7XG4gICAgbG9kYXNoLmlzTGVuZ3RoID0gaXNMZW5ndGg7XG4gICAgbG9kYXNoLmlzTWFwID0gaXNNYXA7XG4gICAgbG9kYXNoLmlzTWF0Y2ggPSBpc01hdGNoO1xuICAgIGxvZGFzaC5pc01hdGNoV2l0aCA9IGlzTWF0Y2hXaXRoO1xuICAgIGxvZGFzaC5pc05hTiA9IGlzTmFOO1xuICAgIGxvZGFzaC5pc05hdGl2ZSA9IGlzTmF0aXZlO1xuICAgIGxvZGFzaC5pc05pbCA9IGlzTmlsO1xuICAgIGxvZGFzaC5pc051bGwgPSBpc051bGw7XG4gICAgbG9kYXNoLmlzTnVtYmVyID0gaXNOdW1iZXI7XG4gICAgbG9kYXNoLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG4gICAgbG9kYXNoLmlzT2JqZWN0TGlrZSA9IGlzT2JqZWN0TGlrZTtcbiAgICBsb2Rhc2guaXNQbGFpbk9iamVjdCA9IGlzUGxhaW5PYmplY3Q7XG4gICAgbG9kYXNoLmlzUmVnRXhwID0gaXNSZWdFeHA7XG4gICAgbG9kYXNoLmlzU2FmZUludGVnZXIgPSBpc1NhZmVJbnRlZ2VyO1xuICAgIGxvZGFzaC5pc1NldCA9IGlzU2V0O1xuICAgIGxvZGFzaC5pc1N0cmluZyA9IGlzU3RyaW5nO1xuICAgIGxvZGFzaC5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuICAgIGxvZGFzaC5pc1R5cGVkQXJyYXkgPSBpc1R5cGVkQXJyYXk7XG4gICAgbG9kYXNoLmlzVW5kZWZpbmVkID0gaXNVbmRlZmluZWQ7XG4gICAgbG9kYXNoLmlzV2Vha01hcCA9IGlzV2Vha01hcDtcbiAgICBsb2Rhc2guaXNXZWFrU2V0ID0gaXNXZWFrU2V0O1xuICAgIGxvZGFzaC5qb2luID0gam9pbjtcbiAgICBsb2Rhc2gua2ViYWJDYXNlID0ga2ViYWJDYXNlO1xuICAgIGxvZGFzaC5sYXN0ID0gbGFzdDtcbiAgICBsb2Rhc2gubGFzdEluZGV4T2YgPSBsYXN0SW5kZXhPZjtcbiAgICBsb2Rhc2gubG93ZXJDYXNlID0gbG93ZXJDYXNlO1xuICAgIGxvZGFzaC5sb3dlckZpcnN0ID0gbG93ZXJGaXJzdDtcbiAgICBsb2Rhc2gubHQgPSBsdDtcbiAgICBsb2Rhc2gubHRlID0gbHRlO1xuICAgIGxvZGFzaC5tYXggPSBtYXg7XG4gICAgbG9kYXNoLm1heEJ5ID0gbWF4Qnk7XG4gICAgbG9kYXNoLm1lYW4gPSBtZWFuO1xuICAgIGxvZGFzaC5tZWFuQnkgPSBtZWFuQnk7XG4gICAgbG9kYXNoLm1pbiA9IG1pbjtcbiAgICBsb2Rhc2gubWluQnkgPSBtaW5CeTtcbiAgICBsb2Rhc2guc3R1YkFycmF5ID0gc3R1YkFycmF5O1xuICAgIGxvZGFzaC5zdHViRmFsc2UgPSBzdHViRmFsc2U7XG4gICAgbG9kYXNoLnN0dWJPYmplY3QgPSBzdHViT2JqZWN0O1xuICAgIGxvZGFzaC5zdHViU3RyaW5nID0gc3R1YlN0cmluZztcbiAgICBsb2Rhc2guc3R1YlRydWUgPSBzdHViVHJ1ZTtcbiAgICBsb2Rhc2gubXVsdGlwbHkgPSBtdWx0aXBseTtcbiAgICBsb2Rhc2gubnRoID0gbnRoO1xuICAgIGxvZGFzaC5ub0NvbmZsaWN0ID0gbm9Db25mbGljdDtcbiAgICBsb2Rhc2gubm9vcCA9IG5vb3A7XG4gICAgbG9kYXNoLm5vdyA9IG5vdztcbiAgICBsb2Rhc2gucGFkID0gcGFkO1xuICAgIGxvZGFzaC5wYWRFbmQgPSBwYWRFbmQ7XG4gICAgbG9kYXNoLnBhZFN0YXJ0ID0gcGFkU3RhcnQ7XG4gICAgbG9kYXNoLnBhcnNlSW50ID0gcGFyc2VJbnQ7XG4gICAgbG9kYXNoLnJhbmRvbSA9IHJhbmRvbTtcbiAgICBsb2Rhc2gucmVkdWNlID0gcmVkdWNlO1xuICAgIGxvZGFzaC5yZWR1Y2VSaWdodCA9IHJlZHVjZVJpZ2h0O1xuICAgIGxvZGFzaC5yZXBlYXQgPSByZXBlYXQ7XG4gICAgbG9kYXNoLnJlcGxhY2UgPSByZXBsYWNlO1xuICAgIGxvZGFzaC5yZXN1bHQgPSByZXN1bHQ7XG4gICAgbG9kYXNoLnJvdW5kID0gcm91bmQ7XG4gICAgbG9kYXNoLnJ1bkluQ29udGV4dCA9IHJ1bkluQ29udGV4dDtcbiAgICBsb2Rhc2guc2FtcGxlID0gc2FtcGxlO1xuICAgIGxvZGFzaC5zaXplID0gc2l6ZTtcbiAgICBsb2Rhc2guc25ha2VDYXNlID0gc25ha2VDYXNlO1xuICAgIGxvZGFzaC5zb21lID0gc29tZTtcbiAgICBsb2Rhc2guc29ydGVkSW5kZXggPSBzb3J0ZWRJbmRleDtcbiAgICBsb2Rhc2guc29ydGVkSW5kZXhCeSA9IHNvcnRlZEluZGV4Qnk7XG4gICAgbG9kYXNoLnNvcnRlZEluZGV4T2YgPSBzb3J0ZWRJbmRleE9mO1xuICAgIGxvZGFzaC5zb3J0ZWRMYXN0SW5kZXggPSBzb3J0ZWRMYXN0SW5kZXg7XG4gICAgbG9kYXNoLnNvcnRlZExhc3RJbmRleEJ5ID0gc29ydGVkTGFzdEluZGV4Qnk7XG4gICAgbG9kYXNoLnNvcnRlZExhc3RJbmRleE9mID0gc29ydGVkTGFzdEluZGV4T2Y7XG4gICAgbG9kYXNoLnN0YXJ0Q2FzZSA9IHN0YXJ0Q2FzZTtcbiAgICBsb2Rhc2guc3RhcnRzV2l0aCA9IHN0YXJ0c1dpdGg7XG4gICAgbG9kYXNoLnN1YnRyYWN0ID0gc3VidHJhY3Q7XG4gICAgbG9kYXNoLnN1bSA9IHN1bTtcbiAgICBsb2Rhc2guc3VtQnkgPSBzdW1CeTtcbiAgICBsb2Rhc2gudGVtcGxhdGUgPSB0ZW1wbGF0ZTtcbiAgICBsb2Rhc2gudGltZXMgPSB0aW1lcztcbiAgICBsb2Rhc2gudG9GaW5pdGUgPSB0b0Zpbml0ZTtcbiAgICBsb2Rhc2gudG9JbnRlZ2VyID0gdG9JbnRlZ2VyO1xuICAgIGxvZGFzaC50b0xlbmd0aCA9IHRvTGVuZ3RoO1xuICAgIGxvZGFzaC50b0xvd2VyID0gdG9Mb3dlcjtcbiAgICBsb2Rhc2gudG9OdW1iZXIgPSB0b051bWJlcjtcbiAgICBsb2Rhc2gudG9TYWZlSW50ZWdlciA9IHRvU2FmZUludGVnZXI7XG4gICAgbG9kYXNoLnRvU3RyaW5nID0gdG9TdHJpbmc7XG4gICAgbG9kYXNoLnRvVXBwZXIgPSB0b1VwcGVyO1xuICAgIGxvZGFzaC50cmltID0gdHJpbTtcbiAgICBsb2Rhc2gudHJpbUVuZCA9IHRyaW1FbmQ7XG4gICAgbG9kYXNoLnRyaW1TdGFydCA9IHRyaW1TdGFydDtcbiAgICBsb2Rhc2gudHJ1bmNhdGUgPSB0cnVuY2F0ZTtcbiAgICBsb2Rhc2gudW5lc2NhcGUgPSB1bmVzY2FwZTtcbiAgICBsb2Rhc2gudW5pcXVlSWQgPSB1bmlxdWVJZDtcbiAgICBsb2Rhc2gudXBwZXJDYXNlID0gdXBwZXJDYXNlO1xuICAgIGxvZGFzaC51cHBlckZpcnN0ID0gdXBwZXJGaXJzdDtcblxuICAgIC8vIEFkZCBhbGlhc2VzLlxuICAgIGxvZGFzaC5lYWNoID0gZm9yRWFjaDtcbiAgICBsb2Rhc2guZWFjaFJpZ2h0ID0gZm9yRWFjaFJpZ2h0O1xuICAgIGxvZGFzaC5maXJzdCA9IGhlYWQ7XG5cbiAgICBtaXhpbihsb2Rhc2gsIChmdW5jdGlvbigpIHtcbiAgICAgIHZhciBzb3VyY2UgPSB7fTtcbiAgICAgIGJhc2VGb3JPd24obG9kYXNoLCBmdW5jdGlvbihmdW5jLCBtZXRob2ROYW1lKSB7XG4gICAgICAgIGlmICghaGFzT3duUHJvcGVydHkuY2FsbChsb2Rhc2gucHJvdG90eXBlLCBtZXRob2ROYW1lKSkge1xuICAgICAgICAgIHNvdXJjZVttZXRob2ROYW1lXSA9IGZ1bmM7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHNvdXJjZTtcbiAgICB9KCkpLCB7ICdjaGFpbic6IGZhbHNlIH0pO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHNlbWFudGljIHZlcnNpb24gbnVtYmVyLlxuICAgICAqXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBtZW1iZXJPZiBfXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBsb2Rhc2guVkVSU0lPTiA9IFZFUlNJT047XG5cbiAgICAvLyBBc3NpZ24gZGVmYXVsdCBwbGFjZWhvbGRlcnMuXG4gICAgYXJyYXlFYWNoKFsnYmluZCcsICdiaW5kS2V5JywgJ2N1cnJ5JywgJ2N1cnJ5UmlnaHQnLCAncGFydGlhbCcsICdwYXJ0aWFsUmlnaHQnXSwgZnVuY3Rpb24obWV0aG9kTmFtZSkge1xuICAgICAgbG9kYXNoW21ldGhvZE5hbWVdLnBsYWNlaG9sZGVyID0gbG9kYXNoO1xuICAgIH0pO1xuXG4gICAgLy8gQWRkIGBMYXp5V3JhcHBlcmAgbWV0aG9kcyBmb3IgYF8uZHJvcGAgYW5kIGBfLnRha2VgIHZhcmlhbnRzLlxuICAgIGFycmF5RWFjaChbJ2Ryb3AnLCAndGFrZSddLCBmdW5jdGlvbihtZXRob2ROYW1lLCBpbmRleCkge1xuICAgICAgTGF6eVdyYXBwZXIucHJvdG90eXBlW21ldGhvZE5hbWVdID0gZnVuY3Rpb24obikge1xuICAgICAgICBuID0gbiA9PT0gdW5kZWZpbmVkID8gMSA6IG5hdGl2ZU1heCh0b0ludGVnZXIobiksIDApO1xuXG4gICAgICAgIHZhciByZXN1bHQgPSAodGhpcy5fX2ZpbHRlcmVkX18gJiYgIWluZGV4KVxuICAgICAgICAgID8gbmV3IExhenlXcmFwcGVyKHRoaXMpXG4gICAgICAgICAgOiB0aGlzLmNsb25lKCk7XG5cbiAgICAgICAgaWYgKHJlc3VsdC5fX2ZpbHRlcmVkX18pIHtcbiAgICAgICAgICByZXN1bHQuX190YWtlQ291bnRfXyA9IG5hdGl2ZU1pbihuLCByZXN1bHQuX190YWtlQ291bnRfXyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdWx0Ll9fdmlld3NfXy5wdXNoKHtcbiAgICAgICAgICAgICdzaXplJzogbmF0aXZlTWluKG4sIE1BWF9BUlJBWV9MRU5HVEgpLFxuICAgICAgICAgICAgJ3R5cGUnOiBtZXRob2ROYW1lICsgKHJlc3VsdC5fX2Rpcl9fIDwgMCA/ICdSaWdodCcgOiAnJylcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfTtcblxuICAgICAgTGF6eVdyYXBwZXIucHJvdG90eXBlW21ldGhvZE5hbWUgKyAnUmlnaHQnXSA9IGZ1bmN0aW9uKG4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmV2ZXJzZSgpW21ldGhvZE5hbWVdKG4pLnJldmVyc2UoKTtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBBZGQgYExhenlXcmFwcGVyYCBtZXRob2RzIHRoYXQgYWNjZXB0IGFuIGBpdGVyYXRlZWAgdmFsdWUuXG4gICAgYXJyYXlFYWNoKFsnZmlsdGVyJywgJ21hcCcsICd0YWtlV2hpbGUnXSwgZnVuY3Rpb24obWV0aG9kTmFtZSwgaW5kZXgpIHtcbiAgICAgIHZhciB0eXBlID0gaW5kZXggKyAxLFxuICAgICAgICAgIGlzRmlsdGVyID0gdHlwZSA9PSBMQVpZX0ZJTFRFUl9GTEFHIHx8IHR5cGUgPT0gTEFaWV9XSElMRV9GTEFHO1xuXG4gICAgICBMYXp5V3JhcHBlci5wcm90b3R5cGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbihpdGVyYXRlZSkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gdGhpcy5jbG9uZSgpO1xuICAgICAgICByZXN1bHQuX19pdGVyYXRlZXNfXy5wdXNoKHtcbiAgICAgICAgICAnaXRlcmF0ZWUnOiBnZXRJdGVyYXRlZShpdGVyYXRlZSwgMyksXG4gICAgICAgICAgJ3R5cGUnOiB0eXBlXG4gICAgICAgIH0pO1xuICAgICAgICByZXN1bHQuX19maWx0ZXJlZF9fID0gcmVzdWx0Ll9fZmlsdGVyZWRfXyB8fCBpc0ZpbHRlcjtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBBZGQgYExhenlXcmFwcGVyYCBtZXRob2RzIGZvciBgXy5oZWFkYCBhbmQgYF8ubGFzdGAuXG4gICAgYXJyYXlFYWNoKFsnaGVhZCcsICdsYXN0J10sIGZ1bmN0aW9uKG1ldGhvZE5hbWUsIGluZGV4KSB7XG4gICAgICB2YXIgdGFrZU5hbWUgPSAndGFrZScgKyAoaW5kZXggPyAnUmlnaHQnIDogJycpO1xuXG4gICAgICBMYXp5V3JhcHBlci5wcm90b3R5cGVbbWV0aG9kTmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbdGFrZU5hbWVdKDEpLnZhbHVlKClbMF07XG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLy8gQWRkIGBMYXp5V3JhcHBlcmAgbWV0aG9kcyBmb3IgYF8uaW5pdGlhbGAgYW5kIGBfLnRhaWxgLlxuICAgIGFycmF5RWFjaChbJ2luaXRpYWwnLCAndGFpbCddLCBmdW5jdGlvbihtZXRob2ROYW1lLCBpbmRleCkge1xuICAgICAgdmFyIGRyb3BOYW1lID0gJ2Ryb3AnICsgKGluZGV4ID8gJycgOiAnUmlnaHQnKTtcblxuICAgICAgTGF6eVdyYXBwZXIucHJvdG90eXBlW21ldGhvZE5hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9fZmlsdGVyZWRfXyA/IG5ldyBMYXp5V3JhcHBlcih0aGlzKSA6IHRoaXNbZHJvcE5hbWVdKDEpO1xuICAgICAgfTtcbiAgICB9KTtcblxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5jb21wYWN0ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5maWx0ZXIoaWRlbnRpdHkpO1xuICAgIH07XG5cbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUuZmluZCA9IGZ1bmN0aW9uKHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyKHByZWRpY2F0ZSkuaGVhZCgpO1xuICAgIH07XG5cbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUuZmluZExhc3QgPSBmdW5jdGlvbihwcmVkaWNhdGUpIHtcbiAgICAgIHJldHVybiB0aGlzLnJldmVyc2UoKS5maW5kKHByZWRpY2F0ZSk7XG4gICAgfTtcblxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5pbnZva2VNYXAgPSBiYXNlUmVzdChmdW5jdGlvbihwYXRoLCBhcmdzKSB7XG4gICAgICBpZiAodHlwZW9mIHBhdGggPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gbmV3IExhenlXcmFwcGVyKHRoaXMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBiYXNlSW52b2tlKHZhbHVlLCBwYXRoLCBhcmdzKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLnJlamVjdCA9IGZ1bmN0aW9uKHByZWRpY2F0ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyKG5lZ2F0ZShnZXRJdGVyYXRlZShwcmVkaWNhdGUpKSk7XG4gICAgfTtcblxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICAgIHN0YXJ0ID0gdG9JbnRlZ2VyKHN0YXJ0KTtcblxuICAgICAgdmFyIHJlc3VsdCA9IHRoaXM7XG4gICAgICBpZiAocmVzdWx0Ll9fZmlsdGVyZWRfXyAmJiAoc3RhcnQgPiAwIHx8IGVuZCA8IDApKSB7XG4gICAgICAgIHJldHVybiBuZXcgTGF6eVdyYXBwZXIocmVzdWx0KTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFydCA8IDApIHtcbiAgICAgICAgcmVzdWx0ID0gcmVzdWx0LnRha2VSaWdodCgtc3RhcnQpO1xuICAgICAgfSBlbHNlIGlmIChzdGFydCkge1xuICAgICAgICByZXN1bHQgPSByZXN1bHQuZHJvcChzdGFydCk7XG4gICAgICB9XG4gICAgICBpZiAoZW5kICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZW5kID0gdG9JbnRlZ2VyKGVuZCk7XG4gICAgICAgIHJlc3VsdCA9IGVuZCA8IDAgPyByZXN1bHQuZHJvcFJpZ2h0KC1lbmQpIDogcmVzdWx0LnRha2UoZW5kIC0gc3RhcnQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgTGF6eVdyYXBwZXIucHJvdG90eXBlLnRha2VSaWdodFdoaWxlID0gZnVuY3Rpb24ocHJlZGljYXRlKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXZlcnNlKCkudGFrZVdoaWxlKHByZWRpY2F0ZSkucmV2ZXJzZSgpO1xuICAgIH07XG5cbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUudG9BcnJheSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMudGFrZShNQVhfQVJSQVlfTEVOR1RIKTtcbiAgICB9O1xuXG4gICAgLy8gQWRkIGBMYXp5V3JhcHBlcmAgbWV0aG9kcyB0byBgbG9kYXNoLnByb3RvdHlwZWAuXG4gICAgYmFzZUZvck93bihMYXp5V3JhcHBlci5wcm90b3R5cGUsIGZ1bmN0aW9uKGZ1bmMsIG1ldGhvZE5hbWUpIHtcbiAgICAgIHZhciBjaGVja0l0ZXJhdGVlID0gL14oPzpmaWx0ZXJ8ZmluZHxtYXB8cmVqZWN0KXxXaGlsZSQvLnRlc3QobWV0aG9kTmFtZSksXG4gICAgICAgICAgaXNUYWtlciA9IC9eKD86aGVhZHxsYXN0KSQvLnRlc3QobWV0aG9kTmFtZSksXG4gICAgICAgICAgbG9kYXNoRnVuYyA9IGxvZGFzaFtpc1Rha2VyID8gKCd0YWtlJyArIChtZXRob2ROYW1lID09ICdsYXN0JyA/ICdSaWdodCcgOiAnJykpIDogbWV0aG9kTmFtZV0sXG4gICAgICAgICAgcmV0VW53cmFwcGVkID0gaXNUYWtlciB8fCAvXmZpbmQvLnRlc3QobWV0aG9kTmFtZSk7XG5cbiAgICAgIGlmICghbG9kYXNoRnVuYykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBsb2Rhc2gucHJvdG90eXBlW21ldGhvZE5hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuX193cmFwcGVkX18sXG4gICAgICAgICAgICBhcmdzID0gaXNUYWtlciA/IFsxXSA6IGFyZ3VtZW50cyxcbiAgICAgICAgICAgIGlzTGF6eSA9IHZhbHVlIGluc3RhbmNlb2YgTGF6eVdyYXBwZXIsXG4gICAgICAgICAgICBpdGVyYXRlZSA9IGFyZ3NbMF0sXG4gICAgICAgICAgICB1c2VMYXp5ID0gaXNMYXp5IHx8IGlzQXJyYXkodmFsdWUpO1xuXG4gICAgICAgIHZhciBpbnRlcmNlcHRvciA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgdmFyIHJlc3VsdCA9IGxvZGFzaEZ1bmMuYXBwbHkobG9kYXNoLCBhcnJheVB1c2goW3ZhbHVlXSwgYXJncykpO1xuICAgICAgICAgIHJldHVybiAoaXNUYWtlciAmJiBjaGFpbkFsbCkgPyByZXN1bHRbMF0gOiByZXN1bHQ7XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKHVzZUxhenkgJiYgY2hlY2tJdGVyYXRlZSAmJiB0eXBlb2YgaXRlcmF0ZWUgPT0gJ2Z1bmN0aW9uJyAmJiBpdGVyYXRlZS5sZW5ndGggIT0gMSkge1xuICAgICAgICAgIC8vIEF2b2lkIGxhenkgdXNlIGlmIHRoZSBpdGVyYXRlZSBoYXMgYSBcImxlbmd0aFwiIHZhbHVlIG90aGVyIHRoYW4gYDFgLlxuICAgICAgICAgIGlzTGF6eSA9IHVzZUxhenkgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgY2hhaW5BbGwgPSB0aGlzLl9fY2hhaW5fXyxcbiAgICAgICAgICAgIGlzSHlicmlkID0gISF0aGlzLl9fYWN0aW9uc19fLmxlbmd0aCxcbiAgICAgICAgICAgIGlzVW53cmFwcGVkID0gcmV0VW53cmFwcGVkICYmICFjaGFpbkFsbCxcbiAgICAgICAgICAgIG9ubHlMYXp5ID0gaXNMYXp5ICYmICFpc0h5YnJpZDtcblxuICAgICAgICBpZiAoIXJldFVud3JhcHBlZCAmJiB1c2VMYXp5KSB7XG4gICAgICAgICAgdmFsdWUgPSBvbmx5TGF6eSA/IHZhbHVlIDogbmV3IExhenlXcmFwcGVyKHRoaXMpO1xuICAgICAgICAgIHZhciByZXN1bHQgPSBmdW5jLmFwcGx5KHZhbHVlLCBhcmdzKTtcbiAgICAgICAgICByZXN1bHQuX19hY3Rpb25zX18ucHVzaCh7ICdmdW5jJzogdGhydSwgJ2FyZ3MnOiBbaW50ZXJjZXB0b3JdLCAndGhpc0FyZyc6IHVuZGVmaW5lZCB9KTtcbiAgICAgICAgICByZXR1cm4gbmV3IExvZGFzaFdyYXBwZXIocmVzdWx0LCBjaGFpbkFsbCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzVW53cmFwcGVkICYmIG9ubHlMYXp5KSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0ID0gdGhpcy50aHJ1KGludGVyY2VwdG9yKTtcbiAgICAgICAgcmV0dXJuIGlzVW53cmFwcGVkID8gKGlzVGFrZXIgPyByZXN1bHQudmFsdWUoKVswXSA6IHJlc3VsdC52YWx1ZSgpKSA6IHJlc3VsdDtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBBZGQgYEFycmF5YCBtZXRob2RzIHRvIGBsb2Rhc2gucHJvdG90eXBlYC5cbiAgICBhcnJheUVhY2goWydwb3AnLCAncHVzaCcsICdzaGlmdCcsICdzb3J0JywgJ3NwbGljZScsICd1bnNoaWZ0J10sIGZ1bmN0aW9uKG1ldGhvZE5hbWUpIHtcbiAgICAgIHZhciBmdW5jID0gYXJyYXlQcm90b1ttZXRob2ROYW1lXSxcbiAgICAgICAgICBjaGFpbk5hbWUgPSAvXig/OnB1c2h8c29ydHx1bnNoaWZ0KSQvLnRlc3QobWV0aG9kTmFtZSkgPyAndGFwJyA6ICd0aHJ1JyxcbiAgICAgICAgICByZXRVbndyYXBwZWQgPSAvXig/OnBvcHxzaGlmdCkkLy50ZXN0KG1ldGhvZE5hbWUpO1xuXG4gICAgICBsb2Rhc2gucHJvdG90eXBlW21ldGhvZE5hbWVdID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgICBpZiAocmV0VW53cmFwcGVkICYmICF0aGlzLl9fY2hhaW5fXykge1xuICAgICAgICAgIHZhciB2YWx1ZSA9IHRoaXMudmFsdWUoKTtcbiAgICAgICAgICByZXR1cm4gZnVuYy5hcHBseShpc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW10sIGFyZ3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzW2NoYWluTmFtZV0oZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICByZXR1cm4gZnVuYy5hcHBseShpc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW10sIGFyZ3MpO1xuICAgICAgICB9KTtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBNYXAgbWluaWZpZWQgbWV0aG9kIG5hbWVzIHRvIHRoZWlyIHJlYWwgbmFtZXMuXG4gICAgYmFzZUZvck93bihMYXp5V3JhcHBlci5wcm90b3R5cGUsIGZ1bmN0aW9uKGZ1bmMsIG1ldGhvZE5hbWUpIHtcbiAgICAgIHZhciBsb2Rhc2hGdW5jID0gbG9kYXNoW21ldGhvZE5hbWVdO1xuICAgICAgaWYgKGxvZGFzaEZ1bmMpIHtcbiAgICAgICAgdmFyIGtleSA9IChsb2Rhc2hGdW5jLm5hbWUgKyAnJyksXG4gICAgICAgICAgICBuYW1lcyA9IHJlYWxOYW1lc1trZXldIHx8IChyZWFsTmFtZXNba2V5XSA9IFtdKTtcblxuICAgICAgICBuYW1lcy5wdXNoKHsgJ25hbWUnOiBtZXRob2ROYW1lLCAnZnVuYyc6IGxvZGFzaEZ1bmMgfSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZWFsTmFtZXNbY3JlYXRlSHlicmlkKHVuZGVmaW5lZCwgV1JBUF9CSU5EX0tFWV9GTEFHKS5uYW1lXSA9IFt7XG4gICAgICAnbmFtZSc6ICd3cmFwcGVyJyxcbiAgICAgICdmdW5jJzogdW5kZWZpbmVkXG4gICAgfV07XG5cbiAgICAvLyBBZGQgbWV0aG9kcyB0byBgTGF6eVdyYXBwZXJgLlxuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS5jbG9uZSA9IGxhenlDbG9uZTtcbiAgICBMYXp5V3JhcHBlci5wcm90b3R5cGUucmV2ZXJzZSA9IGxhenlSZXZlcnNlO1xuICAgIExhenlXcmFwcGVyLnByb3RvdHlwZS52YWx1ZSA9IGxhenlWYWx1ZTtcblxuICAgIC8vIEFkZCBjaGFpbiBzZXF1ZW5jZSBtZXRob2RzIHRvIHRoZSBgbG9kYXNoYCB3cmFwcGVyLlxuICAgIGxvZGFzaC5wcm90b3R5cGUuYXQgPSB3cmFwcGVyQXQ7XG4gICAgbG9kYXNoLnByb3RvdHlwZS5jaGFpbiA9IHdyYXBwZXJDaGFpbjtcbiAgICBsb2Rhc2gucHJvdG90eXBlLmNvbW1pdCA9IHdyYXBwZXJDb21taXQ7XG4gICAgbG9kYXNoLnByb3RvdHlwZS5uZXh0ID0gd3JhcHBlck5leHQ7XG4gICAgbG9kYXNoLnByb3RvdHlwZS5wbGFudCA9IHdyYXBwZXJQbGFudDtcbiAgICBsb2Rhc2gucHJvdG90eXBlLnJldmVyc2UgPSB3cmFwcGVyUmV2ZXJzZTtcbiAgICBsb2Rhc2gucHJvdG90eXBlLnRvSlNPTiA9IGxvZGFzaC5wcm90b3R5cGUudmFsdWVPZiA9IGxvZGFzaC5wcm90b3R5cGUudmFsdWUgPSB3cmFwcGVyVmFsdWU7XG5cbiAgICAvLyBBZGQgbGF6eSBhbGlhc2VzLlxuICAgIGxvZGFzaC5wcm90b3R5cGUuZmlyc3QgPSBsb2Rhc2gucHJvdG90eXBlLmhlYWQ7XG5cbiAgICBpZiAoc3ltSXRlcmF0b3IpIHtcbiAgICAgIGxvZGFzaC5wcm90b3R5cGVbc3ltSXRlcmF0b3JdID0gd3JhcHBlclRvSXRlcmF0b3I7XG4gICAgfVxuICAgIHJldHVybiBsb2Rhc2g7XG4gIH0pO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8vIEV4cG9ydCBsb2Rhc2guXG4gIHZhciBfID0gcnVuSW5Db250ZXh0KCk7XG5cbiAgLy8gU29tZSBBTUQgYnVpbGQgb3B0aW1pemVycywgbGlrZSByLmpzLCBjaGVjayBmb3IgY29uZGl0aW9uIHBhdHRlcm5zIGxpa2U6XG4gIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgIC8vIEV4cG9zZSBMb2Rhc2ggb24gdGhlIGdsb2JhbCBvYmplY3QgdG8gcHJldmVudCBlcnJvcnMgd2hlbiBMb2Rhc2ggaXNcbiAgICAvLyBsb2FkZWQgYnkgYSBzY3JpcHQgdGFnIGluIHRoZSBwcmVzZW5jZSBvZiBhbiBBTUQgbG9hZGVyLlxuICAgIC8vIFNlZSBodHRwOi8vcmVxdWlyZWpzLm9yZy9kb2NzL2Vycm9ycy5odG1sI21pc21hdGNoIGZvciBtb3JlIGRldGFpbHMuXG4gICAgLy8gVXNlIGBfLm5vQ29uZmxpY3RgIHRvIHJlbW92ZSBMb2Rhc2ggZnJvbSB0aGUgZ2xvYmFsIG9iamVjdC5cbiAgICByb290Ll8gPSBfO1xuXG4gICAgLy8gRGVmaW5lIGFzIGFuIGFub255bW91cyBtb2R1bGUgc28sIHRocm91Z2ggcGF0aCBtYXBwaW5nLCBpdCBjYW4gYmVcbiAgICAvLyByZWZlcmVuY2VkIGFzIHRoZSBcInVuZGVyc2NvcmVcIiBtb2R1bGUuXG4gICAgZGVmaW5lKGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIF87XG4gICAgfSk7XG4gIH1cbiAgLy8gQ2hlY2sgZm9yIGBleHBvcnRzYCBhZnRlciBgZGVmaW5lYCBpbiBjYXNlIGEgYnVpbGQgb3B0aW1pemVyIGFkZHMgaXQuXG4gIGVsc2UgaWYgKGZyZWVNb2R1bGUpIHtcbiAgICAvLyBFeHBvcnQgZm9yIE5vZGUuanMuXG4gICAgKGZyZWVNb2R1bGUuZXhwb3J0cyA9IF8pLl8gPSBfO1xuICAgIC8vIEV4cG9ydCBmb3IgQ29tbW9uSlMgc3VwcG9ydC5cbiAgICBmcmVlRXhwb3J0cy5fID0gXztcbiAgfVxuICBlbHNlIHtcbiAgICAvLyBFeHBvcnQgdG8gdGhlIGdsb2JhbCBvYmplY3QuXG4gICAgcm9vdC5fID0gXztcbiAgfVxufS5jYWxsKHRoaXMpKTtcbiIsIid1c2Ugc3RyaWN0J1xudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEhhc2hCYXNlID0gcmVxdWlyZSgnaGFzaC1iYXNlJylcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxuXG52YXIgQVJSQVkxNiA9IG5ldyBBcnJheSgxNilcblxuZnVuY3Rpb24gTUQ1ICgpIHtcbiAgSGFzaEJhc2UuY2FsbCh0aGlzLCA2NClcblxuICAvLyBzdGF0ZVxuICB0aGlzLl9hID0gMHg2NzQ1MjMwMVxuICB0aGlzLl9iID0gMHhlZmNkYWI4OVxuICB0aGlzLl9jID0gMHg5OGJhZGNmZVxuICB0aGlzLl9kID0gMHgxMDMyNTQ3NlxufVxuXG5pbmhlcml0cyhNRDUsIEhhc2hCYXNlKVxuXG5NRDUucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBNID0gQVJSQVkxNlxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyArK2kpIE1baV0gPSB0aGlzLl9ibG9jay5yZWFkSW50MzJMRShpICogNClcblxuICB2YXIgYSA9IHRoaXMuX2FcbiAgdmFyIGIgPSB0aGlzLl9iXG4gIHZhciBjID0gdGhpcy5fY1xuICB2YXIgZCA9IHRoaXMuX2RcblxuICBhID0gZm5GKGEsIGIsIGMsIGQsIE1bMF0sIDB4ZDc2YWE0NzgsIDcpXG4gIGQgPSBmbkYoZCwgYSwgYiwgYywgTVsxXSwgMHhlOGM3Yjc1NiwgMTIpXG4gIGMgPSBmbkYoYywgZCwgYSwgYiwgTVsyXSwgMHgyNDIwNzBkYiwgMTcpXG4gIGIgPSBmbkYoYiwgYywgZCwgYSwgTVszXSwgMHhjMWJkY2VlZSwgMjIpXG4gIGEgPSBmbkYoYSwgYiwgYywgZCwgTVs0XSwgMHhmNTdjMGZhZiwgNylcbiAgZCA9IGZuRihkLCBhLCBiLCBjLCBNWzVdLCAweDQ3ODdjNjJhLCAxMilcbiAgYyA9IGZuRihjLCBkLCBhLCBiLCBNWzZdLCAweGE4MzA0NjEzLCAxNylcbiAgYiA9IGZuRihiLCBjLCBkLCBhLCBNWzddLCAweGZkNDY5NTAxLCAyMilcbiAgYSA9IGZuRihhLCBiLCBjLCBkLCBNWzhdLCAweDY5ODA5OGQ4LCA3KVxuICBkID0gZm5GKGQsIGEsIGIsIGMsIE1bOV0sIDB4OGI0NGY3YWYsIDEyKVxuICBjID0gZm5GKGMsIGQsIGEsIGIsIE1bMTBdLCAweGZmZmY1YmIxLCAxNylcbiAgYiA9IGZuRihiLCBjLCBkLCBhLCBNWzExXSwgMHg4OTVjZDdiZSwgMjIpXG4gIGEgPSBmbkYoYSwgYiwgYywgZCwgTVsxMl0sIDB4NmI5MDExMjIsIDcpXG4gIGQgPSBmbkYoZCwgYSwgYiwgYywgTVsxM10sIDB4ZmQ5ODcxOTMsIDEyKVxuICBjID0gZm5GKGMsIGQsIGEsIGIsIE1bMTRdLCAweGE2Nzk0MzhlLCAxNylcbiAgYiA9IGZuRihiLCBjLCBkLCBhLCBNWzE1XSwgMHg0OWI0MDgyMSwgMjIpXG5cbiAgYSA9IGZuRyhhLCBiLCBjLCBkLCBNWzFdLCAweGY2MWUyNTYyLCA1KVxuICBkID0gZm5HKGQsIGEsIGIsIGMsIE1bNl0sIDB4YzA0MGIzNDAsIDkpXG4gIGMgPSBmbkcoYywgZCwgYSwgYiwgTVsxMV0sIDB4MjY1ZTVhNTEsIDE0KVxuICBiID0gZm5HKGIsIGMsIGQsIGEsIE1bMF0sIDB4ZTliNmM3YWEsIDIwKVxuICBhID0gZm5HKGEsIGIsIGMsIGQsIE1bNV0sIDB4ZDYyZjEwNWQsIDUpXG4gIGQgPSBmbkcoZCwgYSwgYiwgYywgTVsxMF0sIDB4MDI0NDE0NTMsIDkpXG4gIGMgPSBmbkcoYywgZCwgYSwgYiwgTVsxNV0sIDB4ZDhhMWU2ODEsIDE0KVxuICBiID0gZm5HKGIsIGMsIGQsIGEsIE1bNF0sIDB4ZTdkM2ZiYzgsIDIwKVxuICBhID0gZm5HKGEsIGIsIGMsIGQsIE1bOV0sIDB4MjFlMWNkZTYsIDUpXG4gIGQgPSBmbkcoZCwgYSwgYiwgYywgTVsxNF0sIDB4YzMzNzA3ZDYsIDkpXG4gIGMgPSBmbkcoYywgZCwgYSwgYiwgTVszXSwgMHhmNGQ1MGQ4NywgMTQpXG4gIGIgPSBmbkcoYiwgYywgZCwgYSwgTVs4XSwgMHg0NTVhMTRlZCwgMjApXG4gIGEgPSBmbkcoYSwgYiwgYywgZCwgTVsxM10sIDB4YTllM2U5MDUsIDUpXG4gIGQgPSBmbkcoZCwgYSwgYiwgYywgTVsyXSwgMHhmY2VmYTNmOCwgOSlcbiAgYyA9IGZuRyhjLCBkLCBhLCBiLCBNWzddLCAweDY3NmYwMmQ5LCAxNClcbiAgYiA9IGZuRyhiLCBjLCBkLCBhLCBNWzEyXSwgMHg4ZDJhNGM4YSwgMjApXG5cbiAgYSA9IGZuSChhLCBiLCBjLCBkLCBNWzVdLCAweGZmZmEzOTQyLCA0KVxuICBkID0gZm5IKGQsIGEsIGIsIGMsIE1bOF0sIDB4ODc3MWY2ODEsIDExKVxuICBjID0gZm5IKGMsIGQsIGEsIGIsIE1bMTFdLCAweDZkOWQ2MTIyLCAxNilcbiAgYiA9IGZuSChiLCBjLCBkLCBhLCBNWzE0XSwgMHhmZGU1MzgwYywgMjMpXG4gIGEgPSBmbkgoYSwgYiwgYywgZCwgTVsxXSwgMHhhNGJlZWE0NCwgNClcbiAgZCA9IGZuSChkLCBhLCBiLCBjLCBNWzRdLCAweDRiZGVjZmE5LCAxMSlcbiAgYyA9IGZuSChjLCBkLCBhLCBiLCBNWzddLCAweGY2YmI0YjYwLCAxNilcbiAgYiA9IGZuSChiLCBjLCBkLCBhLCBNWzEwXSwgMHhiZWJmYmM3MCwgMjMpXG4gIGEgPSBmbkgoYSwgYiwgYywgZCwgTVsxM10sIDB4Mjg5YjdlYzYsIDQpXG4gIGQgPSBmbkgoZCwgYSwgYiwgYywgTVswXSwgMHhlYWExMjdmYSwgMTEpXG4gIGMgPSBmbkgoYywgZCwgYSwgYiwgTVszXSwgMHhkNGVmMzA4NSwgMTYpXG4gIGIgPSBmbkgoYiwgYywgZCwgYSwgTVs2XSwgMHgwNDg4MWQwNSwgMjMpXG4gIGEgPSBmbkgoYSwgYiwgYywgZCwgTVs5XSwgMHhkOWQ0ZDAzOSwgNClcbiAgZCA9IGZuSChkLCBhLCBiLCBjLCBNWzEyXSwgMHhlNmRiOTllNSwgMTEpXG4gIGMgPSBmbkgoYywgZCwgYSwgYiwgTVsxNV0sIDB4MWZhMjdjZjgsIDE2KVxuICBiID0gZm5IKGIsIGMsIGQsIGEsIE1bMl0sIDB4YzRhYzU2NjUsIDIzKVxuXG4gIGEgPSBmbkkoYSwgYiwgYywgZCwgTVswXSwgMHhmNDI5MjI0NCwgNilcbiAgZCA9IGZuSShkLCBhLCBiLCBjLCBNWzddLCAweDQzMmFmZjk3LCAxMClcbiAgYyA9IGZuSShjLCBkLCBhLCBiLCBNWzE0XSwgMHhhYjk0MjNhNywgMTUpXG4gIGIgPSBmbkkoYiwgYywgZCwgYSwgTVs1XSwgMHhmYzkzYTAzOSwgMjEpXG4gIGEgPSBmbkkoYSwgYiwgYywgZCwgTVsxMl0sIDB4NjU1YjU5YzMsIDYpXG4gIGQgPSBmbkkoZCwgYSwgYiwgYywgTVszXSwgMHg4ZjBjY2M5MiwgMTApXG4gIGMgPSBmbkkoYywgZCwgYSwgYiwgTVsxMF0sIDB4ZmZlZmY0N2QsIDE1KVxuICBiID0gZm5JKGIsIGMsIGQsIGEsIE1bMV0sIDB4ODU4NDVkZDEsIDIxKVxuICBhID0gZm5JKGEsIGIsIGMsIGQsIE1bOF0sIDB4NmZhODdlNGYsIDYpXG4gIGQgPSBmbkkoZCwgYSwgYiwgYywgTVsxNV0sIDB4ZmUyY2U2ZTAsIDEwKVxuICBjID0gZm5JKGMsIGQsIGEsIGIsIE1bNl0sIDB4YTMwMTQzMTQsIDE1KVxuICBiID0gZm5JKGIsIGMsIGQsIGEsIE1bMTNdLCAweDRlMDgxMWExLCAyMSlcbiAgYSA9IGZuSShhLCBiLCBjLCBkLCBNWzRdLCAweGY3NTM3ZTgyLCA2KVxuICBkID0gZm5JKGQsIGEsIGIsIGMsIE1bMTFdLCAweGJkM2FmMjM1LCAxMClcbiAgYyA9IGZuSShjLCBkLCBhLCBiLCBNWzJdLCAweDJhZDdkMmJiLCAxNSlcbiAgYiA9IGZuSShiLCBjLCBkLCBhLCBNWzldLCAweGViODZkMzkxLCAyMSlcblxuICB0aGlzLl9hID0gKHRoaXMuX2EgKyBhKSB8IDBcbiAgdGhpcy5fYiA9ICh0aGlzLl9iICsgYikgfCAwXG4gIHRoaXMuX2MgPSAodGhpcy5fYyArIGMpIHwgMFxuICB0aGlzLl9kID0gKHRoaXMuX2QgKyBkKSB8IDBcbn1cblxuTUQ1LnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gKCkge1xuICAvLyBjcmVhdGUgcGFkZGluZyBhbmQgaGFuZGxlIGJsb2Nrc1xuICB0aGlzLl9ibG9ja1t0aGlzLl9ibG9ja09mZnNldCsrXSA9IDB4ODBcbiAgaWYgKHRoaXMuX2Jsb2NrT2Zmc2V0ID4gNTYpIHtcbiAgICB0aGlzLl9ibG9jay5maWxsKDAsIHRoaXMuX2Jsb2NrT2Zmc2V0LCA2NClcbiAgICB0aGlzLl91cGRhdGUoKVxuICAgIHRoaXMuX2Jsb2NrT2Zmc2V0ID0gMFxuICB9XG5cbiAgdGhpcy5fYmxvY2suZmlsbCgwLCB0aGlzLl9ibG9ja09mZnNldCwgNTYpXG4gIHRoaXMuX2Jsb2NrLndyaXRlVUludDMyTEUodGhpcy5fbGVuZ3RoWzBdLCA1NilcbiAgdGhpcy5fYmxvY2sud3JpdGVVSW50MzJMRSh0aGlzLl9sZW5ndGhbMV0sIDYwKVxuICB0aGlzLl91cGRhdGUoKVxuXG4gIC8vIHByb2R1Y2UgcmVzdWx0XG4gIHZhciBidWZmZXIgPSBCdWZmZXIuYWxsb2NVbnNhZmUoMTYpXG4gIGJ1ZmZlci53cml0ZUludDMyTEUodGhpcy5fYSwgMClcbiAgYnVmZmVyLndyaXRlSW50MzJMRSh0aGlzLl9iLCA0KVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2MsIDgpXG4gIGJ1ZmZlci53cml0ZUludDMyTEUodGhpcy5fZCwgMTIpXG4gIHJldHVybiBidWZmZXJcbn1cblxuZnVuY3Rpb24gcm90bCAoeCwgbikge1xuICByZXR1cm4gKHggPDwgbikgfCAoeCA+Pj4gKDMyIC0gbikpXG59XG5cbmZ1bmN0aW9uIGZuRiAoYSwgYiwgYywgZCwgbSwgaywgcykge1xuICByZXR1cm4gKHJvdGwoKGEgKyAoKGIgJiBjKSB8ICgofmIpICYgZCkpICsgbSArIGspIHwgMCwgcykgKyBiKSB8IDBcbn1cblxuZnVuY3Rpb24gZm5HIChhLCBiLCBjLCBkLCBtLCBrLCBzKSB7XG4gIHJldHVybiAocm90bCgoYSArICgoYiAmIGQpIHwgKGMgJiAofmQpKSkgKyBtICsgaykgfCAwLCBzKSArIGIpIHwgMFxufVxuXG5mdW5jdGlvbiBmbkggKGEsIGIsIGMsIGQsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKGIgXiBjIF4gZCkgKyBtICsgaykgfCAwLCBzKSArIGIpIHwgMFxufVxuXG5mdW5jdGlvbiBmbkkgKGEsIGIsIGMsIGQsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKChjIF4gKGIgfCAofmQpKSkpICsgbSArIGspIHwgMCwgcykgKyBiKSB8IDBcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBNRDVcbiIsInZhciBibiA9IHJlcXVpcmUoJ2JuLmpzJyk7XG52YXIgYnJvcmFuZCA9IHJlcXVpcmUoJ2Jyb3JhbmQnKTtcblxuZnVuY3Rpb24gTWlsbGVyUmFiaW4ocmFuZCkge1xuICB0aGlzLnJhbmQgPSByYW5kIHx8IG5ldyBicm9yYW5kLlJhbmQoKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gTWlsbGVyUmFiaW47XG5cbk1pbGxlclJhYmluLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShyYW5kKSB7XG4gIHJldHVybiBuZXcgTWlsbGVyUmFiaW4ocmFuZCk7XG59O1xuXG5NaWxsZXJSYWJpbi5wcm90b3R5cGUuX3JhbmRiZWxvdyA9IGZ1bmN0aW9uIF9yYW5kYmVsb3cobikge1xuICB2YXIgbGVuID0gbi5iaXRMZW5ndGgoKTtcbiAgdmFyIG1pbl9ieXRlcyA9IE1hdGguY2VpbChsZW4gLyA4KTtcblxuICAvLyBHZW5lcmFnZSByYW5kb20gYnl0ZXMgdW50aWwgYSBudW1iZXIgbGVzcyB0aGFuIG4gaXMgZm91bmQuXG4gIC8vIFRoaXMgZW5zdXJlcyB0aGF0IDAuLm4tMSBoYXZlIGFuIGVxdWFsIHByb2JhYmlsaXR5IG9mIGJlaW5nIHNlbGVjdGVkLlxuICBkb1xuICAgIHZhciBhID0gbmV3IGJuKHRoaXMucmFuZC5nZW5lcmF0ZShtaW5fYnl0ZXMpKTtcbiAgd2hpbGUgKGEuY21wKG4pID49IDApO1xuXG4gIHJldHVybiBhO1xufTtcblxuTWlsbGVyUmFiaW4ucHJvdG90eXBlLl9yYW5kcmFuZ2UgPSBmdW5jdGlvbiBfcmFuZHJhbmdlKHN0YXJ0LCBzdG9wKSB7XG4gIC8vIEdlbmVyYXRlIGEgcmFuZG9tIG51bWJlciBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gc3RhcnQgYW5kIGxlc3MgdGhhbiBzdG9wLlxuICB2YXIgc2l6ZSA9IHN0b3Auc3ViKHN0YXJ0KTtcbiAgcmV0dXJuIHN0YXJ0LmFkZCh0aGlzLl9yYW5kYmVsb3coc2l6ZSkpO1xufTtcblxuTWlsbGVyUmFiaW4ucHJvdG90eXBlLnRlc3QgPSBmdW5jdGlvbiB0ZXN0KG4sIGssIGNiKSB7XG4gIHZhciBsZW4gPSBuLmJpdExlbmd0aCgpO1xuICB2YXIgcmVkID0gYm4ubW9udChuKTtcbiAgdmFyIHJvbmUgPSBuZXcgYm4oMSkudG9SZWQocmVkKTtcblxuICBpZiAoIWspXG4gICAgayA9IE1hdGgubWF4KDEsIChsZW4gLyA0OCkgfCAwKTtcblxuICAvLyBGaW5kIGQgYW5kIHMsIChuIC0gMSkgPSAoMiBeIHMpICogZDtcbiAgdmFyIG4xID0gbi5zdWJuKDEpO1xuICBmb3IgKHZhciBzID0gMDsgIW4xLnRlc3RuKHMpOyBzKyspIHt9XG4gIHZhciBkID0gbi5zaHJuKHMpO1xuXG4gIHZhciBybjEgPSBuMS50b1JlZChyZWQpO1xuXG4gIHZhciBwcmltZSA9IHRydWU7XG4gIGZvciAoOyBrID4gMDsgay0tKSB7XG4gICAgdmFyIGEgPSB0aGlzLl9yYW5kcmFuZ2UobmV3IGJuKDIpLCBuMSk7XG4gICAgaWYgKGNiKVxuICAgICAgY2IoYSk7XG5cbiAgICB2YXIgeCA9IGEudG9SZWQocmVkKS5yZWRQb3coZCk7XG4gICAgaWYgKHguY21wKHJvbmUpID09PSAwIHx8IHguY21wKHJuMSkgPT09IDApXG4gICAgICBjb250aW51ZTtcblxuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgczsgaSsrKSB7XG4gICAgICB4ID0geC5yZWRTcXIoKTtcblxuICAgICAgaWYgKHguY21wKHJvbmUpID09PSAwKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICBpZiAoeC5jbXAocm4xKSA9PT0gMClcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKGkgPT09IHMpXG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gcHJpbWU7XG59O1xuXG5NaWxsZXJSYWJpbi5wcm90b3R5cGUuZ2V0RGl2aXNvciA9IGZ1bmN0aW9uIGdldERpdmlzb3Iobiwgaykge1xuICB2YXIgbGVuID0gbi5iaXRMZW5ndGgoKTtcbiAgdmFyIHJlZCA9IGJuLm1vbnQobik7XG4gIHZhciByb25lID0gbmV3IGJuKDEpLnRvUmVkKHJlZCk7XG5cbiAgaWYgKCFrKVxuICAgIGsgPSBNYXRoLm1heCgxLCAobGVuIC8gNDgpIHwgMCk7XG5cbiAgLy8gRmluZCBkIGFuZCBzLCAobiAtIDEpID0gKDIgXiBzKSAqIGQ7XG4gIHZhciBuMSA9IG4uc3VibigxKTtcbiAgZm9yICh2YXIgcyA9IDA7ICFuMS50ZXN0bihzKTsgcysrKSB7fVxuICB2YXIgZCA9IG4uc2hybihzKTtcblxuICB2YXIgcm4xID0gbjEudG9SZWQocmVkKTtcblxuICBmb3IgKDsgayA+IDA7IGstLSkge1xuICAgIHZhciBhID0gdGhpcy5fcmFuZHJhbmdlKG5ldyBibigyKSwgbjEpO1xuXG4gICAgdmFyIGcgPSBuLmdjZChhKTtcbiAgICBpZiAoZy5jbXBuKDEpICE9PSAwKVxuICAgICAgcmV0dXJuIGc7XG5cbiAgICB2YXIgeCA9IGEudG9SZWQocmVkKS5yZWRQb3coZCk7XG4gICAgaWYgKHguY21wKHJvbmUpID09PSAwIHx8IHguY21wKHJuMSkgPT09IDApXG4gICAgICBjb250aW51ZTtcblxuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgczsgaSsrKSB7XG4gICAgICB4ID0geC5yZWRTcXIoKTtcblxuICAgICAgaWYgKHguY21wKHJvbmUpID09PSAwKVxuICAgICAgICByZXR1cm4geC5mcm9tUmVkKCkuc3VibigxKS5nY2Qobik7XG4gICAgICBpZiAoeC5jbXAocm4xKSA9PT0gMClcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKGkgPT09IHMpIHtcbiAgICAgIHggPSB4LnJlZFNxcigpO1xuICAgICAgcmV0dXJuIHguZnJvbVJlZCgpLnN1Ym4oMSkuZ2NkKG4pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGFzc2VydDtcblxuZnVuY3Rpb24gYXNzZXJ0KHZhbCwgbXNnKSB7XG4gIGlmICghdmFsKVxuICAgIHRocm93IG5ldyBFcnJvcihtc2cgfHwgJ0Fzc2VydGlvbiBmYWlsZWQnKTtcbn1cblxuYXNzZXJ0LmVxdWFsID0gZnVuY3Rpb24gYXNzZXJ0RXF1YWwobCwgciwgbXNnKSB7XG4gIGlmIChsICE9IHIpXG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZyB8fCAoJ0Fzc2VydGlvbiBmYWlsZWQ6ICcgKyBsICsgJyAhPSAnICsgcikpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gZXhwb3J0cztcblxuZnVuY3Rpb24gdG9BcnJheShtc2csIGVuYykge1xuICBpZiAoQXJyYXkuaXNBcnJheShtc2cpKVxuICAgIHJldHVybiBtc2cuc2xpY2UoKTtcbiAgaWYgKCFtc2cpXG4gICAgcmV0dXJuIFtdO1xuICB2YXIgcmVzID0gW107XG4gIGlmICh0eXBlb2YgbXNnICE9PSAnc3RyaW5nJykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKVxuICAgICAgcmVzW2ldID0gbXNnW2ldIHwgMDtcbiAgICByZXR1cm4gcmVzO1xuICB9XG4gIGlmIChlbmMgPT09ICdoZXgnKSB7XG4gICAgbXNnID0gbXNnLnJlcGxhY2UoL1teYS16MC05XSsvaWcsICcnKTtcbiAgICBpZiAobXNnLmxlbmd0aCAlIDIgIT09IDApXG4gICAgICBtc2cgPSAnMCcgKyBtc2c7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpICs9IDIpXG4gICAgICByZXMucHVzaChwYXJzZUludChtc2dbaV0gKyBtc2dbaSArIDFdLCAxNikpO1xuICB9IGVsc2Uge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXNnLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgYyA9IG1zZy5jaGFyQ29kZUF0KGkpO1xuICAgICAgdmFyIGhpID0gYyA+PiA4O1xuICAgICAgdmFyIGxvID0gYyAmIDB4ZmY7XG4gICAgICBpZiAoaGkpXG4gICAgICAgIHJlcy5wdXNoKGhpLCBsbyk7XG4gICAgICBlbHNlXG4gICAgICAgIHJlcy5wdXNoKGxvKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cbnV0aWxzLnRvQXJyYXkgPSB0b0FycmF5O1xuXG5mdW5jdGlvbiB6ZXJvMih3b3JkKSB7XG4gIGlmICh3b3JkLmxlbmd0aCA9PT0gMSlcbiAgICByZXR1cm4gJzAnICsgd29yZDtcbiAgZWxzZVxuICAgIHJldHVybiB3b3JkO1xufVxudXRpbHMuemVybzIgPSB6ZXJvMjtcblxuZnVuY3Rpb24gdG9IZXgobXNnKSB7XG4gIHZhciByZXMgPSAnJztcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyBpKyspXG4gICAgcmVzICs9IHplcm8yKG1zZ1tpXS50b1N0cmluZygxNikpO1xuICByZXR1cm4gcmVzO1xufVxudXRpbHMudG9IZXggPSB0b0hleDtcblxudXRpbHMuZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKGFyciwgZW5jKSB7XG4gIGlmIChlbmMgPT09ICdoZXgnKVxuICAgIHJldHVybiB0b0hleChhcnIpO1xuICBlbHNlXG4gICAgcmV0dXJuIGFycjtcbn07XG4iLCIvLyBUb3AgbGV2ZWwgZmlsZSBpcyBqdXN0IGEgbWl4aW4gb2Ygc3VibW9kdWxlcyAmIGNvbnN0YW50c1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXNzaWduICAgID0gcmVxdWlyZSgnLi9saWIvdXRpbHMvY29tbW9uJykuYXNzaWduO1xuXG52YXIgZGVmbGF0ZSAgID0gcmVxdWlyZSgnLi9saWIvZGVmbGF0ZScpO1xudmFyIGluZmxhdGUgICA9IHJlcXVpcmUoJy4vbGliL2luZmxhdGUnKTtcbnZhciBjb25zdGFudHMgPSByZXF1aXJlKCcuL2xpYi96bGliL2NvbnN0YW50cycpO1xuXG52YXIgcGFrbyA9IHt9O1xuXG5hc3NpZ24ocGFrbywgZGVmbGF0ZSwgaW5mbGF0ZSwgY29uc3RhbnRzKTtcblxubW9kdWxlLmV4cG9ydHMgPSBwYWtvO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciB6bGliX2RlZmxhdGUgPSByZXF1aXJlKCcuL3psaWIvZGVmbGF0ZScpO1xudmFyIHV0aWxzICAgICAgICA9IHJlcXVpcmUoJy4vdXRpbHMvY29tbW9uJyk7XG52YXIgc3RyaW5ncyAgICAgID0gcmVxdWlyZSgnLi91dGlscy9zdHJpbmdzJyk7XG52YXIgbXNnICAgICAgICAgID0gcmVxdWlyZSgnLi96bGliL21lc3NhZ2VzJyk7XG52YXIgWlN0cmVhbSAgICAgID0gcmVxdWlyZSgnLi96bGliL3pzdHJlYW0nKTtcblxudmFyIHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxuLyogUHVibGljIGNvbnN0YW50cyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG5cbnZhciBaX05PX0ZMVVNIICAgICAgPSAwO1xudmFyIFpfRklOSVNIICAgICAgICA9IDQ7XG5cbnZhciBaX09LICAgICAgICAgICAgPSAwO1xudmFyIFpfU1RSRUFNX0VORCAgICA9IDE7XG52YXIgWl9TWU5DX0ZMVVNIICAgID0gMjtcblxudmFyIFpfREVGQVVMVF9DT01QUkVTU0lPTiA9IC0xO1xuXG52YXIgWl9ERUZBVUxUX1NUUkFURUdZICAgID0gMDtcblxudmFyIFpfREVGTEFURUQgID0gODtcblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cblxuXG4vKipcbiAqIGNsYXNzIERlZmxhdGVcbiAqXG4gKiBHZW5lcmljIEpTLXN0eWxlIHdyYXBwZXIgZm9yIHpsaWIgY2FsbHMuIElmIHlvdSBkb24ndCBuZWVkXG4gKiBzdHJlYW1pbmcgYmVoYXZpb3VyIC0gdXNlIG1vcmUgc2ltcGxlIGZ1bmN0aW9uczogW1tkZWZsYXRlXV0sXG4gKiBbW2RlZmxhdGVSYXddXSBhbmQgW1tnemlwXV0uXG4gKiovXG5cbi8qIGludGVybmFsXG4gKiBEZWZsYXRlLmNodW5rcyAtPiBBcnJheVxuICpcbiAqIENodW5rcyBvZiBvdXRwdXQgZGF0YSwgaWYgW1tEZWZsYXRlI29uRGF0YV1dIG5vdCBvdmVycmlkZGVuLlxuICoqL1xuXG4vKipcbiAqIERlZmxhdGUucmVzdWx0IC0+IFVpbnQ4QXJyYXl8QXJyYXlcbiAqXG4gKiBDb21wcmVzc2VkIHJlc3VsdCwgZ2VuZXJhdGVkIGJ5IGRlZmF1bHQgW1tEZWZsYXRlI29uRGF0YV1dXG4gKiBhbmQgW1tEZWZsYXRlI29uRW5kXV0gaGFuZGxlcnMuIEZpbGxlZCBhZnRlciB5b3UgcHVzaCBsYXN0IGNodW5rXG4gKiAoY2FsbCBbW0RlZmxhdGUjcHVzaF1dIHdpdGggYFpfRklOSVNIYCAvIGB0cnVlYCBwYXJhbSkgIG9yIGlmIHlvdVxuICogcHVzaCBhIGNodW5rIHdpdGggZXhwbGljaXQgZmx1c2ggKGNhbGwgW1tEZWZsYXRlI3B1c2hdXSB3aXRoXG4gKiBgWl9TWU5DX0ZMVVNIYCBwYXJhbSkuXG4gKiovXG5cbi8qKlxuICogRGVmbGF0ZS5lcnIgLT4gTnVtYmVyXG4gKlxuICogRXJyb3IgY29kZSBhZnRlciBkZWZsYXRlIGZpbmlzaGVkLiAwIChaX09LKSBvbiBzdWNjZXNzLlxuICogWW91IHdpbGwgbm90IG5lZWQgaXQgaW4gcmVhbCBsaWZlLCBiZWNhdXNlIGRlZmxhdGUgZXJyb3JzXG4gKiBhcmUgcG9zc2libGUgb25seSBvbiB3cm9uZyBvcHRpb25zIG9yIGJhZCBgb25EYXRhYCAvIGBvbkVuZGBcbiAqIGN1c3RvbSBoYW5kbGVycy5cbiAqKi9cblxuLyoqXG4gKiBEZWZsYXRlLm1zZyAtPiBTdHJpbmdcbiAqXG4gKiBFcnJvciBtZXNzYWdlLCBpZiBbW0RlZmxhdGUuZXJyXV0gIT0gMFxuICoqL1xuXG5cbi8qKlxuICogbmV3IERlZmxhdGUob3B0aW9ucylcbiAqIC0gb3B0aW9ucyAoT2JqZWN0KTogemxpYiBkZWZsYXRlIG9wdGlvbnMuXG4gKlxuICogQ3JlYXRlcyBuZXcgZGVmbGF0b3IgaW5zdGFuY2Ugd2l0aCBzcGVjaWZpZWQgcGFyYW1zLiBUaHJvd3MgZXhjZXB0aW9uXG4gKiBvbiBiYWQgcGFyYW1zLiBTdXBwb3J0ZWQgb3B0aW9uczpcbiAqXG4gKiAtIGBsZXZlbGBcbiAqIC0gYHdpbmRvd0JpdHNgXG4gKiAtIGBtZW1MZXZlbGBcbiAqIC0gYHN0cmF0ZWd5YFxuICogLSBgZGljdGlvbmFyeWBcbiAqXG4gKiBbaHR0cDovL3psaWIubmV0L21hbnVhbC5odG1sI0FkdmFuY2VkXShodHRwOi8vemxpYi5uZXQvbWFudWFsLmh0bWwjQWR2YW5jZWQpXG4gKiBmb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiB0aGVzZS5cbiAqXG4gKiBBZGRpdGlvbmFsIG9wdGlvbnMsIGZvciBpbnRlcm5hbCBuZWVkczpcbiAqXG4gKiAtIGBjaHVua1NpemVgIC0gc2l6ZSBvZiBnZW5lcmF0ZWQgZGF0YSBjaHVua3MgKDE2SyBieSBkZWZhdWx0KVxuICogLSBgcmF3YCAoQm9vbGVhbikgLSBkbyByYXcgZGVmbGF0ZVxuICogLSBgZ3ppcGAgKEJvb2xlYW4pIC0gY3JlYXRlIGd6aXAgd3JhcHBlclxuICogLSBgdG9gIChTdHJpbmcpIC0gaWYgZXF1YWwgdG8gJ3N0cmluZycsIHRoZW4gcmVzdWx0IHdpbGwgYmUgXCJiaW5hcnkgc3RyaW5nXCJcbiAqICAgIChlYWNoIGNoYXIgY29kZSBbMC4uMjU1XSlcbiAqIC0gYGhlYWRlcmAgKE9iamVjdCkgLSBjdXN0b20gaGVhZGVyIGZvciBnemlwXG4gKiAgIC0gYHRleHRgIChCb29sZWFuKSAtIHRydWUgaWYgY29tcHJlc3NlZCBkYXRhIGJlbGlldmVkIHRvIGJlIHRleHRcbiAqICAgLSBgdGltZWAgKE51bWJlcikgLSBtb2RpZmljYXRpb24gdGltZSwgdW5peCB0aW1lc3RhbXBcbiAqICAgLSBgb3NgIChOdW1iZXIpIC0gb3BlcmF0aW9uIHN5c3RlbSBjb2RlXG4gKiAgIC0gYGV4dHJhYCAoQXJyYXkpIC0gYXJyYXkgb2YgYnl0ZXMgd2l0aCBleHRyYSBkYXRhIChtYXggNjU1MzYpXG4gKiAgIC0gYG5hbWVgIChTdHJpbmcpIC0gZmlsZSBuYW1lIChiaW5hcnkgc3RyaW5nKVxuICogICAtIGBjb21tZW50YCAoU3RyaW5nKSAtIGNvbW1lbnQgKGJpbmFyeSBzdHJpbmcpXG4gKiAgIC0gYGhjcmNgIChCb29sZWFuKSAtIHRydWUgaWYgaGVhZGVyIGNyYyBzaG91bGQgYmUgYWRkZWRcbiAqXG4gKiAjIyMjIyBFeGFtcGxlOlxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIHZhciBwYWtvID0gcmVxdWlyZSgncGFrbycpXG4gKiAgICwgY2h1bmsxID0gVWludDhBcnJheShbMSwyLDMsNCw1LDYsNyw4LDldKVxuICogICAsIGNodW5rMiA9IFVpbnQ4QXJyYXkoWzEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5XSk7XG4gKlxuICogdmFyIGRlZmxhdGUgPSBuZXcgcGFrby5EZWZsYXRlKHsgbGV2ZWw6IDN9KTtcbiAqXG4gKiBkZWZsYXRlLnB1c2goY2h1bmsxLCBmYWxzZSk7XG4gKiBkZWZsYXRlLnB1c2goY2h1bmsyLCB0cnVlKTsgIC8vIHRydWUgLT4gbGFzdCBjaHVua1xuICpcbiAqIGlmIChkZWZsYXRlLmVycikgeyB0aHJvdyBuZXcgRXJyb3IoZGVmbGF0ZS5lcnIpOyB9XG4gKlxuICogY29uc29sZS5sb2coZGVmbGF0ZS5yZXN1bHQpO1xuICogYGBgXG4gKiovXG5mdW5jdGlvbiBEZWZsYXRlKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIERlZmxhdGUpKSByZXR1cm4gbmV3IERlZmxhdGUob3B0aW9ucyk7XG5cbiAgdGhpcy5vcHRpb25zID0gdXRpbHMuYXNzaWduKHtcbiAgICBsZXZlbDogWl9ERUZBVUxUX0NPTVBSRVNTSU9OLFxuICAgIG1ldGhvZDogWl9ERUZMQVRFRCxcbiAgICBjaHVua1NpemU6IDE2Mzg0LFxuICAgIHdpbmRvd0JpdHM6IDE1LFxuICAgIG1lbUxldmVsOiA4LFxuICAgIHN0cmF0ZWd5OiBaX0RFRkFVTFRfU1RSQVRFR1ksXG4gICAgdG86ICcnXG4gIH0sIG9wdGlvbnMgfHwge30pO1xuXG4gIHZhciBvcHQgPSB0aGlzLm9wdGlvbnM7XG5cbiAgaWYgKG9wdC5yYXcgJiYgKG9wdC53aW5kb3dCaXRzID4gMCkpIHtcbiAgICBvcHQud2luZG93Qml0cyA9IC1vcHQud2luZG93Qml0cztcbiAgfVxuXG4gIGVsc2UgaWYgKG9wdC5nemlwICYmIChvcHQud2luZG93Qml0cyA+IDApICYmIChvcHQud2luZG93Qml0cyA8IDE2KSkge1xuICAgIG9wdC53aW5kb3dCaXRzICs9IDE2O1xuICB9XG5cbiAgdGhpcy5lcnIgICAgPSAwOyAgICAgIC8vIGVycm9yIGNvZGUsIGlmIGhhcHBlbnMgKDAgPSBaX09LKVxuICB0aGlzLm1zZyAgICA9ICcnOyAgICAgLy8gZXJyb3IgbWVzc2FnZVxuICB0aGlzLmVuZGVkICA9IGZhbHNlOyAgLy8gdXNlZCB0byBhdm9pZCBtdWx0aXBsZSBvbkVuZCgpIGNhbGxzXG4gIHRoaXMuY2h1bmtzID0gW107ICAgICAvLyBjaHVua3Mgb2YgY29tcHJlc3NlZCBkYXRhXG5cbiAgdGhpcy5zdHJtID0gbmV3IFpTdHJlYW0oKTtcbiAgdGhpcy5zdHJtLmF2YWlsX291dCA9IDA7XG5cbiAgdmFyIHN0YXR1cyA9IHpsaWJfZGVmbGF0ZS5kZWZsYXRlSW5pdDIoXG4gICAgdGhpcy5zdHJtLFxuICAgIG9wdC5sZXZlbCxcbiAgICBvcHQubWV0aG9kLFxuICAgIG9wdC53aW5kb3dCaXRzLFxuICAgIG9wdC5tZW1MZXZlbCxcbiAgICBvcHQuc3RyYXRlZ3lcbiAgKTtcblxuICBpZiAoc3RhdHVzICE9PSBaX09LKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZ1tzdGF0dXNdKTtcbiAgfVxuXG4gIGlmIChvcHQuaGVhZGVyKSB7XG4gICAgemxpYl9kZWZsYXRlLmRlZmxhdGVTZXRIZWFkZXIodGhpcy5zdHJtLCBvcHQuaGVhZGVyKTtcbiAgfVxuXG4gIGlmIChvcHQuZGljdGlvbmFyeSkge1xuICAgIHZhciBkaWN0O1xuICAgIC8vIENvbnZlcnQgZGF0YSBpZiBuZWVkZWRcbiAgICBpZiAodHlwZW9mIG9wdC5kaWN0aW9uYXJ5ID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gSWYgd2UgbmVlZCB0byBjb21wcmVzcyB0ZXh0LCBjaGFuZ2UgZW5jb2RpbmcgdG8gdXRmOC5cbiAgICAgIGRpY3QgPSBzdHJpbmdzLnN0cmluZzJidWYob3B0LmRpY3Rpb25hcnkpO1xuICAgIH0gZWxzZSBpZiAodG9TdHJpbmcuY2FsbChvcHQuZGljdGlvbmFyeSkgPT09ICdbb2JqZWN0IEFycmF5QnVmZmVyXScpIHtcbiAgICAgIGRpY3QgPSBuZXcgVWludDhBcnJheShvcHQuZGljdGlvbmFyeSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRpY3QgPSBvcHQuZGljdGlvbmFyeTtcbiAgICB9XG5cbiAgICBzdGF0dXMgPSB6bGliX2RlZmxhdGUuZGVmbGF0ZVNldERpY3Rpb25hcnkodGhpcy5zdHJtLCBkaWN0KTtcblxuICAgIGlmIChzdGF0dXMgIT09IFpfT0spIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihtc2dbc3RhdHVzXSk7XG4gICAgfVxuXG4gICAgdGhpcy5fZGljdF9zZXQgPSB0cnVlO1xuICB9XG59XG5cbi8qKlxuICogRGVmbGF0ZSNwdXNoKGRhdGFbLCBtb2RlXSkgLT4gQm9vbGVhblxuICogLSBkYXRhIChVaW50OEFycmF5fEFycmF5fEFycmF5QnVmZmVyfFN0cmluZyk6IGlucHV0IGRhdGEuIFN0cmluZ3Mgd2lsbCBiZVxuICogICBjb252ZXJ0ZWQgdG8gdXRmOCBieXRlIHNlcXVlbmNlLlxuICogLSBtb2RlIChOdW1iZXJ8Qm9vbGVhbik6IDAuLjYgZm9yIGNvcnJlc3BvbmRpbmcgWl9OT19GTFVTSC4uWl9UUkVFIG1vZGVzLlxuICogICBTZWUgY29uc3RhbnRzLiBTa2lwcGVkIG9yIGBmYWxzZWAgbWVhbnMgWl9OT19GTFVTSCwgYHRydWVgIG1lYW5zIFpfRklOSVNILlxuICpcbiAqIFNlbmRzIGlucHV0IGRhdGEgdG8gZGVmbGF0ZSBwaXBlLCBnZW5lcmF0aW5nIFtbRGVmbGF0ZSNvbkRhdGFdXSBjYWxscyB3aXRoXG4gKiBuZXcgY29tcHJlc3NlZCBjaHVua3MuIFJldHVybnMgYHRydWVgIG9uIHN1Y2Nlc3MuIFRoZSBsYXN0IGRhdGEgYmxvY2sgbXVzdCBoYXZlXG4gKiBtb2RlIFpfRklOSVNIIChvciBgdHJ1ZWApLiBUaGF0IHdpbGwgZmx1c2ggaW50ZXJuYWwgcGVuZGluZyBidWZmZXJzIGFuZCBjYWxsXG4gKiBbW0RlZmxhdGUjb25FbmRdXS4gRm9yIGludGVyaW0gZXhwbGljaXQgZmx1c2hlcyAod2l0aG91dCBlbmRpbmcgdGhlIHN0cmVhbSkgeW91XG4gKiBjYW4gdXNlIG1vZGUgWl9TWU5DX0ZMVVNILCBrZWVwaW5nIHRoZSBjb21wcmVzc2lvbiBjb250ZXh0LlxuICpcbiAqIE9uIGZhaWwgY2FsbCBbW0RlZmxhdGUjb25FbmRdXSB3aXRoIGVycm9yIGNvZGUgYW5kIHJldHVybiBmYWxzZS5cbiAqXG4gKiBXZSBzdHJvbmdseSByZWNvbW1lbmQgdG8gdXNlIGBVaW50OEFycmF5YCBvbiBpbnB1dCBmb3IgYmVzdCBzcGVlZCAob3V0cHV0XG4gKiBhcnJheSBmb3JtYXQgaXMgZGV0ZWN0ZWQgYXV0b21hdGljYWxseSkuIEFsc28sIGRvbid0IHNraXAgbGFzdCBwYXJhbSBhbmQgYWx3YXlzXG4gKiB1c2UgdGhlIHNhbWUgdHlwZSBpbiB5b3VyIGNvZGUgKGJvb2xlYW4gb3IgbnVtYmVyKS4gVGhhdCB3aWxsIGltcHJvdmUgSlMgc3BlZWQuXG4gKlxuICogRm9yIHJlZ3VsYXIgYEFycmF5YC1zIG1ha2Ugc3VyZSBhbGwgZWxlbWVudHMgYXJlIFswLi4yNTVdLlxuICpcbiAqICMjIyMjIEV4YW1wbGVcbiAqXG4gKiBgYGBqYXZhc2NyaXB0XG4gKiBwdXNoKGNodW5rLCBmYWxzZSk7IC8vIHB1c2ggb25lIG9mIGRhdGEgY2h1bmtzXG4gKiAuLi5cbiAqIHB1c2goY2h1bmssIHRydWUpOyAgLy8gcHVzaCBsYXN0IGNodW5rXG4gKiBgYGBcbiAqKi9cbkRlZmxhdGUucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbiAoZGF0YSwgbW9kZSkge1xuICB2YXIgc3RybSA9IHRoaXMuc3RybTtcbiAgdmFyIGNodW5rU2l6ZSA9IHRoaXMub3B0aW9ucy5jaHVua1NpemU7XG4gIHZhciBzdGF0dXMsIF9tb2RlO1xuXG4gIGlmICh0aGlzLmVuZGVkKSB7IHJldHVybiBmYWxzZTsgfVxuXG4gIF9tb2RlID0gKG1vZGUgPT09IH5+bW9kZSkgPyBtb2RlIDogKChtb2RlID09PSB0cnVlKSA/IFpfRklOSVNIIDogWl9OT19GTFVTSCk7XG5cbiAgLy8gQ29udmVydCBkYXRhIGlmIG5lZWRlZFxuICBpZiAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSB7XG4gICAgLy8gSWYgd2UgbmVlZCB0byBjb21wcmVzcyB0ZXh0LCBjaGFuZ2UgZW5jb2RpbmcgdG8gdXRmOC5cbiAgICBzdHJtLmlucHV0ID0gc3RyaW5ncy5zdHJpbmcyYnVmKGRhdGEpO1xuICB9IGVsc2UgaWYgKHRvU3RyaW5nLmNhbGwoZGF0YSkgPT09ICdbb2JqZWN0IEFycmF5QnVmZmVyXScpIHtcbiAgICBzdHJtLmlucHV0ID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSk7XG4gIH0gZWxzZSB7XG4gICAgc3RybS5pbnB1dCA9IGRhdGE7XG4gIH1cblxuICBzdHJtLm5leHRfaW4gPSAwO1xuICBzdHJtLmF2YWlsX2luID0gc3RybS5pbnB1dC5sZW5ndGg7XG5cbiAgZG8ge1xuICAgIGlmIChzdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgc3RybS5vdXRwdXQgPSBuZXcgdXRpbHMuQnVmOChjaHVua1NpemUpO1xuICAgICAgc3RybS5uZXh0X291dCA9IDA7XG4gICAgICBzdHJtLmF2YWlsX291dCA9IGNodW5rU2l6ZTtcbiAgICB9XG4gICAgc3RhdHVzID0gemxpYl9kZWZsYXRlLmRlZmxhdGUoc3RybSwgX21vZGUpOyAgICAvKiBubyBiYWQgcmV0dXJuIHZhbHVlICovXG5cbiAgICBpZiAoc3RhdHVzICE9PSBaX1NUUkVBTV9FTkQgJiYgc3RhdHVzICE9PSBaX09LKSB7XG4gICAgICB0aGlzLm9uRW5kKHN0YXR1cyk7XG4gICAgICB0aGlzLmVuZGVkID0gdHJ1ZTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHN0cm0uYXZhaWxfb3V0ID09PSAwIHx8IChzdHJtLmF2YWlsX2luID09PSAwICYmIChfbW9kZSA9PT0gWl9GSU5JU0ggfHwgX21vZGUgPT09IFpfU1lOQ19GTFVTSCkpKSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLnRvID09PSAnc3RyaW5nJykge1xuICAgICAgICB0aGlzLm9uRGF0YShzdHJpbmdzLmJ1ZjJiaW5zdHJpbmcodXRpbHMuc2hyaW5rQnVmKHN0cm0ub3V0cHV0LCBzdHJtLm5leHRfb3V0KSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5vbkRhdGEodXRpbHMuc2hyaW5rQnVmKHN0cm0ub3V0cHV0LCBzdHJtLm5leHRfb3V0KSk7XG4gICAgICB9XG4gICAgfVxuICB9IHdoaWxlICgoc3RybS5hdmFpbF9pbiA+IDAgfHwgc3RybS5hdmFpbF9vdXQgPT09IDApICYmIHN0YXR1cyAhPT0gWl9TVFJFQU1fRU5EKTtcblxuICAvLyBGaW5hbGl6ZSBvbiB0aGUgbGFzdCBjaHVuay5cbiAgaWYgKF9tb2RlID09PSBaX0ZJTklTSCkge1xuICAgIHN0YXR1cyA9IHpsaWJfZGVmbGF0ZS5kZWZsYXRlRW5kKHRoaXMuc3RybSk7XG4gICAgdGhpcy5vbkVuZChzdGF0dXMpO1xuICAgIHRoaXMuZW5kZWQgPSB0cnVlO1xuICAgIHJldHVybiBzdGF0dXMgPT09IFpfT0s7XG4gIH1cblxuICAvLyBjYWxsYmFjayBpbnRlcmltIHJlc3VsdHMgaWYgWl9TWU5DX0ZMVVNILlxuICBpZiAoX21vZGUgPT09IFpfU1lOQ19GTFVTSCkge1xuICAgIHRoaXMub25FbmQoWl9PSyk7XG4gICAgc3RybS5hdmFpbF9vdXQgPSAwO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5cbi8qKlxuICogRGVmbGF0ZSNvbkRhdGEoY2h1bmspIC0+IFZvaWRcbiAqIC0gY2h1bmsgKFVpbnQ4QXJyYXl8QXJyYXl8U3RyaW5nKTogb3V0cHV0IGRhdGEuIFR5cGUgb2YgYXJyYXkgZGVwZW5kc1xuICogICBvbiBqcyBlbmdpbmUgc3VwcG9ydC4gV2hlbiBzdHJpbmcgb3V0cHV0IHJlcXVlc3RlZCwgZWFjaCBjaHVua1xuICogICB3aWxsIGJlIHN0cmluZy5cbiAqXG4gKiBCeSBkZWZhdWx0LCBzdG9yZXMgZGF0YSBibG9ja3MgaW4gYGNodW5rc1tdYCBwcm9wZXJ0eSBhbmQgZ2x1ZVxuICogdGhvc2UgaW4gYG9uRW5kYC4gT3ZlcnJpZGUgdGhpcyBoYW5kbGVyLCBpZiB5b3UgbmVlZCBhbm90aGVyIGJlaGF2aW91ci5cbiAqKi9cbkRlZmxhdGUucHJvdG90eXBlLm9uRGF0YSA9IGZ1bmN0aW9uIChjaHVuaykge1xuICB0aGlzLmNodW5rcy5wdXNoKGNodW5rKTtcbn07XG5cblxuLyoqXG4gKiBEZWZsYXRlI29uRW5kKHN0YXR1cykgLT4gVm9pZFxuICogLSBzdGF0dXMgKE51bWJlcik6IGRlZmxhdGUgc3RhdHVzLiAwIChaX09LKSBvbiBzdWNjZXNzLFxuICogICBvdGhlciBpZiBub3QuXG4gKlxuICogQ2FsbGVkIG9uY2UgYWZ0ZXIgeW91IHRlbGwgZGVmbGF0ZSB0aGF0IHRoZSBpbnB1dCBzdHJlYW0gaXNcbiAqIGNvbXBsZXRlIChaX0ZJTklTSCkgb3Igc2hvdWxkIGJlIGZsdXNoZWQgKFpfU1lOQ19GTFVTSClcbiAqIG9yIGlmIGFuIGVycm9yIGhhcHBlbmVkLiBCeSBkZWZhdWx0IC0gam9pbiBjb2xsZWN0ZWQgY2h1bmtzLFxuICogZnJlZSBtZW1vcnkgYW5kIGZpbGwgYHJlc3VsdHNgIC8gYGVycmAgcHJvcGVydGllcy5cbiAqKi9cbkRlZmxhdGUucHJvdG90eXBlLm9uRW5kID0gZnVuY3Rpb24gKHN0YXR1cykge1xuICAvLyBPbiBzdWNjZXNzIC0gam9pblxuICBpZiAoc3RhdHVzID09PSBaX09LKSB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy50byA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRoaXMucmVzdWx0ID0gdGhpcy5jaHVua3Muam9pbignJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmVzdWx0ID0gdXRpbHMuZmxhdHRlbkNodW5rcyh0aGlzLmNodW5rcyk7XG4gICAgfVxuICB9XG4gIHRoaXMuY2h1bmtzID0gW107XG4gIHRoaXMuZXJyID0gc3RhdHVzO1xuICB0aGlzLm1zZyA9IHRoaXMuc3RybS5tc2c7XG59O1xuXG5cbi8qKlxuICogZGVmbGF0ZShkYXRhWywgb3B0aW9uc10pIC0+IFVpbnQ4QXJyYXl8QXJyYXl8U3RyaW5nXG4gKiAtIGRhdGEgKFVpbnQ4QXJyYXl8QXJyYXl8U3RyaW5nKTogaW5wdXQgZGF0YSB0byBjb21wcmVzcy5cbiAqIC0gb3B0aW9ucyAoT2JqZWN0KTogemxpYiBkZWZsYXRlIG9wdGlvbnMuXG4gKlxuICogQ29tcHJlc3MgYGRhdGFgIHdpdGggZGVmbGF0ZSBhbGdvcml0aG0gYW5kIGBvcHRpb25zYC5cbiAqXG4gKiBTdXBwb3J0ZWQgb3B0aW9ucyBhcmU6XG4gKlxuICogLSBsZXZlbFxuICogLSB3aW5kb3dCaXRzXG4gKiAtIG1lbUxldmVsXG4gKiAtIHN0cmF0ZWd5XG4gKiAtIGRpY3Rpb25hcnlcbiAqXG4gKiBbaHR0cDovL3psaWIubmV0L21hbnVhbC5odG1sI0FkdmFuY2VkXShodHRwOi8vemxpYi5uZXQvbWFudWFsLmh0bWwjQWR2YW5jZWQpXG4gKiBmb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiB0aGVzZS5cbiAqXG4gKiBTdWdhciAob3B0aW9ucyk6XG4gKlxuICogLSBgcmF3YCAoQm9vbGVhbikgLSBzYXkgdGhhdCB3ZSB3b3JrIHdpdGggcmF3IHN0cmVhbSwgaWYgeW91IGRvbid0IHdpc2ggdG8gc3BlY2lmeVxuICogICBuZWdhdGl2ZSB3aW5kb3dCaXRzIGltcGxpY2l0bHkuXG4gKiAtIGB0b2AgKFN0cmluZykgLSBpZiBlcXVhbCB0byAnc3RyaW5nJywgdGhlbiByZXN1bHQgd2lsbCBiZSBcImJpbmFyeSBzdHJpbmdcIlxuICogICAgKGVhY2ggY2hhciBjb2RlIFswLi4yNTVdKVxuICpcbiAqICMjIyMjIEV4YW1wbGU6XG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogdmFyIHBha28gPSByZXF1aXJlKCdwYWtvJylcbiAqICAgLCBkYXRhID0gVWludDhBcnJheShbMSwyLDMsNCw1LDYsNyw4LDldKTtcbiAqXG4gKiBjb25zb2xlLmxvZyhwYWtvLmRlZmxhdGUoZGF0YSkpO1xuICogYGBgXG4gKiovXG5mdW5jdGlvbiBkZWZsYXRlKGlucHV0LCBvcHRpb25zKSB7XG4gIHZhciBkZWZsYXRvciA9IG5ldyBEZWZsYXRlKG9wdGlvbnMpO1xuXG4gIGRlZmxhdG9yLnB1c2goaW5wdXQsIHRydWUpO1xuXG4gIC8vIFRoYXQgd2lsbCBuZXZlciBoYXBwZW5zLCBpZiB5b3UgZG9uJ3QgY2hlYXQgd2l0aCBvcHRpb25zIDopXG4gIGlmIChkZWZsYXRvci5lcnIpIHsgdGhyb3cgZGVmbGF0b3IubXNnIHx8IG1zZ1tkZWZsYXRvci5lcnJdOyB9XG5cbiAgcmV0dXJuIGRlZmxhdG9yLnJlc3VsdDtcbn1cblxuXG4vKipcbiAqIGRlZmxhdGVSYXcoZGF0YVssIG9wdGlvbnNdKSAtPiBVaW50OEFycmF5fEFycmF5fFN0cmluZ1xuICogLSBkYXRhIChVaW50OEFycmF5fEFycmF5fFN0cmluZyk6IGlucHV0IGRhdGEgdG8gY29tcHJlc3MuXG4gKiAtIG9wdGlvbnMgKE9iamVjdCk6IHpsaWIgZGVmbGF0ZSBvcHRpb25zLlxuICpcbiAqIFRoZSBzYW1lIGFzIFtbZGVmbGF0ZV1dLCBidXQgY3JlYXRlcyByYXcgZGF0YSwgd2l0aG91dCB3cmFwcGVyXG4gKiAoaGVhZGVyIGFuZCBhZGxlcjMyIGNyYykuXG4gKiovXG5mdW5jdGlvbiBkZWZsYXRlUmF3KGlucHV0LCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBvcHRpb25zLnJhdyA9IHRydWU7XG4gIHJldHVybiBkZWZsYXRlKGlucHV0LCBvcHRpb25zKTtcbn1cblxuXG4vKipcbiAqIGd6aXAoZGF0YVssIG9wdGlvbnNdKSAtPiBVaW50OEFycmF5fEFycmF5fFN0cmluZ1xuICogLSBkYXRhIChVaW50OEFycmF5fEFycmF5fFN0cmluZyk6IGlucHV0IGRhdGEgdG8gY29tcHJlc3MuXG4gKiAtIG9wdGlvbnMgKE9iamVjdCk6IHpsaWIgZGVmbGF0ZSBvcHRpb25zLlxuICpcbiAqIFRoZSBzYW1lIGFzIFtbZGVmbGF0ZV1dLCBidXQgY3JlYXRlIGd6aXAgd3JhcHBlciBpbnN0ZWFkIG9mXG4gKiBkZWZsYXRlIG9uZS5cbiAqKi9cbmZ1bmN0aW9uIGd6aXAoaW5wdXQsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIG9wdGlvbnMuZ3ppcCA9IHRydWU7XG4gIHJldHVybiBkZWZsYXRlKGlucHV0LCBvcHRpb25zKTtcbn1cblxuXG5leHBvcnRzLkRlZmxhdGUgPSBEZWZsYXRlO1xuZXhwb3J0cy5kZWZsYXRlID0gZGVmbGF0ZTtcbmV4cG9ydHMuZGVmbGF0ZVJhdyA9IGRlZmxhdGVSYXc7XG5leHBvcnRzLmd6aXAgPSBnemlwO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciB6bGliX2luZmxhdGUgPSByZXF1aXJlKCcuL3psaWIvaW5mbGF0ZScpO1xudmFyIHV0aWxzICAgICAgICA9IHJlcXVpcmUoJy4vdXRpbHMvY29tbW9uJyk7XG52YXIgc3RyaW5ncyAgICAgID0gcmVxdWlyZSgnLi91dGlscy9zdHJpbmdzJyk7XG52YXIgYyAgICAgICAgICAgID0gcmVxdWlyZSgnLi96bGliL2NvbnN0YW50cycpO1xudmFyIG1zZyAgICAgICAgICA9IHJlcXVpcmUoJy4vemxpYi9tZXNzYWdlcycpO1xudmFyIFpTdHJlYW0gICAgICA9IHJlcXVpcmUoJy4vemxpYi96c3RyZWFtJyk7XG52YXIgR1poZWFkZXIgICAgID0gcmVxdWlyZSgnLi96bGliL2d6aGVhZGVyJyk7XG5cbnZhciB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbi8qKlxuICogY2xhc3MgSW5mbGF0ZVxuICpcbiAqIEdlbmVyaWMgSlMtc3R5bGUgd3JhcHBlciBmb3IgemxpYiBjYWxscy4gSWYgeW91IGRvbid0IG5lZWRcbiAqIHN0cmVhbWluZyBiZWhhdmlvdXIgLSB1c2UgbW9yZSBzaW1wbGUgZnVuY3Rpb25zOiBbW2luZmxhdGVdXVxuICogYW5kIFtbaW5mbGF0ZVJhd11dLlxuICoqL1xuXG4vKiBpbnRlcm5hbFxuICogaW5mbGF0ZS5jaHVua3MgLT4gQXJyYXlcbiAqXG4gKiBDaHVua3Mgb2Ygb3V0cHV0IGRhdGEsIGlmIFtbSW5mbGF0ZSNvbkRhdGFdXSBub3Qgb3ZlcnJpZGRlbi5cbiAqKi9cblxuLyoqXG4gKiBJbmZsYXRlLnJlc3VsdCAtPiBVaW50OEFycmF5fEFycmF5fFN0cmluZ1xuICpcbiAqIFVuY29tcHJlc3NlZCByZXN1bHQsIGdlbmVyYXRlZCBieSBkZWZhdWx0IFtbSW5mbGF0ZSNvbkRhdGFdXVxuICogYW5kIFtbSW5mbGF0ZSNvbkVuZF1dIGhhbmRsZXJzLiBGaWxsZWQgYWZ0ZXIgeW91IHB1c2ggbGFzdCBjaHVua1xuICogKGNhbGwgW1tJbmZsYXRlI3B1c2hdXSB3aXRoIGBaX0ZJTklTSGAgLyBgdHJ1ZWAgcGFyYW0pIG9yIGlmIHlvdVxuICogcHVzaCBhIGNodW5rIHdpdGggZXhwbGljaXQgZmx1c2ggKGNhbGwgW1tJbmZsYXRlI3B1c2hdXSB3aXRoXG4gKiBgWl9TWU5DX0ZMVVNIYCBwYXJhbSkuXG4gKiovXG5cbi8qKlxuICogSW5mbGF0ZS5lcnIgLT4gTnVtYmVyXG4gKlxuICogRXJyb3IgY29kZSBhZnRlciBpbmZsYXRlIGZpbmlzaGVkLiAwIChaX09LKSBvbiBzdWNjZXNzLlxuICogU2hvdWxkIGJlIGNoZWNrZWQgaWYgYnJva2VuIGRhdGEgcG9zc2libGUuXG4gKiovXG5cbi8qKlxuICogSW5mbGF0ZS5tc2cgLT4gU3RyaW5nXG4gKlxuICogRXJyb3IgbWVzc2FnZSwgaWYgW1tJbmZsYXRlLmVycl1dICE9IDBcbiAqKi9cblxuXG4vKipcbiAqIG5ldyBJbmZsYXRlKG9wdGlvbnMpXG4gKiAtIG9wdGlvbnMgKE9iamVjdCk6IHpsaWIgaW5mbGF0ZSBvcHRpb25zLlxuICpcbiAqIENyZWF0ZXMgbmV3IGluZmxhdG9yIGluc3RhbmNlIHdpdGggc3BlY2lmaWVkIHBhcmFtcy4gVGhyb3dzIGV4Y2VwdGlvblxuICogb24gYmFkIHBhcmFtcy4gU3VwcG9ydGVkIG9wdGlvbnM6XG4gKlxuICogLSBgd2luZG93Qml0c2BcbiAqIC0gYGRpY3Rpb25hcnlgXG4gKlxuICogW2h0dHA6Ly96bGliLm5ldC9tYW51YWwuaHRtbCNBZHZhbmNlZF0oaHR0cDovL3psaWIubmV0L21hbnVhbC5odG1sI0FkdmFuY2VkKVxuICogZm9yIG1vcmUgaW5mb3JtYXRpb24gb24gdGhlc2UuXG4gKlxuICogQWRkaXRpb25hbCBvcHRpb25zLCBmb3IgaW50ZXJuYWwgbmVlZHM6XG4gKlxuICogLSBgY2h1bmtTaXplYCAtIHNpemUgb2YgZ2VuZXJhdGVkIGRhdGEgY2h1bmtzICgxNksgYnkgZGVmYXVsdClcbiAqIC0gYHJhd2AgKEJvb2xlYW4pIC0gZG8gcmF3IGluZmxhdGVcbiAqIC0gYHRvYCAoU3RyaW5nKSAtIGlmIGVxdWFsIHRvICdzdHJpbmcnLCB0aGVuIHJlc3VsdCB3aWxsIGJlIGNvbnZlcnRlZFxuICogICBmcm9tIHV0ZjggdG8gdXRmMTYgKGphdmFzY3JpcHQpIHN0cmluZy4gV2hlbiBzdHJpbmcgb3V0cHV0IHJlcXVlc3RlZCxcbiAqICAgY2h1bmsgbGVuZ3RoIGNhbiBkaWZmZXIgZnJvbSBgY2h1bmtTaXplYCwgZGVwZW5kaW5nIG9uIGNvbnRlbnQuXG4gKlxuICogQnkgZGVmYXVsdCwgd2hlbiBubyBvcHRpb25zIHNldCwgYXV0b2RldGVjdCBkZWZsYXRlL2d6aXAgZGF0YSBmb3JtYXQgdmlhXG4gKiB3cmFwcGVyIGhlYWRlci5cbiAqXG4gKiAjIyMjIyBFeGFtcGxlOlxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIHZhciBwYWtvID0gcmVxdWlyZSgncGFrbycpXG4gKiAgICwgY2h1bmsxID0gVWludDhBcnJheShbMSwyLDMsNCw1LDYsNyw4LDldKVxuICogICAsIGNodW5rMiA9IFVpbnQ4QXJyYXkoWzEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5XSk7XG4gKlxuICogdmFyIGluZmxhdGUgPSBuZXcgcGFrby5JbmZsYXRlKHsgbGV2ZWw6IDN9KTtcbiAqXG4gKiBpbmZsYXRlLnB1c2goY2h1bmsxLCBmYWxzZSk7XG4gKiBpbmZsYXRlLnB1c2goY2h1bmsyLCB0cnVlKTsgIC8vIHRydWUgLT4gbGFzdCBjaHVua1xuICpcbiAqIGlmIChpbmZsYXRlLmVycikgeyB0aHJvdyBuZXcgRXJyb3IoaW5mbGF0ZS5lcnIpOyB9XG4gKlxuICogY29uc29sZS5sb2coaW5mbGF0ZS5yZXN1bHQpO1xuICogYGBgXG4gKiovXG5mdW5jdGlvbiBJbmZsYXRlKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEluZmxhdGUpKSByZXR1cm4gbmV3IEluZmxhdGUob3B0aW9ucyk7XG5cbiAgdGhpcy5vcHRpb25zID0gdXRpbHMuYXNzaWduKHtcbiAgICBjaHVua1NpemU6IDE2Mzg0LFxuICAgIHdpbmRvd0JpdHM6IDAsXG4gICAgdG86ICcnXG4gIH0sIG9wdGlvbnMgfHwge30pO1xuXG4gIHZhciBvcHQgPSB0aGlzLm9wdGlvbnM7XG5cbiAgLy8gRm9yY2Ugd2luZG93IHNpemUgZm9yIGByYXdgIGRhdGEsIGlmIG5vdCBzZXQgZGlyZWN0bHksXG4gIC8vIGJlY2F1c2Ugd2UgaGF2ZSBubyBoZWFkZXIgZm9yIGF1dG9kZXRlY3QuXG4gIGlmIChvcHQucmF3ICYmIChvcHQud2luZG93Qml0cyA+PSAwKSAmJiAob3B0LndpbmRvd0JpdHMgPCAxNikpIHtcbiAgICBvcHQud2luZG93Qml0cyA9IC1vcHQud2luZG93Qml0cztcbiAgICBpZiAob3B0LndpbmRvd0JpdHMgPT09IDApIHsgb3B0LndpbmRvd0JpdHMgPSAtMTU7IH1cbiAgfVxuXG4gIC8vIElmIGB3aW5kb3dCaXRzYCBub3QgZGVmaW5lZCAoYW5kIG1vZGUgbm90IHJhdykgLSBzZXQgYXV0b2RldGVjdCBmbGFnIGZvciBnemlwL2RlZmxhdGVcbiAgaWYgKChvcHQud2luZG93Qml0cyA+PSAwKSAmJiAob3B0LndpbmRvd0JpdHMgPCAxNikgJiZcbiAgICAgICEob3B0aW9ucyAmJiBvcHRpb25zLndpbmRvd0JpdHMpKSB7XG4gICAgb3B0LndpbmRvd0JpdHMgKz0gMzI7XG4gIH1cblxuICAvLyBHemlwIGhlYWRlciBoYXMgbm8gaW5mbyBhYm91dCB3aW5kb3dzIHNpemUsIHdlIGNhbiBkbyBhdXRvZGV0ZWN0IG9ubHlcbiAgLy8gZm9yIGRlZmxhdGUuIFNvLCBpZiB3aW5kb3cgc2l6ZSBub3Qgc2V0LCBmb3JjZSBpdCB0byBtYXggd2hlbiBnemlwIHBvc3NpYmxlXG4gIGlmICgob3B0LndpbmRvd0JpdHMgPiAxNSkgJiYgKG9wdC53aW5kb3dCaXRzIDwgNDgpKSB7XG4gICAgLy8gYml0IDMgKDE2KSAtPiBnemlwcGVkIGRhdGFcbiAgICAvLyBiaXQgNCAoMzIpIC0+IGF1dG9kZXRlY3QgZ3ppcC9kZWZsYXRlXG4gICAgaWYgKChvcHQud2luZG93Qml0cyAmIDE1KSA9PT0gMCkge1xuICAgICAgb3B0LndpbmRvd0JpdHMgfD0gMTU7XG4gICAgfVxuICB9XG5cbiAgdGhpcy5lcnIgICAgPSAwOyAgICAgIC8vIGVycm9yIGNvZGUsIGlmIGhhcHBlbnMgKDAgPSBaX09LKVxuICB0aGlzLm1zZyAgICA9ICcnOyAgICAgLy8gZXJyb3IgbWVzc2FnZVxuICB0aGlzLmVuZGVkICA9IGZhbHNlOyAgLy8gdXNlZCB0byBhdm9pZCBtdWx0aXBsZSBvbkVuZCgpIGNhbGxzXG4gIHRoaXMuY2h1bmtzID0gW107ICAgICAvLyBjaHVua3Mgb2YgY29tcHJlc3NlZCBkYXRhXG5cbiAgdGhpcy5zdHJtICAgPSBuZXcgWlN0cmVhbSgpO1xuICB0aGlzLnN0cm0uYXZhaWxfb3V0ID0gMDtcblxuICB2YXIgc3RhdHVzICA9IHpsaWJfaW5mbGF0ZS5pbmZsYXRlSW5pdDIoXG4gICAgdGhpcy5zdHJtLFxuICAgIG9wdC53aW5kb3dCaXRzXG4gICk7XG5cbiAgaWYgKHN0YXR1cyAhPT0gYy5aX09LKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZ1tzdGF0dXNdKTtcbiAgfVxuXG4gIHRoaXMuaGVhZGVyID0gbmV3IEdaaGVhZGVyKCk7XG5cbiAgemxpYl9pbmZsYXRlLmluZmxhdGVHZXRIZWFkZXIodGhpcy5zdHJtLCB0aGlzLmhlYWRlcik7XG59XG5cbi8qKlxuICogSW5mbGF0ZSNwdXNoKGRhdGFbLCBtb2RlXSkgLT4gQm9vbGVhblxuICogLSBkYXRhIChVaW50OEFycmF5fEFycmF5fEFycmF5QnVmZmVyfFN0cmluZyk6IGlucHV0IGRhdGFcbiAqIC0gbW9kZSAoTnVtYmVyfEJvb2xlYW4pOiAwLi42IGZvciBjb3JyZXNwb25kaW5nIFpfTk9fRkxVU0guLlpfVFJFRSBtb2Rlcy5cbiAqICAgU2VlIGNvbnN0YW50cy4gU2tpcHBlZCBvciBgZmFsc2VgIG1lYW5zIFpfTk9fRkxVU0gsIGB0cnVlYCBtZWFucyBaX0ZJTklTSC5cbiAqXG4gKiBTZW5kcyBpbnB1dCBkYXRhIHRvIGluZmxhdGUgcGlwZSwgZ2VuZXJhdGluZyBbW0luZmxhdGUjb25EYXRhXV0gY2FsbHMgd2l0aFxuICogbmV3IG91dHB1dCBjaHVua3MuIFJldHVybnMgYHRydWVgIG9uIHN1Y2Nlc3MuIFRoZSBsYXN0IGRhdGEgYmxvY2sgbXVzdCBoYXZlXG4gKiBtb2RlIFpfRklOSVNIIChvciBgdHJ1ZWApLiBUaGF0IHdpbGwgZmx1c2ggaW50ZXJuYWwgcGVuZGluZyBidWZmZXJzIGFuZCBjYWxsXG4gKiBbW0luZmxhdGUjb25FbmRdXS4gRm9yIGludGVyaW0gZXhwbGljaXQgZmx1c2hlcyAod2l0aG91dCBlbmRpbmcgdGhlIHN0cmVhbSkgeW91XG4gKiBjYW4gdXNlIG1vZGUgWl9TWU5DX0ZMVVNILCBrZWVwaW5nIHRoZSBkZWNvbXByZXNzaW9uIGNvbnRleHQuXG4gKlxuICogT24gZmFpbCBjYWxsIFtbSW5mbGF0ZSNvbkVuZF1dIHdpdGggZXJyb3IgY29kZSBhbmQgcmV0dXJuIGZhbHNlLlxuICpcbiAqIFdlIHN0cm9uZ2x5IHJlY29tbWVuZCB0byB1c2UgYFVpbnQ4QXJyYXlgIG9uIGlucHV0IGZvciBiZXN0IHNwZWVkIChvdXRwdXRcbiAqIGZvcm1hdCBpcyBkZXRlY3RlZCBhdXRvbWF0aWNhbGx5KS4gQWxzbywgZG9uJ3Qgc2tpcCBsYXN0IHBhcmFtIGFuZCBhbHdheXNcbiAqIHVzZSB0aGUgc2FtZSB0eXBlIGluIHlvdXIgY29kZSAoYm9vbGVhbiBvciBudW1iZXIpLiBUaGF0IHdpbGwgaW1wcm92ZSBKUyBzcGVlZC5cbiAqXG4gKiBGb3IgcmVndWxhciBgQXJyYXlgLXMgbWFrZSBzdXJlIGFsbCBlbGVtZW50cyBhcmUgWzAuLjI1NV0uXG4gKlxuICogIyMjIyMgRXhhbXBsZVxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIHB1c2goY2h1bmssIGZhbHNlKTsgLy8gcHVzaCBvbmUgb2YgZGF0YSBjaHVua3NcbiAqIC4uLlxuICogcHVzaChjaHVuaywgdHJ1ZSk7ICAvLyBwdXNoIGxhc3QgY2h1bmtcbiAqIGBgYFxuICoqL1xuSW5mbGF0ZS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIChkYXRhLCBtb2RlKSB7XG4gIHZhciBzdHJtID0gdGhpcy5zdHJtO1xuICB2YXIgY2h1bmtTaXplID0gdGhpcy5vcHRpb25zLmNodW5rU2l6ZTtcbiAgdmFyIGRpY3Rpb25hcnkgPSB0aGlzLm9wdGlvbnMuZGljdGlvbmFyeTtcbiAgdmFyIHN0YXR1cywgX21vZGU7XG4gIHZhciBuZXh0X291dF91dGY4LCB0YWlsLCB1dGY4c3RyO1xuICB2YXIgZGljdDtcblxuICAvLyBGbGFnIHRvIHByb3Blcmx5IHByb2Nlc3MgWl9CVUZfRVJST1Igb24gdGVzdGluZyBpbmZsYXRlIGNhbGxcbiAgLy8gd2hlbiB3ZSBjaGVjayB0aGF0IGFsbCBvdXRwdXQgZGF0YSB3YXMgZmx1c2hlZC5cbiAgdmFyIGFsbG93QnVmRXJyb3IgPSBmYWxzZTtcblxuICBpZiAodGhpcy5lbmRlZCkgeyByZXR1cm4gZmFsc2U7IH1cbiAgX21vZGUgPSAobW9kZSA9PT0gfn5tb2RlKSA/IG1vZGUgOiAoKG1vZGUgPT09IHRydWUpID8gYy5aX0ZJTklTSCA6IGMuWl9OT19GTFVTSCk7XG5cbiAgLy8gQ29udmVydCBkYXRhIGlmIG5lZWRlZFxuICBpZiAodHlwZW9mIGRhdGEgPT09ICdzdHJpbmcnKSB7XG4gICAgLy8gT25seSBiaW5hcnkgc3RyaW5ncyBjYW4gYmUgZGVjb21wcmVzc2VkIG9uIHByYWN0aWNlXG4gICAgc3RybS5pbnB1dCA9IHN0cmluZ3MuYmluc3RyaW5nMmJ1ZihkYXRhKTtcbiAgfSBlbHNlIGlmICh0b1N0cmluZy5jYWxsKGRhdGEpID09PSAnW29iamVjdCBBcnJheUJ1ZmZlcl0nKSB7XG4gICAgc3RybS5pbnB1dCA9IG5ldyBVaW50OEFycmF5KGRhdGEpO1xuICB9IGVsc2Uge1xuICAgIHN0cm0uaW5wdXQgPSBkYXRhO1xuICB9XG5cbiAgc3RybS5uZXh0X2luID0gMDtcbiAgc3RybS5hdmFpbF9pbiA9IHN0cm0uaW5wdXQubGVuZ3RoO1xuXG4gIGRvIHtcbiAgICBpZiAoc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIHN0cm0ub3V0cHV0ID0gbmV3IHV0aWxzLkJ1ZjgoY2h1bmtTaXplKTtcbiAgICAgIHN0cm0ubmV4dF9vdXQgPSAwO1xuICAgICAgc3RybS5hdmFpbF9vdXQgPSBjaHVua1NpemU7XG4gICAgfVxuXG4gICAgc3RhdHVzID0gemxpYl9pbmZsYXRlLmluZmxhdGUoc3RybSwgYy5aX05PX0ZMVVNIKTsgICAgLyogbm8gYmFkIHJldHVybiB2YWx1ZSAqL1xuXG4gICAgaWYgKHN0YXR1cyA9PT0gYy5aX05FRURfRElDVCAmJiBkaWN0aW9uYXJ5KSB7XG4gICAgICAvLyBDb252ZXJ0IGRhdGEgaWYgbmVlZGVkXG4gICAgICBpZiAodHlwZW9mIGRpY3Rpb25hcnkgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGRpY3QgPSBzdHJpbmdzLnN0cmluZzJidWYoZGljdGlvbmFyeSk7XG4gICAgICB9IGVsc2UgaWYgKHRvU3RyaW5nLmNhbGwoZGljdGlvbmFyeSkgPT09ICdbb2JqZWN0IEFycmF5QnVmZmVyXScpIHtcbiAgICAgICAgZGljdCA9IG5ldyBVaW50OEFycmF5KGRpY3Rpb25hcnkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGljdCA9IGRpY3Rpb25hcnk7XG4gICAgICB9XG5cbiAgICAgIHN0YXR1cyA9IHpsaWJfaW5mbGF0ZS5pbmZsYXRlU2V0RGljdGlvbmFyeSh0aGlzLnN0cm0sIGRpY3QpO1xuXG4gICAgfVxuXG4gICAgaWYgKHN0YXR1cyA9PT0gYy5aX0JVRl9FUlJPUiAmJiBhbGxvd0J1ZkVycm9yID09PSB0cnVlKSB7XG4gICAgICBzdGF0dXMgPSBjLlpfT0s7XG4gICAgICBhbGxvd0J1ZkVycm9yID0gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKHN0YXR1cyAhPT0gYy5aX1NUUkVBTV9FTkQgJiYgc3RhdHVzICE9PSBjLlpfT0spIHtcbiAgICAgIHRoaXMub25FbmQoc3RhdHVzKTtcbiAgICAgIHRoaXMuZW5kZWQgPSB0cnVlO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChzdHJtLm5leHRfb3V0KSB7XG4gICAgICBpZiAoc3RybS5hdmFpbF9vdXQgPT09IDAgfHwgc3RhdHVzID09PSBjLlpfU1RSRUFNX0VORCB8fCAoc3RybS5hdmFpbF9pbiA9PT0gMCAmJiAoX21vZGUgPT09IGMuWl9GSU5JU0ggfHwgX21vZGUgPT09IGMuWl9TWU5DX0ZMVVNIKSkpIHtcblxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnRvID09PSAnc3RyaW5nJykge1xuXG4gICAgICAgICAgbmV4dF9vdXRfdXRmOCA9IHN0cmluZ3MudXRmOGJvcmRlcihzdHJtLm91dHB1dCwgc3RybS5uZXh0X291dCk7XG5cbiAgICAgICAgICB0YWlsID0gc3RybS5uZXh0X291dCAtIG5leHRfb3V0X3V0Zjg7XG4gICAgICAgICAgdXRmOHN0ciA9IHN0cmluZ3MuYnVmMnN0cmluZyhzdHJtLm91dHB1dCwgbmV4dF9vdXRfdXRmOCk7XG5cbiAgICAgICAgICAvLyBtb3ZlIHRhaWxcbiAgICAgICAgICBzdHJtLm5leHRfb3V0ID0gdGFpbDtcbiAgICAgICAgICBzdHJtLmF2YWlsX291dCA9IGNodW5rU2l6ZSAtIHRhaWw7XG4gICAgICAgICAgaWYgKHRhaWwpIHsgdXRpbHMuYXJyYXlTZXQoc3RybS5vdXRwdXQsIHN0cm0ub3V0cHV0LCBuZXh0X291dF91dGY4LCB0YWlsLCAwKTsgfVxuXG4gICAgICAgICAgdGhpcy5vbkRhdGEodXRmOHN0cik7XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLm9uRGF0YSh1dGlscy5zaHJpbmtCdWYoc3RybS5vdXRwdXQsIHN0cm0ubmV4dF9vdXQpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFdoZW4gbm8gbW9yZSBpbnB1dCBkYXRhLCB3ZSBzaG91bGQgY2hlY2sgdGhhdCBpbnRlcm5hbCBpbmZsYXRlIGJ1ZmZlcnNcbiAgICAvLyBhcmUgZmx1c2hlZC4gVGhlIG9ubHkgd2F5IHRvIGRvIGl0IHdoZW4gYXZhaWxfb3V0ID0gMCAtIHJ1biBvbmUgbW9yZVxuICAgIC8vIGluZmxhdGUgcGFzcy4gQnV0IGlmIG91dHB1dCBkYXRhIG5vdCBleGlzdHMsIGluZmxhdGUgcmV0dXJuIFpfQlVGX0VSUk9SLlxuICAgIC8vIEhlcmUgd2Ugc2V0IGZsYWcgdG8gcHJvY2VzcyB0aGlzIGVycm9yIHByb3Blcmx5LlxuICAgIC8vXG4gICAgLy8gTk9URS4gRGVmbGF0ZSBkb2VzIG5vdCByZXR1cm4gZXJyb3IgaW4gdGhpcyBjYXNlIGFuZCBkb2VzIG5vdCBuZWVkcyBzdWNoXG4gICAgLy8gbG9naWMuXG4gICAgaWYgKHN0cm0uYXZhaWxfaW4gPT09IDAgJiYgc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIGFsbG93QnVmRXJyb3IgPSB0cnVlO1xuICAgIH1cblxuICB9IHdoaWxlICgoc3RybS5hdmFpbF9pbiA+IDAgfHwgc3RybS5hdmFpbF9vdXQgPT09IDApICYmIHN0YXR1cyAhPT0gYy5aX1NUUkVBTV9FTkQpO1xuXG4gIGlmIChzdGF0dXMgPT09IGMuWl9TVFJFQU1fRU5EKSB7XG4gICAgX21vZGUgPSBjLlpfRklOSVNIO1xuICB9XG5cbiAgLy8gRmluYWxpemUgb24gdGhlIGxhc3QgY2h1bmsuXG4gIGlmIChfbW9kZSA9PT0gYy5aX0ZJTklTSCkge1xuICAgIHN0YXR1cyA9IHpsaWJfaW5mbGF0ZS5pbmZsYXRlRW5kKHRoaXMuc3RybSk7XG4gICAgdGhpcy5vbkVuZChzdGF0dXMpO1xuICAgIHRoaXMuZW5kZWQgPSB0cnVlO1xuICAgIHJldHVybiBzdGF0dXMgPT09IGMuWl9PSztcbiAgfVxuXG4gIC8vIGNhbGxiYWNrIGludGVyaW0gcmVzdWx0cyBpZiBaX1NZTkNfRkxVU0guXG4gIGlmIChfbW9kZSA9PT0gYy5aX1NZTkNfRkxVU0gpIHtcbiAgICB0aGlzLm9uRW5kKGMuWl9PSyk7XG4gICAgc3RybS5hdmFpbF9vdXQgPSAwO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5cbi8qKlxuICogSW5mbGF0ZSNvbkRhdGEoY2h1bmspIC0+IFZvaWRcbiAqIC0gY2h1bmsgKFVpbnQ4QXJyYXl8QXJyYXl8U3RyaW5nKTogb3V0cHV0IGRhdGEuIFR5cGUgb2YgYXJyYXkgZGVwZW5kc1xuICogICBvbiBqcyBlbmdpbmUgc3VwcG9ydC4gV2hlbiBzdHJpbmcgb3V0cHV0IHJlcXVlc3RlZCwgZWFjaCBjaHVua1xuICogICB3aWxsIGJlIHN0cmluZy5cbiAqXG4gKiBCeSBkZWZhdWx0LCBzdG9yZXMgZGF0YSBibG9ja3MgaW4gYGNodW5rc1tdYCBwcm9wZXJ0eSBhbmQgZ2x1ZVxuICogdGhvc2UgaW4gYG9uRW5kYC4gT3ZlcnJpZGUgdGhpcyBoYW5kbGVyLCBpZiB5b3UgbmVlZCBhbm90aGVyIGJlaGF2aW91ci5cbiAqKi9cbkluZmxhdGUucHJvdG90eXBlLm9uRGF0YSA9IGZ1bmN0aW9uIChjaHVuaykge1xuICB0aGlzLmNodW5rcy5wdXNoKGNodW5rKTtcbn07XG5cblxuLyoqXG4gKiBJbmZsYXRlI29uRW5kKHN0YXR1cykgLT4gVm9pZFxuICogLSBzdGF0dXMgKE51bWJlcik6IGluZmxhdGUgc3RhdHVzLiAwIChaX09LKSBvbiBzdWNjZXNzLFxuICogICBvdGhlciBpZiBub3QuXG4gKlxuICogQ2FsbGVkIGVpdGhlciBhZnRlciB5b3UgdGVsbCBpbmZsYXRlIHRoYXQgdGhlIGlucHV0IHN0cmVhbSBpc1xuICogY29tcGxldGUgKFpfRklOSVNIKSBvciBzaG91bGQgYmUgZmx1c2hlZCAoWl9TWU5DX0ZMVVNIKVxuICogb3IgaWYgYW4gZXJyb3IgaGFwcGVuZWQuIEJ5IGRlZmF1bHQgLSBqb2luIGNvbGxlY3RlZCBjaHVua3MsXG4gKiBmcmVlIG1lbW9yeSBhbmQgZmlsbCBgcmVzdWx0c2AgLyBgZXJyYCBwcm9wZXJ0aWVzLlxuICoqL1xuSW5mbGF0ZS5wcm90b3R5cGUub25FbmQgPSBmdW5jdGlvbiAoc3RhdHVzKSB7XG4gIC8vIE9uIHN1Y2Nlc3MgLSBqb2luXG4gIGlmIChzdGF0dXMgPT09IGMuWl9PSykge1xuICAgIGlmICh0aGlzLm9wdGlvbnMudG8gPT09ICdzdHJpbmcnKSB7XG4gICAgICAvLyBHbHVlICYgY29udmVydCBoZXJlLCB1bnRpbCB3ZSB0ZWFjaCBwYWtvIHRvIHNlbmRcbiAgICAgIC8vIHV0ZjggYWxpZ25lZCBzdHJpbmdzIHRvIG9uRGF0YVxuICAgICAgdGhpcy5yZXN1bHQgPSB0aGlzLmNodW5rcy5qb2luKCcnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yZXN1bHQgPSB1dGlscy5mbGF0dGVuQ2h1bmtzKHRoaXMuY2h1bmtzKTtcbiAgICB9XG4gIH1cbiAgdGhpcy5jaHVua3MgPSBbXTtcbiAgdGhpcy5lcnIgPSBzdGF0dXM7XG4gIHRoaXMubXNnID0gdGhpcy5zdHJtLm1zZztcbn07XG5cblxuLyoqXG4gKiBpbmZsYXRlKGRhdGFbLCBvcHRpb25zXSkgLT4gVWludDhBcnJheXxBcnJheXxTdHJpbmdcbiAqIC0gZGF0YSAoVWludDhBcnJheXxBcnJheXxTdHJpbmcpOiBpbnB1dCBkYXRhIHRvIGRlY29tcHJlc3MuXG4gKiAtIG9wdGlvbnMgKE9iamVjdCk6IHpsaWIgaW5mbGF0ZSBvcHRpb25zLlxuICpcbiAqIERlY29tcHJlc3MgYGRhdGFgIHdpdGggaW5mbGF0ZS91bmd6aXAgYW5kIGBvcHRpb25zYC4gQXV0b2RldGVjdFxuICogZm9ybWF0IHZpYSB3cmFwcGVyIGhlYWRlciBieSBkZWZhdWx0LiBUaGF0J3Mgd2h5IHdlIGRvbid0IHByb3ZpZGVcbiAqIHNlcGFyYXRlIGB1bmd6aXBgIG1ldGhvZC5cbiAqXG4gKiBTdXBwb3J0ZWQgb3B0aW9ucyBhcmU6XG4gKlxuICogLSB3aW5kb3dCaXRzXG4gKlxuICogW2h0dHA6Ly96bGliLm5ldC9tYW51YWwuaHRtbCNBZHZhbmNlZF0oaHR0cDovL3psaWIubmV0L21hbnVhbC5odG1sI0FkdmFuY2VkKVxuICogZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gKlxuICogU3VnYXIgKG9wdGlvbnMpOlxuICpcbiAqIC0gYHJhd2AgKEJvb2xlYW4pIC0gc2F5IHRoYXQgd2Ugd29yayB3aXRoIHJhdyBzdHJlYW0sIGlmIHlvdSBkb24ndCB3aXNoIHRvIHNwZWNpZnlcbiAqICAgbmVnYXRpdmUgd2luZG93Qml0cyBpbXBsaWNpdGx5LlxuICogLSBgdG9gIChTdHJpbmcpIC0gaWYgZXF1YWwgdG8gJ3N0cmluZycsIHRoZW4gcmVzdWx0IHdpbGwgYmUgY29udmVydGVkXG4gKiAgIGZyb20gdXRmOCB0byB1dGYxNiAoamF2YXNjcmlwdCkgc3RyaW5nLiBXaGVuIHN0cmluZyBvdXRwdXQgcmVxdWVzdGVkLFxuICogICBjaHVuayBsZW5ndGggY2FuIGRpZmZlciBmcm9tIGBjaHVua1NpemVgLCBkZXBlbmRpbmcgb24gY29udGVudC5cbiAqXG4gKlxuICogIyMjIyMgRXhhbXBsZTpcbiAqXG4gKiBgYGBqYXZhc2NyaXB0XG4gKiB2YXIgcGFrbyA9IHJlcXVpcmUoJ3Bha28nKVxuICogICAsIGlucHV0ID0gcGFrby5kZWZsYXRlKFsxLDIsMyw0LDUsNiw3LDgsOV0pXG4gKiAgICwgb3V0cHV0O1xuICpcbiAqIHRyeSB7XG4gKiAgIG91dHB1dCA9IHBha28uaW5mbGF0ZShpbnB1dCk7XG4gKiB9IGNhdGNoIChlcnIpXG4gKiAgIGNvbnNvbGUubG9nKGVycik7XG4gKiB9XG4gKiBgYGBcbiAqKi9cbmZ1bmN0aW9uIGluZmxhdGUoaW5wdXQsIG9wdGlvbnMpIHtcbiAgdmFyIGluZmxhdG9yID0gbmV3IEluZmxhdGUob3B0aW9ucyk7XG5cbiAgaW5mbGF0b3IucHVzaChpbnB1dCwgdHJ1ZSk7XG5cbiAgLy8gVGhhdCB3aWxsIG5ldmVyIGhhcHBlbnMsIGlmIHlvdSBkb24ndCBjaGVhdCB3aXRoIG9wdGlvbnMgOilcbiAgaWYgKGluZmxhdG9yLmVycikgeyB0aHJvdyBpbmZsYXRvci5tc2cgfHwgbXNnW2luZmxhdG9yLmVycl07IH1cblxuICByZXR1cm4gaW5mbGF0b3IucmVzdWx0O1xufVxuXG5cbi8qKlxuICogaW5mbGF0ZVJhdyhkYXRhWywgb3B0aW9uc10pIC0+IFVpbnQ4QXJyYXl8QXJyYXl8U3RyaW5nXG4gKiAtIGRhdGEgKFVpbnQ4QXJyYXl8QXJyYXl8U3RyaW5nKTogaW5wdXQgZGF0YSB0byBkZWNvbXByZXNzLlxuICogLSBvcHRpb25zIChPYmplY3QpOiB6bGliIGluZmxhdGUgb3B0aW9ucy5cbiAqXG4gKiBUaGUgc2FtZSBhcyBbW2luZmxhdGVdXSwgYnV0IGNyZWF0ZXMgcmF3IGRhdGEsIHdpdGhvdXQgd3JhcHBlclxuICogKGhlYWRlciBhbmQgYWRsZXIzMiBjcmMpLlxuICoqL1xuZnVuY3Rpb24gaW5mbGF0ZVJhdyhpbnB1dCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgb3B0aW9ucy5yYXcgPSB0cnVlO1xuICByZXR1cm4gaW5mbGF0ZShpbnB1dCwgb3B0aW9ucyk7XG59XG5cblxuLyoqXG4gKiB1bmd6aXAoZGF0YVssIG9wdGlvbnNdKSAtPiBVaW50OEFycmF5fEFycmF5fFN0cmluZ1xuICogLSBkYXRhIChVaW50OEFycmF5fEFycmF5fFN0cmluZyk6IGlucHV0IGRhdGEgdG8gZGVjb21wcmVzcy5cbiAqIC0gb3B0aW9ucyAoT2JqZWN0KTogemxpYiBpbmZsYXRlIG9wdGlvbnMuXG4gKlxuICogSnVzdCBzaG9ydGN1dCB0byBbW2luZmxhdGVdXSwgYmVjYXVzZSBpdCBhdXRvZGV0ZWN0cyBmb3JtYXRcbiAqIGJ5IGhlYWRlci5jb250ZW50LiBEb25lIGZvciBjb252ZW5pZW5jZS5cbiAqKi9cblxuXG5leHBvcnRzLkluZmxhdGUgPSBJbmZsYXRlO1xuZXhwb3J0cy5pbmZsYXRlID0gaW5mbGF0ZTtcbmV4cG9ydHMuaW5mbGF0ZVJhdyA9IGluZmxhdGVSYXc7XG5leHBvcnRzLnVuZ3ppcCAgPSBpbmZsYXRlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciBUWVBFRF9PSyA9ICAodHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnKSAmJlxuICAgICAgICAgICAgICAgICh0eXBlb2YgVWludDE2QXJyYXkgIT09ICd1bmRlZmluZWQnKSAmJlxuICAgICAgICAgICAgICAgICh0eXBlb2YgSW50MzJBcnJheSAhPT0gJ3VuZGVmaW5lZCcpO1xuXG5mdW5jdGlvbiBfaGFzKG9iaiwga2V5KSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpO1xufVxuXG5leHBvcnRzLmFzc2lnbiA9IGZ1bmN0aW9uIChvYmogLypmcm9tMSwgZnJvbTIsIGZyb20zLCAuLi4qLykge1xuICB2YXIgc291cmNlcyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gIHdoaWxlIChzb3VyY2VzLmxlbmd0aCkge1xuICAgIHZhciBzb3VyY2UgPSBzb3VyY2VzLnNoaWZ0KCk7XG4gICAgaWYgKCFzb3VyY2UpIHsgY29udGludWU7IH1cblxuICAgIGlmICh0eXBlb2Ygc291cmNlICE9PSAnb2JqZWN0Jykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihzb3VyY2UgKyAnbXVzdCBiZSBub24tb2JqZWN0Jyk7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgcCBpbiBzb3VyY2UpIHtcbiAgICAgIGlmIChfaGFzKHNvdXJjZSwgcCkpIHtcbiAgICAgICAgb2JqW3BdID0gc291cmNlW3BdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvYmo7XG59O1xuXG5cbi8vIHJlZHVjZSBidWZmZXIgc2l6ZSwgYXZvaWRpbmcgbWVtIGNvcHlcbmV4cG9ydHMuc2hyaW5rQnVmID0gZnVuY3Rpb24gKGJ1Ziwgc2l6ZSkge1xuICBpZiAoYnVmLmxlbmd0aCA9PT0gc2l6ZSkgeyByZXR1cm4gYnVmOyB9XG4gIGlmIChidWYuc3ViYXJyYXkpIHsgcmV0dXJuIGJ1Zi5zdWJhcnJheSgwLCBzaXplKTsgfVxuICBidWYubGVuZ3RoID0gc2l6ZTtcbiAgcmV0dXJuIGJ1Zjtcbn07XG5cblxudmFyIGZuVHlwZWQgPSB7XG4gIGFycmF5U2V0OiBmdW5jdGlvbiAoZGVzdCwgc3JjLCBzcmNfb2ZmcywgbGVuLCBkZXN0X29mZnMpIHtcbiAgICBpZiAoc3JjLnN1YmFycmF5ICYmIGRlc3Quc3ViYXJyYXkpIHtcbiAgICAgIGRlc3Quc2V0KHNyYy5zdWJhcnJheShzcmNfb2Zmcywgc3JjX29mZnMgKyBsZW4pLCBkZXN0X29mZnMpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBGYWxsYmFjayB0byBvcmRpbmFyeSBhcnJheVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGRlc3RbZGVzdF9vZmZzICsgaV0gPSBzcmNbc3JjX29mZnMgKyBpXTtcbiAgICB9XG4gIH0sXG4gIC8vIEpvaW4gYXJyYXkgb2YgY2h1bmtzIHRvIHNpbmdsZSBhcnJheS5cbiAgZmxhdHRlbkNodW5rczogZnVuY3Rpb24gKGNodW5rcykge1xuICAgIHZhciBpLCBsLCBsZW4sIHBvcywgY2h1bmssIHJlc3VsdDtcblxuICAgIC8vIGNhbGN1bGF0ZSBkYXRhIGxlbmd0aFxuICAgIGxlbiA9IDA7XG4gICAgZm9yIChpID0gMCwgbCA9IGNodW5rcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIGxlbiArPSBjaHVua3NbaV0ubGVuZ3RoO1xuICAgIH1cblxuICAgIC8vIGpvaW4gY2h1bmtzXG4gICAgcmVzdWx0ID0gbmV3IFVpbnQ4QXJyYXkobGVuKTtcbiAgICBwb3MgPSAwO1xuICAgIGZvciAoaSA9IDAsIGwgPSBjaHVua3MubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICBjaHVuayA9IGNodW5rc1tpXTtcbiAgICAgIHJlc3VsdC5zZXQoY2h1bmssIHBvcyk7XG4gICAgICBwb3MgKz0gY2h1bmsubGVuZ3RoO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn07XG5cbnZhciBmblVudHlwZWQgPSB7XG4gIGFycmF5U2V0OiBmdW5jdGlvbiAoZGVzdCwgc3JjLCBzcmNfb2ZmcywgbGVuLCBkZXN0X29mZnMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBkZXN0W2Rlc3Rfb2ZmcyArIGldID0gc3JjW3NyY19vZmZzICsgaV07XG4gICAgfVxuICB9LFxuICAvLyBKb2luIGFycmF5IG9mIGNodW5rcyB0byBzaW5nbGUgYXJyYXkuXG4gIGZsYXR0ZW5DaHVua3M6IGZ1bmN0aW9uIChjaHVua3MpIHtcbiAgICByZXR1cm4gW10uY29uY2F0LmFwcGx5KFtdLCBjaHVua3MpO1xuICB9XG59O1xuXG5cbi8vIEVuYWJsZS9EaXNhYmxlIHR5cGVkIGFycmF5cyB1c2UsIGZvciB0ZXN0aW5nXG4vL1xuZXhwb3J0cy5zZXRUeXBlZCA9IGZ1bmN0aW9uIChvbikge1xuICBpZiAob24pIHtcbiAgICBleHBvcnRzLkJ1ZjggID0gVWludDhBcnJheTtcbiAgICBleHBvcnRzLkJ1ZjE2ID0gVWludDE2QXJyYXk7XG4gICAgZXhwb3J0cy5CdWYzMiA9IEludDMyQXJyYXk7XG4gICAgZXhwb3J0cy5hc3NpZ24oZXhwb3J0cywgZm5UeXBlZCk7XG4gIH0gZWxzZSB7XG4gICAgZXhwb3J0cy5CdWY4ICA9IEFycmF5O1xuICAgIGV4cG9ydHMuQnVmMTYgPSBBcnJheTtcbiAgICBleHBvcnRzLkJ1ZjMyID0gQXJyYXk7XG4gICAgZXhwb3J0cy5hc3NpZ24oZXhwb3J0cywgZm5VbnR5cGVkKTtcbiAgfVxufTtcblxuZXhwb3J0cy5zZXRUeXBlZChUWVBFRF9PSyk7XG4iLCIvLyBTdHJpbmcgZW5jb2RlL2RlY29kZSBoZWxwZXJzXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi9jb21tb24nKTtcblxuXG4vLyBRdWljayBjaGVjayBpZiB3ZSBjYW4gdXNlIGZhc3QgYXJyYXkgdG8gYmluIHN0cmluZyBjb252ZXJzaW9uXG4vL1xuLy8gLSBhcHBseShBcnJheSkgY2FuIGZhaWwgb24gQW5kcm9pZCAyLjJcbi8vIC0gYXBwbHkoVWludDhBcnJheSkgY2FuIGZhaWwgb24gaU9TIDUuMSBTYWZhcmlcbi8vXG52YXIgU1RSX0FQUExZX09LID0gdHJ1ZTtcbnZhciBTVFJfQVBQTFlfVUlBX09LID0gdHJ1ZTtcblxudHJ5IHsgU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBbIDAgXSk7IH0gY2F0Y2ggKF9fKSB7IFNUUl9BUFBMWV9PSyA9IGZhbHNlOyB9XG50cnkgeyBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIG5ldyBVaW50OEFycmF5KDEpKTsgfSBjYXRjaCAoX18pIHsgU1RSX0FQUExZX1VJQV9PSyA9IGZhbHNlOyB9XG5cblxuLy8gVGFibGUgd2l0aCB1dGY4IGxlbmd0aHMgKGNhbGN1bGF0ZWQgYnkgZmlyc3QgYnl0ZSBvZiBzZXF1ZW5jZSlcbi8vIE5vdGUsIHRoYXQgNSAmIDYtYnl0ZSB2YWx1ZXMgYW5kIHNvbWUgNC1ieXRlIHZhbHVlcyBjYW4gbm90IGJlIHJlcHJlc2VudGVkIGluIEpTLFxuLy8gYmVjYXVzZSBtYXggcG9zc2libGUgY29kZXBvaW50IGlzIDB4MTBmZmZmXG52YXIgX3V0ZjhsZW4gPSBuZXcgdXRpbHMuQnVmOCgyNTYpO1xuZm9yICh2YXIgcSA9IDA7IHEgPCAyNTY7IHErKykge1xuICBfdXRmOGxlbltxXSA9IChxID49IDI1MiA/IDYgOiBxID49IDI0OCA/IDUgOiBxID49IDI0MCA/IDQgOiBxID49IDIyNCA/IDMgOiBxID49IDE5MiA/IDIgOiAxKTtcbn1cbl91dGY4bGVuWzI1NF0gPSBfdXRmOGxlblsyNTRdID0gMTsgLy8gSW52YWxpZCBzZXF1ZW5jZSBzdGFydFxuXG5cbi8vIGNvbnZlcnQgc3RyaW5nIHRvIGFycmF5ICh0eXBlZCwgd2hlbiBwb3NzaWJsZSlcbmV4cG9ydHMuc3RyaW5nMmJ1ZiA9IGZ1bmN0aW9uIChzdHIpIHtcbiAgdmFyIGJ1ZiwgYywgYzIsIG1fcG9zLCBpLCBzdHJfbGVuID0gc3RyLmxlbmd0aCwgYnVmX2xlbiA9IDA7XG5cbiAgLy8gY291bnQgYmluYXJ5IHNpemVcbiAgZm9yIChtX3BvcyA9IDA7IG1fcG9zIDwgc3RyX2xlbjsgbV9wb3MrKykge1xuICAgIGMgPSBzdHIuY2hhckNvZGVBdChtX3Bvcyk7XG4gICAgaWYgKChjICYgMHhmYzAwKSA9PT0gMHhkODAwICYmIChtX3BvcyArIDEgPCBzdHJfbGVuKSkge1xuICAgICAgYzIgPSBzdHIuY2hhckNvZGVBdChtX3BvcyArIDEpO1xuICAgICAgaWYgKChjMiAmIDB4ZmMwMCkgPT09IDB4ZGMwMCkge1xuICAgICAgICBjID0gMHgxMDAwMCArICgoYyAtIDB4ZDgwMCkgPDwgMTApICsgKGMyIC0gMHhkYzAwKTtcbiAgICAgICAgbV9wb3MrKztcbiAgICAgIH1cbiAgICB9XG4gICAgYnVmX2xlbiArPSBjIDwgMHg4MCA/IDEgOiBjIDwgMHg4MDAgPyAyIDogYyA8IDB4MTAwMDAgPyAzIDogNDtcbiAgfVxuXG4gIC8vIGFsbG9jYXRlIGJ1ZmZlclxuICBidWYgPSBuZXcgdXRpbHMuQnVmOChidWZfbGVuKTtcblxuICAvLyBjb252ZXJ0XG4gIGZvciAoaSA9IDAsIG1fcG9zID0gMDsgaSA8IGJ1Zl9sZW47IG1fcG9zKyspIHtcbiAgICBjID0gc3RyLmNoYXJDb2RlQXQobV9wb3MpO1xuICAgIGlmICgoYyAmIDB4ZmMwMCkgPT09IDB4ZDgwMCAmJiAobV9wb3MgKyAxIDwgc3RyX2xlbikpIHtcbiAgICAgIGMyID0gc3RyLmNoYXJDb2RlQXQobV9wb3MgKyAxKTtcbiAgICAgIGlmICgoYzIgJiAweGZjMDApID09PSAweGRjMDApIHtcbiAgICAgICAgYyA9IDB4MTAwMDAgKyAoKGMgLSAweGQ4MDApIDw8IDEwKSArIChjMiAtIDB4ZGMwMCk7XG4gICAgICAgIG1fcG9zKys7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChjIDwgMHg4MCkge1xuICAgICAgLyogb25lIGJ5dGUgKi9cbiAgICAgIGJ1ZltpKytdID0gYztcbiAgICB9IGVsc2UgaWYgKGMgPCAweDgwMCkge1xuICAgICAgLyogdHdvIGJ5dGVzICovXG4gICAgICBidWZbaSsrXSA9IDB4QzAgfCAoYyA+Pj4gNik7XG4gICAgICBidWZbaSsrXSA9IDB4ODAgfCAoYyAmIDB4M2YpO1xuICAgIH0gZWxzZSBpZiAoYyA8IDB4MTAwMDApIHtcbiAgICAgIC8qIHRocmVlIGJ5dGVzICovXG4gICAgICBidWZbaSsrXSA9IDB4RTAgfCAoYyA+Pj4gMTIpO1xuICAgICAgYnVmW2krK10gPSAweDgwIHwgKGMgPj4+IDYgJiAweDNmKTtcbiAgICAgIGJ1ZltpKytdID0gMHg4MCB8IChjICYgMHgzZik7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8qIGZvdXIgYnl0ZXMgKi9cbiAgICAgIGJ1ZltpKytdID0gMHhmMCB8IChjID4+PiAxOCk7XG4gICAgICBidWZbaSsrXSA9IDB4ODAgfCAoYyA+Pj4gMTIgJiAweDNmKTtcbiAgICAgIGJ1ZltpKytdID0gMHg4MCB8IChjID4+PiA2ICYgMHgzZik7XG4gICAgICBidWZbaSsrXSA9IDB4ODAgfCAoYyAmIDB4M2YpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBidWY7XG59O1xuXG4vLyBIZWxwZXIgKHVzZWQgaW4gMiBwbGFjZXMpXG5mdW5jdGlvbiBidWYyYmluc3RyaW5nKGJ1ZiwgbGVuKSB7XG4gIC8vIHVzZSBmYWxsYmFjayBmb3IgYmlnIGFycmF5cyB0byBhdm9pZCBzdGFjayBvdmVyZmxvd1xuICBpZiAobGVuIDwgNjU1MzcpIHtcbiAgICBpZiAoKGJ1Zi5zdWJhcnJheSAmJiBTVFJfQVBQTFlfVUlBX09LKSB8fCAoIWJ1Zi5zdWJhcnJheSAmJiBTVFJfQVBQTFlfT0spKSB7XG4gICAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCB1dGlscy5zaHJpbmtCdWYoYnVmLCBsZW4pKTtcbiAgICB9XG4gIH1cblxuICB2YXIgcmVzdWx0ID0gJyc7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cblxuLy8gQ29udmVydCBieXRlIGFycmF5IHRvIGJpbmFyeSBzdHJpbmdcbmV4cG9ydHMuYnVmMmJpbnN0cmluZyA9IGZ1bmN0aW9uIChidWYpIHtcbiAgcmV0dXJuIGJ1ZjJiaW5zdHJpbmcoYnVmLCBidWYubGVuZ3RoKTtcbn07XG5cblxuLy8gQ29udmVydCBiaW5hcnkgc3RyaW5nICh0eXBlZCwgd2hlbiBwb3NzaWJsZSlcbmV4cG9ydHMuYmluc3RyaW5nMmJ1ZiA9IGZ1bmN0aW9uIChzdHIpIHtcbiAgdmFyIGJ1ZiA9IG5ldyB1dGlscy5CdWY4KHN0ci5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMCwgbGVuID0gYnVmLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgYnVmW2ldID0gc3RyLmNoYXJDb2RlQXQoaSk7XG4gIH1cbiAgcmV0dXJuIGJ1Zjtcbn07XG5cblxuLy8gY29udmVydCBhcnJheSB0byBzdHJpbmdcbmV4cG9ydHMuYnVmMnN0cmluZyA9IGZ1bmN0aW9uIChidWYsIG1heCkge1xuICB2YXIgaSwgb3V0LCBjLCBjX2xlbjtcbiAgdmFyIGxlbiA9IG1heCB8fCBidWYubGVuZ3RoO1xuXG4gIC8vIFJlc2VydmUgbWF4IHBvc3NpYmxlIGxlbmd0aCAoMiB3b3JkcyBwZXIgY2hhcilcbiAgLy8gTkI6IGJ5IHVua25vd24gcmVhc29ucywgQXJyYXkgaXMgc2lnbmlmaWNhbnRseSBmYXN0ZXIgZm9yXG4gIC8vICAgICBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5IHRoYW4gVWludDE2QXJyYXkuXG4gIHZhciB1dGYxNmJ1ZiA9IG5ldyBBcnJheShsZW4gKiAyKTtcblxuICBmb3IgKG91dCA9IDAsIGkgPSAwOyBpIDwgbGVuOykge1xuICAgIGMgPSBidWZbaSsrXTtcbiAgICAvLyBxdWljayBwcm9jZXNzIGFzY2lpXG4gICAgaWYgKGMgPCAweDgwKSB7IHV0ZjE2YnVmW291dCsrXSA9IGM7IGNvbnRpbnVlOyB9XG5cbiAgICBjX2xlbiA9IF91dGY4bGVuW2NdO1xuICAgIC8vIHNraXAgNSAmIDYgYnl0ZSBjb2Rlc1xuICAgIGlmIChjX2xlbiA+IDQpIHsgdXRmMTZidWZbb3V0KytdID0gMHhmZmZkOyBpICs9IGNfbGVuIC0gMTsgY29udGludWU7IH1cblxuICAgIC8vIGFwcGx5IG1hc2sgb24gZmlyc3QgYnl0ZVxuICAgIGMgJj0gY19sZW4gPT09IDIgPyAweDFmIDogY19sZW4gPT09IDMgPyAweDBmIDogMHgwNztcbiAgICAvLyBqb2luIHRoZSByZXN0XG4gICAgd2hpbGUgKGNfbGVuID4gMSAmJiBpIDwgbGVuKSB7XG4gICAgICBjID0gKGMgPDwgNikgfCAoYnVmW2krK10gJiAweDNmKTtcbiAgICAgIGNfbGVuLS07XG4gICAgfVxuXG4gICAgLy8gdGVybWluYXRlZCBieSBlbmQgb2Ygc3RyaW5nP1xuICAgIGlmIChjX2xlbiA+IDEpIHsgdXRmMTZidWZbb3V0KytdID0gMHhmZmZkOyBjb250aW51ZTsgfVxuXG4gICAgaWYgKGMgPCAweDEwMDAwKSB7XG4gICAgICB1dGYxNmJ1ZltvdXQrK10gPSBjO1xuICAgIH0gZWxzZSB7XG4gICAgICBjIC09IDB4MTAwMDA7XG4gICAgICB1dGYxNmJ1ZltvdXQrK10gPSAweGQ4MDAgfCAoKGMgPj4gMTApICYgMHgzZmYpO1xuICAgICAgdXRmMTZidWZbb3V0KytdID0gMHhkYzAwIHwgKGMgJiAweDNmZik7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ1ZjJiaW5zdHJpbmcodXRmMTZidWYsIG91dCk7XG59O1xuXG5cbi8vIENhbGN1bGF0ZSBtYXggcG9zc2libGUgcG9zaXRpb24gaW4gdXRmOCBidWZmZXIsXG4vLyB0aGF0IHdpbGwgbm90IGJyZWFrIHNlcXVlbmNlLiBJZiB0aGF0J3Mgbm90IHBvc3NpYmxlXG4vLyAtICh2ZXJ5IHNtYWxsIGxpbWl0cykgcmV0dXJuIG1heCBzaXplIGFzIGlzLlxuLy9cbi8vIGJ1ZltdIC0gdXRmOCBieXRlcyBhcnJheVxuLy8gbWF4ICAgLSBsZW5ndGggbGltaXQgKG1hbmRhdG9yeSk7XG5leHBvcnRzLnV0Zjhib3JkZXIgPSBmdW5jdGlvbiAoYnVmLCBtYXgpIHtcbiAgdmFyIHBvcztcblxuICBtYXggPSBtYXggfHwgYnVmLmxlbmd0aDtcbiAgaWYgKG1heCA+IGJ1Zi5sZW5ndGgpIHsgbWF4ID0gYnVmLmxlbmd0aDsgfVxuXG4gIC8vIGdvIGJhY2sgZnJvbSBsYXN0IHBvc2l0aW9uLCB1bnRpbCBzdGFydCBvZiBzZXF1ZW5jZSBmb3VuZFxuICBwb3MgPSBtYXggLSAxO1xuICB3aGlsZSAocG9zID49IDAgJiYgKGJ1Zltwb3NdICYgMHhDMCkgPT09IDB4ODApIHsgcG9zLS07IH1cblxuICAvLyBWZXJ5IHNtYWxsIGFuZCBicm9rZW4gc2VxdWVuY2UsXG4gIC8vIHJldHVybiBtYXgsIGJlY2F1c2Ugd2Ugc2hvdWxkIHJldHVybiBzb21ldGhpbmcgYW55d2F5LlxuICBpZiAocG9zIDwgMCkgeyByZXR1cm4gbWF4OyB9XG5cbiAgLy8gSWYgd2UgY2FtZSB0byBzdGFydCBvZiBidWZmZXIgLSB0aGF0IG1lYW5zIGJ1ZmZlciBpcyB0b28gc21hbGwsXG4gIC8vIHJldHVybiBtYXggdG9vLlxuICBpZiAocG9zID09PSAwKSB7IHJldHVybiBtYXg7IH1cblxuICByZXR1cm4gKHBvcyArIF91dGY4bGVuW2J1Zltwb3NdXSA+IG1heCkgPyBwb3MgOiBtYXg7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyBOb3RlOiBhZGxlcjMyIHRha2VzIDEyJSBmb3IgbGV2ZWwgMCBhbmQgMiUgZm9yIGxldmVsIDYuXG4vLyBJdCBpc24ndCB3b3J0aCBpdCB0byBtYWtlIGFkZGl0aW9uYWwgb3B0aW1pemF0aW9ucyBhcyBpbiBvcmlnaW5hbC5cbi8vIFNtYWxsIHNpemUgaXMgcHJlZmVyYWJsZS5cblxuLy8gKEMpIDE5OTUtMjAxMyBKZWFuLWxvdXAgR2FpbGx5IGFuZCBNYXJrIEFkbGVyXG4vLyAoQykgMjAxNC0yMDE3IFZpdGFseSBQdXpyaW4gYW5kIEFuZHJleSBUdXBpdHNpblxuLy9cbi8vIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgJ2FzLWlzJywgd2l0aG91dCBhbnkgZXhwcmVzcyBvciBpbXBsaWVkXG4vLyB3YXJyYW50eS4gSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXNcbi8vIGFyaXNpbmcgZnJvbSB0aGUgdXNlIG9mIHRoaXMgc29mdHdhcmUuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsXG4vLyBpbmNsdWRpbmcgY29tbWVyY2lhbCBhcHBsaWNhdGlvbnMsIGFuZCB0byBhbHRlciBpdCBhbmQgcmVkaXN0cmlidXRlIGl0XG4vLyBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6XG4vL1xuLy8gMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvZnR3YXJlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkOyB5b3UgbXVzdCBub3Rcbi8vICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmVcbi8vICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlXG4vLyAgIGFwcHJlY2lhdGVkIGJ1dCBpcyBub3QgcmVxdWlyZWQuXG4vLyAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZVxuLy8gICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuXG4vLyAzLiBUaGlzIG5vdGljZSBtYXkgbm90IGJlIHJlbW92ZWQgb3IgYWx0ZXJlZCBmcm9tIGFueSBzb3VyY2UgZGlzdHJpYnV0aW9uLlxuXG5mdW5jdGlvbiBhZGxlcjMyKGFkbGVyLCBidWYsIGxlbiwgcG9zKSB7XG4gIHZhciBzMSA9IChhZGxlciAmIDB4ZmZmZikgfDAsXG4gICAgICBzMiA9ICgoYWRsZXIgPj4+IDE2KSAmIDB4ZmZmZikgfDAsXG4gICAgICBuID0gMDtcblxuICB3aGlsZSAobGVuICE9PSAwKSB7XG4gICAgLy8gU2V0IGxpbWl0IH4gdHdpY2UgbGVzcyB0aGFuIDU1NTIsIHRvIGtlZXBcbiAgICAvLyBzMiBpbiAzMS1iaXRzLCBiZWNhdXNlIHdlIGZvcmNlIHNpZ25lZCBpbnRzLlxuICAgIC8vIGluIG90aGVyIGNhc2UgJT0gd2lsbCBmYWlsLlxuICAgIG4gPSBsZW4gPiAyMDAwID8gMjAwMCA6IGxlbjtcbiAgICBsZW4gLT0gbjtcblxuICAgIGRvIHtcbiAgICAgIHMxID0gKHMxICsgYnVmW3BvcysrXSkgfDA7XG4gICAgICBzMiA9IChzMiArIHMxKSB8MDtcbiAgICB9IHdoaWxlICgtLW4pO1xuXG4gICAgczEgJT0gNjU1MjE7XG4gICAgczIgJT0gNjU1MjE7XG4gIH1cblxuICByZXR1cm4gKHMxIHwgKHMyIDw8IDE2KSkgfDA7XG59XG5cblxubW9kdWxlLmV4cG9ydHMgPSBhZGxlcjMyO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXJcbi8vIChDKSAyMDE0LTIwMTcgVml0YWx5IFB1enJpbiBhbmQgQW5kcmV5IFR1cGl0c2luXG4vL1xuLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWRcbi8vIHdhcnJhbnR5LiBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlc1xuLy8gYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSxcbi8vIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXRcbi8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczpcbi8vXG4vLyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdFxuLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZVxuLy8gICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmVcbi8vICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC5cbi8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlXG4vLyAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS5cbi8vIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXG4gIC8qIEFsbG93ZWQgZmx1c2ggdmFsdWVzOyBzZWUgZGVmbGF0ZSgpIGFuZCBpbmZsYXRlKCkgYmVsb3cgZm9yIGRldGFpbHMgKi9cbiAgWl9OT19GTFVTSDogICAgICAgICAwLFxuICBaX1BBUlRJQUxfRkxVU0g6ICAgIDEsXG4gIFpfU1lOQ19GTFVTSDogICAgICAgMixcbiAgWl9GVUxMX0ZMVVNIOiAgICAgICAzLFxuICBaX0ZJTklTSDogICAgICAgICAgIDQsXG4gIFpfQkxPQ0s6ICAgICAgICAgICAgNSxcbiAgWl9UUkVFUzogICAgICAgICAgICA2LFxuXG4gIC8qIFJldHVybiBjb2RlcyBmb3IgdGhlIGNvbXByZXNzaW9uL2RlY29tcHJlc3Npb24gZnVuY3Rpb25zLiBOZWdhdGl2ZSB2YWx1ZXNcbiAgKiBhcmUgZXJyb3JzLCBwb3NpdGl2ZSB2YWx1ZXMgYXJlIHVzZWQgZm9yIHNwZWNpYWwgYnV0IG5vcm1hbCBldmVudHMuXG4gICovXG4gIFpfT0s6ICAgICAgICAgICAgICAgMCxcbiAgWl9TVFJFQU1fRU5EOiAgICAgICAxLFxuICBaX05FRURfRElDVDogICAgICAgIDIsXG4gIFpfRVJSTk86ICAgICAgICAgICAtMSxcbiAgWl9TVFJFQU1fRVJST1I6ICAgIC0yLFxuICBaX0RBVEFfRVJST1I6ICAgICAgLTMsXG4gIC8vWl9NRU1fRVJST1I6ICAgICAtNCxcbiAgWl9CVUZfRVJST1I6ICAgICAgIC01LFxuICAvL1pfVkVSU0lPTl9FUlJPUjogLTYsXG5cbiAgLyogY29tcHJlc3Npb24gbGV2ZWxzICovXG4gIFpfTk9fQ09NUFJFU1NJT046ICAgICAgICAgMCxcbiAgWl9CRVNUX1NQRUVEOiAgICAgICAgICAgICAxLFxuICBaX0JFU1RfQ09NUFJFU1NJT046ICAgICAgIDksXG4gIFpfREVGQVVMVF9DT01QUkVTU0lPTjogICAtMSxcblxuXG4gIFpfRklMVEVSRUQ6ICAgICAgICAgICAgICAgMSxcbiAgWl9IVUZGTUFOX09OTFk6ICAgICAgICAgICAyLFxuICBaX1JMRTogICAgICAgICAgICAgICAgICAgIDMsXG4gIFpfRklYRUQ6ICAgICAgICAgICAgICAgICAgNCxcbiAgWl9ERUZBVUxUX1NUUkFURUdZOiAgICAgICAwLFxuXG4gIC8qIFBvc3NpYmxlIHZhbHVlcyBvZiB0aGUgZGF0YV90eXBlIGZpZWxkICh0aG91Z2ggc2VlIGluZmxhdGUoKSkgKi9cbiAgWl9CSU5BUlk6ICAgICAgICAgICAgICAgICAwLFxuICBaX1RFWFQ6ICAgICAgICAgICAgICAgICAgIDEsXG4gIC8vWl9BU0NJSTogICAgICAgICAgICAgICAgMSwgLy8gPSBaX1RFWFQgKGRlcHJlY2F0ZWQpXG4gIFpfVU5LTk9XTjogICAgICAgICAgICAgICAgMixcblxuICAvKiBUaGUgZGVmbGF0ZSBjb21wcmVzc2lvbiBtZXRob2QgKi9cbiAgWl9ERUZMQVRFRDogICAgICAgICAgICAgICA4XG4gIC8vWl9OVUxMOiAgICAgICAgICAgICAgICAgbnVsbCAvLyBVc2UgLTEgb3IgbnVsbCBpbmxpbmUsIGRlcGVuZGluZyBvbiB2YXIgdHlwZVxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxuLy8gTm90ZTogd2UgY2FuJ3QgZ2V0IHNpZ25pZmljYW50IHNwZWVkIGJvb3N0IGhlcmUuXG4vLyBTbyB3cml0ZSBjb2RlIHRvIG1pbmltaXplIHNpemUgLSBubyBwcmVnZW5lcmF0ZWQgdGFibGVzXG4vLyBhbmQgYXJyYXkgdG9vbHMgZGVwZW5kZW5jaWVzLlxuXG4vLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXJcbi8vIChDKSAyMDE0LTIwMTcgVml0YWx5IFB1enJpbiBhbmQgQW5kcmV5IFR1cGl0c2luXG4vL1xuLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWRcbi8vIHdhcnJhbnR5LiBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlc1xuLy8gYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSxcbi8vIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXRcbi8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczpcbi8vXG4vLyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdFxuLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZVxuLy8gICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmVcbi8vICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC5cbi8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlXG4vLyAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS5cbi8vIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uXG5cbi8vIFVzZSBvcmRpbmFyeSBhcnJheSwgc2luY2UgdW50eXBlZCBtYWtlcyBubyBib29zdCBoZXJlXG5mdW5jdGlvbiBtYWtlVGFibGUoKSB7XG4gIHZhciBjLCB0YWJsZSA9IFtdO1xuXG4gIGZvciAodmFyIG4gPSAwOyBuIDwgMjU2OyBuKyspIHtcbiAgICBjID0gbjtcbiAgICBmb3IgKHZhciBrID0gMDsgayA8IDg7IGsrKykge1xuICAgICAgYyA9ICgoYyAmIDEpID8gKDB4RURCODgzMjAgXiAoYyA+Pj4gMSkpIDogKGMgPj4+IDEpKTtcbiAgICB9XG4gICAgdGFibGVbbl0gPSBjO1xuICB9XG5cbiAgcmV0dXJuIHRhYmxlO1xufVxuXG4vLyBDcmVhdGUgdGFibGUgb24gbG9hZC4gSnVzdCAyNTUgc2lnbmVkIGxvbmdzLiBOb3QgYSBwcm9ibGVtLlxudmFyIGNyY1RhYmxlID0gbWFrZVRhYmxlKCk7XG5cblxuZnVuY3Rpb24gY3JjMzIoY3JjLCBidWYsIGxlbiwgcG9zKSB7XG4gIHZhciB0ID0gY3JjVGFibGUsXG4gICAgICBlbmQgPSBwb3MgKyBsZW47XG5cbiAgY3JjIF49IC0xO1xuXG4gIGZvciAodmFyIGkgPSBwb3M7IGkgPCBlbmQ7IGkrKykge1xuICAgIGNyYyA9IChjcmMgPj4+IDgpIF4gdFsoY3JjIF4gYnVmW2ldKSAmIDB4RkZdO1xuICB9XG5cbiAgcmV0dXJuIChjcmMgXiAoLTEpKTsgLy8gPj4+IDA7XG59XG5cblxubW9kdWxlLmV4cG9ydHMgPSBjcmMzMjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLy8gKEMpIDE5OTUtMjAxMyBKZWFuLWxvdXAgR2FpbGx5IGFuZCBNYXJrIEFkbGVyXG4vLyAoQykgMjAxNC0yMDE3IFZpdGFseSBQdXpyaW4gYW5kIEFuZHJleSBUdXBpdHNpblxuLy9cbi8vIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgJ2FzLWlzJywgd2l0aG91dCBhbnkgZXhwcmVzcyBvciBpbXBsaWVkXG4vLyB3YXJyYW50eS4gSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXNcbi8vIGFyaXNpbmcgZnJvbSB0aGUgdXNlIG9mIHRoaXMgc29mdHdhcmUuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsXG4vLyBpbmNsdWRpbmcgY29tbWVyY2lhbCBhcHBsaWNhdGlvbnMsIGFuZCB0byBhbHRlciBpdCBhbmQgcmVkaXN0cmlidXRlIGl0XG4vLyBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6XG4vL1xuLy8gMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvZnR3YXJlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkOyB5b3UgbXVzdCBub3Rcbi8vICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmVcbi8vICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlXG4vLyAgIGFwcHJlY2lhdGVkIGJ1dCBpcyBub3QgcmVxdWlyZWQuXG4vLyAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZVxuLy8gICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuXG4vLyAzLiBUaGlzIG5vdGljZSBtYXkgbm90IGJlIHJlbW92ZWQgb3IgYWx0ZXJlZCBmcm9tIGFueSBzb3VyY2UgZGlzdHJpYnV0aW9uLlxuXG52YXIgdXRpbHMgICA9IHJlcXVpcmUoJy4uL3V0aWxzL2NvbW1vbicpO1xudmFyIHRyZWVzICAgPSByZXF1aXJlKCcuL3RyZWVzJyk7XG52YXIgYWRsZXIzMiA9IHJlcXVpcmUoJy4vYWRsZXIzMicpO1xudmFyIGNyYzMyICAgPSByZXF1aXJlKCcuL2NyYzMyJyk7XG52YXIgbXNnICAgICA9IHJlcXVpcmUoJy4vbWVzc2FnZXMnKTtcblxuLyogUHVibGljIGNvbnN0YW50cyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG5cblxuLyogQWxsb3dlZCBmbHVzaCB2YWx1ZXM7IHNlZSBkZWZsYXRlKCkgYW5kIGluZmxhdGUoKSBiZWxvdyBmb3IgZGV0YWlscyAqL1xudmFyIFpfTk9fRkxVU0ggICAgICA9IDA7XG52YXIgWl9QQVJUSUFMX0ZMVVNIID0gMTtcbi8vdmFyIFpfU1lOQ19GTFVTSCAgICA9IDI7XG52YXIgWl9GVUxMX0ZMVVNIICAgID0gMztcbnZhciBaX0ZJTklTSCAgICAgICAgPSA0O1xudmFyIFpfQkxPQ0sgICAgICAgICA9IDU7XG4vL3ZhciBaX1RSRUVTICAgICAgICAgPSA2O1xuXG5cbi8qIFJldHVybiBjb2RlcyBmb3IgdGhlIGNvbXByZXNzaW9uL2RlY29tcHJlc3Npb24gZnVuY3Rpb25zLiBOZWdhdGl2ZSB2YWx1ZXNcbiAqIGFyZSBlcnJvcnMsIHBvc2l0aXZlIHZhbHVlcyBhcmUgdXNlZCBmb3Igc3BlY2lhbCBidXQgbm9ybWFsIGV2ZW50cy5cbiAqL1xudmFyIFpfT0sgICAgICAgICAgICA9IDA7XG52YXIgWl9TVFJFQU1fRU5EICAgID0gMTtcbi8vdmFyIFpfTkVFRF9ESUNUICAgICA9IDI7XG4vL3ZhciBaX0VSUk5PICAgICAgICAgPSAtMTtcbnZhciBaX1NUUkVBTV9FUlJPUiAgPSAtMjtcbnZhciBaX0RBVEFfRVJST1IgICAgPSAtMztcbi8vdmFyIFpfTUVNX0VSUk9SICAgICA9IC00O1xudmFyIFpfQlVGX0VSUk9SICAgICA9IC01O1xuLy92YXIgWl9WRVJTSU9OX0VSUk9SID0gLTY7XG5cblxuLyogY29tcHJlc3Npb24gbGV2ZWxzICovXG4vL3ZhciBaX05PX0NPTVBSRVNTSU9OICAgICAgPSAwO1xuLy92YXIgWl9CRVNUX1NQRUVEICAgICAgICAgID0gMTtcbi8vdmFyIFpfQkVTVF9DT01QUkVTU0lPTiAgICA9IDk7XG52YXIgWl9ERUZBVUxUX0NPTVBSRVNTSU9OID0gLTE7XG5cblxudmFyIFpfRklMVEVSRUQgICAgICAgICAgICA9IDE7XG52YXIgWl9IVUZGTUFOX09OTFkgICAgICAgID0gMjtcbnZhciBaX1JMRSAgICAgICAgICAgICAgICAgPSAzO1xudmFyIFpfRklYRUQgICAgICAgICAgICAgICA9IDQ7XG52YXIgWl9ERUZBVUxUX1NUUkFURUdZICAgID0gMDtcblxuLyogUG9zc2libGUgdmFsdWVzIG9mIHRoZSBkYXRhX3R5cGUgZmllbGQgKHRob3VnaCBzZWUgaW5mbGF0ZSgpKSAqL1xuLy92YXIgWl9CSU5BUlkgICAgICAgICAgICAgID0gMDtcbi8vdmFyIFpfVEVYVCAgICAgICAgICAgICAgICA9IDE7XG4vL3ZhciBaX0FTQ0lJICAgICAgICAgICAgICAgPSAxOyAvLyA9IFpfVEVYVFxudmFyIFpfVU5LTk9XTiAgICAgICAgICAgICA9IDI7XG5cblxuLyogVGhlIGRlZmxhdGUgY29tcHJlc3Npb24gbWV0aG9kICovXG52YXIgWl9ERUZMQVRFRCAgPSA4O1xuXG4vKj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuXG5cbnZhciBNQVhfTUVNX0xFVkVMID0gOTtcbi8qIE1heGltdW0gdmFsdWUgZm9yIG1lbUxldmVsIGluIGRlZmxhdGVJbml0MiAqL1xudmFyIE1BWF9XQklUUyA9IDE1O1xuLyogMzJLIExaNzcgd2luZG93ICovXG52YXIgREVGX01FTV9MRVZFTCA9IDg7XG5cblxudmFyIExFTkdUSF9DT0RFUyAgPSAyOTtcbi8qIG51bWJlciBvZiBsZW5ndGggY29kZXMsIG5vdCBjb3VudGluZyB0aGUgc3BlY2lhbCBFTkRfQkxPQ0sgY29kZSAqL1xudmFyIExJVEVSQUxTICAgICAgPSAyNTY7XG4vKiBudW1iZXIgb2YgbGl0ZXJhbCBieXRlcyAwLi4yNTUgKi9cbnZhciBMX0NPREVTICAgICAgID0gTElURVJBTFMgKyAxICsgTEVOR1RIX0NPREVTO1xuLyogbnVtYmVyIG9mIExpdGVyYWwgb3IgTGVuZ3RoIGNvZGVzLCBpbmNsdWRpbmcgdGhlIEVORF9CTE9DSyBjb2RlICovXG52YXIgRF9DT0RFUyAgICAgICA9IDMwO1xuLyogbnVtYmVyIG9mIGRpc3RhbmNlIGNvZGVzICovXG52YXIgQkxfQ09ERVMgICAgICA9IDE5O1xuLyogbnVtYmVyIG9mIGNvZGVzIHVzZWQgdG8gdHJhbnNmZXIgdGhlIGJpdCBsZW5ndGhzICovXG52YXIgSEVBUF9TSVpFICAgICA9IDIgKiBMX0NPREVTICsgMTtcbi8qIG1heGltdW0gaGVhcCBzaXplICovXG52YXIgTUFYX0JJVFMgID0gMTU7XG4vKiBBbGwgY29kZXMgbXVzdCBub3QgZXhjZWVkIE1BWF9CSVRTIGJpdHMgKi9cblxudmFyIE1JTl9NQVRDSCA9IDM7XG52YXIgTUFYX01BVENIID0gMjU4O1xudmFyIE1JTl9MT09LQUhFQUQgPSAoTUFYX01BVENIICsgTUlOX01BVENIICsgMSk7XG5cbnZhciBQUkVTRVRfRElDVCA9IDB4MjA7XG5cbnZhciBJTklUX1NUQVRFID0gNDI7XG52YXIgRVhUUkFfU1RBVEUgPSA2OTtcbnZhciBOQU1FX1NUQVRFID0gNzM7XG52YXIgQ09NTUVOVF9TVEFURSA9IDkxO1xudmFyIEhDUkNfU1RBVEUgPSAxMDM7XG52YXIgQlVTWV9TVEFURSA9IDExMztcbnZhciBGSU5JU0hfU1RBVEUgPSA2NjY7XG5cbnZhciBCU19ORUVEX01PUkUgICAgICA9IDE7IC8qIGJsb2NrIG5vdCBjb21wbGV0ZWQsIG5lZWQgbW9yZSBpbnB1dCBvciBtb3JlIG91dHB1dCAqL1xudmFyIEJTX0JMT0NLX0RPTkUgICAgID0gMjsgLyogYmxvY2sgZmx1c2ggcGVyZm9ybWVkICovXG52YXIgQlNfRklOSVNIX1NUQVJURUQgPSAzOyAvKiBmaW5pc2ggc3RhcnRlZCwgbmVlZCBvbmx5IG1vcmUgb3V0cHV0IGF0IG5leHQgZGVmbGF0ZSAqL1xudmFyIEJTX0ZJTklTSF9ET05FICAgID0gNDsgLyogZmluaXNoIGRvbmUsIGFjY2VwdCBubyBtb3JlIGlucHV0IG9yIG91dHB1dCAqL1xuXG52YXIgT1NfQ09ERSA9IDB4MDM7IC8vIFVuaXggOikgLiBEb24ndCBkZXRlY3QsIHVzZSB0aGlzIGRlZmF1bHQuXG5cbmZ1bmN0aW9uIGVycihzdHJtLCBlcnJvckNvZGUpIHtcbiAgc3RybS5tc2cgPSBtc2dbZXJyb3JDb2RlXTtcbiAgcmV0dXJuIGVycm9yQ29kZTtcbn1cblxuZnVuY3Rpb24gcmFuayhmKSB7XG4gIHJldHVybiAoKGYpIDw8IDEpIC0gKChmKSA+IDQgPyA5IDogMCk7XG59XG5cbmZ1bmN0aW9uIHplcm8oYnVmKSB7IHZhciBsZW4gPSBidWYubGVuZ3RoOyB3aGlsZSAoLS1sZW4gPj0gMCkgeyBidWZbbGVuXSA9IDA7IH0gfVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEZsdXNoIGFzIG11Y2ggcGVuZGluZyBvdXRwdXQgYXMgcG9zc2libGUuIEFsbCBkZWZsYXRlKCkgb3V0cHV0IGdvZXNcbiAqIHRocm91Z2ggdGhpcyBmdW5jdGlvbiBzbyBzb21lIGFwcGxpY2F0aW9ucyBtYXkgd2lzaCB0byBtb2RpZnkgaXRcbiAqIHRvIGF2b2lkIGFsbG9jYXRpbmcgYSBsYXJnZSBzdHJtLT5vdXRwdXQgYnVmZmVyIGFuZCBjb3B5aW5nIGludG8gaXQuXG4gKiAoU2VlIGFsc28gcmVhZF9idWYoKSkuXG4gKi9cbmZ1bmN0aW9uIGZsdXNoX3BlbmRpbmcoc3RybSkge1xuICB2YXIgcyA9IHN0cm0uc3RhdGU7XG5cbiAgLy9fdHJfZmx1c2hfYml0cyhzKTtcbiAgdmFyIGxlbiA9IHMucGVuZGluZztcbiAgaWYgKGxlbiA+IHN0cm0uYXZhaWxfb3V0KSB7XG4gICAgbGVuID0gc3RybS5hdmFpbF9vdXQ7XG4gIH1cbiAgaWYgKGxlbiA9PT0gMCkgeyByZXR1cm47IH1cblxuICB1dGlscy5hcnJheVNldChzdHJtLm91dHB1dCwgcy5wZW5kaW5nX2J1Ziwgcy5wZW5kaW5nX291dCwgbGVuLCBzdHJtLm5leHRfb3V0KTtcbiAgc3RybS5uZXh0X291dCArPSBsZW47XG4gIHMucGVuZGluZ19vdXQgKz0gbGVuO1xuICBzdHJtLnRvdGFsX291dCArPSBsZW47XG4gIHN0cm0uYXZhaWxfb3V0IC09IGxlbjtcbiAgcy5wZW5kaW5nIC09IGxlbjtcbiAgaWYgKHMucGVuZGluZyA9PT0gMCkge1xuICAgIHMucGVuZGluZ19vdXQgPSAwO1xuICB9XG59XG5cblxuZnVuY3Rpb24gZmx1c2hfYmxvY2tfb25seShzLCBsYXN0KSB7XG4gIHRyZWVzLl90cl9mbHVzaF9ibG9jayhzLCAocy5ibG9ja19zdGFydCA+PSAwID8gcy5ibG9ja19zdGFydCA6IC0xKSwgcy5zdHJzdGFydCAtIHMuYmxvY2tfc3RhcnQsIGxhc3QpO1xuICBzLmJsb2NrX3N0YXJ0ID0gcy5zdHJzdGFydDtcbiAgZmx1c2hfcGVuZGluZyhzLnN0cm0pO1xufVxuXG5cbmZ1bmN0aW9uIHB1dF9ieXRlKHMsIGIpIHtcbiAgcy5wZW5kaW5nX2J1ZltzLnBlbmRpbmcrK10gPSBiO1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFB1dCBhIHNob3J0IGluIHRoZSBwZW5kaW5nIGJ1ZmZlci4gVGhlIDE2LWJpdCB2YWx1ZSBpcyBwdXQgaW4gTVNCIG9yZGVyLlxuICogSU4gYXNzZXJ0aW9uOiB0aGUgc3RyZWFtIHN0YXRlIGlzIGNvcnJlY3QgYW5kIHRoZXJlIGlzIGVub3VnaCByb29tIGluXG4gKiBwZW5kaW5nX2J1Zi5cbiAqL1xuZnVuY3Rpb24gcHV0U2hvcnRNU0IocywgYikge1xuLy8gIHB1dF9ieXRlKHMsIChCeXRlKShiID4+IDgpKTtcbi8vICBwdXRfYnl0ZShzLCAoQnl0ZSkoYiAmIDB4ZmYpKTtcbiAgcy5wZW5kaW5nX2J1ZltzLnBlbmRpbmcrK10gPSAoYiA+Pj4gOCkgJiAweGZmO1xuICBzLnBlbmRpbmdfYnVmW3MucGVuZGluZysrXSA9IGIgJiAweGZmO1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogUmVhZCBhIG5ldyBidWZmZXIgZnJvbSB0aGUgY3VycmVudCBpbnB1dCBzdHJlYW0sIHVwZGF0ZSB0aGUgYWRsZXIzMlxuICogYW5kIHRvdGFsIG51bWJlciBvZiBieXRlcyByZWFkLiAgQWxsIGRlZmxhdGUoKSBpbnB1dCBnb2VzIHRocm91Z2hcbiAqIHRoaXMgZnVuY3Rpb24gc28gc29tZSBhcHBsaWNhdGlvbnMgbWF5IHdpc2ggdG8gbW9kaWZ5IGl0IHRvIGF2b2lkXG4gKiBhbGxvY2F0aW5nIGEgbGFyZ2Ugc3RybS0+aW5wdXQgYnVmZmVyIGFuZCBjb3B5aW5nIGZyb20gaXQuXG4gKiAoU2VlIGFsc28gZmx1c2hfcGVuZGluZygpKS5cbiAqL1xuZnVuY3Rpb24gcmVhZF9idWYoc3RybSwgYnVmLCBzdGFydCwgc2l6ZSkge1xuICB2YXIgbGVuID0gc3RybS5hdmFpbF9pbjtcblxuICBpZiAobGVuID4gc2l6ZSkgeyBsZW4gPSBzaXplOyB9XG4gIGlmIChsZW4gPT09IDApIHsgcmV0dXJuIDA7IH1cblxuICBzdHJtLmF2YWlsX2luIC09IGxlbjtcblxuICAvLyB6bWVtY3B5KGJ1Ziwgc3RybS0+bmV4dF9pbiwgbGVuKTtcbiAgdXRpbHMuYXJyYXlTZXQoYnVmLCBzdHJtLmlucHV0LCBzdHJtLm5leHRfaW4sIGxlbiwgc3RhcnQpO1xuICBpZiAoc3RybS5zdGF0ZS53cmFwID09PSAxKSB7XG4gICAgc3RybS5hZGxlciA9IGFkbGVyMzIoc3RybS5hZGxlciwgYnVmLCBsZW4sIHN0YXJ0KTtcbiAgfVxuXG4gIGVsc2UgaWYgKHN0cm0uc3RhdGUud3JhcCA9PT0gMikge1xuICAgIHN0cm0uYWRsZXIgPSBjcmMzMihzdHJtLmFkbGVyLCBidWYsIGxlbiwgc3RhcnQpO1xuICB9XG5cbiAgc3RybS5uZXh0X2luICs9IGxlbjtcbiAgc3RybS50b3RhbF9pbiArPSBsZW47XG5cbiAgcmV0dXJuIGxlbjtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFNldCBtYXRjaF9zdGFydCB0byB0aGUgbG9uZ2VzdCBtYXRjaCBzdGFydGluZyBhdCB0aGUgZ2l2ZW4gc3RyaW5nIGFuZFxuICogcmV0dXJuIGl0cyBsZW5ndGguIE1hdGNoZXMgc2hvcnRlciBvciBlcXVhbCB0byBwcmV2X2xlbmd0aCBhcmUgZGlzY2FyZGVkLFxuICogaW4gd2hpY2ggY2FzZSB0aGUgcmVzdWx0IGlzIGVxdWFsIHRvIHByZXZfbGVuZ3RoIGFuZCBtYXRjaF9zdGFydCBpc1xuICogZ2FyYmFnZS5cbiAqIElOIGFzc2VydGlvbnM6IGN1cl9tYXRjaCBpcyB0aGUgaGVhZCBvZiB0aGUgaGFzaCBjaGFpbiBmb3IgdGhlIGN1cnJlbnRcbiAqICAgc3RyaW5nIChzdHJzdGFydCkgYW5kIGl0cyBkaXN0YW5jZSBpcyA8PSBNQVhfRElTVCwgYW5kIHByZXZfbGVuZ3RoID49IDFcbiAqIE9VVCBhc3NlcnRpb246IHRoZSBtYXRjaCBsZW5ndGggaXMgbm90IGdyZWF0ZXIgdGhhbiBzLT5sb29rYWhlYWQuXG4gKi9cbmZ1bmN0aW9uIGxvbmdlc3RfbWF0Y2gocywgY3VyX21hdGNoKSB7XG4gIHZhciBjaGFpbl9sZW5ndGggPSBzLm1heF9jaGFpbl9sZW5ndGg7ICAgICAgLyogbWF4IGhhc2ggY2hhaW4gbGVuZ3RoICovXG4gIHZhciBzY2FuID0gcy5zdHJzdGFydDsgLyogY3VycmVudCBzdHJpbmcgKi9cbiAgdmFyIG1hdGNoOyAgICAgICAgICAgICAgICAgICAgICAgLyogbWF0Y2hlZCBzdHJpbmcgKi9cbiAgdmFyIGxlbjsgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBsZW5ndGggb2YgY3VycmVudCBtYXRjaCAqL1xuICB2YXIgYmVzdF9sZW4gPSBzLnByZXZfbGVuZ3RoOyAgICAgICAgICAgICAgLyogYmVzdCBtYXRjaCBsZW5ndGggc28gZmFyICovXG4gIHZhciBuaWNlX21hdGNoID0gcy5uaWNlX21hdGNoOyAgICAgICAgICAgICAvKiBzdG9wIGlmIG1hdGNoIGxvbmcgZW5vdWdoICovXG4gIHZhciBsaW1pdCA9IChzLnN0cnN0YXJ0ID4gKHMud19zaXplIC0gTUlOX0xPT0tBSEVBRCkpID9cbiAgICAgIHMuc3Ryc3RhcnQgLSAocy53X3NpemUgLSBNSU5fTE9PS0FIRUFEKSA6IDAvKk5JTCovO1xuXG4gIHZhciBfd2luID0gcy53aW5kb3c7IC8vIHNob3J0Y3V0XG5cbiAgdmFyIHdtYXNrID0gcy53X21hc2s7XG4gIHZhciBwcmV2ICA9IHMucHJldjtcblxuICAvKiBTdG9wIHdoZW4gY3VyX21hdGNoIGJlY29tZXMgPD0gbGltaXQuIFRvIHNpbXBsaWZ5IHRoZSBjb2RlLFxuICAgKiB3ZSBwcmV2ZW50IG1hdGNoZXMgd2l0aCB0aGUgc3RyaW5nIG9mIHdpbmRvdyBpbmRleCAwLlxuICAgKi9cblxuICB2YXIgc3RyZW5kID0gcy5zdHJzdGFydCArIE1BWF9NQVRDSDtcbiAgdmFyIHNjYW5fZW5kMSAgPSBfd2luW3NjYW4gKyBiZXN0X2xlbiAtIDFdO1xuICB2YXIgc2Nhbl9lbmQgICA9IF93aW5bc2NhbiArIGJlc3RfbGVuXTtcblxuICAvKiBUaGUgY29kZSBpcyBvcHRpbWl6ZWQgZm9yIEhBU0hfQklUUyA+PSA4IGFuZCBNQVhfTUFUQ0gtMiBtdWx0aXBsZSBvZiAxNi5cbiAgICogSXQgaXMgZWFzeSB0byBnZXQgcmlkIG9mIHRoaXMgb3B0aW1pemF0aW9uIGlmIG5lY2Vzc2FyeS5cbiAgICovXG4gIC8vIEFzc2VydChzLT5oYXNoX2JpdHMgPj0gOCAmJiBNQVhfTUFUQ0ggPT0gMjU4LCBcIkNvZGUgdG9vIGNsZXZlclwiKTtcblxuICAvKiBEbyBub3Qgd2FzdGUgdG9vIG11Y2ggdGltZSBpZiB3ZSBhbHJlYWR5IGhhdmUgYSBnb29kIG1hdGNoOiAqL1xuICBpZiAocy5wcmV2X2xlbmd0aCA+PSBzLmdvb2RfbWF0Y2gpIHtcbiAgICBjaGFpbl9sZW5ndGggPj49IDI7XG4gIH1cbiAgLyogRG8gbm90IGxvb2sgZm9yIG1hdGNoZXMgYmV5b25kIHRoZSBlbmQgb2YgdGhlIGlucHV0LiBUaGlzIGlzIG5lY2Vzc2FyeVxuICAgKiB0byBtYWtlIGRlZmxhdGUgZGV0ZXJtaW5pc3RpYy5cbiAgICovXG4gIGlmIChuaWNlX21hdGNoID4gcy5sb29rYWhlYWQpIHsgbmljZV9tYXRjaCA9IHMubG9va2FoZWFkOyB9XG5cbiAgLy8gQXNzZXJ0KCh1bGcpcy0+c3Ryc3RhcnQgPD0gcy0+d2luZG93X3NpemUtTUlOX0xPT0tBSEVBRCwgXCJuZWVkIGxvb2thaGVhZFwiKTtcblxuICBkbyB7XG4gICAgLy8gQXNzZXJ0KGN1cl9tYXRjaCA8IHMtPnN0cnN0YXJ0LCBcIm5vIGZ1dHVyZVwiKTtcbiAgICBtYXRjaCA9IGN1cl9tYXRjaDtcblxuICAgIC8qIFNraXAgdG8gbmV4dCBtYXRjaCBpZiB0aGUgbWF0Y2ggbGVuZ3RoIGNhbm5vdCBpbmNyZWFzZVxuICAgICAqIG9yIGlmIHRoZSBtYXRjaCBsZW5ndGggaXMgbGVzcyB0aGFuIDIuICBOb3RlIHRoYXQgdGhlIGNoZWNrcyBiZWxvd1xuICAgICAqIGZvciBpbnN1ZmZpY2llbnQgbG9va2FoZWFkIG9ubHkgb2NjdXIgb2NjYXNpb25hbGx5IGZvciBwZXJmb3JtYW5jZVxuICAgICAqIHJlYXNvbnMuICBUaGVyZWZvcmUgdW5pbml0aWFsaXplZCBtZW1vcnkgd2lsbCBiZSBhY2Nlc3NlZCwgYW5kXG4gICAgICogY29uZGl0aW9uYWwganVtcHMgd2lsbCBiZSBtYWRlIHRoYXQgZGVwZW5kIG9uIHRob3NlIHZhbHVlcy5cbiAgICAgKiBIb3dldmVyIHRoZSBsZW5ndGggb2YgdGhlIG1hdGNoIGlzIGxpbWl0ZWQgdG8gdGhlIGxvb2thaGVhZCwgc29cbiAgICAgKiB0aGUgb3V0cHV0IG9mIGRlZmxhdGUgaXMgbm90IGFmZmVjdGVkIGJ5IHRoZSB1bmluaXRpYWxpemVkIHZhbHVlcy5cbiAgICAgKi9cblxuICAgIGlmIChfd2luW21hdGNoICsgYmVzdF9sZW5dICAgICAhPT0gc2Nhbl9lbmQgIHx8XG4gICAgICAgIF93aW5bbWF0Y2ggKyBiZXN0X2xlbiAtIDFdICE9PSBzY2FuX2VuZDEgfHxcbiAgICAgICAgX3dpblttYXRjaF0gICAgICAgICAgICAgICAgIT09IF93aW5bc2Nhbl0gfHxcbiAgICAgICAgX3dpblsrK21hdGNoXSAgICAgICAgICAgICAgIT09IF93aW5bc2NhbiArIDFdKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvKiBUaGUgY2hlY2sgYXQgYmVzdF9sZW4tMSBjYW4gYmUgcmVtb3ZlZCBiZWNhdXNlIGl0IHdpbGwgYmUgbWFkZVxuICAgICAqIGFnYWluIGxhdGVyLiAoVGhpcyBoZXVyaXN0aWMgaXMgbm90IGFsd2F5cyBhIHdpbi4pXG4gICAgICogSXQgaXMgbm90IG5lY2Vzc2FyeSB0byBjb21wYXJlIHNjYW5bMl0gYW5kIG1hdGNoWzJdIHNpbmNlIHRoZXlcbiAgICAgKiBhcmUgYWx3YXlzIGVxdWFsIHdoZW4gdGhlIG90aGVyIGJ5dGVzIG1hdGNoLCBnaXZlbiB0aGF0XG4gICAgICogdGhlIGhhc2gga2V5cyBhcmUgZXF1YWwgYW5kIHRoYXQgSEFTSF9CSVRTID49IDguXG4gICAgICovXG4gICAgc2NhbiArPSAyO1xuICAgIG1hdGNoKys7XG4gICAgLy8gQXNzZXJ0KCpzY2FuID09ICptYXRjaCwgXCJtYXRjaFsyXT9cIik7XG5cbiAgICAvKiBXZSBjaGVjayBmb3IgaW5zdWZmaWNpZW50IGxvb2thaGVhZCBvbmx5IGV2ZXJ5IDh0aCBjb21wYXJpc29uO1xuICAgICAqIHRoZSAyNTZ0aCBjaGVjayB3aWxsIGJlIG1hZGUgYXQgc3Ryc3RhcnQrMjU4LlxuICAgICAqL1xuICAgIGRvIHtcbiAgICAgIC8qanNoaW50IG5vZW1wdHk6ZmFsc2UqL1xuICAgIH0gd2hpbGUgKF93aW5bKytzY2FuXSA9PT0gX3dpblsrK21hdGNoXSAmJiBfd2luWysrc2Nhbl0gPT09IF93aW5bKyttYXRjaF0gJiZcbiAgICAgICAgICAgICBfd2luWysrc2Nhbl0gPT09IF93aW5bKyttYXRjaF0gJiYgX3dpblsrK3NjYW5dID09PSBfd2luWysrbWF0Y2hdICYmXG4gICAgICAgICAgICAgX3dpblsrK3NjYW5dID09PSBfd2luWysrbWF0Y2hdICYmIF93aW5bKytzY2FuXSA9PT0gX3dpblsrK21hdGNoXSAmJlxuICAgICAgICAgICAgIF93aW5bKytzY2FuXSA9PT0gX3dpblsrK21hdGNoXSAmJiBfd2luWysrc2Nhbl0gPT09IF93aW5bKyttYXRjaF0gJiZcbiAgICAgICAgICAgICBzY2FuIDwgc3RyZW5kKTtcblxuICAgIC8vIEFzc2VydChzY2FuIDw9IHMtPndpbmRvdysodW5zaWduZWQpKHMtPndpbmRvd19zaXplLTEpLCBcIndpbGQgc2NhblwiKTtcblxuICAgIGxlbiA9IE1BWF9NQVRDSCAtIChzdHJlbmQgLSBzY2FuKTtcbiAgICBzY2FuID0gc3RyZW5kIC0gTUFYX01BVENIO1xuXG4gICAgaWYgKGxlbiA+IGJlc3RfbGVuKSB7XG4gICAgICBzLm1hdGNoX3N0YXJ0ID0gY3VyX21hdGNoO1xuICAgICAgYmVzdF9sZW4gPSBsZW47XG4gICAgICBpZiAobGVuID49IG5pY2VfbWF0Y2gpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBzY2FuX2VuZDEgID0gX3dpbltzY2FuICsgYmVzdF9sZW4gLSAxXTtcbiAgICAgIHNjYW5fZW5kICAgPSBfd2luW3NjYW4gKyBiZXN0X2xlbl07XG4gICAgfVxuICB9IHdoaWxlICgoY3VyX21hdGNoID0gcHJldltjdXJfbWF0Y2ggJiB3bWFza10pID4gbGltaXQgJiYgLS1jaGFpbl9sZW5ndGggIT09IDApO1xuXG4gIGlmIChiZXN0X2xlbiA8PSBzLmxvb2thaGVhZCkge1xuICAgIHJldHVybiBiZXN0X2xlbjtcbiAgfVxuICByZXR1cm4gcy5sb29rYWhlYWQ7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBGaWxsIHRoZSB3aW5kb3cgd2hlbiB0aGUgbG9va2FoZWFkIGJlY29tZXMgaW5zdWZmaWNpZW50LlxuICogVXBkYXRlcyBzdHJzdGFydCBhbmQgbG9va2FoZWFkLlxuICpcbiAqIElOIGFzc2VydGlvbjogbG9va2FoZWFkIDwgTUlOX0xPT0tBSEVBRFxuICogT1VUIGFzc2VydGlvbnM6IHN0cnN0YXJ0IDw9IHdpbmRvd19zaXplLU1JTl9MT09LQUhFQURcbiAqICAgIEF0IGxlYXN0IG9uZSBieXRlIGhhcyBiZWVuIHJlYWQsIG9yIGF2YWlsX2luID09IDA7IHJlYWRzIGFyZVxuICogICAgcGVyZm9ybWVkIGZvciBhdCBsZWFzdCB0d28gYnl0ZXMgKHJlcXVpcmVkIGZvciB0aGUgemlwIHRyYW5zbGF0ZV9lb2xcbiAqICAgIG9wdGlvbiAtLSBub3Qgc3VwcG9ydGVkIGhlcmUpLlxuICovXG5mdW5jdGlvbiBmaWxsX3dpbmRvdyhzKSB7XG4gIHZhciBfd19zaXplID0gcy53X3NpemU7XG4gIHZhciBwLCBuLCBtLCBtb3JlLCBzdHI7XG5cbiAgLy9Bc3NlcnQocy0+bG9va2FoZWFkIDwgTUlOX0xPT0tBSEVBRCwgXCJhbHJlYWR5IGVub3VnaCBsb29rYWhlYWRcIik7XG5cbiAgZG8ge1xuICAgIG1vcmUgPSBzLndpbmRvd19zaXplIC0gcy5sb29rYWhlYWQgLSBzLnN0cnN0YXJ0O1xuXG4gICAgLy8gSlMgaW50cyBoYXZlIDMyIGJpdCwgYmxvY2sgYmVsb3cgbm90IG5lZWRlZFxuICAgIC8qIERlYWwgd2l0aCAhQCMkJSA2NEsgbGltaXQ6ICovXG4gICAgLy9pZiAoc2l6ZW9mKGludCkgPD0gMikge1xuICAgIC8vICAgIGlmIChtb3JlID09IDAgJiYgcy0+c3Ryc3RhcnQgPT0gMCAmJiBzLT5sb29rYWhlYWQgPT0gMCkge1xuICAgIC8vICAgICAgICBtb3JlID0gd3NpemU7XG4gICAgLy9cbiAgICAvLyAgfSBlbHNlIGlmIChtb3JlID09ICh1bnNpZ25lZCkoLTEpKSB7XG4gICAgLy8gICAgICAgIC8qIFZlcnkgdW5saWtlbHksIGJ1dCBwb3NzaWJsZSBvbiAxNiBiaXQgbWFjaGluZSBpZlxuICAgIC8vICAgICAgICAgKiBzdHJzdGFydCA9PSAwICYmIGxvb2thaGVhZCA9PSAxIChpbnB1dCBkb25lIGEgYnl0ZSBhdCB0aW1lKVxuICAgIC8vICAgICAgICAgKi9cbiAgICAvLyAgICAgICAgbW9yZS0tO1xuICAgIC8vICAgIH1cbiAgICAvL31cblxuXG4gICAgLyogSWYgdGhlIHdpbmRvdyBpcyBhbG1vc3QgZnVsbCBhbmQgdGhlcmUgaXMgaW5zdWZmaWNpZW50IGxvb2thaGVhZCxcbiAgICAgKiBtb3ZlIHRoZSB1cHBlciBoYWxmIHRvIHRoZSBsb3dlciBvbmUgdG8gbWFrZSByb29tIGluIHRoZSB1cHBlciBoYWxmLlxuICAgICAqL1xuICAgIGlmIChzLnN0cnN0YXJ0ID49IF93X3NpemUgKyAoX3dfc2l6ZSAtIE1JTl9MT09LQUhFQUQpKSB7XG5cbiAgICAgIHV0aWxzLmFycmF5U2V0KHMud2luZG93LCBzLndpbmRvdywgX3dfc2l6ZSwgX3dfc2l6ZSwgMCk7XG4gICAgICBzLm1hdGNoX3N0YXJ0IC09IF93X3NpemU7XG4gICAgICBzLnN0cnN0YXJ0IC09IF93X3NpemU7XG4gICAgICAvKiB3ZSBub3cgaGF2ZSBzdHJzdGFydCA+PSBNQVhfRElTVCAqL1xuICAgICAgcy5ibG9ja19zdGFydCAtPSBfd19zaXplO1xuXG4gICAgICAvKiBTbGlkZSB0aGUgaGFzaCB0YWJsZSAoY291bGQgYmUgYXZvaWRlZCB3aXRoIDMyIGJpdCB2YWx1ZXNcbiAgICAgICBhdCB0aGUgZXhwZW5zZSBvZiBtZW1vcnkgdXNhZ2UpLiBXZSBzbGlkZSBldmVuIHdoZW4gbGV2ZWwgPT0gMFxuICAgICAgIHRvIGtlZXAgdGhlIGhhc2ggdGFibGUgY29uc2lzdGVudCBpZiB3ZSBzd2l0Y2ggYmFjayB0byBsZXZlbCA+IDBcbiAgICAgICBsYXRlci4gKFVzaW5nIGxldmVsIDAgcGVybWFuZW50bHkgaXMgbm90IGFuIG9wdGltYWwgdXNhZ2Ugb2ZcbiAgICAgICB6bGliLCBzbyB3ZSBkb24ndCBjYXJlIGFib3V0IHRoaXMgcGF0aG9sb2dpY2FsIGNhc2UuKVxuICAgICAgICovXG5cbiAgICAgIG4gPSBzLmhhc2hfc2l6ZTtcbiAgICAgIHAgPSBuO1xuICAgICAgZG8ge1xuICAgICAgICBtID0gcy5oZWFkWy0tcF07XG4gICAgICAgIHMuaGVhZFtwXSA9IChtID49IF93X3NpemUgPyBtIC0gX3dfc2l6ZSA6IDApO1xuICAgICAgfSB3aGlsZSAoLS1uKTtcblxuICAgICAgbiA9IF93X3NpemU7XG4gICAgICBwID0gbjtcbiAgICAgIGRvIHtcbiAgICAgICAgbSA9IHMucHJldlstLXBdO1xuICAgICAgICBzLnByZXZbcF0gPSAobSA+PSBfd19zaXplID8gbSAtIF93X3NpemUgOiAwKTtcbiAgICAgICAgLyogSWYgbiBpcyBub3Qgb24gYW55IGhhc2ggY2hhaW4sIHByZXZbbl0gaXMgZ2FyYmFnZSBidXRcbiAgICAgICAgICogaXRzIHZhbHVlIHdpbGwgbmV2ZXIgYmUgdXNlZC5cbiAgICAgICAgICovXG4gICAgICB9IHdoaWxlICgtLW4pO1xuXG4gICAgICBtb3JlICs9IF93X3NpemU7XG4gICAgfVxuICAgIGlmIChzLnN0cm0uYXZhaWxfaW4gPT09IDApIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8qIElmIHRoZXJlIHdhcyBubyBzbGlkaW5nOlxuICAgICAqICAgIHN0cnN0YXJ0IDw9IFdTSVpFK01BWF9ESVNULTEgJiYgbG9va2FoZWFkIDw9IE1JTl9MT09LQUhFQUQgLSAxICYmXG4gICAgICogICAgbW9yZSA9PSB3aW5kb3dfc2l6ZSAtIGxvb2thaGVhZCAtIHN0cnN0YXJ0XG4gICAgICogPT4gbW9yZSA+PSB3aW5kb3dfc2l6ZSAtIChNSU5fTE9PS0FIRUFELTEgKyBXU0laRSArIE1BWF9ESVNULTEpXG4gICAgICogPT4gbW9yZSA+PSB3aW5kb3dfc2l6ZSAtIDIqV1NJWkUgKyAyXG4gICAgICogSW4gdGhlIEJJR19NRU0gb3IgTU1BUCBjYXNlIChub3QgeWV0IHN1cHBvcnRlZCksXG4gICAgICogICB3aW5kb3dfc2l6ZSA9PSBpbnB1dF9zaXplICsgTUlOX0xPT0tBSEVBRCAgJiZcbiAgICAgKiAgIHN0cnN0YXJ0ICsgcy0+bG9va2FoZWFkIDw9IGlucHV0X3NpemUgPT4gbW9yZSA+PSBNSU5fTE9PS0FIRUFELlxuICAgICAqIE90aGVyd2lzZSwgd2luZG93X3NpemUgPT0gMipXU0laRSBzbyBtb3JlID49IDIuXG4gICAgICogSWYgdGhlcmUgd2FzIHNsaWRpbmcsIG1vcmUgPj0gV1NJWkUuIFNvIGluIGFsbCBjYXNlcywgbW9yZSA+PSAyLlxuICAgICAqL1xuICAgIC8vQXNzZXJ0KG1vcmUgPj0gMiwgXCJtb3JlIDwgMlwiKTtcbiAgICBuID0gcmVhZF9idWYocy5zdHJtLCBzLndpbmRvdywgcy5zdHJzdGFydCArIHMubG9va2FoZWFkLCBtb3JlKTtcbiAgICBzLmxvb2thaGVhZCArPSBuO1xuXG4gICAgLyogSW5pdGlhbGl6ZSB0aGUgaGFzaCB2YWx1ZSBub3cgdGhhdCB3ZSBoYXZlIHNvbWUgaW5wdXQ6ICovXG4gICAgaWYgKHMubG9va2FoZWFkICsgcy5pbnNlcnQgPj0gTUlOX01BVENIKSB7XG4gICAgICBzdHIgPSBzLnN0cnN0YXJ0IC0gcy5pbnNlcnQ7XG4gICAgICBzLmluc19oID0gcy53aW5kb3dbc3RyXTtcblxuICAgICAgLyogVVBEQVRFX0hBU0gocywgcy0+aW5zX2gsIHMtPndpbmRvd1tzdHIgKyAxXSk7ICovXG4gICAgICBzLmluc19oID0gKChzLmluc19oIDw8IHMuaGFzaF9zaGlmdCkgXiBzLndpbmRvd1tzdHIgKyAxXSkgJiBzLmhhc2hfbWFzaztcbi8vI2lmIE1JTl9NQVRDSCAhPSAzXG4vLyAgICAgICAgQ2FsbCB1cGRhdGVfaGFzaCgpIE1JTl9NQVRDSC0zIG1vcmUgdGltZXNcbi8vI2VuZGlmXG4gICAgICB3aGlsZSAocy5pbnNlcnQpIHtcbiAgICAgICAgLyogVVBEQVRFX0hBU0gocywgcy0+aW5zX2gsIHMtPndpbmRvd1tzdHIgKyBNSU5fTUFUQ0gtMV0pOyAqL1xuICAgICAgICBzLmluc19oID0gKChzLmluc19oIDw8IHMuaGFzaF9zaGlmdCkgXiBzLndpbmRvd1tzdHIgKyBNSU5fTUFUQ0ggLSAxXSkgJiBzLmhhc2hfbWFzaztcblxuICAgICAgICBzLnByZXZbc3RyICYgcy53X21hc2tdID0gcy5oZWFkW3MuaW5zX2hdO1xuICAgICAgICBzLmhlYWRbcy5pbnNfaF0gPSBzdHI7XG4gICAgICAgIHN0cisrO1xuICAgICAgICBzLmluc2VydC0tO1xuICAgICAgICBpZiAocy5sb29rYWhlYWQgKyBzLmluc2VydCA8IE1JTl9NQVRDSCkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIC8qIElmIHRoZSB3aG9sZSBpbnB1dCBoYXMgbGVzcyB0aGFuIE1JTl9NQVRDSCBieXRlcywgaW5zX2ggaXMgZ2FyYmFnZSxcbiAgICAgKiBidXQgdGhpcyBpcyBub3QgaW1wb3J0YW50IHNpbmNlIG9ubHkgbGl0ZXJhbCBieXRlcyB3aWxsIGJlIGVtaXR0ZWQuXG4gICAgICovXG5cbiAgfSB3aGlsZSAocy5sb29rYWhlYWQgPCBNSU5fTE9PS0FIRUFEICYmIHMuc3RybS5hdmFpbF9pbiAhPT0gMCk7XG5cbiAgLyogSWYgdGhlIFdJTl9JTklUIGJ5dGVzIGFmdGVyIHRoZSBlbmQgb2YgdGhlIGN1cnJlbnQgZGF0YSBoYXZlIG5ldmVyIGJlZW5cbiAgICogd3JpdHRlbiwgdGhlbiB6ZXJvIHRob3NlIGJ5dGVzIGluIG9yZGVyIHRvIGF2b2lkIG1lbW9yeSBjaGVjayByZXBvcnRzIG9mXG4gICAqIHRoZSB1c2Ugb2YgdW5pbml0aWFsaXplZCAob3IgdW5pbml0aWFsaXNlZCBhcyBKdWxpYW4gd3JpdGVzKSBieXRlcyBieVxuICAgKiB0aGUgbG9uZ2VzdCBtYXRjaCByb3V0aW5lcy4gIFVwZGF0ZSB0aGUgaGlnaCB3YXRlciBtYXJrIGZvciB0aGUgbmV4dFxuICAgKiB0aW1lIHRocm91Z2ggaGVyZS4gIFdJTl9JTklUIGlzIHNldCB0byBNQVhfTUFUQ0ggc2luY2UgdGhlIGxvbmdlc3QgbWF0Y2hcbiAgICogcm91dGluZXMgYWxsb3cgc2Nhbm5pbmcgdG8gc3Ryc3RhcnQgKyBNQVhfTUFUQ0gsIGlnbm9yaW5nIGxvb2thaGVhZC5cbiAgICovXG4vLyAgaWYgKHMuaGlnaF93YXRlciA8IHMud2luZG93X3NpemUpIHtcbi8vICAgIHZhciBjdXJyID0gcy5zdHJzdGFydCArIHMubG9va2FoZWFkO1xuLy8gICAgdmFyIGluaXQgPSAwO1xuLy9cbi8vICAgIGlmIChzLmhpZ2hfd2F0ZXIgPCBjdXJyKSB7XG4vLyAgICAgIC8qIFByZXZpb3VzIGhpZ2ggd2F0ZXIgbWFyayBiZWxvdyBjdXJyZW50IGRhdGEgLS0gemVybyBXSU5fSU5JVFxuLy8gICAgICAgKiBieXRlcyBvciB1cCB0byBlbmQgb2Ygd2luZG93LCB3aGljaGV2ZXIgaXMgbGVzcy5cbi8vICAgICAgICovXG4vLyAgICAgIGluaXQgPSBzLndpbmRvd19zaXplIC0gY3Vycjtcbi8vICAgICAgaWYgKGluaXQgPiBXSU5fSU5JVClcbi8vICAgICAgICBpbml0ID0gV0lOX0lOSVQ7XG4vLyAgICAgIHptZW16ZXJvKHMtPndpbmRvdyArIGN1cnIsICh1bnNpZ25lZClpbml0KTtcbi8vICAgICAgcy0+aGlnaF93YXRlciA9IGN1cnIgKyBpbml0O1xuLy8gICAgfVxuLy8gICAgZWxzZSBpZiAocy0+aGlnaF93YXRlciA8ICh1bGcpY3VyciArIFdJTl9JTklUKSB7XG4vLyAgICAgIC8qIEhpZ2ggd2F0ZXIgbWFyayBhdCBvciBhYm92ZSBjdXJyZW50IGRhdGEsIGJ1dCBiZWxvdyBjdXJyZW50IGRhdGFcbi8vICAgICAgICogcGx1cyBXSU5fSU5JVCAtLSB6ZXJvIG91dCB0byBjdXJyZW50IGRhdGEgcGx1cyBXSU5fSU5JVCwgb3IgdXBcbi8vICAgICAgICogdG8gZW5kIG9mIHdpbmRvdywgd2hpY2hldmVyIGlzIGxlc3MuXG4vLyAgICAgICAqL1xuLy8gICAgICBpbml0ID0gKHVsZyljdXJyICsgV0lOX0lOSVQgLSBzLT5oaWdoX3dhdGVyO1xuLy8gICAgICBpZiAoaW5pdCA+IHMtPndpbmRvd19zaXplIC0gcy0+aGlnaF93YXRlcilcbi8vICAgICAgICBpbml0ID0gcy0+d2luZG93X3NpemUgLSBzLT5oaWdoX3dhdGVyO1xuLy8gICAgICB6bWVtemVybyhzLT53aW5kb3cgKyBzLT5oaWdoX3dhdGVyLCAodW5zaWduZWQpaW5pdCk7XG4vLyAgICAgIHMtPmhpZ2hfd2F0ZXIgKz0gaW5pdDtcbi8vICAgIH1cbi8vICB9XG4vL1xuLy8gIEFzc2VydCgodWxnKXMtPnN0cnN0YXJ0IDw9IHMtPndpbmRvd19zaXplIC0gTUlOX0xPT0tBSEVBRCxcbi8vICAgIFwibm90IGVub3VnaCByb29tIGZvciBzZWFyY2hcIik7XG59XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQ29weSB3aXRob3V0IGNvbXByZXNzaW9uIGFzIG11Y2ggYXMgcG9zc2libGUgZnJvbSB0aGUgaW5wdXQgc3RyZWFtLCByZXR1cm5cbiAqIHRoZSBjdXJyZW50IGJsb2NrIHN0YXRlLlxuICogVGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBpbnNlcnQgbmV3IHN0cmluZ3MgaW4gdGhlIGRpY3Rpb25hcnkgc2luY2VcbiAqIHVuY29tcHJlc3NpYmxlIGRhdGEgaXMgcHJvYmFibHkgbm90IHVzZWZ1bC4gVGhpcyBmdW5jdGlvbiBpcyB1c2VkXG4gKiBvbmx5IGZvciB0aGUgbGV2ZWw9MCBjb21wcmVzc2lvbiBvcHRpb24uXG4gKiBOT1RFOiB0aGlzIGZ1bmN0aW9uIHNob3VsZCBiZSBvcHRpbWl6ZWQgdG8gYXZvaWQgZXh0cmEgY29weWluZyBmcm9tXG4gKiB3aW5kb3cgdG8gcGVuZGluZ19idWYuXG4gKi9cbmZ1bmN0aW9uIGRlZmxhdGVfc3RvcmVkKHMsIGZsdXNoKSB7XG4gIC8qIFN0b3JlZCBibG9ja3MgYXJlIGxpbWl0ZWQgdG8gMHhmZmZmIGJ5dGVzLCBwZW5kaW5nX2J1ZiBpcyBsaW1pdGVkXG4gICAqIHRvIHBlbmRpbmdfYnVmX3NpemUsIGFuZCBlYWNoIHN0b3JlZCBibG9jayBoYXMgYSA1IGJ5dGUgaGVhZGVyOlxuICAgKi9cbiAgdmFyIG1heF9ibG9ja19zaXplID0gMHhmZmZmO1xuXG4gIGlmIChtYXhfYmxvY2tfc2l6ZSA+IHMucGVuZGluZ19idWZfc2l6ZSAtIDUpIHtcbiAgICBtYXhfYmxvY2tfc2l6ZSA9IHMucGVuZGluZ19idWZfc2l6ZSAtIDU7XG4gIH1cblxuICAvKiBDb3B5IGFzIG11Y2ggYXMgcG9zc2libGUgZnJvbSBpbnB1dCB0byBvdXRwdXQ6ICovXG4gIGZvciAoOzspIHtcbiAgICAvKiBGaWxsIHRoZSB3aW5kb3cgYXMgbXVjaCBhcyBwb3NzaWJsZTogKi9cbiAgICBpZiAocy5sb29rYWhlYWQgPD0gMSkge1xuXG4gICAgICAvL0Fzc2VydChzLT5zdHJzdGFydCA8IHMtPndfc2l6ZStNQVhfRElTVChzKSB8fFxuICAgICAgLy8gIHMtPmJsb2NrX3N0YXJ0ID49IChsb25nKXMtPndfc2l6ZSwgXCJzbGlkZSB0b28gbGF0ZVwiKTtcbi8vICAgICAgaWYgKCEocy5zdHJzdGFydCA8IHMud19zaXplICsgKHMud19zaXplIC0gTUlOX0xPT0tBSEVBRCkgfHxcbi8vICAgICAgICBzLmJsb2NrX3N0YXJ0ID49IHMud19zaXplKSkge1xuLy8gICAgICAgIHRocm93ICBuZXcgRXJyb3IoXCJzbGlkZSB0b28gbGF0ZVwiKTtcbi8vICAgICAgfVxuXG4gICAgICBmaWxsX3dpbmRvdyhzKTtcbiAgICAgIGlmIChzLmxvb2thaGVhZCA9PT0gMCAmJiBmbHVzaCA9PT0gWl9OT19GTFVTSCkge1xuICAgICAgICByZXR1cm4gQlNfTkVFRF9NT1JFO1xuICAgICAgfVxuXG4gICAgICBpZiAocy5sb29rYWhlYWQgPT09IDApIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICAvKiBmbHVzaCB0aGUgY3VycmVudCBibG9jayAqL1xuICAgIH1cbiAgICAvL0Fzc2VydChzLT5ibG9ja19zdGFydCA+PSAwTCwgXCJibG9jayBnb25lXCIpO1xuLy8gICAgaWYgKHMuYmxvY2tfc3RhcnQgPCAwKSB0aHJvdyBuZXcgRXJyb3IoXCJibG9jayBnb25lXCIpO1xuXG4gICAgcy5zdHJzdGFydCArPSBzLmxvb2thaGVhZDtcbiAgICBzLmxvb2thaGVhZCA9IDA7XG5cbiAgICAvKiBFbWl0IGEgc3RvcmVkIGJsb2NrIGlmIHBlbmRpbmdfYnVmIHdpbGwgYmUgZnVsbDogKi9cbiAgICB2YXIgbWF4X3N0YXJ0ID0gcy5ibG9ja19zdGFydCArIG1heF9ibG9ja19zaXplO1xuXG4gICAgaWYgKHMuc3Ryc3RhcnQgPT09IDAgfHwgcy5zdHJzdGFydCA+PSBtYXhfc3RhcnQpIHtcbiAgICAgIC8qIHN0cnN0YXJ0ID09IDAgaXMgcG9zc2libGUgd2hlbiB3cmFwYXJvdW5kIG9uIDE2LWJpdCBtYWNoaW5lICovXG4gICAgICBzLmxvb2thaGVhZCA9IHMuc3Ryc3RhcnQgLSBtYXhfc3RhcnQ7XG4gICAgICBzLnN0cnN0YXJ0ID0gbWF4X3N0YXJ0O1xuICAgICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAwKTsgKioqL1xuICAgICAgZmx1c2hfYmxvY2tfb25seShzLCBmYWxzZSk7XG4gICAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gQlNfTkVFRF9NT1JFO1xuICAgICAgfVxuICAgICAgLyoqKi9cblxuXG4gICAgfVxuICAgIC8qIEZsdXNoIGlmIHdlIG1heSBoYXZlIHRvIHNsaWRlLCBvdGhlcndpc2UgYmxvY2tfc3RhcnQgbWF5IGJlY29tZVxuICAgICAqIG5lZ2F0aXZlIGFuZCB0aGUgZGF0YSB3aWxsIGJlIGdvbmU6XG4gICAgICovXG4gICAgaWYgKHMuc3Ryc3RhcnQgLSBzLmJsb2NrX3N0YXJ0ID49IChzLndfc2l6ZSAtIE1JTl9MT09LQUhFQUQpKSB7XG4gICAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovXG4gICAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTtcbiAgICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgICB9XG4gICAgICAvKioqL1xuICAgIH1cbiAgfVxuXG4gIHMuaW5zZXJ0ID0gMDtcblxuICBpZiAoZmx1c2ggPT09IFpfRklOSVNIKSB7XG4gICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAxKTsgKioqL1xuICAgIGZsdXNoX2Jsb2NrX29ubHkocywgdHJ1ZSk7XG4gICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIHJldHVybiBCU19GSU5JU0hfU1RBUlRFRDtcbiAgICB9XG4gICAgLyoqKi9cbiAgICByZXR1cm4gQlNfRklOSVNIX0RPTkU7XG4gIH1cblxuICBpZiAocy5zdHJzdGFydCA+IHMuYmxvY2tfc3RhcnQpIHtcbiAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovXG4gICAgZmx1c2hfYmxvY2tfb25seShzLCBmYWxzZSk7XG4gICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgfVxuICAgIC8qKiovXG4gIH1cblxuICByZXR1cm4gQlNfTkVFRF9NT1JFO1xufVxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvbXByZXNzIGFzIG11Y2ggYXMgcG9zc2libGUgZnJvbSB0aGUgaW5wdXQgc3RyZWFtLCByZXR1cm4gdGhlIGN1cnJlbnRcbiAqIGJsb2NrIHN0YXRlLlxuICogVGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBwZXJmb3JtIGxhenkgZXZhbHVhdGlvbiBvZiBtYXRjaGVzIGFuZCBpbnNlcnRzXG4gKiBuZXcgc3RyaW5ncyBpbiB0aGUgZGljdGlvbmFyeSBvbmx5IGZvciB1bm1hdGNoZWQgc3RyaW5ncyBvciBmb3Igc2hvcnRcbiAqIG1hdGNoZXMuIEl0IGlzIHVzZWQgb25seSBmb3IgdGhlIGZhc3QgY29tcHJlc3Npb24gb3B0aW9ucy5cbiAqL1xuZnVuY3Rpb24gZGVmbGF0ZV9mYXN0KHMsIGZsdXNoKSB7XG4gIHZhciBoYXNoX2hlYWQ7ICAgICAgICAvKiBoZWFkIG9mIHRoZSBoYXNoIGNoYWluICovXG4gIHZhciBiZmx1c2g7ICAgICAgICAgICAvKiBzZXQgaWYgY3VycmVudCBibG9jayBtdXN0IGJlIGZsdXNoZWQgKi9cblxuICBmb3IgKDs7KSB7XG4gICAgLyogTWFrZSBzdXJlIHRoYXQgd2UgYWx3YXlzIGhhdmUgZW5vdWdoIGxvb2thaGVhZCwgZXhjZXB0XG4gICAgICogYXQgdGhlIGVuZCBvZiB0aGUgaW5wdXQgZmlsZS4gV2UgbmVlZCBNQVhfTUFUQ0ggYnl0ZXNcbiAgICAgKiBmb3IgdGhlIG5leHQgbWF0Y2gsIHBsdXMgTUlOX01BVENIIGJ5dGVzIHRvIGluc2VydCB0aGVcbiAgICAgKiBzdHJpbmcgZm9sbG93aW5nIHRoZSBuZXh0IG1hdGNoLlxuICAgICAqL1xuICAgIGlmIChzLmxvb2thaGVhZCA8IE1JTl9MT09LQUhFQUQpIHtcbiAgICAgIGZpbGxfd2luZG93KHMpO1xuICAgICAgaWYgKHMubG9va2FoZWFkIDwgTUlOX0xPT0tBSEVBRCAmJiBmbHVzaCA9PT0gWl9OT19GTFVTSCkge1xuICAgICAgICByZXR1cm4gQlNfTkVFRF9NT1JFO1xuICAgICAgfVxuICAgICAgaWYgKHMubG9va2FoZWFkID09PSAwKSB7XG4gICAgICAgIGJyZWFrOyAvKiBmbHVzaCB0aGUgY3VycmVudCBibG9jayAqL1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qIEluc2VydCB0aGUgc3RyaW5nIHdpbmRvd1tzdHJzdGFydCAuLiBzdHJzdGFydCsyXSBpbiB0aGVcbiAgICAgKiBkaWN0aW9uYXJ5LCBhbmQgc2V0IGhhc2hfaGVhZCB0byB0aGUgaGVhZCBvZiB0aGUgaGFzaCBjaGFpbjpcbiAgICAgKi9cbiAgICBoYXNoX2hlYWQgPSAwLypOSUwqLztcbiAgICBpZiAocy5sb29rYWhlYWQgPj0gTUlOX01BVENIKSB7XG4gICAgICAvKioqIElOU0VSVF9TVFJJTkcocywgcy5zdHJzdGFydCwgaGFzaF9oZWFkKTsgKioqL1xuICAgICAgcy5pbnNfaCA9ICgocy5pbnNfaCA8PCBzLmhhc2hfc2hpZnQpIF4gcy53aW5kb3dbcy5zdHJzdGFydCArIE1JTl9NQVRDSCAtIDFdKSAmIHMuaGFzaF9tYXNrO1xuICAgICAgaGFzaF9oZWFkID0gcy5wcmV2W3Muc3Ryc3RhcnQgJiBzLndfbWFza10gPSBzLmhlYWRbcy5pbnNfaF07XG4gICAgICBzLmhlYWRbcy5pbnNfaF0gPSBzLnN0cnN0YXJ0O1xuICAgICAgLyoqKi9cbiAgICB9XG5cbiAgICAvKiBGaW5kIHRoZSBsb25nZXN0IG1hdGNoLCBkaXNjYXJkaW5nIHRob3NlIDw9IHByZXZfbGVuZ3RoLlxuICAgICAqIEF0IHRoaXMgcG9pbnQgd2UgaGF2ZSBhbHdheXMgbWF0Y2hfbGVuZ3RoIDwgTUlOX01BVENIXG4gICAgICovXG4gICAgaWYgKGhhc2hfaGVhZCAhPT0gMC8qTklMKi8gJiYgKChzLnN0cnN0YXJ0IC0gaGFzaF9oZWFkKSA8PSAocy53X3NpemUgLSBNSU5fTE9PS0FIRUFEKSkpIHtcbiAgICAgIC8qIFRvIHNpbXBsaWZ5IHRoZSBjb2RlLCB3ZSBwcmV2ZW50IG1hdGNoZXMgd2l0aCB0aGUgc3RyaW5nXG4gICAgICAgKiBvZiB3aW5kb3cgaW5kZXggMCAoaW4gcGFydGljdWxhciB3ZSBoYXZlIHRvIGF2b2lkIGEgbWF0Y2hcbiAgICAgICAqIG9mIHRoZSBzdHJpbmcgd2l0aCBpdHNlbGYgYXQgdGhlIHN0YXJ0IG9mIHRoZSBpbnB1dCBmaWxlKS5cbiAgICAgICAqL1xuICAgICAgcy5tYXRjaF9sZW5ndGggPSBsb25nZXN0X21hdGNoKHMsIGhhc2hfaGVhZCk7XG4gICAgICAvKiBsb25nZXN0X21hdGNoKCkgc2V0cyBtYXRjaF9zdGFydCAqL1xuICAgIH1cbiAgICBpZiAocy5tYXRjaF9sZW5ndGggPj0gTUlOX01BVENIKSB7XG4gICAgICAvLyBjaGVja19tYXRjaChzLCBzLnN0cnN0YXJ0LCBzLm1hdGNoX3N0YXJ0LCBzLm1hdGNoX2xlbmd0aCk7IC8vIGZvciBkZWJ1ZyBvbmx5XG5cbiAgICAgIC8qKiogX3RyX3RhbGx5X2Rpc3Qocywgcy5zdHJzdGFydCAtIHMubWF0Y2hfc3RhcnQsXG4gICAgICAgICAgICAgICAgICAgICBzLm1hdGNoX2xlbmd0aCAtIE1JTl9NQVRDSCwgYmZsdXNoKTsgKioqL1xuICAgICAgYmZsdXNoID0gdHJlZXMuX3RyX3RhbGx5KHMsIHMuc3Ryc3RhcnQgLSBzLm1hdGNoX3N0YXJ0LCBzLm1hdGNoX2xlbmd0aCAtIE1JTl9NQVRDSCk7XG5cbiAgICAgIHMubG9va2FoZWFkIC09IHMubWF0Y2hfbGVuZ3RoO1xuXG4gICAgICAvKiBJbnNlcnQgbmV3IHN0cmluZ3MgaW4gdGhlIGhhc2ggdGFibGUgb25seSBpZiB0aGUgbWF0Y2ggbGVuZ3RoXG4gICAgICAgKiBpcyBub3QgdG9vIGxhcmdlLiBUaGlzIHNhdmVzIHRpbWUgYnV0IGRlZ3JhZGVzIGNvbXByZXNzaW9uLlxuICAgICAgICovXG4gICAgICBpZiAocy5tYXRjaF9sZW5ndGggPD0gcy5tYXhfbGF6eV9tYXRjaC8qbWF4X2luc2VydF9sZW5ndGgqLyAmJiBzLmxvb2thaGVhZCA+PSBNSU5fTUFUQ0gpIHtcbiAgICAgICAgcy5tYXRjaF9sZW5ndGgtLTsgLyogc3RyaW5nIGF0IHN0cnN0YXJ0IGFscmVhZHkgaW4gdGFibGUgKi9cbiAgICAgICAgZG8ge1xuICAgICAgICAgIHMuc3Ryc3RhcnQrKztcbiAgICAgICAgICAvKioqIElOU0VSVF9TVFJJTkcocywgcy5zdHJzdGFydCwgaGFzaF9oZWFkKTsgKioqL1xuICAgICAgICAgIHMuaW5zX2ggPSAoKHMuaW5zX2ggPDwgcy5oYXNoX3NoaWZ0KSBeIHMud2luZG93W3Muc3Ryc3RhcnQgKyBNSU5fTUFUQ0ggLSAxXSkgJiBzLmhhc2hfbWFzaztcbiAgICAgICAgICBoYXNoX2hlYWQgPSBzLnByZXZbcy5zdHJzdGFydCAmIHMud19tYXNrXSA9IHMuaGVhZFtzLmluc19oXTtcbiAgICAgICAgICBzLmhlYWRbcy5pbnNfaF0gPSBzLnN0cnN0YXJ0O1xuICAgICAgICAgIC8qKiovXG4gICAgICAgICAgLyogc3Ryc3RhcnQgbmV2ZXIgZXhjZWVkcyBXU0laRS1NQVhfTUFUQ0gsIHNvIHRoZXJlIGFyZVxuICAgICAgICAgICAqIGFsd2F5cyBNSU5fTUFUQ0ggYnl0ZXMgYWhlYWQuXG4gICAgICAgICAgICovXG4gICAgICAgIH0gd2hpbGUgKC0tcy5tYXRjaF9sZW5ndGggIT09IDApO1xuICAgICAgICBzLnN0cnN0YXJ0Kys7XG4gICAgICB9IGVsc2VcbiAgICAgIHtcbiAgICAgICAgcy5zdHJzdGFydCArPSBzLm1hdGNoX2xlbmd0aDtcbiAgICAgICAgcy5tYXRjaF9sZW5ndGggPSAwO1xuICAgICAgICBzLmluc19oID0gcy53aW5kb3dbcy5zdHJzdGFydF07XG4gICAgICAgIC8qIFVQREFURV9IQVNIKHMsIHMuaW5zX2gsIHMud2luZG93W3Muc3Ryc3RhcnQrMV0pOyAqL1xuICAgICAgICBzLmluc19oID0gKChzLmluc19oIDw8IHMuaGFzaF9zaGlmdCkgXiBzLndpbmRvd1tzLnN0cnN0YXJ0ICsgMV0pICYgcy5oYXNoX21hc2s7XG5cbi8vI2lmIE1JTl9NQVRDSCAhPSAzXG4vLyAgICAgICAgICAgICAgICBDYWxsIFVQREFURV9IQVNIKCkgTUlOX01BVENILTMgbW9yZSB0aW1lc1xuLy8jZW5kaWZcbiAgICAgICAgLyogSWYgbG9va2FoZWFkIDwgTUlOX01BVENILCBpbnNfaCBpcyBnYXJiYWdlLCBidXQgaXQgZG9lcyBub3RcbiAgICAgICAgICogbWF0dGVyIHNpbmNlIGl0IHdpbGwgYmUgcmVjb21wdXRlZCBhdCBuZXh0IGRlZmxhdGUgY2FsbC5cbiAgICAgICAgICovXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8qIE5vIG1hdGNoLCBvdXRwdXQgYSBsaXRlcmFsIGJ5dGUgKi9cbiAgICAgIC8vVHJhY2V2digoc3RkZXJyLFwiJWNcIiwgcy53aW5kb3dbcy5zdHJzdGFydF0pKTtcbiAgICAgIC8qKiogX3RyX3RhbGx5X2xpdChzLCBzLndpbmRvd1tzLnN0cnN0YXJ0XSwgYmZsdXNoKTsgKioqL1xuICAgICAgYmZsdXNoID0gdHJlZXMuX3RyX3RhbGx5KHMsIDAsIHMud2luZG93W3Muc3Ryc3RhcnRdKTtcblxuICAgICAgcy5sb29rYWhlYWQtLTtcbiAgICAgIHMuc3Ryc3RhcnQrKztcbiAgICB9XG4gICAgaWYgKGJmbHVzaCkge1xuICAgICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAwKTsgKioqL1xuICAgICAgZmx1c2hfYmxvY2tfb25seShzLCBmYWxzZSk7XG4gICAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gQlNfTkVFRF9NT1JFO1xuICAgICAgfVxuICAgICAgLyoqKi9cbiAgICB9XG4gIH1cbiAgcy5pbnNlcnQgPSAoKHMuc3Ryc3RhcnQgPCAoTUlOX01BVENIIC0gMSkpID8gcy5zdHJzdGFydCA6IE1JTl9NQVRDSCAtIDEpO1xuICBpZiAoZmx1c2ggPT09IFpfRklOSVNIKSB7XG4gICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAxKTsgKioqL1xuICAgIGZsdXNoX2Jsb2NrX29ubHkocywgdHJ1ZSk7XG4gICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIHJldHVybiBCU19GSU5JU0hfU1RBUlRFRDtcbiAgICB9XG4gICAgLyoqKi9cbiAgICByZXR1cm4gQlNfRklOSVNIX0RPTkU7XG4gIH1cbiAgaWYgKHMubGFzdF9saXQpIHtcbiAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovXG4gICAgZmx1c2hfYmxvY2tfb25seShzLCBmYWxzZSk7XG4gICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgfVxuICAgIC8qKiovXG4gIH1cbiAgcmV0dXJuIEJTX0JMT0NLX0RPTkU7XG59XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogU2FtZSBhcyBhYm92ZSwgYnV0IGFjaGlldmVzIGJldHRlciBjb21wcmVzc2lvbi4gV2UgdXNlIGEgbGF6eVxuICogZXZhbHVhdGlvbiBmb3IgbWF0Y2hlczogYSBtYXRjaCBpcyBmaW5hbGx5IGFkb3B0ZWQgb25seSBpZiB0aGVyZSBpc1xuICogbm8gYmV0dGVyIG1hdGNoIGF0IHRoZSBuZXh0IHdpbmRvdyBwb3NpdGlvbi5cbiAqL1xuZnVuY3Rpb24gZGVmbGF0ZV9zbG93KHMsIGZsdXNoKSB7XG4gIHZhciBoYXNoX2hlYWQ7ICAgICAgICAgIC8qIGhlYWQgb2YgaGFzaCBjaGFpbiAqL1xuICB2YXIgYmZsdXNoOyAgICAgICAgICAgICAgLyogc2V0IGlmIGN1cnJlbnQgYmxvY2sgbXVzdCBiZSBmbHVzaGVkICovXG5cbiAgdmFyIG1heF9pbnNlcnQ7XG5cbiAgLyogUHJvY2VzcyB0aGUgaW5wdXQgYmxvY2suICovXG4gIGZvciAoOzspIHtcbiAgICAvKiBNYWtlIHN1cmUgdGhhdCB3ZSBhbHdheXMgaGF2ZSBlbm91Z2ggbG9va2FoZWFkLCBleGNlcHRcbiAgICAgKiBhdCB0aGUgZW5kIG9mIHRoZSBpbnB1dCBmaWxlLiBXZSBuZWVkIE1BWF9NQVRDSCBieXRlc1xuICAgICAqIGZvciB0aGUgbmV4dCBtYXRjaCwgcGx1cyBNSU5fTUFUQ0ggYnl0ZXMgdG8gaW5zZXJ0IHRoZVxuICAgICAqIHN0cmluZyBmb2xsb3dpbmcgdGhlIG5leHQgbWF0Y2guXG4gICAgICovXG4gICAgaWYgKHMubG9va2FoZWFkIDwgTUlOX0xPT0tBSEVBRCkge1xuICAgICAgZmlsbF93aW5kb3cocyk7XG4gICAgICBpZiAocy5sb29rYWhlYWQgPCBNSU5fTE9PS0FIRUFEICYmIGZsdXNoID09PSBaX05PX0ZMVVNIKSB7XG4gICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgICB9XG4gICAgICBpZiAocy5sb29rYWhlYWQgPT09IDApIHsgYnJlYWs7IH0gLyogZmx1c2ggdGhlIGN1cnJlbnQgYmxvY2sgKi9cbiAgICB9XG5cbiAgICAvKiBJbnNlcnQgdGhlIHN0cmluZyB3aW5kb3dbc3Ryc3RhcnQgLi4gc3Ryc3RhcnQrMl0gaW4gdGhlXG4gICAgICogZGljdGlvbmFyeSwgYW5kIHNldCBoYXNoX2hlYWQgdG8gdGhlIGhlYWQgb2YgdGhlIGhhc2ggY2hhaW46XG4gICAgICovXG4gICAgaGFzaF9oZWFkID0gMC8qTklMKi87XG4gICAgaWYgKHMubG9va2FoZWFkID49IE1JTl9NQVRDSCkge1xuICAgICAgLyoqKiBJTlNFUlRfU1RSSU5HKHMsIHMuc3Ryc3RhcnQsIGhhc2hfaGVhZCk7ICoqKi9cbiAgICAgIHMuaW5zX2ggPSAoKHMuaW5zX2ggPDwgcy5oYXNoX3NoaWZ0KSBeIHMud2luZG93W3Muc3Ryc3RhcnQgKyBNSU5fTUFUQ0ggLSAxXSkgJiBzLmhhc2hfbWFzaztcbiAgICAgIGhhc2hfaGVhZCA9IHMucHJldltzLnN0cnN0YXJ0ICYgcy53X21hc2tdID0gcy5oZWFkW3MuaW5zX2hdO1xuICAgICAgcy5oZWFkW3MuaW5zX2hdID0gcy5zdHJzdGFydDtcbiAgICAgIC8qKiovXG4gICAgfVxuXG4gICAgLyogRmluZCB0aGUgbG9uZ2VzdCBtYXRjaCwgZGlzY2FyZGluZyB0aG9zZSA8PSBwcmV2X2xlbmd0aC5cbiAgICAgKi9cbiAgICBzLnByZXZfbGVuZ3RoID0gcy5tYXRjaF9sZW5ndGg7XG4gICAgcy5wcmV2X21hdGNoID0gcy5tYXRjaF9zdGFydDtcbiAgICBzLm1hdGNoX2xlbmd0aCA9IE1JTl9NQVRDSCAtIDE7XG5cbiAgICBpZiAoaGFzaF9oZWFkICE9PSAwLypOSUwqLyAmJiBzLnByZXZfbGVuZ3RoIDwgcy5tYXhfbGF6eV9tYXRjaCAmJlxuICAgICAgICBzLnN0cnN0YXJ0IC0gaGFzaF9oZWFkIDw9IChzLndfc2l6ZSAtIE1JTl9MT09LQUhFQUQpLypNQVhfRElTVChzKSovKSB7XG4gICAgICAvKiBUbyBzaW1wbGlmeSB0aGUgY29kZSwgd2UgcHJldmVudCBtYXRjaGVzIHdpdGggdGhlIHN0cmluZ1xuICAgICAgICogb2Ygd2luZG93IGluZGV4IDAgKGluIHBhcnRpY3VsYXIgd2UgaGF2ZSB0byBhdm9pZCBhIG1hdGNoXG4gICAgICAgKiBvZiB0aGUgc3RyaW5nIHdpdGggaXRzZWxmIGF0IHRoZSBzdGFydCBvZiB0aGUgaW5wdXQgZmlsZSkuXG4gICAgICAgKi9cbiAgICAgIHMubWF0Y2hfbGVuZ3RoID0gbG9uZ2VzdF9tYXRjaChzLCBoYXNoX2hlYWQpO1xuICAgICAgLyogbG9uZ2VzdF9tYXRjaCgpIHNldHMgbWF0Y2hfc3RhcnQgKi9cblxuICAgICAgaWYgKHMubWF0Y2hfbGVuZ3RoIDw9IDUgJiZcbiAgICAgICAgIChzLnN0cmF0ZWd5ID09PSBaX0ZJTFRFUkVEIHx8IChzLm1hdGNoX2xlbmd0aCA9PT0gTUlOX01BVENIICYmIHMuc3Ryc3RhcnQgLSBzLm1hdGNoX3N0YXJ0ID4gNDA5Ni8qVE9PX0ZBUiovKSkpIHtcblxuICAgICAgICAvKiBJZiBwcmV2X21hdGNoIGlzIGFsc28gTUlOX01BVENILCBtYXRjaF9zdGFydCBpcyBnYXJiYWdlXG4gICAgICAgICAqIGJ1dCB3ZSB3aWxsIGlnbm9yZSB0aGUgY3VycmVudCBtYXRjaCBhbnl3YXkuXG4gICAgICAgICAqL1xuICAgICAgICBzLm1hdGNoX2xlbmd0aCA9IE1JTl9NQVRDSCAtIDE7XG4gICAgICB9XG4gICAgfVxuICAgIC8qIElmIHRoZXJlIHdhcyBhIG1hdGNoIGF0IHRoZSBwcmV2aW91cyBzdGVwIGFuZCB0aGUgY3VycmVudFxuICAgICAqIG1hdGNoIGlzIG5vdCBiZXR0ZXIsIG91dHB1dCB0aGUgcHJldmlvdXMgbWF0Y2g6XG4gICAgICovXG4gICAgaWYgKHMucHJldl9sZW5ndGggPj0gTUlOX01BVENIICYmIHMubWF0Y2hfbGVuZ3RoIDw9IHMucHJldl9sZW5ndGgpIHtcbiAgICAgIG1heF9pbnNlcnQgPSBzLnN0cnN0YXJ0ICsgcy5sb29rYWhlYWQgLSBNSU5fTUFUQ0g7XG4gICAgICAvKiBEbyBub3QgaW5zZXJ0IHN0cmluZ3MgaW4gaGFzaCB0YWJsZSBiZXlvbmQgdGhpcy4gKi9cblxuICAgICAgLy9jaGVja19tYXRjaChzLCBzLnN0cnN0YXJ0LTEsIHMucHJldl9tYXRjaCwgcy5wcmV2X2xlbmd0aCk7XG5cbiAgICAgIC8qKipfdHJfdGFsbHlfZGlzdChzLCBzLnN0cnN0YXJ0IC0gMSAtIHMucHJldl9tYXRjaCxcbiAgICAgICAgICAgICAgICAgICAgIHMucHJldl9sZW5ndGggLSBNSU5fTUFUQ0gsIGJmbHVzaCk7KioqL1xuICAgICAgYmZsdXNoID0gdHJlZXMuX3RyX3RhbGx5KHMsIHMuc3Ryc3RhcnQgLSAxIC0gcy5wcmV2X21hdGNoLCBzLnByZXZfbGVuZ3RoIC0gTUlOX01BVENIKTtcbiAgICAgIC8qIEluc2VydCBpbiBoYXNoIHRhYmxlIGFsbCBzdHJpbmdzIHVwIHRvIHRoZSBlbmQgb2YgdGhlIG1hdGNoLlxuICAgICAgICogc3Ryc3RhcnQtMSBhbmQgc3Ryc3RhcnQgYXJlIGFscmVhZHkgaW5zZXJ0ZWQuIElmIHRoZXJlIGlzIG5vdFxuICAgICAgICogZW5vdWdoIGxvb2thaGVhZCwgdGhlIGxhc3QgdHdvIHN0cmluZ3MgYXJlIG5vdCBpbnNlcnRlZCBpblxuICAgICAgICogdGhlIGhhc2ggdGFibGUuXG4gICAgICAgKi9cbiAgICAgIHMubG9va2FoZWFkIC09IHMucHJldl9sZW5ndGggLSAxO1xuICAgICAgcy5wcmV2X2xlbmd0aCAtPSAyO1xuICAgICAgZG8ge1xuICAgICAgICBpZiAoKytzLnN0cnN0YXJ0IDw9IG1heF9pbnNlcnQpIHtcbiAgICAgICAgICAvKioqIElOU0VSVF9TVFJJTkcocywgcy5zdHJzdGFydCwgaGFzaF9oZWFkKTsgKioqL1xuICAgICAgICAgIHMuaW5zX2ggPSAoKHMuaW5zX2ggPDwgcy5oYXNoX3NoaWZ0KSBeIHMud2luZG93W3Muc3Ryc3RhcnQgKyBNSU5fTUFUQ0ggLSAxXSkgJiBzLmhhc2hfbWFzaztcbiAgICAgICAgICBoYXNoX2hlYWQgPSBzLnByZXZbcy5zdHJzdGFydCAmIHMud19tYXNrXSA9IHMuaGVhZFtzLmluc19oXTtcbiAgICAgICAgICBzLmhlYWRbcy5pbnNfaF0gPSBzLnN0cnN0YXJ0O1xuICAgICAgICAgIC8qKiovXG4gICAgICAgIH1cbiAgICAgIH0gd2hpbGUgKC0tcy5wcmV2X2xlbmd0aCAhPT0gMCk7XG4gICAgICBzLm1hdGNoX2F2YWlsYWJsZSA9IDA7XG4gICAgICBzLm1hdGNoX2xlbmd0aCA9IE1JTl9NQVRDSCAtIDE7XG4gICAgICBzLnN0cnN0YXJ0Kys7XG5cbiAgICAgIGlmIChiZmx1c2gpIHtcbiAgICAgICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAwKTsgKioqL1xuICAgICAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTtcbiAgICAgICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gQlNfTkVFRF9NT1JFO1xuICAgICAgICB9XG4gICAgICAgIC8qKiovXG4gICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKHMubWF0Y2hfYXZhaWxhYmxlKSB7XG4gICAgICAvKiBJZiB0aGVyZSB3YXMgbm8gbWF0Y2ggYXQgdGhlIHByZXZpb3VzIHBvc2l0aW9uLCBvdXRwdXQgYVxuICAgICAgICogc2luZ2xlIGxpdGVyYWwuIElmIHRoZXJlIHdhcyBhIG1hdGNoIGJ1dCB0aGUgY3VycmVudCBtYXRjaFxuICAgICAgICogaXMgbG9uZ2VyLCB0cnVuY2F0ZSB0aGUgcHJldmlvdXMgbWF0Y2ggdG8gYSBzaW5nbGUgbGl0ZXJhbC5cbiAgICAgICAqL1xuICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsXCIlY1wiLCBzLT53aW5kb3dbcy0+c3Ryc3RhcnQtMV0pKTtcbiAgICAgIC8qKiogX3RyX3RhbGx5X2xpdChzLCBzLndpbmRvd1tzLnN0cnN0YXJ0LTFdLCBiZmx1c2gpOyAqKiovXG4gICAgICBiZmx1c2ggPSB0cmVlcy5fdHJfdGFsbHkocywgMCwgcy53aW5kb3dbcy5zdHJzdGFydCAtIDFdKTtcblxuICAgICAgaWYgKGJmbHVzaCkge1xuICAgICAgICAvKioqIEZMVVNIX0JMT0NLX09OTFkocywgMCkgKioqL1xuICAgICAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTtcbiAgICAgICAgLyoqKi9cbiAgICAgIH1cbiAgICAgIHMuc3Ryc3RhcnQrKztcbiAgICAgIHMubG9va2FoZWFkLS07XG4gICAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gQlNfTkVFRF9NT1JFO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvKiBUaGVyZSBpcyBubyBwcmV2aW91cyBtYXRjaCB0byBjb21wYXJlIHdpdGgsIHdhaXQgZm9yXG4gICAgICAgKiB0aGUgbmV4dCBzdGVwIHRvIGRlY2lkZS5cbiAgICAgICAqL1xuICAgICAgcy5tYXRjaF9hdmFpbGFibGUgPSAxO1xuICAgICAgcy5zdHJzdGFydCsrO1xuICAgICAgcy5sb29rYWhlYWQtLTtcbiAgICB9XG4gIH1cbiAgLy9Bc3NlcnQgKGZsdXNoICE9IFpfTk9fRkxVU0gsIFwibm8gZmx1c2g/XCIpO1xuICBpZiAocy5tYXRjaF9hdmFpbGFibGUpIHtcbiAgICAvL1RyYWNldnYoKHN0ZGVycixcIiVjXCIsIHMtPndpbmRvd1tzLT5zdHJzdGFydC0xXSkpO1xuICAgIC8qKiogX3RyX3RhbGx5X2xpdChzLCBzLndpbmRvd1tzLnN0cnN0YXJ0LTFdLCBiZmx1c2gpOyAqKiovXG4gICAgYmZsdXNoID0gdHJlZXMuX3RyX3RhbGx5KHMsIDAsIHMud2luZG93W3Muc3Ryc3RhcnQgLSAxXSk7XG5cbiAgICBzLm1hdGNoX2F2YWlsYWJsZSA9IDA7XG4gIH1cbiAgcy5pbnNlcnQgPSBzLnN0cnN0YXJ0IDwgTUlOX01BVENIIC0gMSA/IHMuc3Ryc3RhcnQgOiBNSU5fTUFUQ0ggLSAxO1xuICBpZiAoZmx1c2ggPT09IFpfRklOSVNIKSB7XG4gICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAxKTsgKioqL1xuICAgIGZsdXNoX2Jsb2NrX29ubHkocywgdHJ1ZSk7XG4gICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIHJldHVybiBCU19GSU5JU0hfU1RBUlRFRDtcbiAgICB9XG4gICAgLyoqKi9cbiAgICByZXR1cm4gQlNfRklOSVNIX0RPTkU7XG4gIH1cbiAgaWYgKHMubGFzdF9saXQpIHtcbiAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovXG4gICAgZmx1c2hfYmxvY2tfb25seShzLCBmYWxzZSk7XG4gICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgfVxuICAgIC8qKiovXG4gIH1cblxuICByZXR1cm4gQlNfQkxPQ0tfRE9ORTtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEZvciBaX1JMRSwgc2ltcGx5IGxvb2sgZm9yIHJ1bnMgb2YgYnl0ZXMsIGdlbmVyYXRlIG1hdGNoZXMgb25seSBvZiBkaXN0YW5jZVxuICogb25lLiAgRG8gbm90IG1haW50YWluIGEgaGFzaCB0YWJsZS4gIChJdCB3aWxsIGJlIHJlZ2VuZXJhdGVkIGlmIHRoaXMgcnVuIG9mXG4gKiBkZWZsYXRlIHN3aXRjaGVzIGF3YXkgZnJvbSBaX1JMRS4pXG4gKi9cbmZ1bmN0aW9uIGRlZmxhdGVfcmxlKHMsIGZsdXNoKSB7XG4gIHZhciBiZmx1c2g7ICAgICAgICAgICAgLyogc2V0IGlmIGN1cnJlbnQgYmxvY2sgbXVzdCBiZSBmbHVzaGVkICovXG4gIHZhciBwcmV2OyAgICAgICAgICAgICAgLyogYnl0ZSBhdCBkaXN0YW5jZSBvbmUgdG8gbWF0Y2ggKi9cbiAgdmFyIHNjYW4sIHN0cmVuZDsgICAgICAvKiBzY2FuIGdvZXMgdXAgdG8gc3RyZW5kIGZvciBsZW5ndGggb2YgcnVuICovXG5cbiAgdmFyIF93aW4gPSBzLndpbmRvdztcblxuICBmb3IgKDs7KSB7XG4gICAgLyogTWFrZSBzdXJlIHRoYXQgd2UgYWx3YXlzIGhhdmUgZW5vdWdoIGxvb2thaGVhZCwgZXhjZXB0XG4gICAgICogYXQgdGhlIGVuZCBvZiB0aGUgaW5wdXQgZmlsZS4gV2UgbmVlZCBNQVhfTUFUQ0ggYnl0ZXNcbiAgICAgKiBmb3IgdGhlIGxvbmdlc3QgcnVuLCBwbHVzIG9uZSBmb3IgdGhlIHVucm9sbGVkIGxvb3AuXG4gICAgICovXG4gICAgaWYgKHMubG9va2FoZWFkIDw9IE1BWF9NQVRDSCkge1xuICAgICAgZmlsbF93aW5kb3cocyk7XG4gICAgICBpZiAocy5sb29rYWhlYWQgPD0gTUFYX01BVENIICYmIGZsdXNoID09PSBaX05PX0ZMVVNIKSB7XG4gICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgICB9XG4gICAgICBpZiAocy5sb29rYWhlYWQgPT09IDApIHsgYnJlYWs7IH0gLyogZmx1c2ggdGhlIGN1cnJlbnQgYmxvY2sgKi9cbiAgICB9XG5cbiAgICAvKiBTZWUgaG93IG1hbnkgdGltZXMgdGhlIHByZXZpb3VzIGJ5dGUgcmVwZWF0cyAqL1xuICAgIHMubWF0Y2hfbGVuZ3RoID0gMDtcbiAgICBpZiAocy5sb29rYWhlYWQgPj0gTUlOX01BVENIICYmIHMuc3Ryc3RhcnQgPiAwKSB7XG4gICAgICBzY2FuID0gcy5zdHJzdGFydCAtIDE7XG4gICAgICBwcmV2ID0gX3dpbltzY2FuXTtcbiAgICAgIGlmIChwcmV2ID09PSBfd2luWysrc2Nhbl0gJiYgcHJldiA9PT0gX3dpblsrK3NjYW5dICYmIHByZXYgPT09IF93aW5bKytzY2FuXSkge1xuICAgICAgICBzdHJlbmQgPSBzLnN0cnN0YXJ0ICsgTUFYX01BVENIO1xuICAgICAgICBkbyB7XG4gICAgICAgICAgLypqc2hpbnQgbm9lbXB0eTpmYWxzZSovXG4gICAgICAgIH0gd2hpbGUgKHByZXYgPT09IF93aW5bKytzY2FuXSAmJiBwcmV2ID09PSBfd2luWysrc2Nhbl0gJiZcbiAgICAgICAgICAgICAgICAgcHJldiA9PT0gX3dpblsrK3NjYW5dICYmIHByZXYgPT09IF93aW5bKytzY2FuXSAmJlxuICAgICAgICAgICAgICAgICBwcmV2ID09PSBfd2luWysrc2Nhbl0gJiYgcHJldiA9PT0gX3dpblsrK3NjYW5dICYmXG4gICAgICAgICAgICAgICAgIHByZXYgPT09IF93aW5bKytzY2FuXSAmJiBwcmV2ID09PSBfd2luWysrc2Nhbl0gJiZcbiAgICAgICAgICAgICAgICAgc2NhbiA8IHN0cmVuZCk7XG4gICAgICAgIHMubWF0Y2hfbGVuZ3RoID0gTUFYX01BVENIIC0gKHN0cmVuZCAtIHNjYW4pO1xuICAgICAgICBpZiAocy5tYXRjaF9sZW5ndGggPiBzLmxvb2thaGVhZCkge1xuICAgICAgICAgIHMubWF0Y2hfbGVuZ3RoID0gcy5sb29rYWhlYWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vQXNzZXJ0KHNjYW4gPD0gcy0+d2luZG93Kyh1SW50KShzLT53aW5kb3dfc2l6ZS0xKSwgXCJ3aWxkIHNjYW5cIik7XG4gICAgfVxuXG4gICAgLyogRW1pdCBtYXRjaCBpZiBoYXZlIHJ1biBvZiBNSU5fTUFUQ0ggb3IgbG9uZ2VyLCBlbHNlIGVtaXQgbGl0ZXJhbCAqL1xuICAgIGlmIChzLm1hdGNoX2xlbmd0aCA+PSBNSU5fTUFUQ0gpIHtcbiAgICAgIC8vY2hlY2tfbWF0Y2gocywgcy5zdHJzdGFydCwgcy5zdHJzdGFydCAtIDEsIHMubWF0Y2hfbGVuZ3RoKTtcblxuICAgICAgLyoqKiBfdHJfdGFsbHlfZGlzdChzLCAxLCBzLm1hdGNoX2xlbmd0aCAtIE1JTl9NQVRDSCwgYmZsdXNoKTsgKioqL1xuICAgICAgYmZsdXNoID0gdHJlZXMuX3RyX3RhbGx5KHMsIDEsIHMubWF0Y2hfbGVuZ3RoIC0gTUlOX01BVENIKTtcblxuICAgICAgcy5sb29rYWhlYWQgLT0gcy5tYXRjaF9sZW5ndGg7XG4gICAgICBzLnN0cnN0YXJ0ICs9IHMubWF0Y2hfbGVuZ3RoO1xuICAgICAgcy5tYXRjaF9sZW5ndGggPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICAvKiBObyBtYXRjaCwgb3V0cHV0IGEgbGl0ZXJhbCBieXRlICovXG4gICAgICAvL1RyYWNldnYoKHN0ZGVycixcIiVjXCIsIHMtPndpbmRvd1tzLT5zdHJzdGFydF0pKTtcbiAgICAgIC8qKiogX3RyX3RhbGx5X2xpdChzLCBzLndpbmRvd1tzLnN0cnN0YXJ0XSwgYmZsdXNoKTsgKioqL1xuICAgICAgYmZsdXNoID0gdHJlZXMuX3RyX3RhbGx5KHMsIDAsIHMud2luZG93W3Muc3Ryc3RhcnRdKTtcblxuICAgICAgcy5sb29rYWhlYWQtLTtcbiAgICAgIHMuc3Ryc3RhcnQrKztcbiAgICB9XG4gICAgaWYgKGJmbHVzaCkge1xuICAgICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAwKTsgKioqL1xuICAgICAgZmx1c2hfYmxvY2tfb25seShzLCBmYWxzZSk7XG4gICAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gQlNfTkVFRF9NT1JFO1xuICAgICAgfVxuICAgICAgLyoqKi9cbiAgICB9XG4gIH1cbiAgcy5pbnNlcnQgPSAwO1xuICBpZiAoZmx1c2ggPT09IFpfRklOSVNIKSB7XG4gICAgLyoqKiBGTFVTSF9CTE9DSyhzLCAxKTsgKioqL1xuICAgIGZsdXNoX2Jsb2NrX29ubHkocywgdHJ1ZSk7XG4gICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIHJldHVybiBCU19GSU5JU0hfU1RBUlRFRDtcbiAgICB9XG4gICAgLyoqKi9cbiAgICByZXR1cm4gQlNfRklOSVNIX0RPTkU7XG4gIH1cbiAgaWYgKHMubGFzdF9saXQpIHtcbiAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovXG4gICAgZmx1c2hfYmxvY2tfb25seShzLCBmYWxzZSk7XG4gICAgaWYgKHMuc3RybS5hdmFpbF9vdXQgPT09IDApIHtcbiAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgfVxuICAgIC8qKiovXG4gIH1cbiAgcmV0dXJuIEJTX0JMT0NLX0RPTkU7XG59XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogRm9yIFpfSFVGRk1BTl9PTkxZLCBkbyBub3QgbG9vayBmb3IgbWF0Y2hlcy4gIERvIG5vdCBtYWludGFpbiBhIGhhc2ggdGFibGUuXG4gKiAoSXQgd2lsbCBiZSByZWdlbmVyYXRlZCBpZiB0aGlzIHJ1biBvZiBkZWZsYXRlIHN3aXRjaGVzIGF3YXkgZnJvbSBIdWZmbWFuLilcbiAqL1xuZnVuY3Rpb24gZGVmbGF0ZV9odWZmKHMsIGZsdXNoKSB7XG4gIHZhciBiZmx1c2g7ICAgICAgICAgICAgIC8qIHNldCBpZiBjdXJyZW50IGJsb2NrIG11c3QgYmUgZmx1c2hlZCAqL1xuXG4gIGZvciAoOzspIHtcbiAgICAvKiBNYWtlIHN1cmUgdGhhdCB3ZSBoYXZlIGEgbGl0ZXJhbCB0byB3cml0ZS4gKi9cbiAgICBpZiAocy5sb29rYWhlYWQgPT09IDApIHtcbiAgICAgIGZpbGxfd2luZG93KHMpO1xuICAgICAgaWYgKHMubG9va2FoZWFkID09PSAwKSB7XG4gICAgICAgIGlmIChmbHVzaCA9PT0gWl9OT19GTFVTSCkge1xuICAgICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7ICAgICAgLyogZmx1c2ggdGhlIGN1cnJlbnQgYmxvY2sgKi9cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKiBPdXRwdXQgYSBsaXRlcmFsIGJ5dGUgKi9cbiAgICBzLm1hdGNoX2xlbmd0aCA9IDA7XG4gICAgLy9UcmFjZXZ2KChzdGRlcnIsXCIlY1wiLCBzLT53aW5kb3dbcy0+c3Ryc3RhcnRdKSk7XG4gICAgLyoqKiBfdHJfdGFsbHlfbGl0KHMsIHMud2luZG93W3Muc3Ryc3RhcnRdLCBiZmx1c2gpOyAqKiovXG4gICAgYmZsdXNoID0gdHJlZXMuX3RyX3RhbGx5KHMsIDAsIHMud2luZG93W3Muc3Ryc3RhcnRdKTtcbiAgICBzLmxvb2thaGVhZC0tO1xuICAgIHMuc3Ryc3RhcnQrKztcbiAgICBpZiAoYmZsdXNoKSB7XG4gICAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDApOyAqKiovXG4gICAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTtcbiAgICAgIGlmIChzLnN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICAgIHJldHVybiBCU19ORUVEX01PUkU7XG4gICAgICB9XG4gICAgICAvKioqL1xuICAgIH1cbiAgfVxuICBzLmluc2VydCA9IDA7XG4gIGlmIChmbHVzaCA9PT0gWl9GSU5JU0gpIHtcbiAgICAvKioqIEZMVVNIX0JMT0NLKHMsIDEpOyAqKiovXG4gICAgZmx1c2hfYmxvY2tfb25seShzLCB0cnVlKTtcbiAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgcmV0dXJuIEJTX0ZJTklTSF9TVEFSVEVEO1xuICAgIH1cbiAgICAvKioqL1xuICAgIHJldHVybiBCU19GSU5JU0hfRE9ORTtcbiAgfVxuICBpZiAocy5sYXN0X2xpdCkge1xuICAgIC8qKiogRkxVU0hfQkxPQ0socywgMCk7ICoqKi9cbiAgICBmbHVzaF9ibG9ja19vbmx5KHMsIGZhbHNlKTtcbiAgICBpZiAocy5zdHJtLmF2YWlsX291dCA9PT0gMCkge1xuICAgICAgcmV0dXJuIEJTX05FRURfTU9SRTtcbiAgICB9XG4gICAgLyoqKi9cbiAgfVxuICByZXR1cm4gQlNfQkxPQ0tfRE9ORTtcbn1cblxuLyogVmFsdWVzIGZvciBtYXhfbGF6eV9tYXRjaCwgZ29vZF9tYXRjaCBhbmQgbWF4X2NoYWluX2xlbmd0aCwgZGVwZW5kaW5nIG9uXG4gKiB0aGUgZGVzaXJlZCBwYWNrIGxldmVsICgwLi45KS4gVGhlIHZhbHVlcyBnaXZlbiBiZWxvdyBoYXZlIGJlZW4gdHVuZWQgdG9cbiAqIGV4Y2x1ZGUgd29yc3QgY2FzZSBwZXJmb3JtYW5jZSBmb3IgcGF0aG9sb2dpY2FsIGZpbGVzLiBCZXR0ZXIgdmFsdWVzIG1heSBiZVxuICogZm91bmQgZm9yIHNwZWNpZmljIGZpbGVzLlxuICovXG5mdW5jdGlvbiBDb25maWcoZ29vZF9sZW5ndGgsIG1heF9sYXp5LCBuaWNlX2xlbmd0aCwgbWF4X2NoYWluLCBmdW5jKSB7XG4gIHRoaXMuZ29vZF9sZW5ndGggPSBnb29kX2xlbmd0aDtcbiAgdGhpcy5tYXhfbGF6eSA9IG1heF9sYXp5O1xuICB0aGlzLm5pY2VfbGVuZ3RoID0gbmljZV9sZW5ndGg7XG4gIHRoaXMubWF4X2NoYWluID0gbWF4X2NoYWluO1xuICB0aGlzLmZ1bmMgPSBmdW5jO1xufVxuXG52YXIgY29uZmlndXJhdGlvbl90YWJsZTtcblxuY29uZmlndXJhdGlvbl90YWJsZSA9IFtcbiAgLyogICAgICBnb29kIGxhenkgbmljZSBjaGFpbiAqL1xuICBuZXcgQ29uZmlnKDAsIDAsIDAsIDAsIGRlZmxhdGVfc3RvcmVkKSwgICAgICAgICAgLyogMCBzdG9yZSBvbmx5ICovXG4gIG5ldyBDb25maWcoNCwgNCwgOCwgNCwgZGVmbGF0ZV9mYXN0KSwgICAgICAgICAgICAvKiAxIG1heCBzcGVlZCwgbm8gbGF6eSBtYXRjaGVzICovXG4gIG5ldyBDb25maWcoNCwgNSwgMTYsIDgsIGRlZmxhdGVfZmFzdCksICAgICAgICAgICAvKiAyICovXG4gIG5ldyBDb25maWcoNCwgNiwgMzIsIDMyLCBkZWZsYXRlX2Zhc3QpLCAgICAgICAgICAvKiAzICovXG5cbiAgbmV3IENvbmZpZyg0LCA0LCAxNiwgMTYsIGRlZmxhdGVfc2xvdyksICAgICAgICAgIC8qIDQgbGF6eSBtYXRjaGVzICovXG4gIG5ldyBDb25maWcoOCwgMTYsIDMyLCAzMiwgZGVmbGF0ZV9zbG93KSwgICAgICAgICAvKiA1ICovXG4gIG5ldyBDb25maWcoOCwgMTYsIDEyOCwgMTI4LCBkZWZsYXRlX3Nsb3cpLCAgICAgICAvKiA2ICovXG4gIG5ldyBDb25maWcoOCwgMzIsIDEyOCwgMjU2LCBkZWZsYXRlX3Nsb3cpLCAgICAgICAvKiA3ICovXG4gIG5ldyBDb25maWcoMzIsIDEyOCwgMjU4LCAxMDI0LCBkZWZsYXRlX3Nsb3cpLCAgICAvKiA4ICovXG4gIG5ldyBDb25maWcoMzIsIDI1OCwgMjU4LCA0MDk2LCBkZWZsYXRlX3Nsb3cpICAgICAvKiA5IG1heCBjb21wcmVzc2lvbiAqL1xuXTtcblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEluaXRpYWxpemUgdGhlIFwibG9uZ2VzdCBtYXRjaFwiIHJvdXRpbmVzIGZvciBhIG5ldyB6bGliIHN0cmVhbVxuICovXG5mdW5jdGlvbiBsbV9pbml0KHMpIHtcbiAgcy53aW5kb3dfc2l6ZSA9IDIgKiBzLndfc2l6ZTtcblxuICAvKioqIENMRUFSX0hBU0gocyk7ICoqKi9cbiAgemVybyhzLmhlYWQpOyAvLyBGaWxsIHdpdGggTklMICg9IDApO1xuXG4gIC8qIFNldCB0aGUgZGVmYXVsdCBjb25maWd1cmF0aW9uIHBhcmFtZXRlcnM6XG4gICAqL1xuICBzLm1heF9sYXp5X21hdGNoID0gY29uZmlndXJhdGlvbl90YWJsZVtzLmxldmVsXS5tYXhfbGF6eTtcbiAgcy5nb29kX21hdGNoID0gY29uZmlndXJhdGlvbl90YWJsZVtzLmxldmVsXS5nb29kX2xlbmd0aDtcbiAgcy5uaWNlX21hdGNoID0gY29uZmlndXJhdGlvbl90YWJsZVtzLmxldmVsXS5uaWNlX2xlbmd0aDtcbiAgcy5tYXhfY2hhaW5fbGVuZ3RoID0gY29uZmlndXJhdGlvbl90YWJsZVtzLmxldmVsXS5tYXhfY2hhaW47XG5cbiAgcy5zdHJzdGFydCA9IDA7XG4gIHMuYmxvY2tfc3RhcnQgPSAwO1xuICBzLmxvb2thaGVhZCA9IDA7XG4gIHMuaW5zZXJ0ID0gMDtcbiAgcy5tYXRjaF9sZW5ndGggPSBzLnByZXZfbGVuZ3RoID0gTUlOX01BVENIIC0gMTtcbiAgcy5tYXRjaF9hdmFpbGFibGUgPSAwO1xuICBzLmluc19oID0gMDtcbn1cblxuXG5mdW5jdGlvbiBEZWZsYXRlU3RhdGUoKSB7XG4gIHRoaXMuc3RybSA9IG51bGw7ICAgICAgICAgICAgLyogcG9pbnRlciBiYWNrIHRvIHRoaXMgemxpYiBzdHJlYW0gKi9cbiAgdGhpcy5zdGF0dXMgPSAwOyAgICAgICAgICAgIC8qIGFzIHRoZSBuYW1lIGltcGxpZXMgKi9cbiAgdGhpcy5wZW5kaW5nX2J1ZiA9IG51bGw7ICAgICAgLyogb3V0cHV0IHN0aWxsIHBlbmRpbmcgKi9cbiAgdGhpcy5wZW5kaW5nX2J1Zl9zaXplID0gMDsgIC8qIHNpemUgb2YgcGVuZGluZ19idWYgKi9cbiAgdGhpcy5wZW5kaW5nX291dCA9IDA7ICAgICAgIC8qIG5leHQgcGVuZGluZyBieXRlIHRvIG91dHB1dCB0byB0aGUgc3RyZWFtICovXG4gIHRoaXMucGVuZGluZyA9IDA7ICAgICAgICAgICAvKiBuYiBvZiBieXRlcyBpbiB0aGUgcGVuZGluZyBidWZmZXIgKi9cbiAgdGhpcy53cmFwID0gMDsgICAgICAgICAgICAgIC8qIGJpdCAwIHRydWUgZm9yIHpsaWIsIGJpdCAxIHRydWUgZm9yIGd6aXAgKi9cbiAgdGhpcy5nemhlYWQgPSBudWxsOyAgICAgICAgIC8qIGd6aXAgaGVhZGVyIGluZm9ybWF0aW9uIHRvIHdyaXRlICovXG4gIHRoaXMuZ3ppbmRleCA9IDA7ICAgICAgICAgICAvKiB3aGVyZSBpbiBleHRyYSwgbmFtZSwgb3IgY29tbWVudCAqL1xuICB0aGlzLm1ldGhvZCA9IFpfREVGTEFURUQ7IC8qIGNhbiBvbmx5IGJlIERFRkxBVEVEICovXG4gIHRoaXMubGFzdF9mbHVzaCA9IC0xOyAgIC8qIHZhbHVlIG9mIGZsdXNoIHBhcmFtIGZvciBwcmV2aW91cyBkZWZsYXRlIGNhbGwgKi9cblxuICB0aGlzLndfc2l6ZSA9IDA7ICAvKiBMWjc3IHdpbmRvdyBzaXplICgzMksgYnkgZGVmYXVsdCkgKi9cbiAgdGhpcy53X2JpdHMgPSAwOyAgLyogbG9nMih3X3NpemUpICAoOC4uMTYpICovXG4gIHRoaXMud19tYXNrID0gMDsgIC8qIHdfc2l6ZSAtIDEgKi9cblxuICB0aGlzLndpbmRvdyA9IG51bGw7XG4gIC8qIFNsaWRpbmcgd2luZG93LiBJbnB1dCBieXRlcyBhcmUgcmVhZCBpbnRvIHRoZSBzZWNvbmQgaGFsZiBvZiB0aGUgd2luZG93LFxuICAgKiBhbmQgbW92ZSB0byB0aGUgZmlyc3QgaGFsZiBsYXRlciB0byBrZWVwIGEgZGljdGlvbmFyeSBvZiBhdCBsZWFzdCB3U2l6ZVxuICAgKiBieXRlcy4gV2l0aCB0aGlzIG9yZ2FuaXphdGlvbiwgbWF0Y2hlcyBhcmUgbGltaXRlZCB0byBhIGRpc3RhbmNlIG9mXG4gICAqIHdTaXplLU1BWF9NQVRDSCBieXRlcywgYnV0IHRoaXMgZW5zdXJlcyB0aGF0IElPIGlzIGFsd2F5c1xuICAgKiBwZXJmb3JtZWQgd2l0aCBhIGxlbmd0aCBtdWx0aXBsZSBvZiB0aGUgYmxvY2sgc2l6ZS5cbiAgICovXG5cbiAgdGhpcy53aW5kb3dfc2l6ZSA9IDA7XG4gIC8qIEFjdHVhbCBzaXplIG9mIHdpbmRvdzogMip3U2l6ZSwgZXhjZXB0IHdoZW4gdGhlIHVzZXIgaW5wdXQgYnVmZmVyXG4gICAqIGlzIGRpcmVjdGx5IHVzZWQgYXMgc2xpZGluZyB3aW5kb3cuXG4gICAqL1xuXG4gIHRoaXMucHJldiA9IG51bGw7XG4gIC8qIExpbmsgdG8gb2xkZXIgc3RyaW5nIHdpdGggc2FtZSBoYXNoIGluZGV4LiBUbyBsaW1pdCB0aGUgc2l6ZSBvZiB0aGlzXG4gICAqIGFycmF5IHRvIDY0SywgdGhpcyBsaW5rIGlzIG1haW50YWluZWQgb25seSBmb3IgdGhlIGxhc3QgMzJLIHN0cmluZ3MuXG4gICAqIEFuIGluZGV4IGluIHRoaXMgYXJyYXkgaXMgdGh1cyBhIHdpbmRvdyBpbmRleCBtb2R1bG8gMzJLLlxuICAgKi9cblxuICB0aGlzLmhlYWQgPSBudWxsOyAgIC8qIEhlYWRzIG9mIHRoZSBoYXNoIGNoYWlucyBvciBOSUwuICovXG5cbiAgdGhpcy5pbnNfaCA9IDA7ICAgICAgIC8qIGhhc2ggaW5kZXggb2Ygc3RyaW5nIHRvIGJlIGluc2VydGVkICovXG4gIHRoaXMuaGFzaF9zaXplID0gMDsgICAvKiBudW1iZXIgb2YgZWxlbWVudHMgaW4gaGFzaCB0YWJsZSAqL1xuICB0aGlzLmhhc2hfYml0cyA9IDA7ICAgLyogbG9nMihoYXNoX3NpemUpICovXG4gIHRoaXMuaGFzaF9tYXNrID0gMDsgICAvKiBoYXNoX3NpemUtMSAqL1xuXG4gIHRoaXMuaGFzaF9zaGlmdCA9IDA7XG4gIC8qIE51bWJlciBvZiBiaXRzIGJ5IHdoaWNoIGluc19oIG11c3QgYmUgc2hpZnRlZCBhdCBlYWNoIGlucHV0XG4gICAqIHN0ZXAuIEl0IG11c3QgYmUgc3VjaCB0aGF0IGFmdGVyIE1JTl9NQVRDSCBzdGVwcywgdGhlIG9sZGVzdFxuICAgKiBieXRlIG5vIGxvbmdlciB0YWtlcyBwYXJ0IGluIHRoZSBoYXNoIGtleSwgdGhhdCBpczpcbiAgICogICBoYXNoX3NoaWZ0ICogTUlOX01BVENIID49IGhhc2hfYml0c1xuICAgKi9cblxuICB0aGlzLmJsb2NrX3N0YXJ0ID0gMDtcbiAgLyogV2luZG93IHBvc2l0aW9uIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGN1cnJlbnQgb3V0cHV0IGJsb2NrLiBHZXRzXG4gICAqIG5lZ2F0aXZlIHdoZW4gdGhlIHdpbmRvdyBpcyBtb3ZlZCBiYWNrd2FyZHMuXG4gICAqL1xuXG4gIHRoaXMubWF0Y2hfbGVuZ3RoID0gMDsgICAgICAvKiBsZW5ndGggb2YgYmVzdCBtYXRjaCAqL1xuICB0aGlzLnByZXZfbWF0Y2ggPSAwOyAgICAgICAgLyogcHJldmlvdXMgbWF0Y2ggKi9cbiAgdGhpcy5tYXRjaF9hdmFpbGFibGUgPSAwOyAgIC8qIHNldCBpZiBwcmV2aW91cyBtYXRjaCBleGlzdHMgKi9cbiAgdGhpcy5zdHJzdGFydCA9IDA7ICAgICAgICAgIC8qIHN0YXJ0IG9mIHN0cmluZyB0byBpbnNlcnQgKi9cbiAgdGhpcy5tYXRjaF9zdGFydCA9IDA7ICAgICAgIC8qIHN0YXJ0IG9mIG1hdGNoaW5nIHN0cmluZyAqL1xuICB0aGlzLmxvb2thaGVhZCA9IDA7ICAgICAgICAgLyogbnVtYmVyIG9mIHZhbGlkIGJ5dGVzIGFoZWFkIGluIHdpbmRvdyAqL1xuXG4gIHRoaXMucHJldl9sZW5ndGggPSAwO1xuICAvKiBMZW5ndGggb2YgdGhlIGJlc3QgbWF0Y2ggYXQgcHJldmlvdXMgc3RlcC4gTWF0Y2hlcyBub3QgZ3JlYXRlciB0aGFuIHRoaXNcbiAgICogYXJlIGRpc2NhcmRlZC4gVGhpcyBpcyB1c2VkIGluIHRoZSBsYXp5IG1hdGNoIGV2YWx1YXRpb24uXG4gICAqL1xuXG4gIHRoaXMubWF4X2NoYWluX2xlbmd0aCA9IDA7XG4gIC8qIFRvIHNwZWVkIHVwIGRlZmxhdGlvbiwgaGFzaCBjaGFpbnMgYXJlIG5ldmVyIHNlYXJjaGVkIGJleW9uZCB0aGlzXG4gICAqIGxlbmd0aC4gIEEgaGlnaGVyIGxpbWl0IGltcHJvdmVzIGNvbXByZXNzaW9uIHJhdGlvIGJ1dCBkZWdyYWRlcyB0aGVcbiAgICogc3BlZWQuXG4gICAqL1xuXG4gIHRoaXMubWF4X2xhenlfbWF0Y2ggPSAwO1xuICAvKiBBdHRlbXB0IHRvIGZpbmQgYSBiZXR0ZXIgbWF0Y2ggb25seSB3aGVuIHRoZSBjdXJyZW50IG1hdGNoIGlzIHN0cmljdGx5XG4gICAqIHNtYWxsZXIgdGhhbiB0aGlzIHZhbHVlLiBUaGlzIG1lY2hhbmlzbSBpcyB1c2VkIG9ubHkgZm9yIGNvbXByZXNzaW9uXG4gICAqIGxldmVscyA+PSA0LlxuICAgKi9cbiAgLy8gVGhhdCdzIGFsaWFzIHRvIG1heF9sYXp5X21hdGNoLCBkb24ndCB1c2UgZGlyZWN0bHlcbiAgLy90aGlzLm1heF9pbnNlcnRfbGVuZ3RoID0gMDtcbiAgLyogSW5zZXJ0IG5ldyBzdHJpbmdzIGluIHRoZSBoYXNoIHRhYmxlIG9ubHkgaWYgdGhlIG1hdGNoIGxlbmd0aCBpcyBub3RcbiAgICogZ3JlYXRlciB0aGFuIHRoaXMgbGVuZ3RoLiBUaGlzIHNhdmVzIHRpbWUgYnV0IGRlZ3JhZGVzIGNvbXByZXNzaW9uLlxuICAgKiBtYXhfaW5zZXJ0X2xlbmd0aCBpcyB1c2VkIG9ubHkgZm9yIGNvbXByZXNzaW9uIGxldmVscyA8PSAzLlxuICAgKi9cblxuICB0aGlzLmxldmVsID0gMDsgICAgIC8qIGNvbXByZXNzaW9uIGxldmVsICgxLi45KSAqL1xuICB0aGlzLnN0cmF0ZWd5ID0gMDsgIC8qIGZhdm9yIG9yIGZvcmNlIEh1ZmZtYW4gY29kaW5nKi9cblxuICB0aGlzLmdvb2RfbWF0Y2ggPSAwO1xuICAvKiBVc2UgYSBmYXN0ZXIgc2VhcmNoIHdoZW4gdGhlIHByZXZpb3VzIG1hdGNoIGlzIGxvbmdlciB0aGFuIHRoaXMgKi9cblxuICB0aGlzLm5pY2VfbWF0Y2ggPSAwOyAvKiBTdG9wIHNlYXJjaGluZyB3aGVuIGN1cnJlbnQgbWF0Y2ggZXhjZWVkcyB0aGlzICovXG5cbiAgICAgICAgICAgICAgLyogdXNlZCBieSB0cmVlcy5jOiAqL1xuXG4gIC8qIERpZG4ndCB1c2UgY3RfZGF0YSB0eXBlZGVmIGJlbG93IHRvIHN1cHByZXNzIGNvbXBpbGVyIHdhcm5pbmcgKi9cblxuICAvLyBzdHJ1Y3QgY3RfZGF0YV9zIGR5bl9sdHJlZVtIRUFQX1NJWkVdOyAgIC8qIGxpdGVyYWwgYW5kIGxlbmd0aCB0cmVlICovXG4gIC8vIHN0cnVjdCBjdF9kYXRhX3MgZHluX2R0cmVlWzIqRF9DT0RFUysxXTsgLyogZGlzdGFuY2UgdHJlZSAqL1xuICAvLyBzdHJ1Y3QgY3RfZGF0YV9zIGJsX3RyZWVbMipCTF9DT0RFUysxXTsgIC8qIEh1ZmZtYW4gdHJlZSBmb3IgYml0IGxlbmd0aHMgKi9cblxuICAvLyBVc2UgZmxhdCBhcnJheSBvZiBET1VCTEUgc2l6ZSwgd2l0aCBpbnRlcmxlYXZlZCBmYXRhLFxuICAvLyBiZWNhdXNlIEpTIGRvZXMgbm90IHN1cHBvcnQgZWZmZWN0aXZlXG4gIHRoaXMuZHluX2x0cmVlICA9IG5ldyB1dGlscy5CdWYxNihIRUFQX1NJWkUgKiAyKTtcbiAgdGhpcy5keW5fZHRyZWUgID0gbmV3IHV0aWxzLkJ1ZjE2KCgyICogRF9DT0RFUyArIDEpICogMik7XG4gIHRoaXMuYmxfdHJlZSAgICA9IG5ldyB1dGlscy5CdWYxNigoMiAqIEJMX0NPREVTICsgMSkgKiAyKTtcbiAgemVybyh0aGlzLmR5bl9sdHJlZSk7XG4gIHplcm8odGhpcy5keW5fZHRyZWUpO1xuICB6ZXJvKHRoaXMuYmxfdHJlZSk7XG5cbiAgdGhpcy5sX2Rlc2MgICA9IG51bGw7ICAgICAgICAgLyogZGVzYy4gZm9yIGxpdGVyYWwgdHJlZSAqL1xuICB0aGlzLmRfZGVzYyAgID0gbnVsbDsgICAgICAgICAvKiBkZXNjLiBmb3IgZGlzdGFuY2UgdHJlZSAqL1xuICB0aGlzLmJsX2Rlc2MgID0gbnVsbDsgICAgICAgICAvKiBkZXNjLiBmb3IgYml0IGxlbmd0aCB0cmVlICovXG5cbiAgLy91c2ggYmxfY291bnRbTUFYX0JJVFMrMV07XG4gIHRoaXMuYmxfY291bnQgPSBuZXcgdXRpbHMuQnVmMTYoTUFYX0JJVFMgKyAxKTtcbiAgLyogbnVtYmVyIG9mIGNvZGVzIGF0IGVhY2ggYml0IGxlbmd0aCBmb3IgYW4gb3B0aW1hbCB0cmVlICovXG5cbiAgLy9pbnQgaGVhcFsyKkxfQ09ERVMrMV07ICAgICAgLyogaGVhcCB1c2VkIHRvIGJ1aWxkIHRoZSBIdWZmbWFuIHRyZWVzICovXG4gIHRoaXMuaGVhcCA9IG5ldyB1dGlscy5CdWYxNigyICogTF9DT0RFUyArIDEpOyAgLyogaGVhcCB1c2VkIHRvIGJ1aWxkIHRoZSBIdWZmbWFuIHRyZWVzICovXG4gIHplcm8odGhpcy5oZWFwKTtcblxuICB0aGlzLmhlYXBfbGVuID0gMDsgICAgICAgICAgICAgICAvKiBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGhlYXAgKi9cbiAgdGhpcy5oZWFwX21heCA9IDA7ICAgICAgICAgICAgICAgLyogZWxlbWVudCBvZiBsYXJnZXN0IGZyZXF1ZW5jeSAqL1xuICAvKiBUaGUgc29ucyBvZiBoZWFwW25dIGFyZSBoZWFwWzIqbl0gYW5kIGhlYXBbMipuKzFdLiBoZWFwWzBdIGlzIG5vdCB1c2VkLlxuICAgKiBUaGUgc2FtZSBoZWFwIGFycmF5IGlzIHVzZWQgdG8gYnVpbGQgYWxsIHRyZWVzLlxuICAgKi9cblxuICB0aGlzLmRlcHRoID0gbmV3IHV0aWxzLkJ1ZjE2KDIgKiBMX0NPREVTICsgMSk7IC8vdWNoIGRlcHRoWzIqTF9DT0RFUysxXTtcbiAgemVybyh0aGlzLmRlcHRoKTtcbiAgLyogRGVwdGggb2YgZWFjaCBzdWJ0cmVlIHVzZWQgYXMgdGllIGJyZWFrZXIgZm9yIHRyZWVzIG9mIGVxdWFsIGZyZXF1ZW5jeVxuICAgKi9cblxuICB0aGlzLmxfYnVmID0gMDsgICAgICAgICAgLyogYnVmZmVyIGluZGV4IGZvciBsaXRlcmFscyBvciBsZW5ndGhzICovXG5cbiAgdGhpcy5saXRfYnVmc2l6ZSA9IDA7XG4gIC8qIFNpemUgb2YgbWF0Y2ggYnVmZmVyIGZvciBsaXRlcmFscy9sZW5ndGhzLiAgVGhlcmUgYXJlIDQgcmVhc29ucyBmb3JcbiAgICogbGltaXRpbmcgbGl0X2J1ZnNpemUgdG8gNjRLOlxuICAgKiAgIC0gZnJlcXVlbmNpZXMgY2FuIGJlIGtlcHQgaW4gMTYgYml0IGNvdW50ZXJzXG4gICAqICAgLSBpZiBjb21wcmVzc2lvbiBpcyBub3Qgc3VjY2Vzc2Z1bCBmb3IgdGhlIGZpcnN0IGJsb2NrLCBhbGwgaW5wdXRcbiAgICogICAgIGRhdGEgaXMgc3RpbGwgaW4gdGhlIHdpbmRvdyBzbyB3ZSBjYW4gc3RpbGwgZW1pdCBhIHN0b3JlZCBibG9jayBldmVuXG4gICAqICAgICB3aGVuIGlucHV0IGNvbWVzIGZyb20gc3RhbmRhcmQgaW5wdXQuICAoVGhpcyBjYW4gYWxzbyBiZSBkb25lIGZvclxuICAgKiAgICAgYWxsIGJsb2NrcyBpZiBsaXRfYnVmc2l6ZSBpcyBub3QgZ3JlYXRlciB0aGFuIDMySy4pXG4gICAqICAgLSBpZiBjb21wcmVzc2lvbiBpcyBub3Qgc3VjY2Vzc2Z1bCBmb3IgYSBmaWxlIHNtYWxsZXIgdGhhbiA2NEssIHdlIGNhblxuICAgKiAgICAgZXZlbiBlbWl0IGEgc3RvcmVkIGZpbGUgaW5zdGVhZCBvZiBhIHN0b3JlZCBibG9jayAoc2F2aW5nIDUgYnl0ZXMpLlxuICAgKiAgICAgVGhpcyBpcyBhcHBsaWNhYmxlIG9ubHkgZm9yIHppcCAobm90IGd6aXAgb3IgemxpYikuXG4gICAqICAgLSBjcmVhdGluZyBuZXcgSHVmZm1hbiB0cmVlcyBsZXNzIGZyZXF1ZW50bHkgbWF5IG5vdCBwcm92aWRlIGZhc3RcbiAgICogICAgIGFkYXB0YXRpb24gdG8gY2hhbmdlcyBpbiB0aGUgaW5wdXQgZGF0YSBzdGF0aXN0aWNzLiAoVGFrZSBmb3JcbiAgICogICAgIGV4YW1wbGUgYSBiaW5hcnkgZmlsZSB3aXRoIHBvb3JseSBjb21wcmVzc2libGUgY29kZSBmb2xsb3dlZCBieVxuICAgKiAgICAgYSBoaWdobHkgY29tcHJlc3NpYmxlIHN0cmluZyB0YWJsZS4pIFNtYWxsZXIgYnVmZmVyIHNpemVzIGdpdmVcbiAgICogICAgIGZhc3QgYWRhcHRhdGlvbiBidXQgaGF2ZSBvZiBjb3Vyc2UgdGhlIG92ZXJoZWFkIG9mIHRyYW5zbWl0dGluZ1xuICAgKiAgICAgdHJlZXMgbW9yZSBmcmVxdWVudGx5LlxuICAgKiAgIC0gSSBjYW4ndCBjb3VudCBhYm92ZSA0XG4gICAqL1xuXG4gIHRoaXMubGFzdF9saXQgPSAwOyAgICAgIC8qIHJ1bm5pbmcgaW5kZXggaW4gbF9idWYgKi9cblxuICB0aGlzLmRfYnVmID0gMDtcbiAgLyogQnVmZmVyIGluZGV4IGZvciBkaXN0YW5jZXMuIFRvIHNpbXBsaWZ5IHRoZSBjb2RlLCBkX2J1ZiBhbmQgbF9idWYgaGF2ZVxuICAgKiB0aGUgc2FtZSBudW1iZXIgb2YgZWxlbWVudHMuIFRvIHVzZSBkaWZmZXJlbnQgbGVuZ3RocywgYW4gZXh0cmEgZmxhZ1xuICAgKiBhcnJheSB3b3VsZCBiZSBuZWNlc3NhcnkuXG4gICAqL1xuXG4gIHRoaXMub3B0X2xlbiA9IDA7ICAgICAgIC8qIGJpdCBsZW5ndGggb2YgY3VycmVudCBibG9jayB3aXRoIG9wdGltYWwgdHJlZXMgKi9cbiAgdGhpcy5zdGF0aWNfbGVuID0gMDsgICAgLyogYml0IGxlbmd0aCBvZiBjdXJyZW50IGJsb2NrIHdpdGggc3RhdGljIHRyZWVzICovXG4gIHRoaXMubWF0Y2hlcyA9IDA7ICAgICAgIC8qIG51bWJlciBvZiBzdHJpbmcgbWF0Y2hlcyBpbiBjdXJyZW50IGJsb2NrICovXG4gIHRoaXMuaW5zZXJ0ID0gMDsgICAgICAgIC8qIGJ5dGVzIGF0IGVuZCBvZiB3aW5kb3cgbGVmdCB0byBpbnNlcnQgKi9cblxuXG4gIHRoaXMuYmlfYnVmID0gMDtcbiAgLyogT3V0cHV0IGJ1ZmZlci4gYml0cyBhcmUgaW5zZXJ0ZWQgc3RhcnRpbmcgYXQgdGhlIGJvdHRvbSAobGVhc3RcbiAgICogc2lnbmlmaWNhbnQgYml0cykuXG4gICAqL1xuICB0aGlzLmJpX3ZhbGlkID0gMDtcbiAgLyogTnVtYmVyIG9mIHZhbGlkIGJpdHMgaW4gYmlfYnVmLiAgQWxsIGJpdHMgYWJvdmUgdGhlIGxhc3QgdmFsaWQgYml0XG4gICAqIGFyZSBhbHdheXMgemVyby5cbiAgICovXG5cbiAgLy8gVXNlZCBmb3Igd2luZG93IG1lbW9yeSBpbml0LiBXZSBzYWZlbHkgaWdub3JlIGl0IGZvciBKUy4gVGhhdCBtYWtlc1xuICAvLyBzZW5zZSBvbmx5IGZvciBwb2ludGVycyBhbmQgbWVtb3J5IGNoZWNrIHRvb2xzLlxuICAvL3RoaXMuaGlnaF93YXRlciA9IDA7XG4gIC8qIEhpZ2ggd2F0ZXIgbWFyayBvZmZzZXQgaW4gd2luZG93IGZvciBpbml0aWFsaXplZCBieXRlcyAtLSBieXRlcyBhYm92ZVxuICAgKiB0aGlzIGFyZSBzZXQgdG8gemVybyBpbiBvcmRlciB0byBhdm9pZCBtZW1vcnkgY2hlY2sgd2FybmluZ3Mgd2hlblxuICAgKiBsb25nZXN0IG1hdGNoIHJvdXRpbmVzIGFjY2VzcyBieXRlcyBwYXN0IHRoZSBpbnB1dC4gIFRoaXMgaXMgdGhlblxuICAgKiB1cGRhdGVkIHRvIHRoZSBuZXcgaGlnaCB3YXRlciBtYXJrLlxuICAgKi9cbn1cblxuXG5mdW5jdGlvbiBkZWZsYXRlUmVzZXRLZWVwKHN0cm0pIHtcbiAgdmFyIHM7XG5cbiAgaWYgKCFzdHJtIHx8ICFzdHJtLnN0YXRlKSB7XG4gICAgcmV0dXJuIGVycihzdHJtLCBaX1NUUkVBTV9FUlJPUik7XG4gIH1cblxuICBzdHJtLnRvdGFsX2luID0gc3RybS50b3RhbF9vdXQgPSAwO1xuICBzdHJtLmRhdGFfdHlwZSA9IFpfVU5LTk9XTjtcblxuICBzID0gc3RybS5zdGF0ZTtcbiAgcy5wZW5kaW5nID0gMDtcbiAgcy5wZW5kaW5nX291dCA9IDA7XG5cbiAgaWYgKHMud3JhcCA8IDApIHtcbiAgICBzLndyYXAgPSAtcy53cmFwO1xuICAgIC8qIHdhcyBtYWRlIG5lZ2F0aXZlIGJ5IGRlZmxhdGUoLi4uLCBaX0ZJTklTSCk7ICovXG4gIH1cbiAgcy5zdGF0dXMgPSAocy53cmFwID8gSU5JVF9TVEFURSA6IEJVU1lfU1RBVEUpO1xuICBzdHJtLmFkbGVyID0gKHMud3JhcCA9PT0gMikgP1xuICAgIDAgIC8vIGNyYzMyKDAsIFpfTlVMTCwgMClcbiAgOlxuICAgIDE7IC8vIGFkbGVyMzIoMCwgWl9OVUxMLCAwKVxuICBzLmxhc3RfZmx1c2ggPSBaX05PX0ZMVVNIO1xuICB0cmVlcy5fdHJfaW5pdChzKTtcbiAgcmV0dXJuIFpfT0s7XG59XG5cblxuZnVuY3Rpb24gZGVmbGF0ZVJlc2V0KHN0cm0pIHtcbiAgdmFyIHJldCA9IGRlZmxhdGVSZXNldEtlZXAoc3RybSk7XG4gIGlmIChyZXQgPT09IFpfT0spIHtcbiAgICBsbV9pbml0KHN0cm0uc3RhdGUpO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cblxuZnVuY3Rpb24gZGVmbGF0ZVNldEhlYWRlcihzdHJtLCBoZWFkKSB7XG4gIGlmICghc3RybSB8fCAhc3RybS5zdGF0ZSkgeyByZXR1cm4gWl9TVFJFQU1fRVJST1I7IH1cbiAgaWYgKHN0cm0uc3RhdGUud3JhcCAhPT0gMikgeyByZXR1cm4gWl9TVFJFQU1fRVJST1I7IH1cbiAgc3RybS5zdGF0ZS5nemhlYWQgPSBoZWFkO1xuICByZXR1cm4gWl9PSztcbn1cblxuXG5mdW5jdGlvbiBkZWZsYXRlSW5pdDIoc3RybSwgbGV2ZWwsIG1ldGhvZCwgd2luZG93Qml0cywgbWVtTGV2ZWwsIHN0cmF0ZWd5KSB7XG4gIGlmICghc3RybSkgeyAvLyA9PT0gWl9OVUxMXG4gICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SO1xuICB9XG4gIHZhciB3cmFwID0gMTtcblxuICBpZiAobGV2ZWwgPT09IFpfREVGQVVMVF9DT01QUkVTU0lPTikge1xuICAgIGxldmVsID0gNjtcbiAgfVxuXG4gIGlmICh3aW5kb3dCaXRzIDwgMCkgeyAvKiBzdXBwcmVzcyB6bGliIHdyYXBwZXIgKi9cbiAgICB3cmFwID0gMDtcbiAgICB3aW5kb3dCaXRzID0gLXdpbmRvd0JpdHM7XG4gIH1cblxuICBlbHNlIGlmICh3aW5kb3dCaXRzID4gMTUpIHtcbiAgICB3cmFwID0gMjsgICAgICAgICAgIC8qIHdyaXRlIGd6aXAgd3JhcHBlciBpbnN0ZWFkICovXG4gICAgd2luZG93Qml0cyAtPSAxNjtcbiAgfVxuXG5cbiAgaWYgKG1lbUxldmVsIDwgMSB8fCBtZW1MZXZlbCA+IE1BWF9NRU1fTEVWRUwgfHwgbWV0aG9kICE9PSBaX0RFRkxBVEVEIHx8XG4gICAgd2luZG93Qml0cyA8IDggfHwgd2luZG93Qml0cyA+IDE1IHx8IGxldmVsIDwgMCB8fCBsZXZlbCA+IDkgfHxcbiAgICBzdHJhdGVneSA8IDAgfHwgc3RyYXRlZ3kgPiBaX0ZJWEVEKSB7XG4gICAgcmV0dXJuIGVycihzdHJtLCBaX1NUUkVBTV9FUlJPUik7XG4gIH1cblxuXG4gIGlmICh3aW5kb3dCaXRzID09PSA4KSB7XG4gICAgd2luZG93Qml0cyA9IDk7XG4gIH1cbiAgLyogdW50aWwgMjU2LWJ5dGUgd2luZG93IGJ1ZyBmaXhlZCAqL1xuXG4gIHZhciBzID0gbmV3IERlZmxhdGVTdGF0ZSgpO1xuXG4gIHN0cm0uc3RhdGUgPSBzO1xuICBzLnN0cm0gPSBzdHJtO1xuXG4gIHMud3JhcCA9IHdyYXA7XG4gIHMuZ3poZWFkID0gbnVsbDtcbiAgcy53X2JpdHMgPSB3aW5kb3dCaXRzO1xuICBzLndfc2l6ZSA9IDEgPDwgcy53X2JpdHM7XG4gIHMud19tYXNrID0gcy53X3NpemUgLSAxO1xuXG4gIHMuaGFzaF9iaXRzID0gbWVtTGV2ZWwgKyA3O1xuICBzLmhhc2hfc2l6ZSA9IDEgPDwgcy5oYXNoX2JpdHM7XG4gIHMuaGFzaF9tYXNrID0gcy5oYXNoX3NpemUgLSAxO1xuICBzLmhhc2hfc2hpZnQgPSB+figocy5oYXNoX2JpdHMgKyBNSU5fTUFUQ0ggLSAxKSAvIE1JTl9NQVRDSCk7XG5cbiAgcy53aW5kb3cgPSBuZXcgdXRpbHMuQnVmOChzLndfc2l6ZSAqIDIpO1xuICBzLmhlYWQgPSBuZXcgdXRpbHMuQnVmMTYocy5oYXNoX3NpemUpO1xuICBzLnByZXYgPSBuZXcgdXRpbHMuQnVmMTYocy53X3NpemUpO1xuXG4gIC8vIERvbid0IG5lZWQgbWVtIGluaXQgbWFnaWMgZm9yIEpTLlxuICAvL3MuaGlnaF93YXRlciA9IDA7ICAvKiBub3RoaW5nIHdyaXR0ZW4gdG8gcy0+d2luZG93IHlldCAqL1xuXG4gIHMubGl0X2J1ZnNpemUgPSAxIDw8IChtZW1MZXZlbCArIDYpOyAvKiAxNksgZWxlbWVudHMgYnkgZGVmYXVsdCAqL1xuXG4gIHMucGVuZGluZ19idWZfc2l6ZSA9IHMubGl0X2J1ZnNpemUgKiA0O1xuXG4gIC8vb3ZlcmxheSA9ICh1c2hmICopIFpBTExPQyhzdHJtLCBzLT5saXRfYnVmc2l6ZSwgc2l6ZW9mKHVzaCkrMik7XG4gIC8vcy0+cGVuZGluZ19idWYgPSAodWNoZiAqKSBvdmVybGF5O1xuICBzLnBlbmRpbmdfYnVmID0gbmV3IHV0aWxzLkJ1Zjgocy5wZW5kaW5nX2J1Zl9zaXplKTtcblxuICAvLyBJdCBpcyBvZmZzZXQgZnJvbSBgcy5wZW5kaW5nX2J1ZmAgKHNpemUgaXMgYHMubGl0X2J1ZnNpemUgKiAyYClcbiAgLy9zLT5kX2J1ZiA9IG92ZXJsYXkgKyBzLT5saXRfYnVmc2l6ZS9zaXplb2YodXNoKTtcbiAgcy5kX2J1ZiA9IDEgKiBzLmxpdF9idWZzaXplO1xuXG4gIC8vcy0+bF9idWYgPSBzLT5wZW5kaW5nX2J1ZiArICgxK3NpemVvZih1c2gpKSpzLT5saXRfYnVmc2l6ZTtcbiAgcy5sX2J1ZiA9ICgxICsgMikgKiBzLmxpdF9idWZzaXplO1xuXG4gIHMubGV2ZWwgPSBsZXZlbDtcbiAgcy5zdHJhdGVneSA9IHN0cmF0ZWd5O1xuICBzLm1ldGhvZCA9IG1ldGhvZDtcblxuICByZXR1cm4gZGVmbGF0ZVJlc2V0KHN0cm0pO1xufVxuXG5mdW5jdGlvbiBkZWZsYXRlSW5pdChzdHJtLCBsZXZlbCkge1xuICByZXR1cm4gZGVmbGF0ZUluaXQyKHN0cm0sIGxldmVsLCBaX0RFRkxBVEVELCBNQVhfV0JJVFMsIERFRl9NRU1fTEVWRUwsIFpfREVGQVVMVF9TVFJBVEVHWSk7XG59XG5cblxuZnVuY3Rpb24gZGVmbGF0ZShzdHJtLCBmbHVzaCkge1xuICB2YXIgb2xkX2ZsdXNoLCBzO1xuICB2YXIgYmVnLCB2YWw7IC8vIGZvciBnemlwIGhlYWRlciB3cml0ZSBvbmx5XG5cbiAgaWYgKCFzdHJtIHx8ICFzdHJtLnN0YXRlIHx8XG4gICAgZmx1c2ggPiBaX0JMT0NLIHx8IGZsdXNoIDwgMCkge1xuICAgIHJldHVybiBzdHJtID8gZXJyKHN0cm0sIFpfU1RSRUFNX0VSUk9SKSA6IFpfU1RSRUFNX0VSUk9SO1xuICB9XG5cbiAgcyA9IHN0cm0uc3RhdGU7XG5cbiAgaWYgKCFzdHJtLm91dHB1dCB8fFxuICAgICAgKCFzdHJtLmlucHV0ICYmIHN0cm0uYXZhaWxfaW4gIT09IDApIHx8XG4gICAgICAocy5zdGF0dXMgPT09IEZJTklTSF9TVEFURSAmJiBmbHVzaCAhPT0gWl9GSU5JU0gpKSB7XG4gICAgcmV0dXJuIGVycihzdHJtLCAoc3RybS5hdmFpbF9vdXQgPT09IDApID8gWl9CVUZfRVJST1IgOiBaX1NUUkVBTV9FUlJPUik7XG4gIH1cblxuICBzLnN0cm0gPSBzdHJtOyAvKiBqdXN0IGluIGNhc2UgKi9cbiAgb2xkX2ZsdXNoID0gcy5sYXN0X2ZsdXNoO1xuICBzLmxhc3RfZmx1c2ggPSBmbHVzaDtcblxuICAvKiBXcml0ZSB0aGUgaGVhZGVyICovXG4gIGlmIChzLnN0YXR1cyA9PT0gSU5JVF9TVEFURSkge1xuXG4gICAgaWYgKHMud3JhcCA9PT0gMikgeyAvLyBHWklQIGhlYWRlclxuICAgICAgc3RybS5hZGxlciA9IDA7ICAvL2NyYzMyKDBMLCBaX05VTEwsIDApO1xuICAgICAgcHV0X2J5dGUocywgMzEpO1xuICAgICAgcHV0X2J5dGUocywgMTM5KTtcbiAgICAgIHB1dF9ieXRlKHMsIDgpO1xuICAgICAgaWYgKCFzLmd6aGVhZCkgeyAvLyBzLT5nemhlYWQgPT0gWl9OVUxMXG4gICAgICAgIHB1dF9ieXRlKHMsIDApO1xuICAgICAgICBwdXRfYnl0ZShzLCAwKTtcbiAgICAgICAgcHV0X2J5dGUocywgMCk7XG4gICAgICAgIHB1dF9ieXRlKHMsIDApO1xuICAgICAgICBwdXRfYnl0ZShzLCAwKTtcbiAgICAgICAgcHV0X2J5dGUocywgcy5sZXZlbCA9PT0gOSA/IDIgOlxuICAgICAgICAgICAgICAgICAgICAocy5zdHJhdGVneSA+PSBaX0hVRkZNQU5fT05MWSB8fCBzLmxldmVsIDwgMiA/XG4gICAgICAgICAgICAgICAgICAgICA0IDogMCkpO1xuICAgICAgICBwdXRfYnl0ZShzLCBPU19DT0RFKTtcbiAgICAgICAgcy5zdGF0dXMgPSBCVVNZX1NUQVRFO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHB1dF9ieXRlKHMsIChzLmd6aGVhZC50ZXh0ID8gMSA6IDApICtcbiAgICAgICAgICAgICAgICAgICAgKHMuZ3poZWFkLmhjcmMgPyAyIDogMCkgK1xuICAgICAgICAgICAgICAgICAgICAoIXMuZ3poZWFkLmV4dHJhID8gMCA6IDQpICtcbiAgICAgICAgICAgICAgICAgICAgKCFzLmd6aGVhZC5uYW1lID8gMCA6IDgpICtcbiAgICAgICAgICAgICAgICAgICAgKCFzLmd6aGVhZC5jb21tZW50ID8gMCA6IDE2KVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgIHB1dF9ieXRlKHMsIHMuZ3poZWFkLnRpbWUgJiAweGZmKTtcbiAgICAgICAgcHV0X2J5dGUocywgKHMuZ3poZWFkLnRpbWUgPj4gOCkgJiAweGZmKTtcbiAgICAgICAgcHV0X2J5dGUocywgKHMuZ3poZWFkLnRpbWUgPj4gMTYpICYgMHhmZik7XG4gICAgICAgIHB1dF9ieXRlKHMsIChzLmd6aGVhZC50aW1lID4+IDI0KSAmIDB4ZmYpO1xuICAgICAgICBwdXRfYnl0ZShzLCBzLmxldmVsID09PSA5ID8gMiA6XG4gICAgICAgICAgICAgICAgICAgIChzLnN0cmF0ZWd5ID49IFpfSFVGRk1BTl9PTkxZIHx8IHMubGV2ZWwgPCAyID9cbiAgICAgICAgICAgICAgICAgICAgIDQgOiAwKSk7XG4gICAgICAgIHB1dF9ieXRlKHMsIHMuZ3poZWFkLm9zICYgMHhmZik7XG4gICAgICAgIGlmIChzLmd6aGVhZC5leHRyYSAmJiBzLmd6aGVhZC5leHRyYS5sZW5ndGgpIHtcbiAgICAgICAgICBwdXRfYnl0ZShzLCBzLmd6aGVhZC5leHRyYS5sZW5ndGggJiAweGZmKTtcbiAgICAgICAgICBwdXRfYnl0ZShzLCAocy5nemhlYWQuZXh0cmEubGVuZ3RoID4+IDgpICYgMHhmZik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHMuZ3poZWFkLmhjcmMpIHtcbiAgICAgICAgICBzdHJtLmFkbGVyID0gY3JjMzIoc3RybS5hZGxlciwgcy5wZW5kaW5nX2J1Ziwgcy5wZW5kaW5nLCAwKTtcbiAgICAgICAgfVxuICAgICAgICBzLmd6aW5kZXggPSAwO1xuICAgICAgICBzLnN0YXR1cyA9IEVYVFJBX1NUQVRFO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIC8vIERFRkxBVEUgaGVhZGVyXG4gICAge1xuICAgICAgdmFyIGhlYWRlciA9IChaX0RFRkxBVEVEICsgKChzLndfYml0cyAtIDgpIDw8IDQpKSA8PCA4O1xuICAgICAgdmFyIGxldmVsX2ZsYWdzID0gLTE7XG5cbiAgICAgIGlmIChzLnN0cmF0ZWd5ID49IFpfSFVGRk1BTl9PTkxZIHx8IHMubGV2ZWwgPCAyKSB7XG4gICAgICAgIGxldmVsX2ZsYWdzID0gMDtcbiAgICAgIH0gZWxzZSBpZiAocy5sZXZlbCA8IDYpIHtcbiAgICAgICAgbGV2ZWxfZmxhZ3MgPSAxO1xuICAgICAgfSBlbHNlIGlmIChzLmxldmVsID09PSA2KSB7XG4gICAgICAgIGxldmVsX2ZsYWdzID0gMjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxldmVsX2ZsYWdzID0gMztcbiAgICAgIH1cbiAgICAgIGhlYWRlciB8PSAobGV2ZWxfZmxhZ3MgPDwgNik7XG4gICAgICBpZiAocy5zdHJzdGFydCAhPT0gMCkgeyBoZWFkZXIgfD0gUFJFU0VUX0RJQ1Q7IH1cbiAgICAgIGhlYWRlciArPSAzMSAtIChoZWFkZXIgJSAzMSk7XG5cbiAgICAgIHMuc3RhdHVzID0gQlVTWV9TVEFURTtcbiAgICAgIHB1dFNob3J0TVNCKHMsIGhlYWRlcik7XG5cbiAgICAgIC8qIFNhdmUgdGhlIGFkbGVyMzIgb2YgdGhlIHByZXNldCBkaWN0aW9uYXJ5OiAqL1xuICAgICAgaWYgKHMuc3Ryc3RhcnQgIT09IDApIHtcbiAgICAgICAgcHV0U2hvcnRNU0Iocywgc3RybS5hZGxlciA+Pj4gMTYpO1xuICAgICAgICBwdXRTaG9ydE1TQihzLCBzdHJtLmFkbGVyICYgMHhmZmZmKTtcbiAgICAgIH1cbiAgICAgIHN0cm0uYWRsZXIgPSAxOyAvLyBhZGxlcjMyKDBMLCBaX05VTEwsIDApO1xuICAgIH1cbiAgfVxuXG4vLyNpZmRlZiBHWklQXG4gIGlmIChzLnN0YXR1cyA9PT0gRVhUUkFfU1RBVEUpIHtcbiAgICBpZiAocy5nemhlYWQuZXh0cmEvKiAhPSBaX05VTEwqLykge1xuICAgICAgYmVnID0gcy5wZW5kaW5nOyAgLyogc3RhcnQgb2YgYnl0ZXMgdG8gdXBkYXRlIGNyYyAqL1xuXG4gICAgICB3aGlsZSAocy5nemluZGV4IDwgKHMuZ3poZWFkLmV4dHJhLmxlbmd0aCAmIDB4ZmZmZikpIHtcbiAgICAgICAgaWYgKHMucGVuZGluZyA9PT0gcy5wZW5kaW5nX2J1Zl9zaXplKSB7XG4gICAgICAgICAgaWYgKHMuZ3poZWFkLmhjcmMgJiYgcy5wZW5kaW5nID4gYmVnKSB7XG4gICAgICAgICAgICBzdHJtLmFkbGVyID0gY3JjMzIoc3RybS5hZGxlciwgcy5wZW5kaW5nX2J1Ziwgcy5wZW5kaW5nIC0gYmVnLCBiZWcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmbHVzaF9wZW5kaW5nKHN0cm0pO1xuICAgICAgICAgIGJlZyA9IHMucGVuZGluZztcbiAgICAgICAgICBpZiAocy5wZW5kaW5nID09PSBzLnBlbmRpbmdfYnVmX3NpemUpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBwdXRfYnl0ZShzLCBzLmd6aGVhZC5leHRyYVtzLmd6aW5kZXhdICYgMHhmZik7XG4gICAgICAgIHMuZ3ppbmRleCsrO1xuICAgICAgfVxuICAgICAgaWYgKHMuZ3poZWFkLmhjcmMgJiYgcy5wZW5kaW5nID4gYmVnKSB7XG4gICAgICAgIHN0cm0uYWRsZXIgPSBjcmMzMihzdHJtLmFkbGVyLCBzLnBlbmRpbmdfYnVmLCBzLnBlbmRpbmcgLSBiZWcsIGJlZyk7XG4gICAgICB9XG4gICAgICBpZiAocy5nemluZGV4ID09PSBzLmd6aGVhZC5leHRyYS5sZW5ndGgpIHtcbiAgICAgICAgcy5nemluZGV4ID0gMDtcbiAgICAgICAgcy5zdGF0dXMgPSBOQU1FX1NUQVRFO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHMuc3RhdHVzID0gTkFNRV9TVEFURTtcbiAgICB9XG4gIH1cbiAgaWYgKHMuc3RhdHVzID09PSBOQU1FX1NUQVRFKSB7XG4gICAgaWYgKHMuZ3poZWFkLm5hbWUvKiAhPSBaX05VTEwqLykge1xuICAgICAgYmVnID0gcy5wZW5kaW5nOyAgLyogc3RhcnQgb2YgYnl0ZXMgdG8gdXBkYXRlIGNyYyAqL1xuICAgICAgLy9pbnQgdmFsO1xuXG4gICAgICBkbyB7XG4gICAgICAgIGlmIChzLnBlbmRpbmcgPT09IHMucGVuZGluZ19idWZfc2l6ZSkge1xuICAgICAgICAgIGlmIChzLmd6aGVhZC5oY3JjICYmIHMucGVuZGluZyA+IGJlZykge1xuICAgICAgICAgICAgc3RybS5hZGxlciA9IGNyYzMyKHN0cm0uYWRsZXIsIHMucGVuZGluZ19idWYsIHMucGVuZGluZyAtIGJlZywgYmVnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZmx1c2hfcGVuZGluZyhzdHJtKTtcbiAgICAgICAgICBiZWcgPSBzLnBlbmRpbmc7XG4gICAgICAgICAgaWYgKHMucGVuZGluZyA9PT0gcy5wZW5kaW5nX2J1Zl9zaXplKSB7XG4gICAgICAgICAgICB2YWwgPSAxO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIEpTIHNwZWNpZmljOiBsaXR0bGUgbWFnaWMgdG8gYWRkIHplcm8gdGVybWluYXRvciB0byBlbmQgb2Ygc3RyaW5nXG4gICAgICAgIGlmIChzLmd6aW5kZXggPCBzLmd6aGVhZC5uYW1lLmxlbmd0aCkge1xuICAgICAgICAgIHZhbCA9IHMuZ3poZWFkLm5hbWUuY2hhckNvZGVBdChzLmd6aW5kZXgrKykgJiAweGZmO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbCA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgcHV0X2J5dGUocywgdmFsKTtcbiAgICAgIH0gd2hpbGUgKHZhbCAhPT0gMCk7XG5cbiAgICAgIGlmIChzLmd6aGVhZC5oY3JjICYmIHMucGVuZGluZyA+IGJlZykge1xuICAgICAgICBzdHJtLmFkbGVyID0gY3JjMzIoc3RybS5hZGxlciwgcy5wZW5kaW5nX2J1Ziwgcy5wZW5kaW5nIC0gYmVnLCBiZWcpO1xuICAgICAgfVxuICAgICAgaWYgKHZhbCA9PT0gMCkge1xuICAgICAgICBzLmd6aW5kZXggPSAwO1xuICAgICAgICBzLnN0YXR1cyA9IENPTU1FTlRfU1RBVEU7XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcy5zdGF0dXMgPSBDT01NRU5UX1NUQVRFO1xuICAgIH1cbiAgfVxuICBpZiAocy5zdGF0dXMgPT09IENPTU1FTlRfU1RBVEUpIHtcbiAgICBpZiAocy5nemhlYWQuY29tbWVudC8qICE9IFpfTlVMTCovKSB7XG4gICAgICBiZWcgPSBzLnBlbmRpbmc7ICAvKiBzdGFydCBvZiBieXRlcyB0byB1cGRhdGUgY3JjICovXG4gICAgICAvL2ludCB2YWw7XG5cbiAgICAgIGRvIHtcbiAgICAgICAgaWYgKHMucGVuZGluZyA9PT0gcy5wZW5kaW5nX2J1Zl9zaXplKSB7XG4gICAgICAgICAgaWYgKHMuZ3poZWFkLmhjcmMgJiYgcy5wZW5kaW5nID4gYmVnKSB7XG4gICAgICAgICAgICBzdHJtLmFkbGVyID0gY3JjMzIoc3RybS5hZGxlciwgcy5wZW5kaW5nX2J1Ziwgcy5wZW5kaW5nIC0gYmVnLCBiZWcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmbHVzaF9wZW5kaW5nKHN0cm0pO1xuICAgICAgICAgIGJlZyA9IHMucGVuZGluZztcbiAgICAgICAgICBpZiAocy5wZW5kaW5nID09PSBzLnBlbmRpbmdfYnVmX3NpemUpIHtcbiAgICAgICAgICAgIHZhbCA9IDE7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gSlMgc3BlY2lmaWM6IGxpdHRsZSBtYWdpYyB0byBhZGQgemVybyB0ZXJtaW5hdG9yIHRvIGVuZCBvZiBzdHJpbmdcbiAgICAgICAgaWYgKHMuZ3ppbmRleCA8IHMuZ3poZWFkLmNvbW1lbnQubGVuZ3RoKSB7XG4gICAgICAgICAgdmFsID0gcy5nemhlYWQuY29tbWVudC5jaGFyQ29kZUF0KHMuZ3ppbmRleCsrKSAmIDB4ZmY7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFsID0gMDtcbiAgICAgICAgfVxuICAgICAgICBwdXRfYnl0ZShzLCB2YWwpO1xuICAgICAgfSB3aGlsZSAodmFsICE9PSAwKTtcblxuICAgICAgaWYgKHMuZ3poZWFkLmhjcmMgJiYgcy5wZW5kaW5nID4gYmVnKSB7XG4gICAgICAgIHN0cm0uYWRsZXIgPSBjcmMzMihzdHJtLmFkbGVyLCBzLnBlbmRpbmdfYnVmLCBzLnBlbmRpbmcgLSBiZWcsIGJlZyk7XG4gICAgICB9XG4gICAgICBpZiAodmFsID09PSAwKSB7XG4gICAgICAgIHMuc3RhdHVzID0gSENSQ19TVEFURTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBzLnN0YXR1cyA9IEhDUkNfU1RBVEU7XG4gICAgfVxuICB9XG4gIGlmIChzLnN0YXR1cyA9PT0gSENSQ19TVEFURSkge1xuICAgIGlmIChzLmd6aGVhZC5oY3JjKSB7XG4gICAgICBpZiAocy5wZW5kaW5nICsgMiA+IHMucGVuZGluZ19idWZfc2l6ZSkge1xuICAgICAgICBmbHVzaF9wZW5kaW5nKHN0cm0pO1xuICAgICAgfVxuICAgICAgaWYgKHMucGVuZGluZyArIDIgPD0gcy5wZW5kaW5nX2J1Zl9zaXplKSB7XG4gICAgICAgIHB1dF9ieXRlKHMsIHN0cm0uYWRsZXIgJiAweGZmKTtcbiAgICAgICAgcHV0X2J5dGUocywgKHN0cm0uYWRsZXIgPj4gOCkgJiAweGZmKTtcbiAgICAgICAgc3RybS5hZGxlciA9IDA7IC8vY3JjMzIoMEwsIFpfTlVMTCwgMCk7XG4gICAgICAgIHMuc3RhdHVzID0gQlVTWV9TVEFURTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBzLnN0YXR1cyA9IEJVU1lfU1RBVEU7XG4gICAgfVxuICB9XG4vLyNlbmRpZlxuXG4gIC8qIEZsdXNoIGFzIG11Y2ggcGVuZGluZyBvdXRwdXQgYXMgcG9zc2libGUgKi9cbiAgaWYgKHMucGVuZGluZyAhPT0gMCkge1xuICAgIGZsdXNoX3BlbmRpbmcoc3RybSk7XG4gICAgaWYgKHN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICAvKiBTaW5jZSBhdmFpbF9vdXQgaXMgMCwgZGVmbGF0ZSB3aWxsIGJlIGNhbGxlZCBhZ2FpbiB3aXRoXG4gICAgICAgKiBtb3JlIG91dHB1dCBzcGFjZSwgYnV0IHBvc3NpYmx5IHdpdGggYm90aCBwZW5kaW5nIGFuZFxuICAgICAgICogYXZhaWxfaW4gZXF1YWwgdG8gemVyby4gVGhlcmUgd29uJ3QgYmUgYW55dGhpbmcgdG8gZG8sXG4gICAgICAgKiBidXQgdGhpcyBpcyBub3QgYW4gZXJyb3Igc2l0dWF0aW9uIHNvIG1ha2Ugc3VyZSB3ZVxuICAgICAgICogcmV0dXJuIE9LIGluc3RlYWQgb2YgQlVGX0VSUk9SIGF0IG5leHQgY2FsbCBvZiBkZWZsYXRlOlxuICAgICAgICovXG4gICAgICBzLmxhc3RfZmx1c2ggPSAtMTtcbiAgICAgIHJldHVybiBaX09LO1xuICAgIH1cblxuICAgIC8qIE1ha2Ugc3VyZSB0aGVyZSBpcyBzb21ldGhpbmcgdG8gZG8gYW5kIGF2b2lkIGR1cGxpY2F0ZSBjb25zZWN1dGl2ZVxuICAgICAqIGZsdXNoZXMuIEZvciByZXBlYXRlZCBhbmQgdXNlbGVzcyBjYWxscyB3aXRoIFpfRklOSVNILCB3ZSBrZWVwXG4gICAgICogcmV0dXJuaW5nIFpfU1RSRUFNX0VORCBpbnN0ZWFkIG9mIFpfQlVGX0VSUk9SLlxuICAgICAqL1xuICB9IGVsc2UgaWYgKHN0cm0uYXZhaWxfaW4gPT09IDAgJiYgcmFuayhmbHVzaCkgPD0gcmFuayhvbGRfZmx1c2gpICYmXG4gICAgZmx1c2ggIT09IFpfRklOSVNIKSB7XG4gICAgcmV0dXJuIGVycihzdHJtLCBaX0JVRl9FUlJPUik7XG4gIH1cblxuICAvKiBVc2VyIG11c3Qgbm90IHByb3ZpZGUgbW9yZSBpbnB1dCBhZnRlciB0aGUgZmlyc3QgRklOSVNIOiAqL1xuICBpZiAocy5zdGF0dXMgPT09IEZJTklTSF9TVEFURSAmJiBzdHJtLmF2YWlsX2luICE9PSAwKSB7XG4gICAgcmV0dXJuIGVycihzdHJtLCBaX0JVRl9FUlJPUik7XG4gIH1cblxuICAvKiBTdGFydCBhIG5ldyBibG9jayBvciBjb250aW51ZSB0aGUgY3VycmVudCBvbmUuXG4gICAqL1xuICBpZiAoc3RybS5hdmFpbF9pbiAhPT0gMCB8fCBzLmxvb2thaGVhZCAhPT0gMCB8fFxuICAgIChmbHVzaCAhPT0gWl9OT19GTFVTSCAmJiBzLnN0YXR1cyAhPT0gRklOSVNIX1NUQVRFKSkge1xuICAgIHZhciBic3RhdGUgPSAocy5zdHJhdGVneSA9PT0gWl9IVUZGTUFOX09OTFkpID8gZGVmbGF0ZV9odWZmKHMsIGZsdXNoKSA6XG4gICAgICAocy5zdHJhdGVneSA9PT0gWl9STEUgPyBkZWZsYXRlX3JsZShzLCBmbHVzaCkgOlxuICAgICAgICBjb25maWd1cmF0aW9uX3RhYmxlW3MubGV2ZWxdLmZ1bmMocywgZmx1c2gpKTtcblxuICAgIGlmIChic3RhdGUgPT09IEJTX0ZJTklTSF9TVEFSVEVEIHx8IGJzdGF0ZSA9PT0gQlNfRklOSVNIX0RPTkUpIHtcbiAgICAgIHMuc3RhdHVzID0gRklOSVNIX1NUQVRFO1xuICAgIH1cbiAgICBpZiAoYnN0YXRlID09PSBCU19ORUVEX01PUkUgfHwgYnN0YXRlID09PSBCU19GSU5JU0hfU1RBUlRFRCkge1xuICAgICAgaWYgKHN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICAgIHMubGFzdF9mbHVzaCA9IC0xO1xuICAgICAgICAvKiBhdm9pZCBCVUZfRVJST1IgbmV4dCBjYWxsLCBzZWUgYWJvdmUgKi9cbiAgICAgIH1cbiAgICAgIHJldHVybiBaX09LO1xuICAgICAgLyogSWYgZmx1c2ggIT0gWl9OT19GTFVTSCAmJiBhdmFpbF9vdXQgPT0gMCwgdGhlIG5leHQgY2FsbFxuICAgICAgICogb2YgZGVmbGF0ZSBzaG91bGQgdXNlIHRoZSBzYW1lIGZsdXNoIHBhcmFtZXRlciB0byBtYWtlIHN1cmVcbiAgICAgICAqIHRoYXQgdGhlIGZsdXNoIGlzIGNvbXBsZXRlLiBTbyB3ZSBkb24ndCBoYXZlIHRvIG91dHB1dCBhblxuICAgICAgICogZW1wdHkgYmxvY2sgaGVyZSwgdGhpcyB3aWxsIGJlIGRvbmUgYXQgbmV4dCBjYWxsLiBUaGlzIGFsc29cbiAgICAgICAqIGVuc3VyZXMgdGhhdCBmb3IgYSB2ZXJ5IHNtYWxsIG91dHB1dCBidWZmZXIsIHdlIGVtaXQgYXQgbW9zdFxuICAgICAgICogb25lIGVtcHR5IGJsb2NrLlxuICAgICAgICovXG4gICAgfVxuICAgIGlmIChic3RhdGUgPT09IEJTX0JMT0NLX0RPTkUpIHtcbiAgICAgIGlmIChmbHVzaCA9PT0gWl9QQVJUSUFMX0ZMVVNIKSB7XG4gICAgICAgIHRyZWVzLl90cl9hbGlnbihzKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGZsdXNoICE9PSBaX0JMT0NLKSB7IC8qIEZVTExfRkxVU0ggb3IgU1lOQ19GTFVTSCAqL1xuXG4gICAgICAgIHRyZWVzLl90cl9zdG9yZWRfYmxvY2socywgMCwgMCwgZmFsc2UpO1xuICAgICAgICAvKiBGb3IgYSBmdWxsIGZsdXNoLCB0aGlzIGVtcHR5IGJsb2NrIHdpbGwgYmUgcmVjb2duaXplZFxuICAgICAgICAgKiBhcyBhIHNwZWNpYWwgbWFya2VyIGJ5IGluZmxhdGVfc3luYygpLlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKGZsdXNoID09PSBaX0ZVTExfRkxVU0gpIHtcbiAgICAgICAgICAvKioqIENMRUFSX0hBU0gocyk7ICoqKi8gICAgICAgICAgICAgLyogZm9yZ2V0IGhpc3RvcnkgKi9cbiAgICAgICAgICB6ZXJvKHMuaGVhZCk7IC8vIEZpbGwgd2l0aCBOSUwgKD0gMCk7XG5cbiAgICAgICAgICBpZiAocy5sb29rYWhlYWQgPT09IDApIHtcbiAgICAgICAgICAgIHMuc3Ryc3RhcnQgPSAwO1xuICAgICAgICAgICAgcy5ibG9ja19zdGFydCA9IDA7XG4gICAgICAgICAgICBzLmluc2VydCA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBmbHVzaF9wZW5kaW5nKHN0cm0pO1xuICAgICAgaWYgKHN0cm0uYXZhaWxfb3V0ID09PSAwKSB7XG4gICAgICAgIHMubGFzdF9mbHVzaCA9IC0xOyAvKiBhdm9pZCBCVUZfRVJST1IgYXQgbmV4dCBjYWxsLCBzZWUgYWJvdmUgKi9cbiAgICAgICAgcmV0dXJuIFpfT0s7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIC8vQXNzZXJ0KHN0cm0tPmF2YWlsX291dCA+IDAsIFwiYnVnMlwiKTtcbiAgLy9pZiAoc3RybS5hdmFpbF9vdXQgPD0gMCkgeyB0aHJvdyBuZXcgRXJyb3IoXCJidWcyXCIpO31cblxuICBpZiAoZmx1c2ggIT09IFpfRklOSVNIKSB7IHJldHVybiBaX09LOyB9XG4gIGlmIChzLndyYXAgPD0gMCkgeyByZXR1cm4gWl9TVFJFQU1fRU5EOyB9XG5cbiAgLyogV3JpdGUgdGhlIHRyYWlsZXIgKi9cbiAgaWYgKHMud3JhcCA9PT0gMikge1xuICAgIHB1dF9ieXRlKHMsIHN0cm0uYWRsZXIgJiAweGZmKTtcbiAgICBwdXRfYnl0ZShzLCAoc3RybS5hZGxlciA+PiA4KSAmIDB4ZmYpO1xuICAgIHB1dF9ieXRlKHMsIChzdHJtLmFkbGVyID4+IDE2KSAmIDB4ZmYpO1xuICAgIHB1dF9ieXRlKHMsIChzdHJtLmFkbGVyID4+IDI0KSAmIDB4ZmYpO1xuICAgIHB1dF9ieXRlKHMsIHN0cm0udG90YWxfaW4gJiAweGZmKTtcbiAgICBwdXRfYnl0ZShzLCAoc3RybS50b3RhbF9pbiA+PiA4KSAmIDB4ZmYpO1xuICAgIHB1dF9ieXRlKHMsIChzdHJtLnRvdGFsX2luID4+IDE2KSAmIDB4ZmYpO1xuICAgIHB1dF9ieXRlKHMsIChzdHJtLnRvdGFsX2luID4+IDI0KSAmIDB4ZmYpO1xuICB9XG4gIGVsc2VcbiAge1xuICAgIHB1dFNob3J0TVNCKHMsIHN0cm0uYWRsZXIgPj4+IDE2KTtcbiAgICBwdXRTaG9ydE1TQihzLCBzdHJtLmFkbGVyICYgMHhmZmZmKTtcbiAgfVxuXG4gIGZsdXNoX3BlbmRpbmcoc3RybSk7XG4gIC8qIElmIGF2YWlsX291dCBpcyB6ZXJvLCB0aGUgYXBwbGljYXRpb24gd2lsbCBjYWxsIGRlZmxhdGUgYWdhaW5cbiAgICogdG8gZmx1c2ggdGhlIHJlc3QuXG4gICAqL1xuICBpZiAocy53cmFwID4gMCkgeyBzLndyYXAgPSAtcy53cmFwOyB9XG4gIC8qIHdyaXRlIHRoZSB0cmFpbGVyIG9ubHkgb25jZSEgKi9cbiAgcmV0dXJuIHMucGVuZGluZyAhPT0gMCA/IFpfT0sgOiBaX1NUUkVBTV9FTkQ7XG59XG5cbmZ1bmN0aW9uIGRlZmxhdGVFbmQoc3RybSkge1xuICB2YXIgc3RhdHVzO1xuXG4gIGlmICghc3RybS8qPT0gWl9OVUxMKi8gfHwgIXN0cm0uc3RhdGUvKj09IFpfTlVMTCovKSB7XG4gICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SO1xuICB9XG5cbiAgc3RhdHVzID0gc3RybS5zdGF0ZS5zdGF0dXM7XG4gIGlmIChzdGF0dXMgIT09IElOSVRfU1RBVEUgJiZcbiAgICBzdGF0dXMgIT09IEVYVFJBX1NUQVRFICYmXG4gICAgc3RhdHVzICE9PSBOQU1FX1NUQVRFICYmXG4gICAgc3RhdHVzICE9PSBDT01NRU5UX1NUQVRFICYmXG4gICAgc3RhdHVzICE9PSBIQ1JDX1NUQVRFICYmXG4gICAgc3RhdHVzICE9PSBCVVNZX1NUQVRFICYmXG4gICAgc3RhdHVzICE9PSBGSU5JU0hfU1RBVEVcbiAgKSB7XG4gICAgcmV0dXJuIGVycihzdHJtLCBaX1NUUkVBTV9FUlJPUik7XG4gIH1cblxuICBzdHJtLnN0YXRlID0gbnVsbDtcblxuICByZXR1cm4gc3RhdHVzID09PSBCVVNZX1NUQVRFID8gZXJyKHN0cm0sIFpfREFUQV9FUlJPUikgOiBaX09LO1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEluaXRpYWxpemVzIHRoZSBjb21wcmVzc2lvbiBkaWN0aW9uYXJ5IGZyb20gdGhlIGdpdmVuIGJ5dGVcbiAqIHNlcXVlbmNlIHdpdGhvdXQgcHJvZHVjaW5nIGFueSBjb21wcmVzc2VkIG91dHB1dC5cbiAqL1xuZnVuY3Rpb24gZGVmbGF0ZVNldERpY3Rpb25hcnkoc3RybSwgZGljdGlvbmFyeSkge1xuICB2YXIgZGljdExlbmd0aCA9IGRpY3Rpb25hcnkubGVuZ3RoO1xuXG4gIHZhciBzO1xuICB2YXIgc3RyLCBuO1xuICB2YXIgd3JhcDtcbiAgdmFyIGF2YWlsO1xuICB2YXIgbmV4dDtcbiAgdmFyIGlucHV0O1xuICB2YXIgdG1wRGljdDtcblxuICBpZiAoIXN0cm0vKj09IFpfTlVMTCovIHx8ICFzdHJtLnN0YXRlLyo9PSBaX05VTEwqLykge1xuICAgIHJldHVybiBaX1NUUkVBTV9FUlJPUjtcbiAgfVxuXG4gIHMgPSBzdHJtLnN0YXRlO1xuICB3cmFwID0gcy53cmFwO1xuXG4gIGlmICh3cmFwID09PSAyIHx8ICh3cmFwID09PSAxICYmIHMuc3RhdHVzICE9PSBJTklUX1NUQVRFKSB8fCBzLmxvb2thaGVhZCkge1xuICAgIHJldHVybiBaX1NUUkVBTV9FUlJPUjtcbiAgfVxuXG4gIC8qIHdoZW4gdXNpbmcgemxpYiB3cmFwcGVycywgY29tcHV0ZSBBZGxlci0zMiBmb3IgcHJvdmlkZWQgZGljdGlvbmFyeSAqL1xuICBpZiAod3JhcCA9PT0gMSkge1xuICAgIC8qIGFkbGVyMzIoc3RybS0+YWRsZXIsIGRpY3Rpb25hcnksIGRpY3RMZW5ndGgpOyAqL1xuICAgIHN0cm0uYWRsZXIgPSBhZGxlcjMyKHN0cm0uYWRsZXIsIGRpY3Rpb25hcnksIGRpY3RMZW5ndGgsIDApO1xuICB9XG5cbiAgcy53cmFwID0gMDsgICAvKiBhdm9pZCBjb21wdXRpbmcgQWRsZXItMzIgaW4gcmVhZF9idWYgKi9cblxuICAvKiBpZiBkaWN0aW9uYXJ5IHdvdWxkIGZpbGwgd2luZG93LCBqdXN0IHJlcGxhY2UgdGhlIGhpc3RvcnkgKi9cbiAgaWYgKGRpY3RMZW5ndGggPj0gcy53X3NpemUpIHtcbiAgICBpZiAod3JhcCA9PT0gMCkgeyAgICAgICAgICAgIC8qIGFscmVhZHkgZW1wdHkgb3RoZXJ3aXNlICovXG4gICAgICAvKioqIENMRUFSX0hBU0gocyk7ICoqKi9cbiAgICAgIHplcm8ocy5oZWFkKTsgLy8gRmlsbCB3aXRoIE5JTCAoPSAwKTtcbiAgICAgIHMuc3Ryc3RhcnQgPSAwO1xuICAgICAgcy5ibG9ja19zdGFydCA9IDA7XG4gICAgICBzLmluc2VydCA9IDA7XG4gICAgfVxuICAgIC8qIHVzZSB0aGUgdGFpbCAqL1xuICAgIC8vIGRpY3Rpb25hcnkgPSBkaWN0aW9uYXJ5LnNsaWNlKGRpY3RMZW5ndGggLSBzLndfc2l6ZSk7XG4gICAgdG1wRGljdCA9IG5ldyB1dGlscy5CdWY4KHMud19zaXplKTtcbiAgICB1dGlscy5hcnJheVNldCh0bXBEaWN0LCBkaWN0aW9uYXJ5LCBkaWN0TGVuZ3RoIC0gcy53X3NpemUsIHMud19zaXplLCAwKTtcbiAgICBkaWN0aW9uYXJ5ID0gdG1wRGljdDtcbiAgICBkaWN0TGVuZ3RoID0gcy53X3NpemU7XG4gIH1cbiAgLyogaW5zZXJ0IGRpY3Rpb25hcnkgaW50byB3aW5kb3cgYW5kIGhhc2ggKi9cbiAgYXZhaWwgPSBzdHJtLmF2YWlsX2luO1xuICBuZXh0ID0gc3RybS5uZXh0X2luO1xuICBpbnB1dCA9IHN0cm0uaW5wdXQ7XG4gIHN0cm0uYXZhaWxfaW4gPSBkaWN0TGVuZ3RoO1xuICBzdHJtLm5leHRfaW4gPSAwO1xuICBzdHJtLmlucHV0ID0gZGljdGlvbmFyeTtcbiAgZmlsbF93aW5kb3cocyk7XG4gIHdoaWxlIChzLmxvb2thaGVhZCA+PSBNSU5fTUFUQ0gpIHtcbiAgICBzdHIgPSBzLnN0cnN0YXJ0O1xuICAgIG4gPSBzLmxvb2thaGVhZCAtIChNSU5fTUFUQ0ggLSAxKTtcbiAgICBkbyB7XG4gICAgICAvKiBVUERBVEVfSEFTSChzLCBzLT5pbnNfaCwgcy0+d2luZG93W3N0ciArIE1JTl9NQVRDSC0xXSk7ICovXG4gICAgICBzLmluc19oID0gKChzLmluc19oIDw8IHMuaGFzaF9zaGlmdCkgXiBzLndpbmRvd1tzdHIgKyBNSU5fTUFUQ0ggLSAxXSkgJiBzLmhhc2hfbWFzaztcblxuICAgICAgcy5wcmV2W3N0ciAmIHMud19tYXNrXSA9IHMuaGVhZFtzLmluc19oXTtcblxuICAgICAgcy5oZWFkW3MuaW5zX2hdID0gc3RyO1xuICAgICAgc3RyKys7XG4gICAgfSB3aGlsZSAoLS1uKTtcbiAgICBzLnN0cnN0YXJ0ID0gc3RyO1xuICAgIHMubG9va2FoZWFkID0gTUlOX01BVENIIC0gMTtcbiAgICBmaWxsX3dpbmRvdyhzKTtcbiAgfVxuICBzLnN0cnN0YXJ0ICs9IHMubG9va2FoZWFkO1xuICBzLmJsb2NrX3N0YXJ0ID0gcy5zdHJzdGFydDtcbiAgcy5pbnNlcnQgPSBzLmxvb2thaGVhZDtcbiAgcy5sb29rYWhlYWQgPSAwO1xuICBzLm1hdGNoX2xlbmd0aCA9IHMucHJldl9sZW5ndGggPSBNSU5fTUFUQ0ggLSAxO1xuICBzLm1hdGNoX2F2YWlsYWJsZSA9IDA7XG4gIHN0cm0ubmV4dF9pbiA9IG5leHQ7XG4gIHN0cm0uaW5wdXQgPSBpbnB1dDtcbiAgc3RybS5hdmFpbF9pbiA9IGF2YWlsO1xuICBzLndyYXAgPSB3cmFwO1xuICByZXR1cm4gWl9PSztcbn1cblxuXG5leHBvcnRzLmRlZmxhdGVJbml0ID0gZGVmbGF0ZUluaXQ7XG5leHBvcnRzLmRlZmxhdGVJbml0MiA9IGRlZmxhdGVJbml0MjtcbmV4cG9ydHMuZGVmbGF0ZVJlc2V0ID0gZGVmbGF0ZVJlc2V0O1xuZXhwb3J0cy5kZWZsYXRlUmVzZXRLZWVwID0gZGVmbGF0ZVJlc2V0S2VlcDtcbmV4cG9ydHMuZGVmbGF0ZVNldEhlYWRlciA9IGRlZmxhdGVTZXRIZWFkZXI7XG5leHBvcnRzLmRlZmxhdGUgPSBkZWZsYXRlO1xuZXhwb3J0cy5kZWZsYXRlRW5kID0gZGVmbGF0ZUVuZDtcbmV4cG9ydHMuZGVmbGF0ZVNldERpY3Rpb25hcnkgPSBkZWZsYXRlU2V0RGljdGlvbmFyeTtcbmV4cG9ydHMuZGVmbGF0ZUluZm8gPSAncGFrbyBkZWZsYXRlIChmcm9tIE5vZGVjYSBwcm9qZWN0KSc7XG5cbi8qIE5vdCBpbXBsZW1lbnRlZFxuZXhwb3J0cy5kZWZsYXRlQm91bmQgPSBkZWZsYXRlQm91bmQ7XG5leHBvcnRzLmRlZmxhdGVDb3B5ID0gZGVmbGF0ZUNvcHk7XG5leHBvcnRzLmRlZmxhdGVQYXJhbXMgPSBkZWZsYXRlUGFyYW1zO1xuZXhwb3J0cy5kZWZsYXRlUGVuZGluZyA9IGRlZmxhdGVQZW5kaW5nO1xuZXhwb3J0cy5kZWZsYXRlUHJpbWUgPSBkZWZsYXRlUHJpbWU7XG5leHBvcnRzLmRlZmxhdGVUdW5lID0gZGVmbGF0ZVR1bmU7XG4qL1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXJcbi8vIChDKSAyMDE0LTIwMTcgVml0YWx5IFB1enJpbiBhbmQgQW5kcmV5IFR1cGl0c2luXG4vL1xuLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWRcbi8vIHdhcnJhbnR5LiBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlc1xuLy8gYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSxcbi8vIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXRcbi8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczpcbi8vXG4vLyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdFxuLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZVxuLy8gICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmVcbi8vICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC5cbi8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlXG4vLyAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS5cbi8vIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uXG5cbmZ1bmN0aW9uIEdaaGVhZGVyKCkge1xuICAvKiB0cnVlIGlmIGNvbXByZXNzZWQgZGF0YSBiZWxpZXZlZCB0byBiZSB0ZXh0ICovXG4gIHRoaXMudGV4dCAgICAgICA9IDA7XG4gIC8qIG1vZGlmaWNhdGlvbiB0aW1lICovXG4gIHRoaXMudGltZSAgICAgICA9IDA7XG4gIC8qIGV4dHJhIGZsYWdzIChub3QgdXNlZCB3aGVuIHdyaXRpbmcgYSBnemlwIGZpbGUpICovXG4gIHRoaXMueGZsYWdzICAgICA9IDA7XG4gIC8qIG9wZXJhdGluZyBzeXN0ZW0gKi9cbiAgdGhpcy5vcyAgICAgICAgID0gMDtcbiAgLyogcG9pbnRlciB0byBleHRyYSBmaWVsZCBvciBaX05VTEwgaWYgbm9uZSAqL1xuICB0aGlzLmV4dHJhICAgICAgPSBudWxsO1xuICAvKiBleHRyYSBmaWVsZCBsZW5ndGggKHZhbGlkIGlmIGV4dHJhICE9IFpfTlVMTCkgKi9cbiAgdGhpcy5leHRyYV9sZW4gID0gMDsgLy8gQWN0dWFsbHksIHdlIGRvbid0IG5lZWQgaXQgaW4gSlMsXG4gICAgICAgICAgICAgICAgICAgICAgIC8vIGJ1dCBsZWF2ZSBmb3IgZmV3IGNvZGUgbW9kaWZpY2F0aW9uc1xuXG4gIC8vXG4gIC8vIFNldHVwIGxpbWl0cyBpcyBub3QgbmVjZXNzYXJ5IGJlY2F1c2UgaW4ganMgd2Ugc2hvdWxkIG5vdCBwcmVhbGxvY2F0ZSBtZW1vcnlcbiAgLy8gZm9yIGluZmxhdGUgdXNlIGNvbnN0YW50IGxpbWl0IGluIDY1NTM2IGJ5dGVzXG4gIC8vXG5cbiAgLyogc3BhY2UgYXQgZXh0cmEgKG9ubHkgd2hlbiByZWFkaW5nIGhlYWRlcikgKi9cbiAgLy8gdGhpcy5leHRyYV9tYXggID0gMDtcbiAgLyogcG9pbnRlciB0byB6ZXJvLXRlcm1pbmF0ZWQgZmlsZSBuYW1lIG9yIFpfTlVMTCAqL1xuICB0aGlzLm5hbWUgICAgICAgPSAnJztcbiAgLyogc3BhY2UgYXQgbmFtZSAob25seSB3aGVuIHJlYWRpbmcgaGVhZGVyKSAqL1xuICAvLyB0aGlzLm5hbWVfbWF4ICAgPSAwO1xuICAvKiBwb2ludGVyIHRvIHplcm8tdGVybWluYXRlZCBjb21tZW50IG9yIFpfTlVMTCAqL1xuICB0aGlzLmNvbW1lbnQgICAgPSAnJztcbiAgLyogc3BhY2UgYXQgY29tbWVudCAob25seSB3aGVuIHJlYWRpbmcgaGVhZGVyKSAqL1xuICAvLyB0aGlzLmNvbW1fbWF4ICAgPSAwO1xuICAvKiB0cnVlIGlmIHRoZXJlIHdhcyBvciB3aWxsIGJlIGEgaGVhZGVyIGNyYyAqL1xuICB0aGlzLmhjcmMgICAgICAgPSAwO1xuICAvKiB0cnVlIHdoZW4gZG9uZSByZWFkaW5nIGd6aXAgaGVhZGVyIChub3QgdXNlZCB3aGVuIHdyaXRpbmcgYSBnemlwIGZpbGUpICovXG4gIHRoaXMuZG9uZSAgICAgICA9IGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IEdaaGVhZGVyO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXJcbi8vIChDKSAyMDE0LTIwMTcgVml0YWx5IFB1enJpbiBhbmQgQW5kcmV5IFR1cGl0c2luXG4vL1xuLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWRcbi8vIHdhcnJhbnR5LiBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlc1xuLy8gYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSxcbi8vIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXRcbi8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczpcbi8vXG4vLyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdFxuLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZVxuLy8gICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmVcbi8vICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC5cbi8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlXG4vLyAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS5cbi8vIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uXG5cbi8vIFNlZSBzdGF0ZSBkZWZzIGZyb20gaW5mbGF0ZS5qc1xudmFyIEJBRCA9IDMwOyAgICAgICAvKiBnb3QgYSBkYXRhIGVycm9yIC0tIHJlbWFpbiBoZXJlIHVudGlsIHJlc2V0ICovXG52YXIgVFlQRSA9IDEyOyAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIHR5cGUgYml0cywgaW5jbHVkaW5nIGxhc3QtZmxhZyBiaXQgKi9cblxuLypcbiAgIERlY29kZSBsaXRlcmFsLCBsZW5ndGgsIGFuZCBkaXN0YW5jZSBjb2RlcyBhbmQgd3JpdGUgb3V0IHRoZSByZXN1bHRpbmdcbiAgIGxpdGVyYWwgYW5kIG1hdGNoIGJ5dGVzIHVudGlsIGVpdGhlciBub3QgZW5vdWdoIGlucHV0IG9yIG91dHB1dCBpc1xuICAgYXZhaWxhYmxlLCBhbiBlbmQtb2YtYmxvY2sgaXMgZW5jb3VudGVyZWQsIG9yIGEgZGF0YSBlcnJvciBpcyBlbmNvdW50ZXJlZC5cbiAgIFdoZW4gbGFyZ2UgZW5vdWdoIGlucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBhcmUgc3VwcGxpZWQgdG8gaW5mbGF0ZSgpLCBmb3JcbiAgIGV4YW1wbGUsIGEgMTZLIGlucHV0IGJ1ZmZlciBhbmQgYSA2NEsgb3V0cHV0IGJ1ZmZlciwgbW9yZSB0aGFuIDk1JSBvZiB0aGVcbiAgIGluZmxhdGUgZXhlY3V0aW9uIHRpbWUgaXMgc3BlbnQgaW4gdGhpcyByb3V0aW5lLlxuXG4gICBFbnRyeSBhc3N1bXB0aW9uczpcblxuICAgICAgICBzdGF0ZS5tb2RlID09PSBMRU5cbiAgICAgICAgc3RybS5hdmFpbF9pbiA+PSA2XG4gICAgICAgIHN0cm0uYXZhaWxfb3V0ID49IDI1OFxuICAgICAgICBzdGFydCA+PSBzdHJtLmF2YWlsX291dFxuICAgICAgICBzdGF0ZS5iaXRzIDwgOFxuXG4gICBPbiByZXR1cm4sIHN0YXRlLm1vZGUgaXMgb25lIG9mOlxuXG4gICAgICAgIExFTiAtLSByYW4gb3V0IG9mIGVub3VnaCBvdXRwdXQgc3BhY2Ugb3IgZW5vdWdoIGF2YWlsYWJsZSBpbnB1dFxuICAgICAgICBUWVBFIC0tIHJlYWNoZWQgZW5kIG9mIGJsb2NrIGNvZGUsIGluZmxhdGUoKSB0byBpbnRlcnByZXQgbmV4dCBibG9ja1xuICAgICAgICBCQUQgLS0gZXJyb3IgaW4gYmxvY2sgZGF0YVxuXG4gICBOb3RlczpcblxuICAgIC0gVGhlIG1heGltdW0gaW5wdXQgYml0cyB1c2VkIGJ5IGEgbGVuZ3RoL2Rpc3RhbmNlIHBhaXIgaXMgMTUgYml0cyBmb3IgdGhlXG4gICAgICBsZW5ndGggY29kZSwgNSBiaXRzIGZvciB0aGUgbGVuZ3RoIGV4dHJhLCAxNSBiaXRzIGZvciB0aGUgZGlzdGFuY2UgY29kZSxcbiAgICAgIGFuZCAxMyBiaXRzIGZvciB0aGUgZGlzdGFuY2UgZXh0cmEuICBUaGlzIHRvdGFscyA0OCBiaXRzLCBvciBzaXggYnl0ZXMuXG4gICAgICBUaGVyZWZvcmUgaWYgc3RybS5hdmFpbF9pbiA+PSA2LCB0aGVuIHRoZXJlIGlzIGVub3VnaCBpbnB1dCB0byBhdm9pZFxuICAgICAgY2hlY2tpbmcgZm9yIGF2YWlsYWJsZSBpbnB1dCB3aGlsZSBkZWNvZGluZy5cblxuICAgIC0gVGhlIG1heGltdW0gYnl0ZXMgdGhhdCBhIHNpbmdsZSBsZW5ndGgvZGlzdGFuY2UgcGFpciBjYW4gb3V0cHV0IGlzIDI1OFxuICAgICAgYnl0ZXMsIHdoaWNoIGlzIHRoZSBtYXhpbXVtIGxlbmd0aCB0aGF0IGNhbiBiZSBjb2RlZC4gIGluZmxhdGVfZmFzdCgpXG4gICAgICByZXF1aXJlcyBzdHJtLmF2YWlsX291dCA+PSAyNTggZm9yIGVhY2ggbG9vcCB0byBhdm9pZCBjaGVja2luZyBmb3JcbiAgICAgIG91dHB1dCBzcGFjZS5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmZsYXRlX2Zhc3Qoc3RybSwgc3RhcnQpIHtcbiAgdmFyIHN0YXRlO1xuICB2YXIgX2luOyAgICAgICAgICAgICAgICAgICAgLyogbG9jYWwgc3RybS5pbnB1dCAqL1xuICB2YXIgbGFzdDsgICAgICAgICAgICAgICAgICAgLyogaGF2ZSBlbm91Z2ggaW5wdXQgd2hpbGUgaW4gPCBsYXN0ICovXG4gIHZhciBfb3V0OyAgICAgICAgICAgICAgICAgICAvKiBsb2NhbCBzdHJtLm91dHB1dCAqL1xuICB2YXIgYmVnOyAgICAgICAgICAgICAgICAgICAgLyogaW5mbGF0ZSgpJ3MgaW5pdGlhbCBzdHJtLm91dHB1dCAqL1xuICB2YXIgZW5kOyAgICAgICAgICAgICAgICAgICAgLyogd2hpbGUgb3V0IDwgZW5kLCBlbm91Z2ggc3BhY2UgYXZhaWxhYmxlICovXG4vLyNpZmRlZiBJTkZMQVRFX1NUUklDVFxuICB2YXIgZG1heDsgICAgICAgICAgICAgICAgICAgLyogbWF4aW11bSBkaXN0YW5jZSBmcm9tIHpsaWIgaGVhZGVyICovXG4vLyNlbmRpZlxuICB2YXIgd3NpemU7ICAgICAgICAgICAgICAgICAgLyogd2luZG93IHNpemUgb3IgemVybyBpZiBub3QgdXNpbmcgd2luZG93ICovXG4gIHZhciB3aGF2ZTsgICAgICAgICAgICAgICAgICAvKiB2YWxpZCBieXRlcyBpbiB0aGUgd2luZG93ICovXG4gIHZhciB3bmV4dDsgICAgICAgICAgICAgICAgICAvKiB3aW5kb3cgd3JpdGUgaW5kZXggKi9cbiAgLy8gVXNlIGBzX3dpbmRvd2AgaW5zdGVhZCBgd2luZG93YCwgYXZvaWQgY29uZmxpY3Qgd2l0aCBpbnN0cnVtZW50YXRpb24gdG9vbHNcbiAgdmFyIHNfd2luZG93OyAgICAgICAgICAgICAgIC8qIGFsbG9jYXRlZCBzbGlkaW5nIHdpbmRvdywgaWYgd3NpemUgIT0gMCAqL1xuICB2YXIgaG9sZDsgICAgICAgICAgICAgICAgICAgLyogbG9jYWwgc3RybS5ob2xkICovXG4gIHZhciBiaXRzOyAgICAgICAgICAgICAgICAgICAvKiBsb2NhbCBzdHJtLmJpdHMgKi9cbiAgdmFyIGxjb2RlOyAgICAgICAgICAgICAgICAgIC8qIGxvY2FsIHN0cm0ubGVuY29kZSAqL1xuICB2YXIgZGNvZGU7ICAgICAgICAgICAgICAgICAgLyogbG9jYWwgc3RybS5kaXN0Y29kZSAqL1xuICB2YXIgbG1hc2s7ICAgICAgICAgICAgICAgICAgLyogbWFzayBmb3IgZmlyc3QgbGV2ZWwgb2YgbGVuZ3RoIGNvZGVzICovXG4gIHZhciBkbWFzazsgICAgICAgICAgICAgICAgICAvKiBtYXNrIGZvciBmaXJzdCBsZXZlbCBvZiBkaXN0YW5jZSBjb2RlcyAqL1xuICB2YXIgaGVyZTsgICAgICAgICAgICAgICAgICAgLyogcmV0cmlldmVkIHRhYmxlIGVudHJ5ICovXG4gIHZhciBvcDsgICAgICAgICAgICAgICAgICAgICAvKiBjb2RlIGJpdHMsIG9wZXJhdGlvbiwgZXh0cmEgYml0cywgb3IgKi9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qICB3aW5kb3cgcG9zaXRpb24sIHdpbmRvdyBieXRlcyB0byBjb3B5ICovXG4gIHZhciBsZW47ICAgICAgICAgICAgICAgICAgICAvKiBtYXRjaCBsZW5ndGgsIHVudXNlZCBieXRlcyAqL1xuICB2YXIgZGlzdDsgICAgICAgICAgICAgICAgICAgLyogbWF0Y2ggZGlzdGFuY2UgKi9cbiAgdmFyIGZyb207ICAgICAgICAgICAgICAgICAgIC8qIHdoZXJlIHRvIGNvcHkgbWF0Y2ggZnJvbSAqL1xuICB2YXIgZnJvbV9zb3VyY2U7XG5cblxuICB2YXIgaW5wdXQsIG91dHB1dDsgLy8gSlMgc3BlY2lmaWMsIGJlY2F1c2Ugd2UgaGF2ZSBubyBwb2ludGVyc1xuXG4gIC8qIGNvcHkgc3RhdGUgdG8gbG9jYWwgdmFyaWFibGVzICovXG4gIHN0YXRlID0gc3RybS5zdGF0ZTtcbiAgLy9oZXJlID0gc3RhdGUuaGVyZTtcbiAgX2luID0gc3RybS5uZXh0X2luO1xuICBpbnB1dCA9IHN0cm0uaW5wdXQ7XG4gIGxhc3QgPSBfaW4gKyAoc3RybS5hdmFpbF9pbiAtIDUpO1xuICBfb3V0ID0gc3RybS5uZXh0X291dDtcbiAgb3V0cHV0ID0gc3RybS5vdXRwdXQ7XG4gIGJlZyA9IF9vdXQgLSAoc3RhcnQgLSBzdHJtLmF2YWlsX291dCk7XG4gIGVuZCA9IF9vdXQgKyAoc3RybS5hdmFpbF9vdXQgLSAyNTcpO1xuLy8jaWZkZWYgSU5GTEFURV9TVFJJQ1RcbiAgZG1heCA9IHN0YXRlLmRtYXg7XG4vLyNlbmRpZlxuICB3c2l6ZSA9IHN0YXRlLndzaXplO1xuICB3aGF2ZSA9IHN0YXRlLndoYXZlO1xuICB3bmV4dCA9IHN0YXRlLnduZXh0O1xuICBzX3dpbmRvdyA9IHN0YXRlLndpbmRvdztcbiAgaG9sZCA9IHN0YXRlLmhvbGQ7XG4gIGJpdHMgPSBzdGF0ZS5iaXRzO1xuICBsY29kZSA9IHN0YXRlLmxlbmNvZGU7XG4gIGRjb2RlID0gc3RhdGUuZGlzdGNvZGU7XG4gIGxtYXNrID0gKDEgPDwgc3RhdGUubGVuYml0cykgLSAxO1xuICBkbWFzayA9ICgxIDw8IHN0YXRlLmRpc3RiaXRzKSAtIDE7XG5cblxuICAvKiBkZWNvZGUgbGl0ZXJhbHMgYW5kIGxlbmd0aC9kaXN0YW5jZXMgdW50aWwgZW5kLW9mLWJsb2NrIG9yIG5vdCBlbm91Z2hcbiAgICAgaW5wdXQgZGF0YSBvciBvdXRwdXQgc3BhY2UgKi9cblxuICB0b3A6XG4gIGRvIHtcbiAgICBpZiAoYml0cyA8IDE1KSB7XG4gICAgICBob2xkICs9IGlucHV0W19pbisrXSA8PCBiaXRzO1xuICAgICAgYml0cyArPSA4O1xuICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0cztcbiAgICAgIGJpdHMgKz0gODtcbiAgICB9XG5cbiAgICBoZXJlID0gbGNvZGVbaG9sZCAmIGxtYXNrXTtcblxuICAgIGRvbGVuOlxuICAgIGZvciAoOzspIHsgLy8gR290byBlbXVsYXRpb25cbiAgICAgIG9wID0gaGVyZSA+Pj4gMjQvKmhlcmUuYml0cyovO1xuICAgICAgaG9sZCA+Pj49IG9wO1xuICAgICAgYml0cyAtPSBvcDtcbiAgICAgIG9wID0gKGhlcmUgPj4+IDE2KSAmIDB4ZmYvKmhlcmUub3AqLztcbiAgICAgIGlmIChvcCA9PT0gMCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbGl0ZXJhbCAqL1xuICAgICAgICAvL1RyYWNldnYoKHN0ZGVyciwgaGVyZS52YWwgPj0gMHgyMCAmJiBoZXJlLnZhbCA8IDB4N2YgP1xuICAgICAgICAvLyAgICAgICAgXCJpbmZsYXRlOiAgICAgICAgIGxpdGVyYWwgJyVjJ1xcblwiIDpcbiAgICAgICAgLy8gICAgICAgIFwiaW5mbGF0ZTogICAgICAgICBsaXRlcmFsIDB4JTAyeFxcblwiLCBoZXJlLnZhbCkpO1xuICAgICAgICBvdXRwdXRbX291dCsrXSA9IGhlcmUgJiAweGZmZmYvKmhlcmUudmFsKi87XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChvcCAmIDE2KSB7ICAgICAgICAgICAgICAgICAgICAgLyogbGVuZ3RoIGJhc2UgKi9cbiAgICAgICAgbGVuID0gaGVyZSAmIDB4ZmZmZi8qaGVyZS52YWwqLztcbiAgICAgICAgb3AgJj0gMTU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGV4dHJhIGJpdHMgKi9cbiAgICAgICAgaWYgKG9wKSB7XG4gICAgICAgICAgaWYgKGJpdHMgPCBvcCkge1xuICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0cztcbiAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICB9XG4gICAgICAgICAgbGVuICs9IGhvbGQgJiAoKDEgPDwgb3ApIC0gMSk7XG4gICAgICAgICAgaG9sZCA+Pj49IG9wO1xuICAgICAgICAgIGJpdHMgLT0gb3A7XG4gICAgICAgIH1cbiAgICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgICBsZW5ndGggJXVcXG5cIiwgbGVuKSk7XG4gICAgICAgIGlmIChiaXRzIDwgMTUpIHtcbiAgICAgICAgICBob2xkICs9IGlucHV0W19pbisrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICBob2xkICs9IGlucHV0W19pbisrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgfVxuICAgICAgICBoZXJlID0gZGNvZGVbaG9sZCAmIGRtYXNrXTtcblxuICAgICAgICBkb2Rpc3Q6XG4gICAgICAgIGZvciAoOzspIHsgLy8gZ290byBlbXVsYXRpb25cbiAgICAgICAgICBvcCA9IGhlcmUgPj4+IDI0LypoZXJlLmJpdHMqLztcbiAgICAgICAgICBob2xkID4+Pj0gb3A7XG4gICAgICAgICAgYml0cyAtPSBvcDtcbiAgICAgICAgICBvcCA9IChoZXJlID4+PiAxNikgJiAweGZmLypoZXJlLm9wKi87XG5cbiAgICAgICAgICBpZiAob3AgJiAxNikgeyAgICAgICAgICAgICAgICAgICAgICAvKiBkaXN0YW5jZSBiYXNlICovXG4gICAgICAgICAgICBkaXN0ID0gaGVyZSAmIDB4ZmZmZi8qaGVyZS52YWwqLztcbiAgICAgICAgICAgIG9wICY9IDE1OyAgICAgICAgICAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGV4dHJhIGJpdHMgKi9cbiAgICAgICAgICAgIGlmIChiaXRzIDwgb3ApIHtcbiAgICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0cztcbiAgICAgICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAgICAgICBpZiAoYml0cyA8IG9wKSB7XG4gICAgICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtfaW4rK10gPDwgYml0cztcbiAgICAgICAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRpc3QgKz0gaG9sZCAmICgoMSA8PCBvcCkgLSAxKTtcbi8vI2lmZGVmIElORkxBVEVfU1RSSUNUXG4gICAgICAgICAgICBpZiAoZGlzdCA+IGRtYXgpIHtcbiAgICAgICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBkaXN0YW5jZSB0b28gZmFyIGJhY2snO1xuICAgICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgICAgICBicmVhayB0b3A7XG4gICAgICAgICAgICB9XG4vLyNlbmRpZlxuICAgICAgICAgICAgaG9sZCA+Pj49IG9wO1xuICAgICAgICAgICAgYml0cyAtPSBvcDtcbiAgICAgICAgICAgIC8vVHJhY2V2digoc3RkZXJyLCBcImluZmxhdGU6ICAgICAgICAgZGlzdGFuY2UgJXVcXG5cIiwgZGlzdCkpO1xuICAgICAgICAgICAgb3AgPSBfb3V0IC0gYmVnOyAgICAgICAgICAgICAgICAvKiBtYXggZGlzdGFuY2UgaW4gb3V0cHV0ICovXG4gICAgICAgICAgICBpZiAoZGlzdCA+IG9wKSB7ICAgICAgICAgICAgICAgIC8qIHNlZSBpZiBjb3B5IGZyb20gd2luZG93ICovXG4gICAgICAgICAgICAgIG9wID0gZGlzdCAtIG9wOyAgICAgICAgICAgICAgIC8qIGRpc3RhbmNlIGJhY2sgaW4gd2luZG93ICovXG4gICAgICAgICAgICAgIGlmIChvcCA+IHdoYXZlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlLnNhbmUpIHtcbiAgICAgICAgICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgZGlzdGFuY2UgdG9vIGZhciBiYWNrJztcbiAgICAgICAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgICAgICAgICBicmVhayB0b3A7XG4gICAgICAgICAgICAgICAgfVxuXG4vLyAoISkgVGhpcyBibG9jayBpcyBkaXNhYmxlZCBpbiB6bGliIGRlZmF1bHRzLFxuLy8gZG9uJ3QgZW5hYmxlIGl0IGZvciBiaW5hcnkgY29tcGF0aWJpbGl0eVxuLy8jaWZkZWYgSU5GTEFURV9BTExPV19JTlZBTElEX0RJU1RBTkNFX1RPT0ZBUl9BUlJSXG4vLyAgICAgICAgICAgICAgICBpZiAobGVuIDw9IG9wIC0gd2hhdmUpIHtcbi8vICAgICAgICAgICAgICAgICAgZG8ge1xuLy8gICAgICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gMDtcbi8vICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoLS1sZW4pO1xuLy8gICAgICAgICAgICAgICAgICBjb250aW51ZSB0b3A7XG4vLyAgICAgICAgICAgICAgICB9XG4vLyAgICAgICAgICAgICAgICBsZW4gLT0gb3AgLSB3aGF2ZTtcbi8vICAgICAgICAgICAgICAgIGRvIHtcbi8vICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSAwO1xuLy8gICAgICAgICAgICAgICAgfSB3aGlsZSAoLS1vcCA+IHdoYXZlKTtcbi8vICAgICAgICAgICAgICAgIGlmIChvcCA9PT0gMCkge1xuLy8gICAgICAgICAgICAgICAgICBmcm9tID0gX291dCAtIGRpc3Q7XG4vLyAgICAgICAgICAgICAgICAgIGRvIHtcbi8vICAgICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IG91dHB1dFtmcm9tKytdO1xuLy8gICAgICAgICAgICAgICAgICB9IHdoaWxlICgtLWxlbik7XG4vLyAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIHRvcDtcbi8vICAgICAgICAgICAgICAgIH1cbi8vI2VuZGlmXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZnJvbSA9IDA7IC8vIHdpbmRvdyBpbmRleFxuICAgICAgICAgICAgICBmcm9tX3NvdXJjZSA9IHNfd2luZG93O1xuICAgICAgICAgICAgICBpZiAod25leHQgPT09IDApIHsgICAgICAgICAgIC8qIHZlcnkgY29tbW9uIGNhc2UgKi9cbiAgICAgICAgICAgICAgICBmcm9tICs9IHdzaXplIC0gb3A7XG4gICAgICAgICAgICAgICAgaWYgKG9wIDwgbGVuKSB7ICAgICAgICAgLyogc29tZSBmcm9tIHdpbmRvdyAqL1xuICAgICAgICAgICAgICAgICAgbGVuIC09IG9wO1xuICAgICAgICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IHNfd2luZG93W2Zyb20rK107XG4gICAgICAgICAgICAgICAgICB9IHdoaWxlICgtLW9wKTtcbiAgICAgICAgICAgICAgICAgIGZyb20gPSBfb3V0IC0gZGlzdDsgIC8qIHJlc3QgZnJvbSBvdXRwdXQgKi9cbiAgICAgICAgICAgICAgICAgIGZyb21fc291cmNlID0gb3V0cHV0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIGlmICh3bmV4dCA8IG9wKSB7ICAgICAgLyogd3JhcCBhcm91bmQgd2luZG93ICovXG4gICAgICAgICAgICAgICAgZnJvbSArPSB3c2l6ZSArIHduZXh0IC0gb3A7XG4gICAgICAgICAgICAgICAgb3AgLT0gd25leHQ7XG4gICAgICAgICAgICAgICAgaWYgKG9wIDwgbGVuKSB7ICAgICAgICAgLyogc29tZSBmcm9tIGVuZCBvZiB3aW5kb3cgKi9cbiAgICAgICAgICAgICAgICAgIGxlbiAtPSBvcDtcbiAgICAgICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBzX3dpbmRvd1tmcm9tKytdO1xuICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoLS1vcCk7XG4gICAgICAgICAgICAgICAgICBmcm9tID0gMDtcbiAgICAgICAgICAgICAgICAgIGlmICh3bmV4dCA8IGxlbikgeyAgLyogc29tZSBmcm9tIHN0YXJ0IG9mIHdpbmRvdyAqL1xuICAgICAgICAgICAgICAgICAgICBvcCA9IHduZXh0O1xuICAgICAgICAgICAgICAgICAgICBsZW4gLT0gb3A7XG4gICAgICAgICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IHNfd2luZG93W2Zyb20rK107XG4gICAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKC0tb3ApO1xuICAgICAgICAgICAgICAgICAgICBmcm9tID0gX291dCAtIGRpc3Q7ICAgICAgLyogcmVzdCBmcm9tIG91dHB1dCAqL1xuICAgICAgICAgICAgICAgICAgICBmcm9tX3NvdXJjZSA9IG91dHB1dDtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgIC8qIGNvbnRpZ3VvdXMgaW4gd2luZG93ICovXG4gICAgICAgICAgICAgICAgZnJvbSArPSB3bmV4dCAtIG9wO1xuICAgICAgICAgICAgICAgIGlmIChvcCA8IGxlbikgeyAgICAgICAgIC8qIHNvbWUgZnJvbSB3aW5kb3cgKi9cbiAgICAgICAgICAgICAgICAgIGxlbiAtPSBvcDtcbiAgICAgICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBzX3dpbmRvd1tmcm9tKytdO1xuICAgICAgICAgICAgICAgICAgfSB3aGlsZSAoLS1vcCk7XG4gICAgICAgICAgICAgICAgICBmcm9tID0gX291dCAtIGRpc3Q7ICAvKiByZXN0IGZyb20gb3V0cHV0ICovXG4gICAgICAgICAgICAgICAgICBmcm9tX3NvdXJjZSA9IG91dHB1dDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgd2hpbGUgKGxlbiA+IDIpIHtcbiAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IGZyb21fc291cmNlW2Zyb20rK107XG4gICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBmcm9tX3NvdXJjZVtmcm9tKytdO1xuICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gZnJvbV9zb3VyY2VbZnJvbSsrXTtcbiAgICAgICAgICAgICAgICBsZW4gLT0gMztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAobGVuKSB7XG4gICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBmcm9tX3NvdXJjZVtmcm9tKytdO1xuICAgICAgICAgICAgICAgIGlmIChsZW4gPiAxKSB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IGZyb21fc291cmNlW2Zyb20rK107XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgZnJvbSA9IF9vdXQgLSBkaXN0OyAgICAgICAgICAvKiBjb3B5IGRpcmVjdCBmcm9tIG91dHB1dCAqL1xuICAgICAgICAgICAgICBkbyB7ICAgICAgICAgICAgICAgICAgICAgICAgLyogbWluaW11bSBsZW5ndGggaXMgdGhyZWUgKi9cbiAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IG91dHB1dFtmcm9tKytdO1xuICAgICAgICAgICAgICAgIG91dHB1dFtfb3V0KytdID0gb3V0cHV0W2Zyb20rK107XG4gICAgICAgICAgICAgICAgb3V0cHV0W19vdXQrK10gPSBvdXRwdXRbZnJvbSsrXTtcbiAgICAgICAgICAgICAgICBsZW4gLT0gMztcbiAgICAgICAgICAgICAgfSB3aGlsZSAobGVuID4gMik7XG4gICAgICAgICAgICAgIGlmIChsZW4pIHtcbiAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IG91dHB1dFtmcm9tKytdO1xuICAgICAgICAgICAgICAgIGlmIChsZW4gPiAxKSB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXRbX291dCsrXSA9IG91dHB1dFtmcm9tKytdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmICgob3AgJiA2NCkgPT09IDApIHsgICAgICAgICAgLyogMm5kIGxldmVsIGRpc3RhbmNlIGNvZGUgKi9cbiAgICAgICAgICAgIGhlcmUgPSBkY29kZVsoaGVyZSAmIDB4ZmZmZikvKmhlcmUudmFsKi8gKyAoaG9sZCAmICgoMSA8PCBvcCkgLSAxKSldO1xuICAgICAgICAgICAgY29udGludWUgZG9kaXN0O1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgZGlzdGFuY2UgY29kZSc7XG4gICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgICAgYnJlYWsgdG9wO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrOyAvLyBuZWVkIHRvIGVtdWxhdGUgZ290byB2aWEgXCJjb250aW51ZVwiXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKChvcCAmIDY0KSA9PT0gMCkgeyAgICAgICAgICAgICAgLyogMm5kIGxldmVsIGxlbmd0aCBjb2RlICovXG4gICAgICAgIGhlcmUgPSBsY29kZVsoaGVyZSAmIDB4ZmZmZikvKmhlcmUudmFsKi8gKyAoaG9sZCAmICgoMSA8PCBvcCkgLSAxKSldO1xuICAgICAgICBjb250aW51ZSBkb2xlbjtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKG9wICYgMzIpIHsgICAgICAgICAgICAgICAgICAgICAvKiBlbmQtb2YtYmxvY2sgKi9cbiAgICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgICBlbmQgb2YgYmxvY2tcXG5cIikpO1xuICAgICAgICBzdGF0ZS5tb2RlID0gVFlQRTtcbiAgICAgICAgYnJlYWsgdG9wO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgbGl0ZXJhbC9sZW5ndGggY29kZSc7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgIGJyZWFrIHRvcDtcbiAgICAgIH1cblxuICAgICAgYnJlYWs7IC8vIG5lZWQgdG8gZW11bGF0ZSBnb3RvIHZpYSBcImNvbnRpbnVlXCJcbiAgICB9XG4gIH0gd2hpbGUgKF9pbiA8IGxhc3QgJiYgX291dCA8IGVuZCk7XG5cbiAgLyogcmV0dXJuIHVudXNlZCBieXRlcyAob24gZW50cnksIGJpdHMgPCA4LCBzbyBpbiB3b24ndCBnbyB0b28gZmFyIGJhY2spICovXG4gIGxlbiA9IGJpdHMgPj4gMztcbiAgX2luIC09IGxlbjtcbiAgYml0cyAtPSBsZW4gPDwgMztcbiAgaG9sZCAmPSAoMSA8PCBiaXRzKSAtIDE7XG5cbiAgLyogdXBkYXRlIHN0YXRlIGFuZCByZXR1cm4gKi9cbiAgc3RybS5uZXh0X2luID0gX2luO1xuICBzdHJtLm5leHRfb3V0ID0gX291dDtcbiAgc3RybS5hdmFpbF9pbiA9IChfaW4gPCBsYXN0ID8gNSArIChsYXN0IC0gX2luKSA6IDUgLSAoX2luIC0gbGFzdCkpO1xuICBzdHJtLmF2YWlsX291dCA9IChfb3V0IDwgZW5kID8gMjU3ICsgKGVuZCAtIF9vdXQpIDogMjU3IC0gKF9vdXQgLSBlbmQpKTtcbiAgc3RhdGUuaG9sZCA9IGhvbGQ7XG4gIHN0YXRlLmJpdHMgPSBiaXRzO1xuICByZXR1cm47XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXJcbi8vIChDKSAyMDE0LTIwMTcgVml0YWx5IFB1enJpbiBhbmQgQW5kcmV5IFR1cGl0c2luXG4vL1xuLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWRcbi8vIHdhcnJhbnR5LiBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlc1xuLy8gYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSxcbi8vIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXRcbi8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczpcbi8vXG4vLyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdFxuLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZVxuLy8gICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmVcbi8vICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC5cbi8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlXG4vLyAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS5cbi8vIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uXG5cbnZhciB1dGlscyAgICAgICAgID0gcmVxdWlyZSgnLi4vdXRpbHMvY29tbW9uJyk7XG52YXIgYWRsZXIzMiAgICAgICA9IHJlcXVpcmUoJy4vYWRsZXIzMicpO1xudmFyIGNyYzMyICAgICAgICAgPSByZXF1aXJlKCcuL2NyYzMyJyk7XG52YXIgaW5mbGF0ZV9mYXN0ICA9IHJlcXVpcmUoJy4vaW5mZmFzdCcpO1xudmFyIGluZmxhdGVfdGFibGUgPSByZXF1aXJlKCcuL2luZnRyZWVzJyk7XG5cbnZhciBDT0RFUyA9IDA7XG52YXIgTEVOUyA9IDE7XG52YXIgRElTVFMgPSAyO1xuXG4vKiBQdWJsaWMgY29uc3RhbnRzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cblxuXG4vKiBBbGxvd2VkIGZsdXNoIHZhbHVlczsgc2VlIGRlZmxhdGUoKSBhbmQgaW5mbGF0ZSgpIGJlbG93IGZvciBkZXRhaWxzICovXG4vL3ZhciBaX05PX0ZMVVNIICAgICAgPSAwO1xuLy92YXIgWl9QQVJUSUFMX0ZMVVNIID0gMTtcbi8vdmFyIFpfU1lOQ19GTFVTSCAgICA9IDI7XG4vL3ZhciBaX0ZVTExfRkxVU0ggICAgPSAzO1xudmFyIFpfRklOSVNIICAgICAgICA9IDQ7XG52YXIgWl9CTE9DSyAgICAgICAgID0gNTtcbnZhciBaX1RSRUVTICAgICAgICAgPSA2O1xuXG5cbi8qIFJldHVybiBjb2RlcyBmb3IgdGhlIGNvbXByZXNzaW9uL2RlY29tcHJlc3Npb24gZnVuY3Rpb25zLiBOZWdhdGl2ZSB2YWx1ZXNcbiAqIGFyZSBlcnJvcnMsIHBvc2l0aXZlIHZhbHVlcyBhcmUgdXNlZCBmb3Igc3BlY2lhbCBidXQgbm9ybWFsIGV2ZW50cy5cbiAqL1xudmFyIFpfT0sgICAgICAgICAgICA9IDA7XG52YXIgWl9TVFJFQU1fRU5EICAgID0gMTtcbnZhciBaX05FRURfRElDVCAgICAgPSAyO1xuLy92YXIgWl9FUlJOTyAgICAgICAgID0gLTE7XG52YXIgWl9TVFJFQU1fRVJST1IgID0gLTI7XG52YXIgWl9EQVRBX0VSUk9SICAgID0gLTM7XG52YXIgWl9NRU1fRVJST1IgICAgID0gLTQ7XG52YXIgWl9CVUZfRVJST1IgICAgID0gLTU7XG4vL3ZhciBaX1ZFUlNJT05fRVJST1IgPSAtNjtcblxuLyogVGhlIGRlZmxhdGUgY29tcHJlc3Npb24gbWV0aG9kICovXG52YXIgWl9ERUZMQVRFRCAgPSA4O1xuXG5cbi8qIFNUQVRFUyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuXG5cbnZhciAgICBIRUFEID0gMTsgICAgICAgLyogaTogd2FpdGluZyBmb3IgbWFnaWMgaGVhZGVyICovXG52YXIgICAgRkxBR1MgPSAyOyAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIG1ldGhvZCBhbmQgZmxhZ3MgKGd6aXApICovXG52YXIgICAgVElNRSA9IDM7ICAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIG1vZGlmaWNhdGlvbiB0aW1lIChnemlwKSAqL1xudmFyICAgIE9TID0gNDsgICAgICAgICAvKiBpOiB3YWl0aW5nIGZvciBleHRyYSBmbGFncyBhbmQgb3BlcmF0aW5nIHN5c3RlbSAoZ3ppcCkgKi9cbnZhciAgICBFWExFTiA9IDU7ICAgICAgLyogaTogd2FpdGluZyBmb3IgZXh0cmEgbGVuZ3RoIChnemlwKSAqL1xudmFyICAgIEVYVFJBID0gNjsgICAgICAvKiBpOiB3YWl0aW5nIGZvciBleHRyYSBieXRlcyAoZ3ppcCkgKi9cbnZhciAgICBOQU1FID0gNzsgICAgICAgLyogaTogd2FpdGluZyBmb3IgZW5kIG9mIGZpbGUgbmFtZSAoZ3ppcCkgKi9cbnZhciAgICBDT01NRU5UID0gODsgICAgLyogaTogd2FpdGluZyBmb3IgZW5kIG9mIGNvbW1lbnQgKGd6aXApICovXG52YXIgICAgSENSQyA9IDk7ICAgICAgIC8qIGk6IHdhaXRpbmcgZm9yIGhlYWRlciBjcmMgKGd6aXApICovXG52YXIgICAgRElDVElEID0gMTA7ICAgIC8qIGk6IHdhaXRpbmcgZm9yIGRpY3Rpb25hcnkgY2hlY2sgdmFsdWUgKi9cbnZhciAgICBESUNUID0gMTE7ICAgICAgLyogd2FpdGluZyBmb3IgaW5mbGF0ZVNldERpY3Rpb25hcnkoKSBjYWxsICovXG52YXIgICAgICAgIFRZUEUgPSAxMjsgICAgICAvKiBpOiB3YWl0aW5nIGZvciB0eXBlIGJpdHMsIGluY2x1ZGluZyBsYXN0LWZsYWcgYml0ICovXG52YXIgICAgICAgIFRZUEVETyA9IDEzOyAgICAvKiBpOiBzYW1lLCBidXQgc2tpcCBjaGVjayB0byBleGl0IGluZmxhdGUgb24gbmV3IGJsb2NrICovXG52YXIgICAgICAgIFNUT1JFRCA9IDE0OyAgICAvKiBpOiB3YWl0aW5nIGZvciBzdG9yZWQgc2l6ZSAobGVuZ3RoIGFuZCBjb21wbGVtZW50KSAqL1xudmFyICAgICAgICBDT1BZXyA9IDE1OyAgICAgLyogaS9vOiBzYW1lIGFzIENPUFkgYmVsb3csIGJ1dCBvbmx5IGZpcnN0IHRpbWUgaW4gKi9cbnZhciAgICAgICAgQ09QWSA9IDE2OyAgICAgIC8qIGkvbzogd2FpdGluZyBmb3IgaW5wdXQgb3Igb3V0cHV0IHRvIGNvcHkgc3RvcmVkIGJsb2NrICovXG52YXIgICAgICAgIFRBQkxFID0gMTc7ICAgICAvKiBpOiB3YWl0aW5nIGZvciBkeW5hbWljIGJsb2NrIHRhYmxlIGxlbmd0aHMgKi9cbnZhciAgICAgICAgTEVOTEVOUyA9IDE4OyAgIC8qIGk6IHdhaXRpbmcgZm9yIGNvZGUgbGVuZ3RoIGNvZGUgbGVuZ3RocyAqL1xudmFyICAgICAgICBDT0RFTEVOUyA9IDE5OyAgLyogaTogd2FpdGluZyBmb3IgbGVuZ3RoL2xpdCBhbmQgZGlzdGFuY2UgY29kZSBsZW5ndGhzICovXG52YXIgICAgICAgICAgICBMRU5fID0gMjA7ICAgICAgLyogaTogc2FtZSBhcyBMRU4gYmVsb3csIGJ1dCBvbmx5IGZpcnN0IHRpbWUgaW4gKi9cbnZhciAgICAgICAgICAgIExFTiA9IDIxOyAgICAgICAvKiBpOiB3YWl0aW5nIGZvciBsZW5ndGgvbGl0L2VvYiBjb2RlICovXG52YXIgICAgICAgICAgICBMRU5FWFQgPSAyMjsgICAgLyogaTogd2FpdGluZyBmb3IgbGVuZ3RoIGV4dHJhIGJpdHMgKi9cbnZhciAgICAgICAgICAgIERJU1QgPSAyMzsgICAgICAvKiBpOiB3YWl0aW5nIGZvciBkaXN0YW5jZSBjb2RlICovXG52YXIgICAgICAgICAgICBESVNURVhUID0gMjQ7ICAgLyogaTogd2FpdGluZyBmb3IgZGlzdGFuY2UgZXh0cmEgYml0cyAqL1xudmFyICAgICAgICAgICAgTUFUQ0ggPSAyNTsgICAgIC8qIG86IHdhaXRpbmcgZm9yIG91dHB1dCBzcGFjZSB0byBjb3B5IHN0cmluZyAqL1xudmFyICAgICAgICAgICAgTElUID0gMjY7ICAgICAgIC8qIG86IHdhaXRpbmcgZm9yIG91dHB1dCBzcGFjZSB0byB3cml0ZSBsaXRlcmFsICovXG52YXIgICAgQ0hFQ0sgPSAyNzsgICAgIC8qIGk6IHdhaXRpbmcgZm9yIDMyLWJpdCBjaGVjayB2YWx1ZSAqL1xudmFyICAgIExFTkdUSCA9IDI4OyAgICAvKiBpOiB3YWl0aW5nIGZvciAzMi1iaXQgbGVuZ3RoIChnemlwKSAqL1xudmFyICAgIERPTkUgPSAyOTsgICAgICAvKiBmaW5pc2hlZCBjaGVjaywgZG9uZSAtLSByZW1haW4gaGVyZSB1bnRpbCByZXNldCAqL1xudmFyICAgIEJBRCA9IDMwOyAgICAgICAvKiBnb3QgYSBkYXRhIGVycm9yIC0tIHJlbWFpbiBoZXJlIHVudGlsIHJlc2V0ICovXG52YXIgICAgTUVNID0gMzE7ICAgICAgIC8qIGdvdCBhbiBpbmZsYXRlKCkgbWVtb3J5IGVycm9yIC0tIHJlbWFpbiBoZXJlIHVudGlsIHJlc2V0ICovXG52YXIgICAgU1lOQyA9IDMyOyAgICAgIC8qIGxvb2tpbmcgZm9yIHN5bmNocm9uaXphdGlvbiBieXRlcyB0byByZXN0YXJ0IGluZmxhdGUoKSAqL1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuXG5cblxudmFyIEVOT1VHSF9MRU5TID0gODUyO1xudmFyIEVOT1VHSF9ESVNUUyA9IDU5Mjtcbi8vdmFyIEVOT1VHSCA9ICAoRU5PVUdIX0xFTlMrRU5PVUdIX0RJU1RTKTtcblxudmFyIE1BWF9XQklUUyA9IDE1O1xuLyogMzJLIExaNzcgd2luZG93ICovXG52YXIgREVGX1dCSVRTID0gTUFYX1dCSVRTO1xuXG5cbmZ1bmN0aW9uIHpzd2FwMzIocSkge1xuICByZXR1cm4gICgoKHEgPj4+IDI0KSAmIDB4ZmYpICtcbiAgICAgICAgICAoKHEgPj4+IDgpICYgMHhmZjAwKSArXG4gICAgICAgICAgKChxICYgMHhmZjAwKSA8PCA4KSArXG4gICAgICAgICAgKChxICYgMHhmZikgPDwgMjQpKTtcbn1cblxuXG5mdW5jdGlvbiBJbmZsYXRlU3RhdGUoKSB7XG4gIHRoaXMubW9kZSA9IDA7ICAgICAgICAgICAgIC8qIGN1cnJlbnQgaW5mbGF0ZSBtb2RlICovXG4gIHRoaXMubGFzdCA9IGZhbHNlOyAgICAgICAgICAvKiB0cnVlIGlmIHByb2Nlc3NpbmcgbGFzdCBibG9jayAqL1xuICB0aGlzLndyYXAgPSAwOyAgICAgICAgICAgICAgLyogYml0IDAgdHJ1ZSBmb3IgemxpYiwgYml0IDEgdHJ1ZSBmb3IgZ3ppcCAqL1xuICB0aGlzLmhhdmVkaWN0ID0gZmFsc2U7ICAgICAgLyogdHJ1ZSBpZiBkaWN0aW9uYXJ5IHByb3ZpZGVkICovXG4gIHRoaXMuZmxhZ3MgPSAwOyAgICAgICAgICAgICAvKiBnemlwIGhlYWRlciBtZXRob2QgYW5kIGZsYWdzICgwIGlmIHpsaWIpICovXG4gIHRoaXMuZG1heCA9IDA7ICAgICAgICAgICAgICAvKiB6bGliIGhlYWRlciBtYXggZGlzdGFuY2UgKElORkxBVEVfU1RSSUNUKSAqL1xuICB0aGlzLmNoZWNrID0gMDsgICAgICAgICAgICAgLyogcHJvdGVjdGVkIGNvcHkgb2YgY2hlY2sgdmFsdWUgKi9cbiAgdGhpcy50b3RhbCA9IDA7ICAgICAgICAgICAgIC8qIHByb3RlY3RlZCBjb3B5IG9mIG91dHB1dCBjb3VudCAqL1xuICAvLyBUT0RPOiBtYXkgYmUge31cbiAgdGhpcy5oZWFkID0gbnVsbDsgICAgICAgICAgIC8qIHdoZXJlIHRvIHNhdmUgZ3ppcCBoZWFkZXIgaW5mb3JtYXRpb24gKi9cblxuICAvKiBzbGlkaW5nIHdpbmRvdyAqL1xuICB0aGlzLndiaXRzID0gMDsgICAgICAgICAgICAgLyogbG9nIGJhc2UgMiBvZiByZXF1ZXN0ZWQgd2luZG93IHNpemUgKi9cbiAgdGhpcy53c2l6ZSA9IDA7ICAgICAgICAgICAgIC8qIHdpbmRvdyBzaXplIG9yIHplcm8gaWYgbm90IHVzaW5nIHdpbmRvdyAqL1xuICB0aGlzLndoYXZlID0gMDsgICAgICAgICAgICAgLyogdmFsaWQgYnl0ZXMgaW4gdGhlIHdpbmRvdyAqL1xuICB0aGlzLnduZXh0ID0gMDsgICAgICAgICAgICAgLyogd2luZG93IHdyaXRlIGluZGV4ICovXG4gIHRoaXMud2luZG93ID0gbnVsbDsgICAgICAgICAvKiBhbGxvY2F0ZWQgc2xpZGluZyB3aW5kb3csIGlmIG5lZWRlZCAqL1xuXG4gIC8qIGJpdCBhY2N1bXVsYXRvciAqL1xuICB0aGlzLmhvbGQgPSAwOyAgICAgICAgICAgICAgLyogaW5wdXQgYml0IGFjY3VtdWxhdG9yICovXG4gIHRoaXMuYml0cyA9IDA7ICAgICAgICAgICAgICAvKiBudW1iZXIgb2YgYml0cyBpbiBcImluXCIgKi9cblxuICAvKiBmb3Igc3RyaW5nIGFuZCBzdG9yZWQgYmxvY2sgY29weWluZyAqL1xuICB0aGlzLmxlbmd0aCA9IDA7ICAgICAgICAgICAgLyogbGl0ZXJhbCBvciBsZW5ndGggb2YgZGF0YSB0byBjb3B5ICovXG4gIHRoaXMub2Zmc2V0ID0gMDsgICAgICAgICAgICAvKiBkaXN0YW5jZSBiYWNrIHRvIGNvcHkgc3RyaW5nIGZyb20gKi9cblxuICAvKiBmb3IgdGFibGUgYW5kIGNvZGUgZGVjb2RpbmcgKi9cbiAgdGhpcy5leHRyYSA9IDA7ICAgICAgICAgICAgIC8qIGV4dHJhIGJpdHMgbmVlZGVkICovXG5cbiAgLyogZml4ZWQgYW5kIGR5bmFtaWMgY29kZSB0YWJsZXMgKi9cbiAgdGhpcy5sZW5jb2RlID0gbnVsbDsgICAgICAgICAgLyogc3RhcnRpbmcgdGFibGUgZm9yIGxlbmd0aC9saXRlcmFsIGNvZGVzICovXG4gIHRoaXMuZGlzdGNvZGUgPSBudWxsOyAgICAgICAgIC8qIHN0YXJ0aW5nIHRhYmxlIGZvciBkaXN0YW5jZSBjb2RlcyAqL1xuICB0aGlzLmxlbmJpdHMgPSAwOyAgICAgICAgICAgLyogaW5kZXggYml0cyBmb3IgbGVuY29kZSAqL1xuICB0aGlzLmRpc3RiaXRzID0gMDsgICAgICAgICAgLyogaW5kZXggYml0cyBmb3IgZGlzdGNvZGUgKi9cblxuICAvKiBkeW5hbWljIHRhYmxlIGJ1aWxkaW5nICovXG4gIHRoaXMubmNvZGUgPSAwOyAgICAgICAgICAgICAvKiBudW1iZXIgb2YgY29kZSBsZW5ndGggY29kZSBsZW5ndGhzICovXG4gIHRoaXMubmxlbiA9IDA7ICAgICAgICAgICAgICAvKiBudW1iZXIgb2YgbGVuZ3RoIGNvZGUgbGVuZ3RocyAqL1xuICB0aGlzLm5kaXN0ID0gMDsgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGRpc3RhbmNlIGNvZGUgbGVuZ3RocyAqL1xuICB0aGlzLmhhdmUgPSAwOyAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGNvZGUgbGVuZ3RocyBpbiBsZW5zW10gKi9cbiAgdGhpcy5uZXh0ID0gbnVsbDsgICAgICAgICAgICAgIC8qIG5leHQgYXZhaWxhYmxlIHNwYWNlIGluIGNvZGVzW10gKi9cblxuICB0aGlzLmxlbnMgPSBuZXcgdXRpbHMuQnVmMTYoMzIwKTsgLyogdGVtcG9yYXJ5IHN0b3JhZ2UgZm9yIGNvZGUgbGVuZ3RocyAqL1xuICB0aGlzLndvcmsgPSBuZXcgdXRpbHMuQnVmMTYoMjg4KTsgLyogd29yayBhcmVhIGZvciBjb2RlIHRhYmxlIGJ1aWxkaW5nICovXG5cbiAgLypcbiAgIGJlY2F1c2Ugd2UgZG9uJ3QgaGF2ZSBwb2ludGVycyBpbiBqcywgd2UgdXNlIGxlbmNvZGUgYW5kIGRpc3Rjb2RlIGRpcmVjdGx5XG4gICBhcyBidWZmZXJzIHNvIHdlIGRvbid0IG5lZWQgY29kZXNcbiAgKi9cbiAgLy90aGlzLmNvZGVzID0gbmV3IHV0aWxzLkJ1ZjMyKEVOT1VHSCk7ICAgICAgIC8qIHNwYWNlIGZvciBjb2RlIHRhYmxlcyAqL1xuICB0aGlzLmxlbmR5biA9IG51bGw7ICAgICAgICAgICAgICAvKiBkeW5hbWljIHRhYmxlIGZvciBsZW5ndGgvbGl0ZXJhbCBjb2RlcyAoSlMgc3BlY2lmaWMpICovXG4gIHRoaXMuZGlzdGR5biA9IG51bGw7ICAgICAgICAgICAgIC8qIGR5bmFtaWMgdGFibGUgZm9yIGRpc3RhbmNlIGNvZGVzIChKUyBzcGVjaWZpYykgKi9cbiAgdGhpcy5zYW5lID0gMDsgICAgICAgICAgICAgICAgICAgLyogaWYgZmFsc2UsIGFsbG93IGludmFsaWQgZGlzdGFuY2UgdG9vIGZhciAqL1xuICB0aGlzLmJhY2sgPSAwOyAgICAgICAgICAgICAgICAgICAvKiBiaXRzIGJhY2sgb2YgbGFzdCB1bnByb2Nlc3NlZCBsZW5ndGgvbGl0ICovXG4gIHRoaXMud2FzID0gMDsgICAgICAgICAgICAgICAgICAgIC8qIGluaXRpYWwgbGVuZ3RoIG9mIG1hdGNoICovXG59XG5cbmZ1bmN0aW9uIGluZmxhdGVSZXNldEtlZXAoc3RybSkge1xuICB2YXIgc3RhdGU7XG5cbiAgaWYgKCFzdHJtIHx8ICFzdHJtLnN0YXRlKSB7IHJldHVybiBaX1NUUkVBTV9FUlJPUjsgfVxuICBzdGF0ZSA9IHN0cm0uc3RhdGU7XG4gIHN0cm0udG90YWxfaW4gPSBzdHJtLnRvdGFsX291dCA9IHN0YXRlLnRvdGFsID0gMDtcbiAgc3RybS5tc2cgPSAnJzsgLypaX05VTEwqL1xuICBpZiAoc3RhdGUud3JhcCkgeyAgICAgICAvKiB0byBzdXBwb3J0IGlsbC1jb25jZWl2ZWQgSmF2YSB0ZXN0IHN1aXRlICovXG4gICAgc3RybS5hZGxlciA9IHN0YXRlLndyYXAgJiAxO1xuICB9XG4gIHN0YXRlLm1vZGUgPSBIRUFEO1xuICBzdGF0ZS5sYXN0ID0gMDtcbiAgc3RhdGUuaGF2ZWRpY3QgPSAwO1xuICBzdGF0ZS5kbWF4ID0gMzI3Njg7XG4gIHN0YXRlLmhlYWQgPSBudWxsLypaX05VTEwqLztcbiAgc3RhdGUuaG9sZCA9IDA7XG4gIHN0YXRlLmJpdHMgPSAwO1xuICAvL3N0YXRlLmxlbmNvZGUgPSBzdGF0ZS5kaXN0Y29kZSA9IHN0YXRlLm5leHQgPSBzdGF0ZS5jb2RlcztcbiAgc3RhdGUubGVuY29kZSA9IHN0YXRlLmxlbmR5biA9IG5ldyB1dGlscy5CdWYzMihFTk9VR0hfTEVOUyk7XG4gIHN0YXRlLmRpc3Rjb2RlID0gc3RhdGUuZGlzdGR5biA9IG5ldyB1dGlscy5CdWYzMihFTk9VR0hfRElTVFMpO1xuXG4gIHN0YXRlLnNhbmUgPSAxO1xuICBzdGF0ZS5iYWNrID0gLTE7XG4gIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogcmVzZXRcXG5cIikpO1xuICByZXR1cm4gWl9PSztcbn1cblxuZnVuY3Rpb24gaW5mbGF0ZVJlc2V0KHN0cm0pIHtcbiAgdmFyIHN0YXRlO1xuXG4gIGlmICghc3RybSB8fCAhc3RybS5zdGF0ZSkgeyByZXR1cm4gWl9TVFJFQU1fRVJST1I7IH1cbiAgc3RhdGUgPSBzdHJtLnN0YXRlO1xuICBzdGF0ZS53c2l6ZSA9IDA7XG4gIHN0YXRlLndoYXZlID0gMDtcbiAgc3RhdGUud25leHQgPSAwO1xuICByZXR1cm4gaW5mbGF0ZVJlc2V0S2VlcChzdHJtKTtcblxufVxuXG5mdW5jdGlvbiBpbmZsYXRlUmVzZXQyKHN0cm0sIHdpbmRvd0JpdHMpIHtcbiAgdmFyIHdyYXA7XG4gIHZhciBzdGF0ZTtcblxuICAvKiBnZXQgdGhlIHN0YXRlICovXG4gIGlmICghc3RybSB8fCAhc3RybS5zdGF0ZSkgeyByZXR1cm4gWl9TVFJFQU1fRVJST1I7IH1cbiAgc3RhdGUgPSBzdHJtLnN0YXRlO1xuXG4gIC8qIGV4dHJhY3Qgd3JhcCByZXF1ZXN0IGZyb20gd2luZG93Qml0cyBwYXJhbWV0ZXIgKi9cbiAgaWYgKHdpbmRvd0JpdHMgPCAwKSB7XG4gICAgd3JhcCA9IDA7XG4gICAgd2luZG93Qml0cyA9IC13aW5kb3dCaXRzO1xuICB9XG4gIGVsc2Uge1xuICAgIHdyYXAgPSAod2luZG93Qml0cyA+PiA0KSArIDE7XG4gICAgaWYgKHdpbmRvd0JpdHMgPCA0OCkge1xuICAgICAgd2luZG93Qml0cyAmPSAxNTtcbiAgICB9XG4gIH1cblxuICAvKiBzZXQgbnVtYmVyIG9mIHdpbmRvdyBiaXRzLCBmcmVlIHdpbmRvdyBpZiBkaWZmZXJlbnQgKi9cbiAgaWYgKHdpbmRvd0JpdHMgJiYgKHdpbmRvd0JpdHMgPCA4IHx8IHdpbmRvd0JpdHMgPiAxNSkpIHtcbiAgICByZXR1cm4gWl9TVFJFQU1fRVJST1I7XG4gIH1cbiAgaWYgKHN0YXRlLndpbmRvdyAhPT0gbnVsbCAmJiBzdGF0ZS53Yml0cyAhPT0gd2luZG93Qml0cykge1xuICAgIHN0YXRlLndpbmRvdyA9IG51bGw7XG4gIH1cblxuICAvKiB1cGRhdGUgc3RhdGUgYW5kIHJlc2V0IHRoZSByZXN0IG9mIGl0ICovXG4gIHN0YXRlLndyYXAgPSB3cmFwO1xuICBzdGF0ZS53Yml0cyA9IHdpbmRvd0JpdHM7XG4gIHJldHVybiBpbmZsYXRlUmVzZXQoc3RybSk7XG59XG5cbmZ1bmN0aW9uIGluZmxhdGVJbml0MihzdHJtLCB3aW5kb3dCaXRzKSB7XG4gIHZhciByZXQ7XG4gIHZhciBzdGF0ZTtcblxuICBpZiAoIXN0cm0pIHsgcmV0dXJuIFpfU1RSRUFNX0VSUk9SOyB9XG4gIC8vc3RybS5tc2cgPSBaX05VTEw7ICAgICAgICAgICAgICAgICAvKiBpbiBjYXNlIHdlIHJldHVybiBhbiBlcnJvciAqL1xuXG4gIHN0YXRlID0gbmV3IEluZmxhdGVTdGF0ZSgpO1xuXG4gIC8vaWYgKHN0YXRlID09PSBaX05VTEwpIHJldHVybiBaX01FTV9FUlJPUjtcbiAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiBhbGxvY2F0ZWRcXG5cIikpO1xuICBzdHJtLnN0YXRlID0gc3RhdGU7XG4gIHN0YXRlLndpbmRvdyA9IG51bGwvKlpfTlVMTCovO1xuICByZXQgPSBpbmZsYXRlUmVzZXQyKHN0cm0sIHdpbmRvd0JpdHMpO1xuICBpZiAocmV0ICE9PSBaX09LKSB7XG4gICAgc3RybS5zdGF0ZSA9IG51bGwvKlpfTlVMTCovO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGluZmxhdGVJbml0KHN0cm0pIHtcbiAgcmV0dXJuIGluZmxhdGVJbml0MihzdHJtLCBERUZfV0JJVFMpO1xufVxuXG5cbi8qXG4gUmV0dXJuIHN0YXRlIHdpdGggbGVuZ3RoIGFuZCBkaXN0YW5jZSBkZWNvZGluZyB0YWJsZXMgYW5kIGluZGV4IHNpemVzIHNldCB0b1xuIGZpeGVkIGNvZGUgZGVjb2RpbmcuICBOb3JtYWxseSB0aGlzIHJldHVybnMgZml4ZWQgdGFibGVzIGZyb20gaW5mZml4ZWQuaC5cbiBJZiBCVUlMREZJWEVEIGlzIGRlZmluZWQsIHRoZW4gaW5zdGVhZCB0aGlzIHJvdXRpbmUgYnVpbGRzIHRoZSB0YWJsZXMgdGhlXG4gZmlyc3QgdGltZSBpdCdzIGNhbGxlZCwgYW5kIHJldHVybnMgdGhvc2UgdGFibGVzIHRoZSBmaXJzdCB0aW1lIGFuZFxuIHRoZXJlYWZ0ZXIuICBUaGlzIHJlZHVjZXMgdGhlIHNpemUgb2YgdGhlIGNvZGUgYnkgYWJvdXQgMksgYnl0ZXMsIGluXG4gZXhjaGFuZ2UgZm9yIGEgbGl0dGxlIGV4ZWN1dGlvbiB0aW1lLiAgSG93ZXZlciwgQlVJTERGSVhFRCBzaG91bGQgbm90IGJlXG4gdXNlZCBmb3IgdGhyZWFkZWQgYXBwbGljYXRpb25zLCBzaW5jZSB0aGUgcmV3cml0aW5nIG9mIHRoZSB0YWJsZXMgYW5kIHZpcmdpblxuIG1heSBub3QgYmUgdGhyZWFkLXNhZmUuXG4gKi9cbnZhciB2aXJnaW4gPSB0cnVlO1xuXG52YXIgbGVuZml4LCBkaXN0Zml4OyAvLyBXZSBoYXZlIG5vIHBvaW50ZXJzIGluIEpTLCBzbyBrZWVwIHRhYmxlcyBzZXBhcmF0ZVxuXG5mdW5jdGlvbiBmaXhlZHRhYmxlcyhzdGF0ZSkge1xuICAvKiBidWlsZCBmaXhlZCBodWZmbWFuIHRhYmxlcyBpZiBmaXJzdCBjYWxsIChtYXkgbm90IGJlIHRocmVhZCBzYWZlKSAqL1xuICBpZiAodmlyZ2luKSB7XG4gICAgdmFyIHN5bTtcblxuICAgIGxlbmZpeCA9IG5ldyB1dGlscy5CdWYzMig1MTIpO1xuICAgIGRpc3RmaXggPSBuZXcgdXRpbHMuQnVmMzIoMzIpO1xuXG4gICAgLyogbGl0ZXJhbC9sZW5ndGggdGFibGUgKi9cbiAgICBzeW0gPSAwO1xuICAgIHdoaWxlIChzeW0gPCAxNDQpIHsgc3RhdGUubGVuc1tzeW0rK10gPSA4OyB9XG4gICAgd2hpbGUgKHN5bSA8IDI1NikgeyBzdGF0ZS5sZW5zW3N5bSsrXSA9IDk7IH1cbiAgICB3aGlsZSAoc3ltIDwgMjgwKSB7IHN0YXRlLmxlbnNbc3ltKytdID0gNzsgfVxuICAgIHdoaWxlIChzeW0gPCAyODgpIHsgc3RhdGUubGVuc1tzeW0rK10gPSA4OyB9XG5cbiAgICBpbmZsYXRlX3RhYmxlKExFTlMsICBzdGF0ZS5sZW5zLCAwLCAyODgsIGxlbmZpeCwgICAwLCBzdGF0ZS53b3JrLCB7IGJpdHM6IDkgfSk7XG5cbiAgICAvKiBkaXN0YW5jZSB0YWJsZSAqL1xuICAgIHN5bSA9IDA7XG4gICAgd2hpbGUgKHN5bSA8IDMyKSB7IHN0YXRlLmxlbnNbc3ltKytdID0gNTsgfVxuXG4gICAgaW5mbGF0ZV90YWJsZShESVNUUywgc3RhdGUubGVucywgMCwgMzIsICAgZGlzdGZpeCwgMCwgc3RhdGUud29yaywgeyBiaXRzOiA1IH0pO1xuXG4gICAgLyogZG8gdGhpcyBqdXN0IG9uY2UgKi9cbiAgICB2aXJnaW4gPSBmYWxzZTtcbiAgfVxuXG4gIHN0YXRlLmxlbmNvZGUgPSBsZW5maXg7XG4gIHN0YXRlLmxlbmJpdHMgPSA5O1xuICBzdGF0ZS5kaXN0Y29kZSA9IGRpc3RmaXg7XG4gIHN0YXRlLmRpc3RiaXRzID0gNTtcbn1cblxuXG4vKlxuIFVwZGF0ZSB0aGUgd2luZG93IHdpdGggdGhlIGxhc3Qgd3NpemUgKG5vcm1hbGx5IDMySykgYnl0ZXMgd3JpdHRlbiBiZWZvcmVcbiByZXR1cm5pbmcuICBJZiB3aW5kb3cgZG9lcyBub3QgZXhpc3QgeWV0LCBjcmVhdGUgaXQuICBUaGlzIGlzIG9ubHkgY2FsbGVkXG4gd2hlbiBhIHdpbmRvdyBpcyBhbHJlYWR5IGluIHVzZSwgb3Igd2hlbiBvdXRwdXQgaGFzIGJlZW4gd3JpdHRlbiBkdXJpbmcgdGhpc1xuIGluZmxhdGUgY2FsbCwgYnV0IHRoZSBlbmQgb2YgdGhlIGRlZmxhdGUgc3RyZWFtIGhhcyBub3QgYmVlbiByZWFjaGVkIHlldC5cbiBJdCBpcyBhbHNvIGNhbGxlZCB0byBjcmVhdGUgYSB3aW5kb3cgZm9yIGRpY3Rpb25hcnkgZGF0YSB3aGVuIGEgZGljdGlvbmFyeVxuIGlzIGxvYWRlZC5cblxuIFByb3ZpZGluZyBvdXRwdXQgYnVmZmVycyBsYXJnZXIgdGhhbiAzMksgdG8gaW5mbGF0ZSgpIHNob3VsZCBwcm92aWRlIGEgc3BlZWRcbiBhZHZhbnRhZ2UsIHNpbmNlIG9ubHkgdGhlIGxhc3QgMzJLIG9mIG91dHB1dCBpcyBjb3BpZWQgdG8gdGhlIHNsaWRpbmcgd2luZG93XG4gdXBvbiByZXR1cm4gZnJvbSBpbmZsYXRlKCksIGFuZCBzaW5jZSBhbGwgZGlzdGFuY2VzIGFmdGVyIHRoZSBmaXJzdCAzMksgb2ZcbiBvdXRwdXQgd2lsbCBmYWxsIGluIHRoZSBvdXRwdXQgZGF0YSwgbWFraW5nIG1hdGNoIGNvcGllcyBzaW1wbGVyIGFuZCBmYXN0ZXIuXG4gVGhlIGFkdmFudGFnZSBtYXkgYmUgZGVwZW5kZW50IG9uIHRoZSBzaXplIG9mIHRoZSBwcm9jZXNzb3IncyBkYXRhIGNhY2hlcy5cbiAqL1xuZnVuY3Rpb24gdXBkYXRld2luZG93KHN0cm0sIHNyYywgZW5kLCBjb3B5KSB7XG4gIHZhciBkaXN0O1xuICB2YXIgc3RhdGUgPSBzdHJtLnN0YXRlO1xuXG4gIC8qIGlmIGl0IGhhc24ndCBiZWVuIGRvbmUgYWxyZWFkeSwgYWxsb2NhdGUgc3BhY2UgZm9yIHRoZSB3aW5kb3cgKi9cbiAgaWYgKHN0YXRlLndpbmRvdyA9PT0gbnVsbCkge1xuICAgIHN0YXRlLndzaXplID0gMSA8PCBzdGF0ZS53Yml0cztcbiAgICBzdGF0ZS53bmV4dCA9IDA7XG4gICAgc3RhdGUud2hhdmUgPSAwO1xuXG4gICAgc3RhdGUud2luZG93ID0gbmV3IHV0aWxzLkJ1Zjgoc3RhdGUud3NpemUpO1xuICB9XG5cbiAgLyogY29weSBzdGF0ZS0+d3NpemUgb3IgbGVzcyBvdXRwdXQgYnl0ZXMgaW50byB0aGUgY2lyY3VsYXIgd2luZG93ICovXG4gIGlmIChjb3B5ID49IHN0YXRlLndzaXplKSB7XG4gICAgdXRpbHMuYXJyYXlTZXQoc3RhdGUud2luZG93LCBzcmMsIGVuZCAtIHN0YXRlLndzaXplLCBzdGF0ZS53c2l6ZSwgMCk7XG4gICAgc3RhdGUud25leHQgPSAwO1xuICAgIHN0YXRlLndoYXZlID0gc3RhdGUud3NpemU7XG4gIH1cbiAgZWxzZSB7XG4gICAgZGlzdCA9IHN0YXRlLndzaXplIC0gc3RhdGUud25leHQ7XG4gICAgaWYgKGRpc3QgPiBjb3B5KSB7XG4gICAgICBkaXN0ID0gY29weTtcbiAgICB9XG4gICAgLy96bWVtY3B5KHN0YXRlLT53aW5kb3cgKyBzdGF0ZS0+d25leHQsIGVuZCAtIGNvcHksIGRpc3QpO1xuICAgIHV0aWxzLmFycmF5U2V0KHN0YXRlLndpbmRvdywgc3JjLCBlbmQgLSBjb3B5LCBkaXN0LCBzdGF0ZS53bmV4dCk7XG4gICAgY29weSAtPSBkaXN0O1xuICAgIGlmIChjb3B5KSB7XG4gICAgICAvL3ptZW1jcHkoc3RhdGUtPndpbmRvdywgZW5kIC0gY29weSwgY29weSk7XG4gICAgICB1dGlscy5hcnJheVNldChzdGF0ZS53aW5kb3csIHNyYywgZW5kIC0gY29weSwgY29weSwgMCk7XG4gICAgICBzdGF0ZS53bmV4dCA9IGNvcHk7XG4gICAgICBzdGF0ZS53aGF2ZSA9IHN0YXRlLndzaXplO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHN0YXRlLnduZXh0ICs9IGRpc3Q7XG4gICAgICBpZiAoc3RhdGUud25leHQgPT09IHN0YXRlLndzaXplKSB7IHN0YXRlLnduZXh0ID0gMDsgfVxuICAgICAgaWYgKHN0YXRlLndoYXZlIDwgc3RhdGUud3NpemUpIHsgc3RhdGUud2hhdmUgKz0gZGlzdDsgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gMDtcbn1cblxuZnVuY3Rpb24gaW5mbGF0ZShzdHJtLCBmbHVzaCkge1xuICB2YXIgc3RhdGU7XG4gIHZhciBpbnB1dCwgb3V0cHV0OyAgICAgICAgICAvLyBpbnB1dC9vdXRwdXQgYnVmZmVyc1xuICB2YXIgbmV4dDsgICAgICAgICAgICAgICAgICAgLyogbmV4dCBpbnB1dCBJTkRFWCAqL1xuICB2YXIgcHV0OyAgICAgICAgICAgICAgICAgICAgLyogbmV4dCBvdXRwdXQgSU5ERVggKi9cbiAgdmFyIGhhdmUsIGxlZnQ7ICAgICAgICAgICAgIC8qIGF2YWlsYWJsZSBpbnB1dCBhbmQgb3V0cHV0ICovXG4gIHZhciBob2xkOyAgICAgICAgICAgICAgICAgICAvKiBiaXQgYnVmZmVyICovXG4gIHZhciBiaXRzOyAgICAgICAgICAgICAgICAgICAvKiBiaXRzIGluIGJpdCBidWZmZXIgKi9cbiAgdmFyIF9pbiwgX291dDsgICAgICAgICAgICAgIC8qIHNhdmUgc3RhcnRpbmcgYXZhaWxhYmxlIGlucHV0IGFuZCBvdXRwdXQgKi9cbiAgdmFyIGNvcHk7ICAgICAgICAgICAgICAgICAgIC8qIG51bWJlciBvZiBzdG9yZWQgb3IgbWF0Y2ggYnl0ZXMgdG8gY29weSAqL1xuICB2YXIgZnJvbTsgICAgICAgICAgICAgICAgICAgLyogd2hlcmUgdG8gY29weSBtYXRjaCBieXRlcyBmcm9tICovXG4gIHZhciBmcm9tX3NvdXJjZTtcbiAgdmFyIGhlcmUgPSAwOyAgICAgICAgICAgICAgIC8qIGN1cnJlbnQgZGVjb2RpbmcgdGFibGUgZW50cnkgKi9cbiAgdmFyIGhlcmVfYml0cywgaGVyZV9vcCwgaGVyZV92YWw7IC8vIHBha2VkIFwiaGVyZVwiIGRlbm9ybWFsaXplZCAoSlMgc3BlY2lmaWMpXG4gIC8vdmFyIGxhc3Q7ICAgICAgICAgICAgICAgICAgIC8qIHBhcmVudCB0YWJsZSBlbnRyeSAqL1xuICB2YXIgbGFzdF9iaXRzLCBsYXN0X29wLCBsYXN0X3ZhbDsgLy8gcGFrZWQgXCJsYXN0XCIgZGVub3JtYWxpemVkIChKUyBzcGVjaWZpYylcbiAgdmFyIGxlbjsgICAgICAgICAgICAgICAgICAgIC8qIGxlbmd0aCB0byBjb3B5IGZvciByZXBlYXRzLCBiaXRzIHRvIGRyb3AgKi9cbiAgdmFyIHJldDsgICAgICAgICAgICAgICAgICAgIC8qIHJldHVybiBjb2RlICovXG4gIHZhciBoYnVmID0gbmV3IHV0aWxzLkJ1ZjgoNCk7ICAgIC8qIGJ1ZmZlciBmb3IgZ3ppcCBoZWFkZXIgY3JjIGNhbGN1bGF0aW9uICovXG4gIHZhciBvcHRzO1xuXG4gIHZhciBuOyAvLyB0ZW1wb3JhcnkgdmFyIGZvciBORUVEX0JJVFNcblxuICB2YXIgb3JkZXIgPSAvKiBwZXJtdXRhdGlvbiBvZiBjb2RlIGxlbmd0aHMgKi9cbiAgICBbIDE2LCAxNywgMTgsIDAsIDgsIDcsIDksIDYsIDEwLCA1LCAxMSwgNCwgMTIsIDMsIDEzLCAyLCAxNCwgMSwgMTUgXTtcblxuXG4gIGlmICghc3RybSB8fCAhc3RybS5zdGF0ZSB8fCAhc3RybS5vdXRwdXQgfHxcbiAgICAgICghc3RybS5pbnB1dCAmJiBzdHJtLmF2YWlsX2luICE9PSAwKSkge1xuICAgIHJldHVybiBaX1NUUkVBTV9FUlJPUjtcbiAgfVxuXG4gIHN0YXRlID0gc3RybS5zdGF0ZTtcbiAgaWYgKHN0YXRlLm1vZGUgPT09IFRZUEUpIHsgc3RhdGUubW9kZSA9IFRZUEVETzsgfSAgICAvKiBza2lwIGNoZWNrICovXG5cblxuICAvLy0tLSBMT0FEKCkgLS0tXG4gIHB1dCA9IHN0cm0ubmV4dF9vdXQ7XG4gIG91dHB1dCA9IHN0cm0ub3V0cHV0O1xuICBsZWZ0ID0gc3RybS5hdmFpbF9vdXQ7XG4gIG5leHQgPSBzdHJtLm5leHRfaW47XG4gIGlucHV0ID0gc3RybS5pbnB1dDtcbiAgaGF2ZSA9IHN0cm0uYXZhaWxfaW47XG4gIGhvbGQgPSBzdGF0ZS5ob2xkO1xuICBiaXRzID0gc3RhdGUuYml0cztcbiAgLy8tLS1cblxuICBfaW4gPSBoYXZlO1xuICBfb3V0ID0gbGVmdDtcbiAgcmV0ID0gWl9PSztcblxuICBpbmZfbGVhdmU6IC8vIGdvdG8gZW11bGF0aW9uXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKHN0YXRlLm1vZGUpIHtcbiAgICAgIGNhc2UgSEVBRDpcbiAgICAgICAgaWYgKHN0YXRlLndyYXAgPT09IDApIHtcbiAgICAgICAgICBzdGF0ZS5tb2RlID0gVFlQRURPO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIC8vPT09IE5FRURCSVRTKDE2KTtcbiAgICAgICAgd2hpbGUgKGJpdHMgPCAxNikge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBpZiAoKHN0YXRlLndyYXAgJiAyKSAmJiBob2xkID09PSAweDhiMWYpIHsgIC8qIGd6aXAgaGVhZGVyICovXG4gICAgICAgICAgc3RhdGUuY2hlY2sgPSAwLypjcmMzMigwTCwgWl9OVUxMLCAwKSovO1xuICAgICAgICAgIC8vPT09IENSQzIoc3RhdGUuY2hlY2ssIGhvbGQpO1xuICAgICAgICAgIGhidWZbMF0gPSBob2xkICYgMHhmZjtcbiAgICAgICAgICBoYnVmWzFdID0gKGhvbGQgPj4+IDgpICYgMHhmZjtcbiAgICAgICAgICBzdGF0ZS5jaGVjayA9IGNyYzMyKHN0YXRlLmNoZWNrLCBoYnVmLCAyLCAwKTtcbiAgICAgICAgICAvLz09PS8vXG5cbiAgICAgICAgICAvLz09PSBJTklUQklUUygpO1xuICAgICAgICAgIGhvbGQgPSAwO1xuICAgICAgICAgIGJpdHMgPSAwO1xuICAgICAgICAgIC8vPT09Ly9cbiAgICAgICAgICBzdGF0ZS5tb2RlID0gRkxBR1M7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGUuZmxhZ3MgPSAwOyAgICAgICAgICAgLyogZXhwZWN0IHpsaWIgaGVhZGVyICovXG4gICAgICAgIGlmIChzdGF0ZS5oZWFkKSB7XG4gICAgICAgICAgc3RhdGUuaGVhZC5kb25lID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEoc3RhdGUud3JhcCAmIDEpIHx8ICAgLyogY2hlY2sgaWYgemxpYiBoZWFkZXIgYWxsb3dlZCAqL1xuICAgICAgICAgICgoKGhvbGQgJiAweGZmKS8qQklUUyg4KSovIDw8IDgpICsgKGhvbGQgPj4gOCkpICUgMzEpIHtcbiAgICAgICAgICBzdHJtLm1zZyA9ICdpbmNvcnJlY3QgaGVhZGVyIGNoZWNrJztcbiAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoaG9sZCAmIDB4MGYpLypCSVRTKDQpKi8gIT09IFpfREVGTEFURUQpIHtcbiAgICAgICAgICBzdHJtLm1zZyA9ICd1bmtub3duIGNvbXByZXNzaW9uIG1ldGhvZCc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICAvLy0tLSBEUk9QQklUUyg0KSAtLS0vL1xuICAgICAgICBob2xkID4+Pj0gNDtcbiAgICAgICAgYml0cyAtPSA0O1xuICAgICAgICAvLy0tLS8vXG4gICAgICAgIGxlbiA9IChob2xkICYgMHgwZikvKkJJVFMoNCkqLyArIDg7XG4gICAgICAgIGlmIChzdGF0ZS53Yml0cyA9PT0gMCkge1xuICAgICAgICAgIHN0YXRlLndiaXRzID0gbGVuO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGxlbiA+IHN0YXRlLndiaXRzKSB7XG4gICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCB3aW5kb3cgc2l6ZSc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBzdGF0ZS5kbWF4ID0gMSA8PCBsZW47XG4gICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICB6bGliIGhlYWRlciBva1xcblwiKSk7XG4gICAgICAgIHN0cm0uYWRsZXIgPSBzdGF0ZS5jaGVjayA9IDEvKmFkbGVyMzIoMEwsIFpfTlVMTCwgMCkqLztcbiAgICAgICAgc3RhdGUubW9kZSA9IGhvbGQgJiAweDIwMCA/IERJQ1RJRCA6IFRZUEU7XG4gICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgIGhvbGQgPSAwO1xuICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgLy89PT0vL1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgRkxBR1M6XG4gICAgICAgIC8vPT09IE5FRURCSVRTKDE2KTsgKi9cbiAgICAgICAgd2hpbGUgKGJpdHMgPCAxNikge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5mbGFncyA9IGhvbGQ7XG4gICAgICAgIGlmICgoc3RhdGUuZmxhZ3MgJiAweGZmKSAhPT0gWl9ERUZMQVRFRCkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ3Vua25vd24gY29tcHJlc3Npb24gbWV0aG9kJztcbiAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4ZTAwMCkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ3Vua25vd24gaGVhZGVyIGZsYWdzIHNldCc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICAgIHN0YXRlLmhlYWQudGV4dCA9ICgoaG9sZCA+PiA4KSAmIDEpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MDIwMCkge1xuICAgICAgICAgIC8vPT09IENSQzIoc3RhdGUuY2hlY2ssIGhvbGQpO1xuICAgICAgICAgIGhidWZbMF0gPSBob2xkICYgMHhmZjtcbiAgICAgICAgICBoYnVmWzFdID0gKGhvbGQgPj4+IDgpICYgMHhmZjtcbiAgICAgICAgICBzdGF0ZS5jaGVjayA9IGNyYzMyKHN0YXRlLmNoZWNrLCBoYnVmLCAyLCAwKTtcbiAgICAgICAgICAvLz09PS8vXG4gICAgICAgIH1cbiAgICAgICAgLy89PT0gSU5JVEJJVFMoKTtcbiAgICAgICAgaG9sZCA9IDA7XG4gICAgICAgIGJpdHMgPSAwO1xuICAgICAgICAvLz09PS8vXG4gICAgICAgIHN0YXRlLm1vZGUgPSBUSU1FO1xuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIFRJTUU6XG4gICAgICAgIC8vPT09IE5FRURCSVRTKDMyKTsgKi9cbiAgICAgICAgd2hpbGUgKGJpdHMgPCAzMikge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICAgIHN0YXRlLmhlYWQudGltZSA9IGhvbGQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwMjAwKSB7XG4gICAgICAgICAgLy89PT0gQ1JDNChzdGF0ZS5jaGVjaywgaG9sZClcbiAgICAgICAgICBoYnVmWzBdID0gaG9sZCAmIDB4ZmY7XG4gICAgICAgICAgaGJ1ZlsxXSA9IChob2xkID4+PiA4KSAmIDB4ZmY7XG4gICAgICAgICAgaGJ1ZlsyXSA9IChob2xkID4+PiAxNikgJiAweGZmO1xuICAgICAgICAgIGhidWZbM10gPSAoaG9sZCA+Pj4gMjQpICYgMHhmZjtcbiAgICAgICAgICBzdGF0ZS5jaGVjayA9IGNyYzMyKHN0YXRlLmNoZWNrLCBoYnVmLCA0LCAwKTtcbiAgICAgICAgICAvLz09PVxuICAgICAgICB9XG4gICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgIGhvbGQgPSAwO1xuICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5tb2RlID0gT1M7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgT1M6XG4gICAgICAgIC8vPT09IE5FRURCSVRTKDE2KTsgKi9cbiAgICAgICAgd2hpbGUgKGJpdHMgPCAxNikge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICAgIHN0YXRlLmhlYWQueGZsYWdzID0gKGhvbGQgJiAweGZmKTtcbiAgICAgICAgICBzdGF0ZS5oZWFkLm9zID0gKGhvbGQgPj4gOCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwMjAwKSB7XG4gICAgICAgICAgLy89PT0gQ1JDMihzdGF0ZS5jaGVjaywgaG9sZCk7XG4gICAgICAgICAgaGJ1ZlswXSA9IGhvbGQgJiAweGZmO1xuICAgICAgICAgIGhidWZbMV0gPSAoaG9sZCA+Pj4gOCkgJiAweGZmO1xuICAgICAgICAgIHN0YXRlLmNoZWNrID0gY3JjMzIoc3RhdGUuY2hlY2ssIGhidWYsIDIsIDApO1xuICAgICAgICAgIC8vPT09Ly9cbiAgICAgICAgfVxuICAgICAgICAvLz09PSBJTklUQklUUygpO1xuICAgICAgICBob2xkID0gMDtcbiAgICAgICAgYml0cyA9IDA7XG4gICAgICAgIC8vPT09Ly9cbiAgICAgICAgc3RhdGUubW9kZSA9IEVYTEVOO1xuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIEVYTEVOOlxuICAgICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDA0MDApIHtcbiAgICAgICAgICAvLz09PSBORUVEQklUUygxNik7ICovXG4gICAgICAgICAgd2hpbGUgKGJpdHMgPCAxNikge1xuICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy89PT0vL1xuICAgICAgICAgIHN0YXRlLmxlbmd0aCA9IGhvbGQ7XG4gICAgICAgICAgaWYgKHN0YXRlLmhlYWQpIHtcbiAgICAgICAgICAgIHN0YXRlLmhlYWQuZXh0cmFfbGVuID0gaG9sZDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwMjAwKSB7XG4gICAgICAgICAgICAvLz09PSBDUkMyKHN0YXRlLmNoZWNrLCBob2xkKTtcbiAgICAgICAgICAgIGhidWZbMF0gPSBob2xkICYgMHhmZjtcbiAgICAgICAgICAgIGhidWZbMV0gPSAoaG9sZCA+Pj4gOCkgJiAweGZmO1xuICAgICAgICAgICAgc3RhdGUuY2hlY2sgPSBjcmMzMihzdGF0ZS5jaGVjaywgaGJ1ZiwgMiwgMCk7XG4gICAgICAgICAgICAvLz09PS8vXG4gICAgICAgICAgfVxuICAgICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgICAgaG9sZCA9IDA7XG4gICAgICAgICAgYml0cyA9IDA7XG4gICAgICAgICAgLy89PT0vL1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHN0YXRlLmhlYWQpIHtcbiAgICAgICAgICBzdGF0ZS5oZWFkLmV4dHJhID0gbnVsbC8qWl9OVUxMKi87XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGUubW9kZSA9IEVYVFJBO1xuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIEVYVFJBOlxuICAgICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDA0MDApIHtcbiAgICAgICAgICBjb3B5ID0gc3RhdGUubGVuZ3RoO1xuICAgICAgICAgIGlmIChjb3B5ID4gaGF2ZSkgeyBjb3B5ID0gaGF2ZTsgfVxuICAgICAgICAgIGlmIChjb3B5KSB7XG4gICAgICAgICAgICBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICAgICAgICBsZW4gPSBzdGF0ZS5oZWFkLmV4dHJhX2xlbiAtIHN0YXRlLmxlbmd0aDtcbiAgICAgICAgICAgICAgaWYgKCFzdGF0ZS5oZWFkLmV4dHJhKSB7XG4gICAgICAgICAgICAgICAgLy8gVXNlIHVudHlwZWQgYXJyYXkgZm9yIG1vcmUgY29udmVuaWVudCBwcm9jZXNzaW5nIGxhdGVyXG4gICAgICAgICAgICAgICAgc3RhdGUuaGVhZC5leHRyYSA9IG5ldyBBcnJheShzdGF0ZS5oZWFkLmV4dHJhX2xlbik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdXRpbHMuYXJyYXlTZXQoXG4gICAgICAgICAgICAgICAgc3RhdGUuaGVhZC5leHRyYSxcbiAgICAgICAgICAgICAgICBpbnB1dCxcbiAgICAgICAgICAgICAgICBuZXh0LFxuICAgICAgICAgICAgICAgIC8vIGV4dHJhIGZpZWxkIGlzIGxpbWl0ZWQgdG8gNjU1MzYgYnl0ZXNcbiAgICAgICAgICAgICAgICAvLyAtIG5vIG5lZWQgZm9yIGFkZGl0aW9uYWwgc2l6ZSBjaGVja1xuICAgICAgICAgICAgICAgIGNvcHksXG4gICAgICAgICAgICAgICAgLypsZW4gKyBjb3B5ID4gc3RhdGUuaGVhZC5leHRyYV9tYXggLSBsZW4gPyBzdGF0ZS5oZWFkLmV4dHJhX21heCA6IGNvcHksKi9cbiAgICAgICAgICAgICAgICBsZW5cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgLy96bWVtY3B5KHN0YXRlLmhlYWQuZXh0cmEgKyBsZW4sIG5leHQsXG4gICAgICAgICAgICAgIC8vICAgICAgICBsZW4gKyBjb3B5ID4gc3RhdGUuaGVhZC5leHRyYV9tYXggP1xuICAgICAgICAgICAgICAvLyAgICAgICAgc3RhdGUuaGVhZC5leHRyYV9tYXggLSBsZW4gOiBjb3B5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MDIwMCkge1xuICAgICAgICAgICAgICBzdGF0ZS5jaGVjayA9IGNyYzMyKHN0YXRlLmNoZWNrLCBpbnB1dCwgY29weSwgbmV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBoYXZlIC09IGNvcHk7XG4gICAgICAgICAgICBuZXh0ICs9IGNvcHk7XG4gICAgICAgICAgICBzdGF0ZS5sZW5ndGggLT0gY29weTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHN0YXRlLmxlbmd0aCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgfVxuICAgICAgICBzdGF0ZS5sZW5ndGggPSAwO1xuICAgICAgICBzdGF0ZS5tb2RlID0gTkFNRTtcbiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgY2FzZSBOQU1FOlxuICAgICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDA4MDApIHtcbiAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICBjb3B5ID0gMDtcbiAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAvLyBUT0RPOiAyIG9yIDEgYnl0ZXM/XG4gICAgICAgICAgICBsZW4gPSBpbnB1dFtuZXh0ICsgY29weSsrXTtcbiAgICAgICAgICAgIC8qIHVzZSBjb25zdGFudCBsaW1pdCBiZWNhdXNlIGluIGpzIHdlIHNob3VsZCBub3QgcHJlYWxsb2NhdGUgbWVtb3J5ICovXG4gICAgICAgICAgICBpZiAoc3RhdGUuaGVhZCAmJiBsZW4gJiZcbiAgICAgICAgICAgICAgICAoc3RhdGUubGVuZ3RoIDwgNjU1MzYgLypzdGF0ZS5oZWFkLm5hbWVfbWF4Ki8pKSB7XG4gICAgICAgICAgICAgIHN0YXRlLmhlYWQubmFtZSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGxlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSB3aGlsZSAobGVuICYmIGNvcHkgPCBoYXZlKTtcblxuICAgICAgICAgIGlmIChzdGF0ZS5mbGFncyAmIDB4MDIwMCkge1xuICAgICAgICAgICAgc3RhdGUuY2hlY2sgPSBjcmMzMihzdGF0ZS5jaGVjaywgaW5wdXQsIGNvcHksIG5leHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBoYXZlIC09IGNvcHk7XG4gICAgICAgICAgbmV4dCArPSBjb3B5O1xuICAgICAgICAgIGlmIChsZW4pIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc3RhdGUuaGVhZCkge1xuICAgICAgICAgIHN0YXRlLmhlYWQubmFtZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGUubGVuZ3RoID0gMDtcbiAgICAgICAgc3RhdGUubW9kZSA9IENPTU1FTlQ7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgQ09NTUVOVDpcbiAgICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgxMDAwKSB7XG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgY29weSA9IDA7XG4gICAgICAgICAgZG8ge1xuICAgICAgICAgICAgbGVuID0gaW5wdXRbbmV4dCArIGNvcHkrK107XG4gICAgICAgICAgICAvKiB1c2UgY29uc3RhbnQgbGltaXQgYmVjYXVzZSBpbiBqcyB3ZSBzaG91bGQgbm90IHByZWFsbG9jYXRlIG1lbW9yeSAqL1xuICAgICAgICAgICAgaWYgKHN0YXRlLmhlYWQgJiYgbGVuICYmXG4gICAgICAgICAgICAgICAgKHN0YXRlLmxlbmd0aCA8IDY1NTM2IC8qc3RhdGUuaGVhZC5jb21tX21heCovKSkge1xuICAgICAgICAgICAgICBzdGF0ZS5oZWFkLmNvbW1lbnQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShsZW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gd2hpbGUgKGxlbiAmJiBjb3B5IDwgaGF2ZSk7XG4gICAgICAgICAgaWYgKHN0YXRlLmZsYWdzICYgMHgwMjAwKSB7XG4gICAgICAgICAgICBzdGF0ZS5jaGVjayA9IGNyYzMyKHN0YXRlLmNoZWNrLCBpbnB1dCwgY29weSwgbmV4dCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGhhdmUgLT0gY29weTtcbiAgICAgICAgICBuZXh0ICs9IGNvcHk7XG4gICAgICAgICAgaWYgKGxlbikgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzdGF0ZS5oZWFkKSB7XG4gICAgICAgICAgc3RhdGUuaGVhZC5jb21tZW50ID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBzdGF0ZS5tb2RlID0gSENSQztcbiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgY2FzZSBIQ1JDOlxuICAgICAgICBpZiAoc3RhdGUuZmxhZ3MgJiAweDAyMDApIHtcbiAgICAgICAgICAvLz09PSBORUVEQklUUygxNik7ICovXG4gICAgICAgICAgd2hpbGUgKGJpdHMgPCAxNikge1xuICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy89PT0vL1xuICAgICAgICAgIGlmIChob2xkICE9PSAoc3RhdGUuY2hlY2sgJiAweGZmZmYpKSB7XG4gICAgICAgICAgICBzdHJtLm1zZyA9ICdoZWFkZXIgY3JjIG1pc21hdGNoJztcbiAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgLy89PT0gSU5JVEJJVFMoKTtcbiAgICAgICAgICBob2xkID0gMDtcbiAgICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgICAvLz09PS8vXG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN0YXRlLmhlYWQpIHtcbiAgICAgICAgICBzdGF0ZS5oZWFkLmhjcmMgPSAoKHN0YXRlLmZsYWdzID4+IDkpICYgMSk7XG4gICAgICAgICAgc3RhdGUuaGVhZC5kb25lID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBzdHJtLmFkbGVyID0gc3RhdGUuY2hlY2sgPSAwO1xuICAgICAgICBzdGF0ZS5tb2RlID0gVFlQRTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIERJQ1RJRDpcbiAgICAgICAgLy89PT0gTkVFREJJVFMoMzIpOyAqL1xuICAgICAgICB3aGlsZSAoYml0cyA8IDMyKSB7XG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgfVxuICAgICAgICAvLz09PS8vXG4gICAgICAgIHN0cm0uYWRsZXIgPSBzdGF0ZS5jaGVjayA9IHpzd2FwMzIoaG9sZCk7XG4gICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgIGhvbGQgPSAwO1xuICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5tb2RlID0gRElDVDtcbiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgY2FzZSBESUNUOlxuICAgICAgICBpZiAoc3RhdGUuaGF2ZWRpY3QgPT09IDApIHtcbiAgICAgICAgICAvLy0tLSBSRVNUT1JFKCkgLS0tXG4gICAgICAgICAgc3RybS5uZXh0X291dCA9IHB1dDtcbiAgICAgICAgICBzdHJtLmF2YWlsX291dCA9IGxlZnQ7XG4gICAgICAgICAgc3RybS5uZXh0X2luID0gbmV4dDtcbiAgICAgICAgICBzdHJtLmF2YWlsX2luID0gaGF2ZTtcbiAgICAgICAgICBzdGF0ZS5ob2xkID0gaG9sZDtcbiAgICAgICAgICBzdGF0ZS5iaXRzID0gYml0cztcbiAgICAgICAgICAvLy0tLVxuICAgICAgICAgIHJldHVybiBaX05FRURfRElDVDtcbiAgICAgICAgfVxuICAgICAgICBzdHJtLmFkbGVyID0gc3RhdGUuY2hlY2sgPSAxLyphZGxlcjMyKDBMLCBaX05VTEwsIDApKi87XG4gICAgICAgIHN0YXRlLm1vZGUgPSBUWVBFO1xuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIFRZUEU6XG4gICAgICAgIGlmIChmbHVzaCA9PT0gWl9CTE9DSyB8fCBmbHVzaCA9PT0gWl9UUkVFUykgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgY2FzZSBUWVBFRE86XG4gICAgICAgIGlmIChzdGF0ZS5sYXN0KSB7XG4gICAgICAgICAgLy8tLS0gQllURUJJVFMoKSAtLS0vL1xuICAgICAgICAgIGhvbGQgPj4+PSBiaXRzICYgNztcbiAgICAgICAgICBiaXRzIC09IGJpdHMgJiA3O1xuICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICBzdGF0ZS5tb2RlID0gQ0hFQ0s7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0gTkVFREJJVFMoMyk7ICovXG4gICAgICAgIHdoaWxlIChiaXRzIDwgMykge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5sYXN0ID0gKGhvbGQgJiAweDAxKS8qQklUUygxKSovO1xuICAgICAgICAvLy0tLSBEUk9QQklUUygxKSAtLS0vL1xuICAgICAgICBob2xkID4+Pj0gMTtcbiAgICAgICAgYml0cyAtPSAxO1xuICAgICAgICAvLy0tLS8vXG5cbiAgICAgICAgc3dpdGNoICgoaG9sZCAmIDB4MDMpLypCSVRTKDIpKi8pIHtcbiAgICAgICAgICBjYXNlIDA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzdG9yZWQgYmxvY2sgKi9cbiAgICAgICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgIHN0b3JlZCBibG9jayVzXFxuXCIsXG4gICAgICAgICAgICAvLyAgICAgICAgc3RhdGUubGFzdCA/IFwiIChsYXN0KVwiIDogXCJcIikpO1xuICAgICAgICAgICAgc3RhdGUubW9kZSA9IFNUT1JFRDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgMTogICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGZpeGVkIGJsb2NrICovXG4gICAgICAgICAgICBmaXhlZHRhYmxlcyhzdGF0ZSk7XG4gICAgICAgICAgICAvL1RyYWNldigoc3RkZXJyLCBcImluZmxhdGU6ICAgICBmaXhlZCBjb2RlcyBibG9jayVzXFxuXCIsXG4gICAgICAgICAgICAvLyAgICAgICAgc3RhdGUubGFzdCA/IFwiIChsYXN0KVwiIDogXCJcIikpO1xuICAgICAgICAgICAgc3RhdGUubW9kZSA9IExFTl87ICAgICAgICAgICAgIC8qIGRlY29kZSBjb2RlcyAqL1xuICAgICAgICAgICAgaWYgKGZsdXNoID09PSBaX1RSRUVTKSB7XG4gICAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKDIpIC0tLS8vXG4gICAgICAgICAgICAgIGhvbGQgPj4+PSAyO1xuICAgICAgICAgICAgICBiaXRzIC09IDI7XG4gICAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICAgICAgYnJlYWsgaW5mX2xlYXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAyOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZHluYW1pYyBibG9jayAqL1xuICAgICAgICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgICAgZHluYW1pYyBjb2RlcyBibG9jayVzXFxuXCIsXG4gICAgICAgICAgICAvLyAgICAgICAgc3RhdGUubGFzdCA/IFwiIChsYXN0KVwiIDogXCJcIikpO1xuICAgICAgICAgICAgc3RhdGUubW9kZSA9IFRBQkxFO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBibG9jayB0eXBlJztcbiAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8tLS0gRFJPUEJJVFMoMikgLS0tLy9cbiAgICAgICAgaG9sZCA+Pj49IDI7XG4gICAgICAgIGJpdHMgLT0gMjtcbiAgICAgICAgLy8tLS0vL1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgU1RPUkVEOlxuICAgICAgICAvLy0tLSBCWVRFQklUUygpIC0tLS8vIC8qIGdvIHRvIGJ5dGUgYm91bmRhcnkgKi9cbiAgICAgICAgaG9sZCA+Pj49IGJpdHMgJiA3O1xuICAgICAgICBiaXRzIC09IGJpdHMgJiA3O1xuICAgICAgICAvLy0tLS8vXG4gICAgICAgIC8vPT09IE5FRURCSVRTKDMyKTsgKi9cbiAgICAgICAgd2hpbGUgKGJpdHMgPCAzMikge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBpZiAoKGhvbGQgJiAweGZmZmYpICE9PSAoKGhvbGQgPj4+IDE2KSBeIDB4ZmZmZikpIHtcbiAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIHN0b3JlZCBibG9jayBsZW5ndGhzJztcbiAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRlLmxlbmd0aCA9IGhvbGQgJiAweGZmZmY7XG4gICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgc3RvcmVkIGxlbmd0aCAldVxcblwiLFxuICAgICAgICAvLyAgICAgICAgc3RhdGUubGVuZ3RoKSk7XG4gICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgIGhvbGQgPSAwO1xuICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5tb2RlID0gQ09QWV87XG4gICAgICAgIGlmIChmbHVzaCA9PT0gWl9UUkVFUykgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgY2FzZSBDT1BZXzpcbiAgICAgICAgc3RhdGUubW9kZSA9IENPUFk7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgQ09QWTpcbiAgICAgICAgY29weSA9IHN0YXRlLmxlbmd0aDtcbiAgICAgICAgaWYgKGNvcHkpIHtcbiAgICAgICAgICBpZiAoY29weSA+IGhhdmUpIHsgY29weSA9IGhhdmU7IH1cbiAgICAgICAgICBpZiAoY29weSA+IGxlZnQpIHsgY29weSA9IGxlZnQ7IH1cbiAgICAgICAgICBpZiAoY29weSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICAvLy0tLSB6bWVtY3B5KHB1dCwgbmV4dCwgY29weSk7IC0tLVxuICAgICAgICAgIHV0aWxzLmFycmF5U2V0KG91dHB1dCwgaW5wdXQsIG5leHQsIGNvcHksIHB1dCk7XG4gICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgIGhhdmUgLT0gY29weTtcbiAgICAgICAgICBuZXh0ICs9IGNvcHk7XG4gICAgICAgICAgbGVmdCAtPSBjb3B5O1xuICAgICAgICAgIHB1dCArPSBjb3B5O1xuICAgICAgICAgIHN0YXRlLmxlbmd0aCAtPSBjb3B5O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgc3RvcmVkIGVuZFxcblwiKSk7XG4gICAgICAgIHN0YXRlLm1vZGUgPSBUWVBFO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgVEFCTEU6XG4gICAgICAgIC8vPT09IE5FRURCSVRTKDE0KTsgKi9cbiAgICAgICAgd2hpbGUgKGJpdHMgPCAxNCkge1xuICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgIH1cbiAgICAgICAgLy89PT0vL1xuICAgICAgICBzdGF0ZS5ubGVuID0gKGhvbGQgJiAweDFmKS8qQklUUyg1KSovICsgMjU3O1xuICAgICAgICAvLy0tLSBEUk9QQklUUyg1KSAtLS0vL1xuICAgICAgICBob2xkID4+Pj0gNTtcbiAgICAgICAgYml0cyAtPSA1O1xuICAgICAgICAvLy0tLS8vXG4gICAgICAgIHN0YXRlLm5kaXN0ID0gKGhvbGQgJiAweDFmKS8qQklUUyg1KSovICsgMTtcbiAgICAgICAgLy8tLS0gRFJPUEJJVFMoNSkgLS0tLy9cbiAgICAgICAgaG9sZCA+Pj49IDU7XG4gICAgICAgIGJpdHMgLT0gNTtcbiAgICAgICAgLy8tLS0vL1xuICAgICAgICBzdGF0ZS5uY29kZSA9IChob2xkICYgMHgwZikvKkJJVFMoNCkqLyArIDQ7XG4gICAgICAgIC8vLS0tIERST1BCSVRTKDQpIC0tLS8vXG4gICAgICAgIGhvbGQgPj4+PSA0O1xuICAgICAgICBiaXRzIC09IDQ7XG4gICAgICAgIC8vLS0tLy9cbi8vI2lmbmRlZiBQS1pJUF9CVUdfV09SS0FST1VORFxuICAgICAgICBpZiAoc3RhdGUubmxlbiA+IDI4NiB8fCBzdGF0ZS5uZGlzdCA+IDMwKSB7XG4gICAgICAgICAgc3RybS5tc2cgPSAndG9vIG1hbnkgbGVuZ3RoIG9yIGRpc3RhbmNlIHN5bWJvbHMnO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbi8vI2VuZGlmXG4gICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgdGFibGUgc2l6ZXMgb2tcXG5cIikpO1xuICAgICAgICBzdGF0ZS5oYXZlID0gMDtcbiAgICAgICAgc3RhdGUubW9kZSA9IExFTkxFTlM7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgTEVOTEVOUzpcbiAgICAgICAgd2hpbGUgKHN0YXRlLmhhdmUgPCBzdGF0ZS5uY29kZSkge1xuICAgICAgICAgIC8vPT09IE5FRURCSVRTKDMpO1xuICAgICAgICAgIHdoaWxlIChiaXRzIDwgMykge1xuICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy89PT0vL1xuICAgICAgICAgIHN0YXRlLmxlbnNbb3JkZXJbc3RhdGUuaGF2ZSsrXV0gPSAoaG9sZCAmIDB4MDcpOy8vQklUUygzKTtcbiAgICAgICAgICAvLy0tLSBEUk9QQklUUygzKSAtLS0vL1xuICAgICAgICAgIGhvbGQgPj4+PSAzO1xuICAgICAgICAgIGJpdHMgLT0gMztcbiAgICAgICAgICAvLy0tLS8vXG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKHN0YXRlLmhhdmUgPCAxOSkge1xuICAgICAgICAgIHN0YXRlLmxlbnNbb3JkZXJbc3RhdGUuaGF2ZSsrXV0gPSAwO1xuICAgICAgICB9XG4gICAgICAgIC8vIFdlIGhhdmUgc2VwYXJhdGUgdGFibGVzICYgbm8gcG9pbnRlcnMuIDIgY29tbWVudGVkIGxpbmVzIGJlbG93IG5vdCBuZWVkZWQuXG4gICAgICAgIC8vc3RhdGUubmV4dCA9IHN0YXRlLmNvZGVzO1xuICAgICAgICAvL3N0YXRlLmxlbmNvZGUgPSBzdGF0ZS5uZXh0O1xuICAgICAgICAvLyBTd2l0Y2ggdG8gdXNlIGR5bmFtaWMgdGFibGVcbiAgICAgICAgc3RhdGUubGVuY29kZSA9IHN0YXRlLmxlbmR5bjtcbiAgICAgICAgc3RhdGUubGVuYml0cyA9IDc7XG5cbiAgICAgICAgb3B0cyA9IHsgYml0czogc3RhdGUubGVuYml0cyB9O1xuICAgICAgICByZXQgPSBpbmZsYXRlX3RhYmxlKENPREVTLCBzdGF0ZS5sZW5zLCAwLCAxOSwgc3RhdGUubGVuY29kZSwgMCwgc3RhdGUud29yaywgb3B0cyk7XG4gICAgICAgIHN0YXRlLmxlbmJpdHMgPSBvcHRzLmJpdHM7XG5cbiAgICAgICAgaWYgKHJldCkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgY29kZSBsZW5ndGhzIHNldCc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICAvL1RyYWNldigoc3RkZXJyLCBcImluZmxhdGU6ICAgICAgIGNvZGUgbGVuZ3RocyBva1xcblwiKSk7XG4gICAgICAgIHN0YXRlLmhhdmUgPSAwO1xuICAgICAgICBzdGF0ZS5tb2RlID0gQ09ERUxFTlM7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgQ09ERUxFTlM6XG4gICAgICAgIHdoaWxlIChzdGF0ZS5oYXZlIDwgc3RhdGUubmxlbiArIHN0YXRlLm5kaXN0KSB7XG4gICAgICAgICAgZm9yICg7Oykge1xuICAgICAgICAgICAgaGVyZSA9IHN0YXRlLmxlbmNvZGVbaG9sZCAmICgoMSA8PCBzdGF0ZS5sZW5iaXRzKSAtIDEpXTsvKkJJVFMoc3RhdGUubGVuYml0cykqL1xuICAgICAgICAgICAgaGVyZV9iaXRzID0gaGVyZSA+Pj4gMjQ7XG4gICAgICAgICAgICBoZXJlX29wID0gKGhlcmUgPj4+IDE2KSAmIDB4ZmY7XG4gICAgICAgICAgICBoZXJlX3ZhbCA9IGhlcmUgJiAweGZmZmY7XG5cbiAgICAgICAgICAgIGlmICgoaGVyZV9iaXRzKSA8PSBiaXRzKSB7IGJyZWFrOyB9XG4gICAgICAgICAgICAvLy0tLSBQVUxMQllURSgpIC0tLS8vXG4gICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaGVyZV92YWwgPCAxNikge1xuICAgICAgICAgICAgLy8tLS0gRFJPUEJJVFMoaGVyZS5iaXRzKSAtLS0vL1xuICAgICAgICAgICAgaG9sZCA+Pj49IGhlcmVfYml0cztcbiAgICAgICAgICAgIGJpdHMgLT0gaGVyZV9iaXRzO1xuICAgICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgICAgc3RhdGUubGVuc1tzdGF0ZS5oYXZlKytdID0gaGVyZV92YWw7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKGhlcmVfdmFsID09PSAxNikge1xuICAgICAgICAgICAgICAvLz09PSBORUVEQklUUyhoZXJlLmJpdHMgKyAyKTtcbiAgICAgICAgICAgICAgbiA9IGhlcmVfYml0cyArIDI7XG4gICAgICAgICAgICAgIHdoaWxlIChiaXRzIDwgbikge1xuICAgICAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy89PT0vL1xuICAgICAgICAgICAgICAvLy0tLSBEUk9QQklUUyhoZXJlLmJpdHMpIC0tLS8vXG4gICAgICAgICAgICAgIGhvbGQgPj4+PSBoZXJlX2JpdHM7XG4gICAgICAgICAgICAgIGJpdHMgLT0gaGVyZV9iaXRzO1xuICAgICAgICAgICAgICAvLy0tLS8vXG4gICAgICAgICAgICAgIGlmIChzdGF0ZS5oYXZlID09PSAwKSB7XG4gICAgICAgICAgICAgICAgc3RybS5tc2cgPSAnaW52YWxpZCBiaXQgbGVuZ3RoIHJlcGVhdCc7XG4gICAgICAgICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBsZW4gPSBzdGF0ZS5sZW5zW3N0YXRlLmhhdmUgLSAxXTtcbiAgICAgICAgICAgICAgY29weSA9IDMgKyAoaG9sZCAmIDB4MDMpOy8vQklUUygyKTtcbiAgICAgICAgICAgICAgLy8tLS0gRFJPUEJJVFMoMikgLS0tLy9cbiAgICAgICAgICAgICAgaG9sZCA+Pj49IDI7XG4gICAgICAgICAgICAgIGJpdHMgLT0gMjtcbiAgICAgICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaGVyZV92YWwgPT09IDE3KSB7XG4gICAgICAgICAgICAgIC8vPT09IE5FRURCSVRTKGhlcmUuYml0cyArIDMpO1xuICAgICAgICAgICAgICBuID0gaGVyZV9iaXRzICsgMztcbiAgICAgICAgICAgICAgd2hpbGUgKGJpdHMgPCBuKSB7XG4gICAgICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAvLz09PS8vXG4gICAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKGhlcmUuYml0cykgLS0tLy9cbiAgICAgICAgICAgICAgaG9sZCA+Pj49IGhlcmVfYml0cztcbiAgICAgICAgICAgICAgYml0cyAtPSBoZXJlX2JpdHM7XG4gICAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICAgICAgbGVuID0gMDtcbiAgICAgICAgICAgICAgY29weSA9IDMgKyAoaG9sZCAmIDB4MDcpOy8vQklUUygzKTtcbiAgICAgICAgICAgICAgLy8tLS0gRFJPUEJJVFMoMykgLS0tLy9cbiAgICAgICAgICAgICAgaG9sZCA+Pj49IDM7XG4gICAgICAgICAgICAgIGJpdHMgLT0gMztcbiAgICAgICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIC8vPT09IE5FRURCSVRTKGhlcmUuYml0cyArIDcpO1xuICAgICAgICAgICAgICBuID0gaGVyZV9iaXRzICsgNztcbiAgICAgICAgICAgICAgd2hpbGUgKGJpdHMgPCBuKSB7XG4gICAgICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAvLz09PS8vXG4gICAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKGhlcmUuYml0cykgLS0tLy9cbiAgICAgICAgICAgICAgaG9sZCA+Pj49IGhlcmVfYml0cztcbiAgICAgICAgICAgICAgYml0cyAtPSBoZXJlX2JpdHM7XG4gICAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICAgICAgbGVuID0gMDtcbiAgICAgICAgICAgICAgY29weSA9IDExICsgKGhvbGQgJiAweDdmKTsvL0JJVFMoNyk7XG4gICAgICAgICAgICAgIC8vLS0tIERST1BCSVRTKDcpIC0tLS8vXG4gICAgICAgICAgICAgIGhvbGQgPj4+PSA3O1xuICAgICAgICAgICAgICBiaXRzIC09IDc7XG4gICAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzdGF0ZS5oYXZlICsgY29weSA+IHN0YXRlLm5sZW4gKyBzdGF0ZS5uZGlzdCkge1xuICAgICAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGJpdCBsZW5ndGggcmVwZWF0JztcbiAgICAgICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB3aGlsZSAoY29weS0tKSB7XG4gICAgICAgICAgICAgIHN0YXRlLmxlbnNbc3RhdGUuaGF2ZSsrXSA9IGxlbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvKiBoYW5kbGUgZXJyb3IgYnJlYWtzIGluIHdoaWxlICovXG4gICAgICAgIGlmIChzdGF0ZS5tb2RlID09PSBCQUQpIHsgYnJlYWs7IH1cblxuICAgICAgICAvKiBjaGVjayBmb3IgZW5kLW9mLWJsb2NrIGNvZGUgKGJldHRlciBoYXZlIG9uZSkgKi9cbiAgICAgICAgaWYgKHN0YXRlLmxlbnNbMjU2XSA9PT0gMCkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgY29kZSAtLSBtaXNzaW5nIGVuZC1vZi1ibG9jayc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIC8qIGJ1aWxkIGNvZGUgdGFibGVzIC0tIG5vdGU6IGRvIG5vdCBjaGFuZ2UgdGhlIGxlbmJpdHMgb3IgZGlzdGJpdHNcbiAgICAgICAgICAgdmFsdWVzIGhlcmUgKDkgYW5kIDYpIHdpdGhvdXQgcmVhZGluZyB0aGUgY29tbWVudHMgaW4gaW5mdHJlZXMuaFxuICAgICAgICAgICBjb25jZXJuaW5nIHRoZSBFTk9VR0ggY29uc3RhbnRzLCB3aGljaCBkZXBlbmQgb24gdGhvc2UgdmFsdWVzICovXG4gICAgICAgIHN0YXRlLmxlbmJpdHMgPSA5O1xuXG4gICAgICAgIG9wdHMgPSB7IGJpdHM6IHN0YXRlLmxlbmJpdHMgfTtcbiAgICAgICAgcmV0ID0gaW5mbGF0ZV90YWJsZShMRU5TLCBzdGF0ZS5sZW5zLCAwLCBzdGF0ZS5ubGVuLCBzdGF0ZS5sZW5jb2RlLCAwLCBzdGF0ZS53b3JrLCBvcHRzKTtcbiAgICAgICAgLy8gV2UgaGF2ZSBzZXBhcmF0ZSB0YWJsZXMgJiBubyBwb2ludGVycy4gMiBjb21tZW50ZWQgbGluZXMgYmVsb3cgbm90IG5lZWRlZC5cbiAgICAgICAgLy8gc3RhdGUubmV4dF9pbmRleCA9IG9wdHMudGFibGVfaW5kZXg7XG4gICAgICAgIHN0YXRlLmxlbmJpdHMgPSBvcHRzLmJpdHM7XG4gICAgICAgIC8vIHN0YXRlLmxlbmNvZGUgPSBzdGF0ZS5uZXh0O1xuXG4gICAgICAgIGlmIChyZXQpIHtcbiAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGxpdGVyYWwvbGVuZ3RocyBzZXQnO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0ZS5kaXN0Yml0cyA9IDY7XG4gICAgICAgIC8vc3RhdGUuZGlzdGNvZGUuY29weShzdGF0ZS5jb2Rlcyk7XG4gICAgICAgIC8vIFN3aXRjaCB0byB1c2UgZHluYW1pYyB0YWJsZVxuICAgICAgICBzdGF0ZS5kaXN0Y29kZSA9IHN0YXRlLmRpc3RkeW47XG4gICAgICAgIG9wdHMgPSB7IGJpdHM6IHN0YXRlLmRpc3RiaXRzIH07XG4gICAgICAgIHJldCA9IGluZmxhdGVfdGFibGUoRElTVFMsIHN0YXRlLmxlbnMsIHN0YXRlLm5sZW4sIHN0YXRlLm5kaXN0LCBzdGF0ZS5kaXN0Y29kZSwgMCwgc3RhdGUud29yaywgb3B0cyk7XG4gICAgICAgIC8vIFdlIGhhdmUgc2VwYXJhdGUgdGFibGVzICYgbm8gcG9pbnRlcnMuIDIgY29tbWVudGVkIGxpbmVzIGJlbG93IG5vdCBuZWVkZWQuXG4gICAgICAgIC8vIHN0YXRlLm5leHRfaW5kZXggPSBvcHRzLnRhYmxlX2luZGV4O1xuICAgICAgICBzdGF0ZS5kaXN0Yml0cyA9IG9wdHMuYml0cztcbiAgICAgICAgLy8gc3RhdGUuZGlzdGNvZGUgPSBzdGF0ZS5uZXh0O1xuXG4gICAgICAgIGlmIChyZXQpIHtcbiAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGRpc3RhbmNlcyBzZXQnO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgJ2luZmxhdGU6ICAgICAgIGNvZGVzIG9rXFxuJykpO1xuICAgICAgICBzdGF0ZS5tb2RlID0gTEVOXztcbiAgICAgICAgaWYgKGZsdXNoID09PSBaX1RSRUVTKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIExFTl86XG4gICAgICAgIHN0YXRlLm1vZGUgPSBMRU47XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgTEVOOlxuICAgICAgICBpZiAoaGF2ZSA+PSA2ICYmIGxlZnQgPj0gMjU4KSB7XG4gICAgICAgICAgLy8tLS0gUkVTVE9SRSgpIC0tLVxuICAgICAgICAgIHN0cm0ubmV4dF9vdXQgPSBwdXQ7XG4gICAgICAgICAgc3RybS5hdmFpbF9vdXQgPSBsZWZ0O1xuICAgICAgICAgIHN0cm0ubmV4dF9pbiA9IG5leHQ7XG4gICAgICAgICAgc3RybS5hdmFpbF9pbiA9IGhhdmU7XG4gICAgICAgICAgc3RhdGUuaG9sZCA9IGhvbGQ7XG4gICAgICAgICAgc3RhdGUuYml0cyA9IGJpdHM7XG4gICAgICAgICAgLy8tLS1cbiAgICAgICAgICBpbmZsYXRlX2Zhc3Qoc3RybSwgX291dCk7XG4gICAgICAgICAgLy8tLS0gTE9BRCgpIC0tLVxuICAgICAgICAgIHB1dCA9IHN0cm0ubmV4dF9vdXQ7XG4gICAgICAgICAgb3V0cHV0ID0gc3RybS5vdXRwdXQ7XG4gICAgICAgICAgbGVmdCA9IHN0cm0uYXZhaWxfb3V0O1xuICAgICAgICAgIG5leHQgPSBzdHJtLm5leHRfaW47XG4gICAgICAgICAgaW5wdXQgPSBzdHJtLmlucHV0O1xuICAgICAgICAgIGhhdmUgPSBzdHJtLmF2YWlsX2luO1xuICAgICAgICAgIGhvbGQgPSBzdGF0ZS5ob2xkO1xuICAgICAgICAgIGJpdHMgPSBzdGF0ZS5iaXRzO1xuICAgICAgICAgIC8vLS0tXG5cbiAgICAgICAgICBpZiAoc3RhdGUubW9kZSA9PT0gVFlQRSkge1xuICAgICAgICAgICAgc3RhdGUuYmFjayA9IC0xO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBzdGF0ZS5iYWNrID0gMDtcbiAgICAgICAgZm9yICg7Oykge1xuICAgICAgICAgIGhlcmUgPSBzdGF0ZS5sZW5jb2RlW2hvbGQgJiAoKDEgPDwgc3RhdGUubGVuYml0cykgLSAxKV07ICAvKkJJVFMoc3RhdGUubGVuYml0cykqL1xuICAgICAgICAgIGhlcmVfYml0cyA9IGhlcmUgPj4+IDI0O1xuICAgICAgICAgIGhlcmVfb3AgPSAoaGVyZSA+Pj4gMTYpICYgMHhmZjtcbiAgICAgICAgICBoZXJlX3ZhbCA9IGhlcmUgJiAweGZmZmY7XG5cbiAgICAgICAgICBpZiAoaGVyZV9iaXRzIDw9IGJpdHMpIHsgYnJlYWs7IH1cbiAgICAgICAgICAvLy0tLSBQVUxMQllURSgpIC0tLS8vXG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICAvLy0tLS8vXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhlcmVfb3AgJiYgKGhlcmVfb3AgJiAweGYwKSA9PT0gMCkge1xuICAgICAgICAgIGxhc3RfYml0cyA9IGhlcmVfYml0cztcbiAgICAgICAgICBsYXN0X29wID0gaGVyZV9vcDtcbiAgICAgICAgICBsYXN0X3ZhbCA9IGhlcmVfdmFsO1xuICAgICAgICAgIGZvciAoOzspIHtcbiAgICAgICAgICAgIGhlcmUgPSBzdGF0ZS5sZW5jb2RlW2xhc3RfdmFsICtcbiAgICAgICAgICAgICAgICAgICAgKChob2xkICYgKCgxIDw8IChsYXN0X2JpdHMgKyBsYXN0X29wKSkgLSAxKSkvKkJJVFMobGFzdC5iaXRzICsgbGFzdC5vcCkqLyA+PiBsYXN0X2JpdHMpXTtcbiAgICAgICAgICAgIGhlcmVfYml0cyA9IGhlcmUgPj4+IDI0O1xuICAgICAgICAgICAgaGVyZV9vcCA9IChoZXJlID4+PiAxNikgJiAweGZmO1xuICAgICAgICAgICAgaGVyZV92YWwgPSBoZXJlICYgMHhmZmZmO1xuXG4gICAgICAgICAgICBpZiAoKGxhc3RfYml0cyArIGhlcmVfYml0cykgPD0gYml0cykgeyBicmVhazsgfVxuICAgICAgICAgICAgLy8tLS0gUFVMTEJZVEUoKSAtLS0vL1xuICAgICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgICBoYXZlLS07XG4gICAgICAgICAgICBob2xkICs9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICAgIC8vLS0tLy9cbiAgICAgICAgICB9XG4gICAgICAgICAgLy8tLS0gRFJPUEJJVFMobGFzdC5iaXRzKSAtLS0vL1xuICAgICAgICAgIGhvbGQgPj4+PSBsYXN0X2JpdHM7XG4gICAgICAgICAgYml0cyAtPSBsYXN0X2JpdHM7XG4gICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgIHN0YXRlLmJhY2sgKz0gbGFzdF9iaXRzO1xuICAgICAgICB9XG4gICAgICAgIC8vLS0tIERST1BCSVRTKGhlcmUuYml0cykgLS0tLy9cbiAgICAgICAgaG9sZCA+Pj49IGhlcmVfYml0cztcbiAgICAgICAgYml0cyAtPSBoZXJlX2JpdHM7XG4gICAgICAgIC8vLS0tLy9cbiAgICAgICAgc3RhdGUuYmFjayArPSBoZXJlX2JpdHM7XG4gICAgICAgIHN0YXRlLmxlbmd0aCA9IGhlcmVfdmFsO1xuICAgICAgICBpZiAoaGVyZV9vcCA9PT0gMCkge1xuICAgICAgICAgIC8vVHJhY2V2digoc3RkZXJyLCBoZXJlLnZhbCA+PSAweDIwICYmIGhlcmUudmFsIDwgMHg3ZiA/XG4gICAgICAgICAgLy8gICAgICAgIFwiaW5mbGF0ZTogICAgICAgICBsaXRlcmFsICclYydcXG5cIiA6XG4gICAgICAgICAgLy8gICAgICAgIFwiaW5mbGF0ZTogICAgICAgICBsaXRlcmFsIDB4JTAyeFxcblwiLCBoZXJlLnZhbCkpO1xuICAgICAgICAgIHN0YXRlLm1vZGUgPSBMSVQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhlcmVfb3AgJiAzMikge1xuICAgICAgICAgIC8vVHJhY2V2digoc3RkZXJyLCBcImluZmxhdGU6ICAgICAgICAgZW5kIG9mIGJsb2NrXFxuXCIpKTtcbiAgICAgICAgICBzdGF0ZS5iYWNrID0gLTE7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IFRZUEU7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhlcmVfb3AgJiA2NCkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgbGl0ZXJhbC9sZW5ndGggY29kZSc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBzdGF0ZS5leHRyYSA9IGhlcmVfb3AgJiAxNTtcbiAgICAgICAgc3RhdGUubW9kZSA9IExFTkVYVDtcbiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgY2FzZSBMRU5FWFQ6XG4gICAgICAgIGlmIChzdGF0ZS5leHRyYSkge1xuICAgICAgICAgIC8vPT09IE5FRURCSVRTKHN0YXRlLmV4dHJhKTtcbiAgICAgICAgICBuID0gc3RhdGUuZXh0cmE7XG4gICAgICAgICAgd2hpbGUgKGJpdHMgPCBuKSB7XG4gICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLz09PS8vXG4gICAgICAgICAgc3RhdGUubGVuZ3RoICs9IGhvbGQgJiAoKDEgPDwgc3RhdGUuZXh0cmEpIC0gMSkvKkJJVFMoc3RhdGUuZXh0cmEpKi87XG4gICAgICAgICAgLy8tLS0gRFJPUEJJVFMoc3RhdGUuZXh0cmEpIC0tLS8vXG4gICAgICAgICAgaG9sZCA+Pj49IHN0YXRlLmV4dHJhO1xuICAgICAgICAgIGJpdHMgLT0gc3RhdGUuZXh0cmE7XG4gICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgIHN0YXRlLmJhY2sgKz0gc3RhdGUuZXh0cmE7XG4gICAgICAgIH1cbiAgICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgICBsZW5ndGggJXVcXG5cIiwgc3RhdGUubGVuZ3RoKSk7XG4gICAgICAgIHN0YXRlLndhcyA9IHN0YXRlLmxlbmd0aDtcbiAgICAgICAgc3RhdGUubW9kZSA9IERJU1Q7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgRElTVDpcbiAgICAgICAgZm9yICg7Oykge1xuICAgICAgICAgIGhlcmUgPSBzdGF0ZS5kaXN0Y29kZVtob2xkICYgKCgxIDw8IHN0YXRlLmRpc3RiaXRzKSAtIDEpXTsvKkJJVFMoc3RhdGUuZGlzdGJpdHMpKi9cbiAgICAgICAgICBoZXJlX2JpdHMgPSBoZXJlID4+PiAyNDtcbiAgICAgICAgICBoZXJlX29wID0gKGhlcmUgPj4+IDE2KSAmIDB4ZmY7XG4gICAgICAgICAgaGVyZV92YWwgPSBoZXJlICYgMHhmZmZmO1xuXG4gICAgICAgICAgaWYgKChoZXJlX2JpdHMpIDw9IGJpdHMpIHsgYnJlYWs7IH1cbiAgICAgICAgICAvLy0tLSBQVUxMQllURSgpIC0tLS8vXG4gICAgICAgICAgaWYgKGhhdmUgPT09IDApIHsgYnJlYWsgaW5mX2xlYXZlOyB9XG4gICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICAvLy0tLS8vXG4gICAgICAgIH1cbiAgICAgICAgaWYgKChoZXJlX29wICYgMHhmMCkgPT09IDApIHtcbiAgICAgICAgICBsYXN0X2JpdHMgPSBoZXJlX2JpdHM7XG4gICAgICAgICAgbGFzdF9vcCA9IGhlcmVfb3A7XG4gICAgICAgICAgbGFzdF92YWwgPSBoZXJlX3ZhbDtcbiAgICAgICAgICBmb3IgKDs7KSB7XG4gICAgICAgICAgICBoZXJlID0gc3RhdGUuZGlzdGNvZGVbbGFzdF92YWwgK1xuICAgICAgICAgICAgICAgICAgICAoKGhvbGQgJiAoKDEgPDwgKGxhc3RfYml0cyArIGxhc3Rfb3ApKSAtIDEpKS8qQklUUyhsYXN0LmJpdHMgKyBsYXN0Lm9wKSovID4+IGxhc3RfYml0cyldO1xuICAgICAgICAgICAgaGVyZV9iaXRzID0gaGVyZSA+Pj4gMjQ7XG4gICAgICAgICAgICBoZXJlX29wID0gKGhlcmUgPj4+IDE2KSAmIDB4ZmY7XG4gICAgICAgICAgICBoZXJlX3ZhbCA9IGhlcmUgJiAweGZmZmY7XG5cbiAgICAgICAgICAgIGlmICgobGFzdF9iaXRzICsgaGVyZV9iaXRzKSA8PSBiaXRzKSB7IGJyZWFrOyB9XG4gICAgICAgICAgICAvLy0tLSBQVUxMQllURSgpIC0tLS8vXG4gICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAgICAgLy8tLS0vL1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLy0tLSBEUk9QQklUUyhsYXN0LmJpdHMpIC0tLS8vXG4gICAgICAgICAgaG9sZCA+Pj49IGxhc3RfYml0cztcbiAgICAgICAgICBiaXRzIC09IGxhc3RfYml0cztcbiAgICAgICAgICAvLy0tLS8vXG4gICAgICAgICAgc3RhdGUuYmFjayArPSBsYXN0X2JpdHM7XG4gICAgICAgIH1cbiAgICAgICAgLy8tLS0gRFJPUEJJVFMoaGVyZS5iaXRzKSAtLS0vL1xuICAgICAgICBob2xkID4+Pj0gaGVyZV9iaXRzO1xuICAgICAgICBiaXRzIC09IGhlcmVfYml0cztcbiAgICAgICAgLy8tLS0vL1xuICAgICAgICBzdGF0ZS5iYWNrICs9IGhlcmVfYml0cztcbiAgICAgICAgaWYgKGhlcmVfb3AgJiA2NCkge1xuICAgICAgICAgIHN0cm0ubXNnID0gJ2ludmFsaWQgZGlzdGFuY2UgY29kZSc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBzdGF0ZS5vZmZzZXQgPSBoZXJlX3ZhbDtcbiAgICAgICAgc3RhdGUuZXh0cmEgPSAoaGVyZV9vcCkgJiAxNTtcbiAgICAgICAgc3RhdGUubW9kZSA9IERJU1RFWFQ7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgRElTVEVYVDpcbiAgICAgICAgaWYgKHN0YXRlLmV4dHJhKSB7XG4gICAgICAgICAgLy89PT0gTkVFREJJVFMoc3RhdGUuZXh0cmEpO1xuICAgICAgICAgIG4gPSBzdGF0ZS5leHRyYTtcbiAgICAgICAgICB3aGlsZSAoYml0cyA8IG4pIHtcbiAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgICAgaG9sZCArPSBpbnB1dFtuZXh0KytdIDw8IGJpdHM7XG4gICAgICAgICAgICBiaXRzICs9IDg7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vPT09Ly9cbiAgICAgICAgICBzdGF0ZS5vZmZzZXQgKz0gaG9sZCAmICgoMSA8PCBzdGF0ZS5leHRyYSkgLSAxKS8qQklUUyhzdGF0ZS5leHRyYSkqLztcbiAgICAgICAgICAvLy0tLSBEUk9QQklUUyhzdGF0ZS5leHRyYSkgLS0tLy9cbiAgICAgICAgICBob2xkID4+Pj0gc3RhdGUuZXh0cmE7XG4gICAgICAgICAgYml0cyAtPSBzdGF0ZS5leHRyYTtcbiAgICAgICAgICAvLy0tLS8vXG4gICAgICAgICAgc3RhdGUuYmFjayArPSBzdGF0ZS5leHRyYTtcbiAgICAgICAgfVxuLy8jaWZkZWYgSU5GTEFURV9TVFJJQ1RcbiAgICAgICAgaWYgKHN0YXRlLm9mZnNldCA+IHN0YXRlLmRtYXgpIHtcbiAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGRpc3RhbmNlIHRvbyBmYXIgYmFjayc7XG4gICAgICAgICAgc3RhdGUubW9kZSA9IEJBRDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuLy8jZW5kaWZcbiAgICAgICAgLy9UcmFjZXZ2KChzdGRlcnIsIFwiaW5mbGF0ZTogICAgICAgICBkaXN0YW5jZSAldVxcblwiLCBzdGF0ZS5vZmZzZXQpKTtcbiAgICAgICAgc3RhdGUubW9kZSA9IE1BVENIO1xuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIE1BVENIOlxuICAgICAgICBpZiAobGVmdCA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgY29weSA9IF9vdXQgLSBsZWZ0O1xuICAgICAgICBpZiAoc3RhdGUub2Zmc2V0ID4gY29weSkgeyAgICAgICAgIC8qIGNvcHkgZnJvbSB3aW5kb3cgKi9cbiAgICAgICAgICBjb3B5ID0gc3RhdGUub2Zmc2V0IC0gY29weTtcbiAgICAgICAgICBpZiAoY29weSA+IHN0YXRlLndoYXZlKSB7XG4gICAgICAgICAgICBpZiAoc3RhdGUuc2FuZSkge1xuICAgICAgICAgICAgICBzdHJtLm1zZyA9ICdpbnZhbGlkIGRpc3RhbmNlIHRvbyBmYXIgYmFjayc7XG4gICAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuLy8gKCEpIFRoaXMgYmxvY2sgaXMgZGlzYWJsZWQgaW4gemxpYiBkZWZhdWx0cyxcbi8vIGRvbid0IGVuYWJsZSBpdCBmb3IgYmluYXJ5IGNvbXBhdGliaWxpdHlcbi8vI2lmZGVmIElORkxBVEVfQUxMT1dfSU5WQUxJRF9ESVNUQU5DRV9UT09GQVJfQVJSUlxuLy8gICAgICAgICAgVHJhY2UoKHN0ZGVyciwgXCJpbmZsYXRlLmMgdG9vIGZhclxcblwiKSk7XG4vLyAgICAgICAgICBjb3B5IC09IHN0YXRlLndoYXZlO1xuLy8gICAgICAgICAgaWYgKGNvcHkgPiBzdGF0ZS5sZW5ndGgpIHsgY29weSA9IHN0YXRlLmxlbmd0aDsgfVxuLy8gICAgICAgICAgaWYgKGNvcHkgPiBsZWZ0KSB7IGNvcHkgPSBsZWZ0OyB9XG4vLyAgICAgICAgICBsZWZ0IC09IGNvcHk7XG4vLyAgICAgICAgICBzdGF0ZS5sZW5ndGggLT0gY29weTtcbi8vICAgICAgICAgIGRvIHtcbi8vICAgICAgICAgICAgb3V0cHV0W3B1dCsrXSA9IDA7XG4vLyAgICAgICAgICB9IHdoaWxlICgtLWNvcHkpO1xuLy8gICAgICAgICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkgeyBzdGF0ZS5tb2RlID0gTEVOOyB9XG4vLyAgICAgICAgICBicmVhaztcbi8vI2VuZGlmXG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChjb3B5ID4gc3RhdGUud25leHQpIHtcbiAgICAgICAgICAgIGNvcHkgLT0gc3RhdGUud25leHQ7XG4gICAgICAgICAgICBmcm9tID0gc3RhdGUud3NpemUgLSBjb3B5O1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGZyb20gPSBzdGF0ZS53bmV4dCAtIGNvcHk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChjb3B5ID4gc3RhdGUubGVuZ3RoKSB7IGNvcHkgPSBzdGF0ZS5sZW5ndGg7IH1cbiAgICAgICAgICBmcm9tX3NvdXJjZSA9IHN0YXRlLndpbmRvdztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBjb3B5IGZyb20gb3V0cHV0ICovXG4gICAgICAgICAgZnJvbV9zb3VyY2UgPSBvdXRwdXQ7XG4gICAgICAgICAgZnJvbSA9IHB1dCAtIHN0YXRlLm9mZnNldDtcbiAgICAgICAgICBjb3B5ID0gc3RhdGUubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb3B5ID4gbGVmdCkgeyBjb3B5ID0gbGVmdDsgfVxuICAgICAgICBsZWZ0IC09IGNvcHk7XG4gICAgICAgIHN0YXRlLmxlbmd0aCAtPSBjb3B5O1xuICAgICAgICBkbyB7XG4gICAgICAgICAgb3V0cHV0W3B1dCsrXSA9IGZyb21fc291cmNlW2Zyb20rK107XG4gICAgICAgIH0gd2hpbGUgKC0tY29weSk7XG4gICAgICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApIHsgc3RhdGUubW9kZSA9IExFTjsgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTElUOlxuICAgICAgICBpZiAobGVmdCA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgb3V0cHV0W3B1dCsrXSA9IHN0YXRlLmxlbmd0aDtcbiAgICAgICAgbGVmdC0tO1xuICAgICAgICBzdGF0ZS5tb2RlID0gTEVOO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQ0hFQ0s6XG4gICAgICAgIGlmIChzdGF0ZS53cmFwKSB7XG4gICAgICAgICAgLy89PT0gTkVFREJJVFMoMzIpO1xuICAgICAgICAgIHdoaWxlIChiaXRzIDwgMzIpIHtcbiAgICAgICAgICAgIGlmIChoYXZlID09PSAwKSB7IGJyZWFrIGluZl9sZWF2ZTsgfVxuICAgICAgICAgICAgaGF2ZS0tO1xuICAgICAgICAgICAgLy8gVXNlICd8JyBpbnN0ZWFkIG9mICcrJyB0byBtYWtlIHN1cmUgdGhhdCByZXN1bHQgaXMgc2lnbmVkXG4gICAgICAgICAgICBob2xkIHw9IGlucHV0W25leHQrK10gPDwgYml0cztcbiAgICAgICAgICAgIGJpdHMgKz0gODtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy89PT0vL1xuICAgICAgICAgIF9vdXQgLT0gbGVmdDtcbiAgICAgICAgICBzdHJtLnRvdGFsX291dCArPSBfb3V0O1xuICAgICAgICAgIHN0YXRlLnRvdGFsICs9IF9vdXQ7XG4gICAgICAgICAgaWYgKF9vdXQpIHtcbiAgICAgICAgICAgIHN0cm0uYWRsZXIgPSBzdGF0ZS5jaGVjayA9XG4gICAgICAgICAgICAgICAgLypVUERBVEUoc3RhdGUuY2hlY2ssIHB1dCAtIF9vdXQsIF9vdXQpOyovXG4gICAgICAgICAgICAgICAgKHN0YXRlLmZsYWdzID8gY3JjMzIoc3RhdGUuY2hlY2ssIG91dHB1dCwgX291dCwgcHV0IC0gX291dCkgOiBhZGxlcjMyKHN0YXRlLmNoZWNrLCBvdXRwdXQsIF9vdXQsIHB1dCAtIF9vdXQpKTtcblxuICAgICAgICAgIH1cbiAgICAgICAgICBfb3V0ID0gbGVmdDtcbiAgICAgICAgICAvLyBOQjogY3JjMzIgc3RvcmVkIGFzIHNpZ25lZCAzMi1iaXQgaW50LCB6c3dhcDMyIHJldHVybnMgc2lnbmVkIHRvb1xuICAgICAgICAgIGlmICgoc3RhdGUuZmxhZ3MgPyBob2xkIDogenN3YXAzMihob2xkKSkgIT09IHN0YXRlLmNoZWNrKSB7XG4gICAgICAgICAgICBzdHJtLm1zZyA9ICdpbmNvcnJlY3QgZGF0YSBjaGVjayc7XG4gICAgICAgICAgICBzdGF0ZS5tb2RlID0gQkFEO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vPT09IElOSVRCSVRTKCk7XG4gICAgICAgICAgaG9sZCA9IDA7XG4gICAgICAgICAgYml0cyA9IDA7XG4gICAgICAgICAgLy89PT0vL1xuICAgICAgICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiaW5mbGF0ZTogICBjaGVjayBtYXRjaGVzIHRyYWlsZXJcXG5cIikpO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRlLm1vZGUgPSBMRU5HVEg7XG4gICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgIGNhc2UgTEVOR1RIOlxuICAgICAgICBpZiAoc3RhdGUud3JhcCAmJiBzdGF0ZS5mbGFncykge1xuICAgICAgICAgIC8vPT09IE5FRURCSVRTKDMyKTtcbiAgICAgICAgICB3aGlsZSAoYml0cyA8IDMyKSB7XG4gICAgICAgICAgICBpZiAoaGF2ZSA9PT0gMCkgeyBicmVhayBpbmZfbGVhdmU7IH1cbiAgICAgICAgICAgIGhhdmUtLTtcbiAgICAgICAgICAgIGhvbGQgKz0gaW5wdXRbbmV4dCsrXSA8PCBiaXRzO1xuICAgICAgICAgICAgYml0cyArPSA4O1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLz09PS8vXG4gICAgICAgICAgaWYgKGhvbGQgIT09IChzdGF0ZS50b3RhbCAmIDB4ZmZmZmZmZmYpKSB7XG4gICAgICAgICAgICBzdHJtLm1zZyA9ICdpbmNvcnJlY3QgbGVuZ3RoIGNoZWNrJztcbiAgICAgICAgICAgIHN0YXRlLm1vZGUgPSBCQUQ7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgLy89PT0gSU5JVEJJVFMoKTtcbiAgICAgICAgICBob2xkID0gMDtcbiAgICAgICAgICBiaXRzID0gMDtcbiAgICAgICAgICAvLz09PS8vXG4gICAgICAgICAgLy9UcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgIGxlbmd0aCBtYXRjaGVzIHRyYWlsZXJcXG5cIikpO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRlLm1vZGUgPSBET05FO1xuICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICBjYXNlIERPTkU6XG4gICAgICAgIHJldCA9IFpfU1RSRUFNX0VORDtcbiAgICAgICAgYnJlYWsgaW5mX2xlYXZlO1xuICAgICAgY2FzZSBCQUQ6XG4gICAgICAgIHJldCA9IFpfREFUQV9FUlJPUjtcbiAgICAgICAgYnJlYWsgaW5mX2xlYXZlO1xuICAgICAgY2FzZSBNRU06XG4gICAgICAgIHJldHVybiBaX01FTV9FUlJPUjtcbiAgICAgIGNhc2UgU1lOQzpcbiAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SO1xuICAgIH1cbiAgfVxuXG4gIC8vIGluZl9sZWF2ZSA8LSBoZXJlIGlzIHJlYWwgcGxhY2UgZm9yIFwiZ290byBpbmZfbGVhdmVcIiwgZW11bGF0ZWQgdmlhIFwiYnJlYWsgaW5mX2xlYXZlXCJcblxuICAvKlxuICAgICBSZXR1cm4gZnJvbSBpbmZsYXRlKCksIHVwZGF0aW5nIHRoZSB0b3RhbCBjb3VudHMgYW5kIHRoZSBjaGVjayB2YWx1ZS5cbiAgICAgSWYgdGhlcmUgd2FzIG5vIHByb2dyZXNzIGR1cmluZyB0aGUgaW5mbGF0ZSgpIGNhbGwsIHJldHVybiBhIGJ1ZmZlclxuICAgICBlcnJvci4gIENhbGwgdXBkYXRld2luZG93KCkgdG8gY3JlYXRlIGFuZC9vciB1cGRhdGUgdGhlIHdpbmRvdyBzdGF0ZS5cbiAgICAgTm90ZTogYSBtZW1vcnkgZXJyb3IgZnJvbSBpbmZsYXRlKCkgaXMgbm9uLXJlY292ZXJhYmxlLlxuICAgKi9cblxuICAvLy0tLSBSRVNUT1JFKCkgLS0tXG4gIHN0cm0ubmV4dF9vdXQgPSBwdXQ7XG4gIHN0cm0uYXZhaWxfb3V0ID0gbGVmdDtcbiAgc3RybS5uZXh0X2luID0gbmV4dDtcbiAgc3RybS5hdmFpbF9pbiA9IGhhdmU7XG4gIHN0YXRlLmhvbGQgPSBob2xkO1xuICBzdGF0ZS5iaXRzID0gYml0cztcbiAgLy8tLS1cblxuICBpZiAoc3RhdGUud3NpemUgfHwgKF9vdXQgIT09IHN0cm0uYXZhaWxfb3V0ICYmIHN0YXRlLm1vZGUgPCBCQUQgJiZcbiAgICAgICAgICAgICAgICAgICAgICAoc3RhdGUubW9kZSA8IENIRUNLIHx8IGZsdXNoICE9PSBaX0ZJTklTSCkpKSB7XG4gICAgaWYgKHVwZGF0ZXdpbmRvdyhzdHJtLCBzdHJtLm91dHB1dCwgc3RybS5uZXh0X291dCwgX291dCAtIHN0cm0uYXZhaWxfb3V0KSkge1xuICAgICAgc3RhdGUubW9kZSA9IE1FTTtcbiAgICAgIHJldHVybiBaX01FTV9FUlJPUjtcbiAgICB9XG4gIH1cbiAgX2luIC09IHN0cm0uYXZhaWxfaW47XG4gIF9vdXQgLT0gc3RybS5hdmFpbF9vdXQ7XG4gIHN0cm0udG90YWxfaW4gKz0gX2luO1xuICBzdHJtLnRvdGFsX291dCArPSBfb3V0O1xuICBzdGF0ZS50b3RhbCArPSBfb3V0O1xuICBpZiAoc3RhdGUud3JhcCAmJiBfb3V0KSB7XG4gICAgc3RybS5hZGxlciA9IHN0YXRlLmNoZWNrID0gLypVUERBVEUoc3RhdGUuY2hlY2ssIHN0cm0ubmV4dF9vdXQgLSBfb3V0LCBfb3V0KTsqL1xuICAgICAgKHN0YXRlLmZsYWdzID8gY3JjMzIoc3RhdGUuY2hlY2ssIG91dHB1dCwgX291dCwgc3RybS5uZXh0X291dCAtIF9vdXQpIDogYWRsZXIzMihzdGF0ZS5jaGVjaywgb3V0cHV0LCBfb3V0LCBzdHJtLm5leHRfb3V0IC0gX291dCkpO1xuICB9XG4gIHN0cm0uZGF0YV90eXBlID0gc3RhdGUuYml0cyArIChzdGF0ZS5sYXN0ID8gNjQgOiAwKSArXG4gICAgICAgICAgICAgICAgICAgIChzdGF0ZS5tb2RlID09PSBUWVBFID8gMTI4IDogMCkgK1xuICAgICAgICAgICAgICAgICAgICAoc3RhdGUubW9kZSA9PT0gTEVOXyB8fCBzdGF0ZS5tb2RlID09PSBDT1BZXyA/IDI1NiA6IDApO1xuICBpZiAoKChfaW4gPT09IDAgJiYgX291dCA9PT0gMCkgfHwgZmx1c2ggPT09IFpfRklOSVNIKSAmJiByZXQgPT09IFpfT0spIHtcbiAgICByZXQgPSBaX0JVRl9FUlJPUjtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBpbmZsYXRlRW5kKHN0cm0pIHtcblxuICBpZiAoIXN0cm0gfHwgIXN0cm0uc3RhdGUgLyp8fCBzdHJtLT56ZnJlZSA9PSAoZnJlZV9mdW5jKTAqLykge1xuICAgIHJldHVybiBaX1NUUkVBTV9FUlJPUjtcbiAgfVxuXG4gIHZhciBzdGF0ZSA9IHN0cm0uc3RhdGU7XG4gIGlmIChzdGF0ZS53aW5kb3cpIHtcbiAgICBzdGF0ZS53aW5kb3cgPSBudWxsO1xuICB9XG4gIHN0cm0uc3RhdGUgPSBudWxsO1xuICByZXR1cm4gWl9PSztcbn1cblxuZnVuY3Rpb24gaW5mbGF0ZUdldEhlYWRlcihzdHJtLCBoZWFkKSB7XG4gIHZhciBzdGF0ZTtcblxuICAvKiBjaGVjayBzdGF0ZSAqL1xuICBpZiAoIXN0cm0gfHwgIXN0cm0uc3RhdGUpIHsgcmV0dXJuIFpfU1RSRUFNX0VSUk9SOyB9XG4gIHN0YXRlID0gc3RybS5zdGF0ZTtcbiAgaWYgKChzdGF0ZS53cmFwICYgMikgPT09IDApIHsgcmV0dXJuIFpfU1RSRUFNX0VSUk9SOyB9XG5cbiAgLyogc2F2ZSBoZWFkZXIgc3RydWN0dXJlICovXG4gIHN0YXRlLmhlYWQgPSBoZWFkO1xuICBoZWFkLmRvbmUgPSBmYWxzZTtcbiAgcmV0dXJuIFpfT0s7XG59XG5cbmZ1bmN0aW9uIGluZmxhdGVTZXREaWN0aW9uYXJ5KHN0cm0sIGRpY3Rpb25hcnkpIHtcbiAgdmFyIGRpY3RMZW5ndGggPSBkaWN0aW9uYXJ5Lmxlbmd0aDtcblxuICB2YXIgc3RhdGU7XG4gIHZhciBkaWN0aWQ7XG4gIHZhciByZXQ7XG5cbiAgLyogY2hlY2sgc3RhdGUgKi9cbiAgaWYgKCFzdHJtIC8qID09IFpfTlVMTCAqLyB8fCAhc3RybS5zdGF0ZSAvKiA9PSBaX05VTEwgKi8pIHsgcmV0dXJuIFpfU1RSRUFNX0VSUk9SOyB9XG4gIHN0YXRlID0gc3RybS5zdGF0ZTtcblxuICBpZiAoc3RhdGUud3JhcCAhPT0gMCAmJiBzdGF0ZS5tb2RlICE9PSBESUNUKSB7XG4gICAgcmV0dXJuIFpfU1RSRUFNX0VSUk9SO1xuICB9XG5cbiAgLyogY2hlY2sgZm9yIGNvcnJlY3QgZGljdGlvbmFyeSBpZGVudGlmaWVyICovXG4gIGlmIChzdGF0ZS5tb2RlID09PSBESUNUKSB7XG4gICAgZGljdGlkID0gMTsgLyogYWRsZXIzMigwLCBudWxsLCAwKSovXG4gICAgLyogZGljdGlkID0gYWRsZXIzMihkaWN0aWQsIGRpY3Rpb25hcnksIGRpY3RMZW5ndGgpOyAqL1xuICAgIGRpY3RpZCA9IGFkbGVyMzIoZGljdGlkLCBkaWN0aW9uYXJ5LCBkaWN0TGVuZ3RoLCAwKTtcbiAgICBpZiAoZGljdGlkICE9PSBzdGF0ZS5jaGVjaykge1xuICAgICAgcmV0dXJuIFpfREFUQV9FUlJPUjtcbiAgICB9XG4gIH1cbiAgLyogY29weSBkaWN0aW9uYXJ5IHRvIHdpbmRvdyB1c2luZyB1cGRhdGV3aW5kb3coKSwgd2hpY2ggd2lsbCBhbWVuZCB0aGVcbiAgIGV4aXN0aW5nIGRpY3Rpb25hcnkgaWYgYXBwcm9wcmlhdGUgKi9cbiAgcmV0ID0gdXBkYXRld2luZG93KHN0cm0sIGRpY3Rpb25hcnksIGRpY3RMZW5ndGgsIGRpY3RMZW5ndGgpO1xuICBpZiAocmV0KSB7XG4gICAgc3RhdGUubW9kZSA9IE1FTTtcbiAgICByZXR1cm4gWl9NRU1fRVJST1I7XG4gIH1cbiAgc3RhdGUuaGF2ZWRpY3QgPSAxO1xuICAvLyBUcmFjZXYoKHN0ZGVyciwgXCJpbmZsYXRlOiAgIGRpY3Rpb25hcnkgc2V0XFxuXCIpKTtcbiAgcmV0dXJuIFpfT0s7XG59XG5cbmV4cG9ydHMuaW5mbGF0ZVJlc2V0ID0gaW5mbGF0ZVJlc2V0O1xuZXhwb3J0cy5pbmZsYXRlUmVzZXQyID0gaW5mbGF0ZVJlc2V0MjtcbmV4cG9ydHMuaW5mbGF0ZVJlc2V0S2VlcCA9IGluZmxhdGVSZXNldEtlZXA7XG5leHBvcnRzLmluZmxhdGVJbml0ID0gaW5mbGF0ZUluaXQ7XG5leHBvcnRzLmluZmxhdGVJbml0MiA9IGluZmxhdGVJbml0MjtcbmV4cG9ydHMuaW5mbGF0ZSA9IGluZmxhdGU7XG5leHBvcnRzLmluZmxhdGVFbmQgPSBpbmZsYXRlRW5kO1xuZXhwb3J0cy5pbmZsYXRlR2V0SGVhZGVyID0gaW5mbGF0ZUdldEhlYWRlcjtcbmV4cG9ydHMuaW5mbGF0ZVNldERpY3Rpb25hcnkgPSBpbmZsYXRlU2V0RGljdGlvbmFyeTtcbmV4cG9ydHMuaW5mbGF0ZUluZm8gPSAncGFrbyBpbmZsYXRlIChmcm9tIE5vZGVjYSBwcm9qZWN0KSc7XG5cbi8qIE5vdCBpbXBsZW1lbnRlZFxuZXhwb3J0cy5pbmZsYXRlQ29weSA9IGluZmxhdGVDb3B5O1xuZXhwb3J0cy5pbmZsYXRlR2V0RGljdGlvbmFyeSA9IGluZmxhdGVHZXREaWN0aW9uYXJ5O1xuZXhwb3J0cy5pbmZsYXRlTWFyayA9IGluZmxhdGVNYXJrO1xuZXhwb3J0cy5pbmZsYXRlUHJpbWUgPSBpbmZsYXRlUHJpbWU7XG5leHBvcnRzLmluZmxhdGVTeW5jID0gaW5mbGF0ZVN5bmM7XG5leHBvcnRzLmluZmxhdGVTeW5jUG9pbnQgPSBpbmZsYXRlU3luY1BvaW50O1xuZXhwb3J0cy5pbmZsYXRlVW5kZXJtaW5lID0gaW5mbGF0ZVVuZGVybWluZTtcbiovXG4iLCIndXNlIHN0cmljdCc7XG5cbi8vIChDKSAxOTk1LTIwMTMgSmVhbi1sb3VwIEdhaWxseSBhbmQgTWFyayBBZGxlclxuLy8gKEMpIDIwMTQtMjAxNyBWaXRhbHkgUHV6cmluIGFuZCBBbmRyZXkgVHVwaXRzaW5cbi8vXG4vLyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZFxuLy8gd2FycmFudHkuIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzXG4vLyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLFxuLy8gaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdFxuLy8gZnJlZWx5LCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOlxuLy9cbi8vIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90XG4vLyAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlXG4vLyAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZVxuLy8gICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLlxuLy8gMi4gQWx0ZXJlZCBzb3VyY2UgdmVyc2lvbnMgbXVzdCBiZSBwbGFpbmx5IG1hcmtlZCBhcyBzdWNoLCBhbmQgbXVzdCBub3QgYmVcbi8vICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLlxuLy8gMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi5cblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMvY29tbW9uJyk7XG5cbnZhciBNQVhCSVRTID0gMTU7XG52YXIgRU5PVUdIX0xFTlMgPSA4NTI7XG52YXIgRU5PVUdIX0RJU1RTID0gNTkyO1xuLy92YXIgRU5PVUdIID0gKEVOT1VHSF9MRU5TK0VOT1VHSF9ESVNUUyk7XG5cbnZhciBDT0RFUyA9IDA7XG52YXIgTEVOUyA9IDE7XG52YXIgRElTVFMgPSAyO1xuXG52YXIgbGJhc2UgPSBbIC8qIExlbmd0aCBjb2RlcyAyNTcuLjI4NSBiYXNlICovXG4gIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTMsIDE1LCAxNywgMTksIDIzLCAyNywgMzEsXG4gIDM1LCA0MywgNTEsIDU5LCA2NywgODMsIDk5LCAxMTUsIDEzMSwgMTYzLCAxOTUsIDIyNywgMjU4LCAwLCAwXG5dO1xuXG52YXIgbGV4dCA9IFsgLyogTGVuZ3RoIGNvZGVzIDI1Ny4uMjg1IGV4dHJhICovXG4gIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTcsIDE3LCAxNywgMTcsIDE4LCAxOCwgMTgsIDE4LFxuICAxOSwgMTksIDE5LCAxOSwgMjAsIDIwLCAyMCwgMjAsIDIxLCAyMSwgMjEsIDIxLCAxNiwgNzIsIDc4XG5dO1xuXG52YXIgZGJhc2UgPSBbIC8qIERpc3RhbmNlIGNvZGVzIDAuLjI5IGJhc2UgKi9cbiAgMSwgMiwgMywgNCwgNSwgNywgOSwgMTMsIDE3LCAyNSwgMzMsIDQ5LCA2NSwgOTcsIDEyOSwgMTkzLFxuICAyNTcsIDM4NSwgNTEzLCA3NjksIDEwMjUsIDE1MzcsIDIwNDksIDMwNzMsIDQwOTcsIDYxNDUsXG4gIDgxOTMsIDEyMjg5LCAxNjM4NSwgMjQ1NzcsIDAsIDBcbl07XG5cbnZhciBkZXh0ID0gWyAvKiBEaXN0YW5jZSBjb2RlcyAwLi4yOSBleHRyYSAqL1xuICAxNiwgMTYsIDE2LCAxNiwgMTcsIDE3LCAxOCwgMTgsIDE5LCAxOSwgMjAsIDIwLCAyMSwgMjEsIDIyLCAyMixcbiAgMjMsIDIzLCAyNCwgMjQsIDI1LCAyNSwgMjYsIDI2LCAyNywgMjcsXG4gIDI4LCAyOCwgMjksIDI5LCA2NCwgNjRcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5mbGF0ZV90YWJsZSh0eXBlLCBsZW5zLCBsZW5zX2luZGV4LCBjb2RlcywgdGFibGUsIHRhYmxlX2luZGV4LCB3b3JrLCBvcHRzKVxue1xuICB2YXIgYml0cyA9IG9wdHMuYml0cztcbiAgICAgIC8vaGVyZSA9IG9wdHMuaGVyZTsgLyogdGFibGUgZW50cnkgZm9yIGR1cGxpY2F0aW9uICovXG5cbiAgdmFyIGxlbiA9IDA7ICAgICAgICAgICAgICAgLyogYSBjb2RlJ3MgbGVuZ3RoIGluIGJpdHMgKi9cbiAgdmFyIHN5bSA9IDA7ICAgICAgICAgICAgICAgLyogaW5kZXggb2YgY29kZSBzeW1ib2xzICovXG4gIHZhciBtaW4gPSAwLCBtYXggPSAwOyAgICAgICAgICAvKiBtaW5pbXVtIGFuZCBtYXhpbXVtIGNvZGUgbGVuZ3RocyAqL1xuICB2YXIgcm9vdCA9IDA7ICAgICAgICAgICAgICAvKiBudW1iZXIgb2YgaW5kZXggYml0cyBmb3Igcm9vdCB0YWJsZSAqL1xuICB2YXIgY3VyciA9IDA7ICAgICAgICAgICAgICAvKiBudW1iZXIgb2YgaW5kZXggYml0cyBmb3IgY3VycmVudCB0YWJsZSAqL1xuICB2YXIgZHJvcCA9IDA7ICAgICAgICAgICAgICAvKiBjb2RlIGJpdHMgdG8gZHJvcCBmb3Igc3ViLXRhYmxlICovXG4gIHZhciBsZWZ0ID0gMDsgICAgICAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIHByZWZpeCBjb2RlcyBhdmFpbGFibGUgKi9cbiAgdmFyIHVzZWQgPSAwOyAgICAgICAgICAgICAgLyogY29kZSBlbnRyaWVzIGluIHRhYmxlIHVzZWQgKi9cbiAgdmFyIGh1ZmYgPSAwOyAgICAgICAgICAgICAgLyogSHVmZm1hbiBjb2RlICovXG4gIHZhciBpbmNyOyAgICAgICAgICAgICAgLyogZm9yIGluY3JlbWVudGluZyBjb2RlLCBpbmRleCAqL1xuICB2YXIgZmlsbDsgICAgICAgICAgICAgIC8qIGluZGV4IGZvciByZXBsaWNhdGluZyBlbnRyaWVzICovXG4gIHZhciBsb3c7ICAgICAgICAgICAgICAgLyogbG93IGJpdHMgZm9yIGN1cnJlbnQgcm9vdCBlbnRyeSAqL1xuICB2YXIgbWFzazsgICAgICAgICAgICAgIC8qIG1hc2sgZm9yIGxvdyByb290IGJpdHMgKi9cbiAgdmFyIG5leHQ7ICAgICAgICAgICAgIC8qIG5leHQgYXZhaWxhYmxlIHNwYWNlIGluIHRhYmxlICovXG4gIHZhciBiYXNlID0gbnVsbDsgICAgIC8qIGJhc2UgdmFsdWUgdGFibGUgdG8gdXNlICovXG4gIHZhciBiYXNlX2luZGV4ID0gMDtcbi8vICB2YXIgc2hvZXh0cmE7ICAgIC8qIGV4dHJhIGJpdHMgdGFibGUgdG8gdXNlICovXG4gIHZhciBlbmQ7ICAgICAgICAgICAgICAgICAgICAvKiB1c2UgYmFzZSBhbmQgZXh0cmEgZm9yIHN5bWJvbCA+IGVuZCAqL1xuICB2YXIgY291bnQgPSBuZXcgdXRpbHMuQnVmMTYoTUFYQklUUyArIDEpOyAvL1tNQVhCSVRTKzFdOyAgICAvKiBudW1iZXIgb2YgY29kZXMgb2YgZWFjaCBsZW5ndGggKi9cbiAgdmFyIG9mZnMgPSBuZXcgdXRpbHMuQnVmMTYoTUFYQklUUyArIDEpOyAvL1tNQVhCSVRTKzFdOyAgICAgLyogb2Zmc2V0cyBpbiB0YWJsZSBmb3IgZWFjaCBsZW5ndGggKi9cbiAgdmFyIGV4dHJhID0gbnVsbDtcbiAgdmFyIGV4dHJhX2luZGV4ID0gMDtcblxuICB2YXIgaGVyZV9iaXRzLCBoZXJlX29wLCBoZXJlX3ZhbDtcblxuICAvKlxuICAgUHJvY2VzcyBhIHNldCBvZiBjb2RlIGxlbmd0aHMgdG8gY3JlYXRlIGEgY2Fub25pY2FsIEh1ZmZtYW4gY29kZS4gIFRoZVxuICAgY29kZSBsZW5ndGhzIGFyZSBsZW5zWzAuLmNvZGVzLTFdLiAgRWFjaCBsZW5ndGggY29ycmVzcG9uZHMgdG8gdGhlXG4gICBzeW1ib2xzIDAuLmNvZGVzLTEuICBUaGUgSHVmZm1hbiBjb2RlIGlzIGdlbmVyYXRlZCBieSBmaXJzdCBzb3J0aW5nIHRoZVxuICAgc3ltYm9scyBieSBsZW5ndGggZnJvbSBzaG9ydCB0byBsb25nLCBhbmQgcmV0YWluaW5nIHRoZSBzeW1ib2wgb3JkZXJcbiAgIGZvciBjb2RlcyB3aXRoIGVxdWFsIGxlbmd0aHMuICBUaGVuIHRoZSBjb2RlIHN0YXJ0cyB3aXRoIGFsbCB6ZXJvIGJpdHNcbiAgIGZvciB0aGUgZmlyc3QgY29kZSBvZiB0aGUgc2hvcnRlc3QgbGVuZ3RoLCBhbmQgdGhlIGNvZGVzIGFyZSBpbnRlZ2VyXG4gICBpbmNyZW1lbnRzIGZvciB0aGUgc2FtZSBsZW5ndGgsIGFuZCB6ZXJvcyBhcmUgYXBwZW5kZWQgYXMgdGhlIGxlbmd0aFxuICAgaW5jcmVhc2VzLiAgRm9yIHRoZSBkZWZsYXRlIGZvcm1hdCwgdGhlc2UgYml0cyBhcmUgc3RvcmVkIGJhY2t3YXJkc1xuICAgZnJvbSB0aGVpciBtb3JlIG5hdHVyYWwgaW50ZWdlciBpbmNyZW1lbnQgb3JkZXJpbmcsIGFuZCBzbyB3aGVuIHRoZVxuICAgZGVjb2RpbmcgdGFibGVzIGFyZSBidWlsdCBpbiB0aGUgbGFyZ2UgbG9vcCBiZWxvdywgdGhlIGludGVnZXIgY29kZXNcbiAgIGFyZSBpbmNyZW1lbnRlZCBiYWNrd2FyZHMuXG5cbiAgIFRoaXMgcm91dGluZSBhc3N1bWVzLCBidXQgZG9lcyBub3QgY2hlY2ssIHRoYXQgYWxsIG9mIHRoZSBlbnRyaWVzIGluXG4gICBsZW5zW10gYXJlIGluIHRoZSByYW5nZSAwLi5NQVhCSVRTLiAgVGhlIGNhbGxlciBtdXN0IGFzc3VyZSB0aGlzLlxuICAgMS4uTUFYQklUUyBpcyBpbnRlcnByZXRlZCBhcyB0aGF0IGNvZGUgbGVuZ3RoLiAgemVybyBtZWFucyB0aGF0IHRoYXRcbiAgIHN5bWJvbCBkb2VzIG5vdCBvY2N1ciBpbiB0aGlzIGNvZGUuXG5cbiAgIFRoZSBjb2RlcyBhcmUgc29ydGVkIGJ5IGNvbXB1dGluZyBhIGNvdW50IG9mIGNvZGVzIGZvciBlYWNoIGxlbmd0aCxcbiAgIGNyZWF0aW5nIGZyb20gdGhhdCBhIHRhYmxlIG9mIHN0YXJ0aW5nIGluZGljZXMgZm9yIGVhY2ggbGVuZ3RoIGluIHRoZVxuICAgc29ydGVkIHRhYmxlLCBhbmQgdGhlbiBlbnRlcmluZyB0aGUgc3ltYm9scyBpbiBvcmRlciBpbiB0aGUgc29ydGVkXG4gICB0YWJsZS4gIFRoZSBzb3J0ZWQgdGFibGUgaXMgd29ya1tdLCB3aXRoIHRoYXQgc3BhY2UgYmVpbmcgcHJvdmlkZWQgYnlcbiAgIHRoZSBjYWxsZXIuXG5cbiAgIFRoZSBsZW5ndGggY291bnRzIGFyZSB1c2VkIGZvciBvdGhlciBwdXJwb3NlcyBhcyB3ZWxsLCBpLmUuIGZpbmRpbmdcbiAgIHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIGxlbmd0aCBjb2RlcywgZGV0ZXJtaW5pbmcgaWYgdGhlcmUgYXJlIGFueVxuICAgY29kZXMgYXQgYWxsLCBjaGVja2luZyBmb3IgYSB2YWxpZCBzZXQgb2YgbGVuZ3RocywgYW5kIGxvb2tpbmcgYWhlYWRcbiAgIGF0IGxlbmd0aCBjb3VudHMgdG8gZGV0ZXJtaW5lIHN1Yi10YWJsZSBzaXplcyB3aGVuIGJ1aWxkaW5nIHRoZVxuICAgZGVjb2RpbmcgdGFibGVzLlxuICAgKi9cblxuICAvKiBhY2N1bXVsYXRlIGxlbmd0aHMgZm9yIGNvZGVzIChhc3N1bWVzIGxlbnNbXSBhbGwgaW4gMC4uTUFYQklUUykgKi9cbiAgZm9yIChsZW4gPSAwOyBsZW4gPD0gTUFYQklUUzsgbGVuKyspIHtcbiAgICBjb3VudFtsZW5dID0gMDtcbiAgfVxuICBmb3IgKHN5bSA9IDA7IHN5bSA8IGNvZGVzOyBzeW0rKykge1xuICAgIGNvdW50W2xlbnNbbGVuc19pbmRleCArIHN5bV1dKys7XG4gIH1cblxuICAvKiBib3VuZCBjb2RlIGxlbmd0aHMsIGZvcmNlIHJvb3QgdG8gYmUgd2l0aGluIGNvZGUgbGVuZ3RocyAqL1xuICByb290ID0gYml0cztcbiAgZm9yIChtYXggPSBNQVhCSVRTOyBtYXggPj0gMTsgbWF4LS0pIHtcbiAgICBpZiAoY291bnRbbWF4XSAhPT0gMCkgeyBicmVhazsgfVxuICB9XG4gIGlmIChyb290ID4gbWF4KSB7XG4gICAgcm9vdCA9IG1heDtcbiAgfVxuICBpZiAobWF4ID09PSAwKSB7ICAgICAgICAgICAgICAgICAgICAgLyogbm8gc3ltYm9scyB0byBjb2RlIGF0IGFsbCAqL1xuICAgIC8vdGFibGUub3Bbb3B0cy50YWJsZV9pbmRleF0gPSA2NDsgIC8vaGVyZS5vcCA9ICh2YXIgY2hhcik2NDsgICAgLyogaW52YWxpZCBjb2RlIG1hcmtlciAqL1xuICAgIC8vdGFibGUuYml0c1tvcHRzLnRhYmxlX2luZGV4XSA9IDE7ICAgLy9oZXJlLmJpdHMgPSAodmFyIGNoYXIpMTtcbiAgICAvL3RhYmxlLnZhbFtvcHRzLnRhYmxlX2luZGV4KytdID0gMDsgICAvL2hlcmUudmFsID0gKHZhciBzaG9ydCkwO1xuICAgIHRhYmxlW3RhYmxlX2luZGV4KytdID0gKDEgPDwgMjQpIHwgKDY0IDw8IDE2KSB8IDA7XG5cblxuICAgIC8vdGFibGUub3Bbb3B0cy50YWJsZV9pbmRleF0gPSA2NDtcbiAgICAvL3RhYmxlLmJpdHNbb3B0cy50YWJsZV9pbmRleF0gPSAxO1xuICAgIC8vdGFibGUudmFsW29wdHMudGFibGVfaW5kZXgrK10gPSAwO1xuICAgIHRhYmxlW3RhYmxlX2luZGV4KytdID0gKDEgPDwgMjQpIHwgKDY0IDw8IDE2KSB8IDA7XG5cbiAgICBvcHRzLmJpdHMgPSAxO1xuICAgIHJldHVybiAwOyAgICAgLyogbm8gc3ltYm9scywgYnV0IHdhaXQgZm9yIGRlY29kaW5nIHRvIHJlcG9ydCBlcnJvciAqL1xuICB9XG4gIGZvciAobWluID0gMTsgbWluIDwgbWF4OyBtaW4rKykge1xuICAgIGlmIChjb3VudFttaW5dICE9PSAwKSB7IGJyZWFrOyB9XG4gIH1cbiAgaWYgKHJvb3QgPCBtaW4pIHtcbiAgICByb290ID0gbWluO1xuICB9XG5cbiAgLyogY2hlY2sgZm9yIGFuIG92ZXItc3Vic2NyaWJlZCBvciBpbmNvbXBsZXRlIHNldCBvZiBsZW5ndGhzICovXG4gIGxlZnQgPSAxO1xuICBmb3IgKGxlbiA9IDE7IGxlbiA8PSBNQVhCSVRTOyBsZW4rKykge1xuICAgIGxlZnQgPDw9IDE7XG4gICAgbGVmdCAtPSBjb3VudFtsZW5dO1xuICAgIGlmIChsZWZ0IDwgMCkge1xuICAgICAgcmV0dXJuIC0xO1xuICAgIH0gICAgICAgIC8qIG92ZXItc3Vic2NyaWJlZCAqL1xuICB9XG4gIGlmIChsZWZ0ID4gMCAmJiAodHlwZSA9PT0gQ09ERVMgfHwgbWF4ICE9PSAxKSkge1xuICAgIHJldHVybiAtMTsgICAgICAgICAgICAgICAgICAgICAgLyogaW5jb21wbGV0ZSBzZXQgKi9cbiAgfVxuXG4gIC8qIGdlbmVyYXRlIG9mZnNldHMgaW50byBzeW1ib2wgdGFibGUgZm9yIGVhY2ggbGVuZ3RoIGZvciBzb3J0aW5nICovXG4gIG9mZnNbMV0gPSAwO1xuICBmb3IgKGxlbiA9IDE7IGxlbiA8IE1BWEJJVFM7IGxlbisrKSB7XG4gICAgb2Zmc1tsZW4gKyAxXSA9IG9mZnNbbGVuXSArIGNvdW50W2xlbl07XG4gIH1cblxuICAvKiBzb3J0IHN5bWJvbHMgYnkgbGVuZ3RoLCBieSBzeW1ib2wgb3JkZXIgd2l0aGluIGVhY2ggbGVuZ3RoICovXG4gIGZvciAoc3ltID0gMDsgc3ltIDwgY29kZXM7IHN5bSsrKSB7XG4gICAgaWYgKGxlbnNbbGVuc19pbmRleCArIHN5bV0gIT09IDApIHtcbiAgICAgIHdvcmtbb2Zmc1tsZW5zW2xlbnNfaW5kZXggKyBzeW1dXSsrXSA9IHN5bTtcbiAgICB9XG4gIH1cblxuICAvKlxuICAgQ3JlYXRlIGFuZCBmaWxsIGluIGRlY29kaW5nIHRhYmxlcy4gIEluIHRoaXMgbG9vcCwgdGhlIHRhYmxlIGJlaW5nXG4gICBmaWxsZWQgaXMgYXQgbmV4dCBhbmQgaGFzIGN1cnIgaW5kZXggYml0cy4gIFRoZSBjb2RlIGJlaW5nIHVzZWQgaXMgaHVmZlxuICAgd2l0aCBsZW5ndGggbGVuLiAgVGhhdCBjb2RlIGlzIGNvbnZlcnRlZCB0byBhbiBpbmRleCBieSBkcm9wcGluZyBkcm9wXG4gICBiaXRzIG9mZiBvZiB0aGUgYm90dG9tLiAgRm9yIGNvZGVzIHdoZXJlIGxlbiBpcyBsZXNzIHRoYW4gZHJvcCArIGN1cnIsXG4gICB0aG9zZSB0b3AgZHJvcCArIGN1cnIgLSBsZW4gYml0cyBhcmUgaW5jcmVtZW50ZWQgdGhyb3VnaCBhbGwgdmFsdWVzIHRvXG4gICBmaWxsIHRoZSB0YWJsZSB3aXRoIHJlcGxpY2F0ZWQgZW50cmllcy5cblxuICAgcm9vdCBpcyB0aGUgbnVtYmVyIG9mIGluZGV4IGJpdHMgZm9yIHRoZSByb290IHRhYmxlLiAgV2hlbiBsZW4gZXhjZWVkc1xuICAgcm9vdCwgc3ViLXRhYmxlcyBhcmUgY3JlYXRlZCBwb2ludGVkIHRvIGJ5IHRoZSByb290IGVudHJ5IHdpdGggYW4gaW5kZXhcbiAgIG9mIHRoZSBsb3cgcm9vdCBiaXRzIG9mIGh1ZmYuICBUaGlzIGlzIHNhdmVkIGluIGxvdyB0byBjaGVjayBmb3Igd2hlbiBhXG4gICBuZXcgc3ViLXRhYmxlIHNob3VsZCBiZSBzdGFydGVkLiAgZHJvcCBpcyB6ZXJvIHdoZW4gdGhlIHJvb3QgdGFibGUgaXNcbiAgIGJlaW5nIGZpbGxlZCwgYW5kIGRyb3AgaXMgcm9vdCB3aGVuIHN1Yi10YWJsZXMgYXJlIGJlaW5nIGZpbGxlZC5cblxuICAgV2hlbiBhIG5ldyBzdWItdGFibGUgaXMgbmVlZGVkLCBpdCBpcyBuZWNlc3NhcnkgdG8gbG9vayBhaGVhZCBpbiB0aGVcbiAgIGNvZGUgbGVuZ3RocyB0byBkZXRlcm1pbmUgd2hhdCBzaXplIHN1Yi10YWJsZSBpcyBuZWVkZWQuICBUaGUgbGVuZ3RoXG4gICBjb3VudHMgYXJlIHVzZWQgZm9yIHRoaXMsIGFuZCBzbyBjb3VudFtdIGlzIGRlY3JlbWVudGVkIGFzIGNvZGVzIGFyZVxuICAgZW50ZXJlZCBpbiB0aGUgdGFibGVzLlxuXG4gICB1c2VkIGtlZXBzIHRyYWNrIG9mIGhvdyBtYW55IHRhYmxlIGVudHJpZXMgaGF2ZSBiZWVuIGFsbG9jYXRlZCBmcm9tIHRoZVxuICAgcHJvdmlkZWQgKnRhYmxlIHNwYWNlLiAgSXQgaXMgY2hlY2tlZCBmb3IgTEVOUyBhbmQgRElTVCB0YWJsZXMgYWdhaW5zdFxuICAgdGhlIGNvbnN0YW50cyBFTk9VR0hfTEVOUyBhbmQgRU5PVUdIX0RJU1RTIHRvIGd1YXJkIGFnYWluc3QgY2hhbmdlcyBpblxuICAgdGhlIGluaXRpYWwgcm9vdCB0YWJsZSBzaXplIGNvbnN0YW50cy4gIFNlZSB0aGUgY29tbWVudHMgaW4gaW5mdHJlZXMuaFxuICAgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG5cbiAgIHN5bSBpbmNyZW1lbnRzIHRocm91Z2ggYWxsIHN5bWJvbHMsIGFuZCB0aGUgbG9vcCB0ZXJtaW5hdGVzIHdoZW5cbiAgIGFsbCBjb2RlcyBvZiBsZW5ndGggbWF4LCBpLmUuIGFsbCBjb2RlcywgaGF2ZSBiZWVuIHByb2Nlc3NlZC4gIFRoaXNcbiAgIHJvdXRpbmUgcGVybWl0cyBpbmNvbXBsZXRlIGNvZGVzLCBzbyBhbm90aGVyIGxvb3AgYWZ0ZXIgdGhpcyBvbmUgZmlsbHNcbiAgIGluIHRoZSByZXN0IG9mIHRoZSBkZWNvZGluZyB0YWJsZXMgd2l0aCBpbnZhbGlkIGNvZGUgbWFya2Vycy5cbiAgICovXG5cbiAgLyogc2V0IHVwIGZvciBjb2RlIHR5cGUgKi9cbiAgLy8gcG9vciBtYW4gb3B0aW1pemF0aW9uIC0gdXNlIGlmLWVsc2UgaW5zdGVhZCBvZiBzd2l0Y2gsXG4gIC8vIHRvIGF2b2lkIGRlb3B0cyBpbiBvbGQgdjhcbiAgaWYgKHR5cGUgPT09IENPREVTKSB7XG4gICAgYmFzZSA9IGV4dHJhID0gd29yazsgICAgLyogZHVtbXkgdmFsdWUtLW5vdCB1c2VkICovXG4gICAgZW5kID0gMTk7XG5cbiAgfSBlbHNlIGlmICh0eXBlID09PSBMRU5TKSB7XG4gICAgYmFzZSA9IGxiYXNlO1xuICAgIGJhc2VfaW5kZXggLT0gMjU3O1xuICAgIGV4dHJhID0gbGV4dDtcbiAgICBleHRyYV9pbmRleCAtPSAyNTc7XG4gICAgZW5kID0gMjU2O1xuXG4gIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAvKiBESVNUUyAqL1xuICAgIGJhc2UgPSBkYmFzZTtcbiAgICBleHRyYSA9IGRleHQ7XG4gICAgZW5kID0gLTE7XG4gIH1cblxuICAvKiBpbml0aWFsaXplIG9wdHMgZm9yIGxvb3AgKi9cbiAgaHVmZiA9IDA7ICAgICAgICAgICAgICAgICAgIC8qIHN0YXJ0aW5nIGNvZGUgKi9cbiAgc3ltID0gMDsgICAgICAgICAgICAgICAgICAgIC8qIHN0YXJ0aW5nIGNvZGUgc3ltYm9sICovXG4gIGxlbiA9IG1pbjsgICAgICAgICAgICAgICAgICAvKiBzdGFydGluZyBjb2RlIGxlbmd0aCAqL1xuICBuZXh0ID0gdGFibGVfaW5kZXg7ICAgICAgICAgICAgICAvKiBjdXJyZW50IHRhYmxlIHRvIGZpbGwgaW4gKi9cbiAgY3VyciA9IHJvb3Q7ICAgICAgICAgICAgICAgIC8qIGN1cnJlbnQgdGFibGUgaW5kZXggYml0cyAqL1xuICBkcm9wID0gMDsgICAgICAgICAgICAgICAgICAgLyogY3VycmVudCBiaXRzIHRvIGRyb3AgZnJvbSBjb2RlIGZvciBpbmRleCAqL1xuICBsb3cgPSAtMTsgICAgICAgICAgICAgICAgICAgLyogdHJpZ2dlciBuZXcgc3ViLXRhYmxlIHdoZW4gbGVuID4gcm9vdCAqL1xuICB1c2VkID0gMSA8PCByb290OyAgICAgICAgICAvKiB1c2Ugcm9vdCB0YWJsZSBlbnRyaWVzICovXG4gIG1hc2sgPSB1c2VkIC0gMTsgICAgICAgICAgICAvKiBtYXNrIGZvciBjb21wYXJpbmcgbG93ICovXG5cbiAgLyogY2hlY2sgYXZhaWxhYmxlIHRhYmxlIHNwYWNlICovXG4gIGlmICgodHlwZSA9PT0gTEVOUyAmJiB1c2VkID4gRU5PVUdIX0xFTlMpIHx8XG4gICAgKHR5cGUgPT09IERJU1RTICYmIHVzZWQgPiBFTk9VR0hfRElTVFMpKSB7XG4gICAgcmV0dXJuIDE7XG4gIH1cblxuICAvKiBwcm9jZXNzIGFsbCBjb2RlcyBhbmQgbWFrZSB0YWJsZSBlbnRyaWVzICovXG4gIGZvciAoOzspIHtcbiAgICAvKiBjcmVhdGUgdGFibGUgZW50cnkgKi9cbiAgICBoZXJlX2JpdHMgPSBsZW4gLSBkcm9wO1xuICAgIGlmICh3b3JrW3N5bV0gPCBlbmQpIHtcbiAgICAgIGhlcmVfb3AgPSAwO1xuICAgICAgaGVyZV92YWwgPSB3b3JrW3N5bV07XG4gICAgfVxuICAgIGVsc2UgaWYgKHdvcmtbc3ltXSA+IGVuZCkge1xuICAgICAgaGVyZV9vcCA9IGV4dHJhW2V4dHJhX2luZGV4ICsgd29ya1tzeW1dXTtcbiAgICAgIGhlcmVfdmFsID0gYmFzZVtiYXNlX2luZGV4ICsgd29ya1tzeW1dXTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBoZXJlX29wID0gMzIgKyA2NDsgICAgICAgICAvKiBlbmQgb2YgYmxvY2sgKi9cbiAgICAgIGhlcmVfdmFsID0gMDtcbiAgICB9XG5cbiAgICAvKiByZXBsaWNhdGUgZm9yIHRob3NlIGluZGljZXMgd2l0aCBsb3cgbGVuIGJpdHMgZXF1YWwgdG8gaHVmZiAqL1xuICAgIGluY3IgPSAxIDw8IChsZW4gLSBkcm9wKTtcbiAgICBmaWxsID0gMSA8PCBjdXJyO1xuICAgIG1pbiA9IGZpbGw7ICAgICAgICAgICAgICAgICAvKiBzYXZlIG9mZnNldCB0byBuZXh0IHRhYmxlICovXG4gICAgZG8ge1xuICAgICAgZmlsbCAtPSBpbmNyO1xuICAgICAgdGFibGVbbmV4dCArIChodWZmID4+IGRyb3ApICsgZmlsbF0gPSAoaGVyZV9iaXRzIDw8IDI0KSB8IChoZXJlX29wIDw8IDE2KSB8IGhlcmVfdmFsIHwwO1xuICAgIH0gd2hpbGUgKGZpbGwgIT09IDApO1xuXG4gICAgLyogYmFja3dhcmRzIGluY3JlbWVudCB0aGUgbGVuLWJpdCBjb2RlIGh1ZmYgKi9cbiAgICBpbmNyID0gMSA8PCAobGVuIC0gMSk7XG4gICAgd2hpbGUgKGh1ZmYgJiBpbmNyKSB7XG4gICAgICBpbmNyID4+PSAxO1xuICAgIH1cbiAgICBpZiAoaW5jciAhPT0gMCkge1xuICAgICAgaHVmZiAmPSBpbmNyIC0gMTtcbiAgICAgIGh1ZmYgKz0gaW5jcjtcbiAgICB9IGVsc2Uge1xuICAgICAgaHVmZiA9IDA7XG4gICAgfVxuXG4gICAgLyogZ28gdG8gbmV4dCBzeW1ib2wsIHVwZGF0ZSBjb3VudCwgbGVuICovXG4gICAgc3ltKys7XG4gICAgaWYgKC0tY291bnRbbGVuXSA9PT0gMCkge1xuICAgICAgaWYgKGxlbiA9PT0gbWF4KSB7IGJyZWFrOyB9XG4gICAgICBsZW4gPSBsZW5zW2xlbnNfaW5kZXggKyB3b3JrW3N5bV1dO1xuICAgIH1cblxuICAgIC8qIGNyZWF0ZSBuZXcgc3ViLXRhYmxlIGlmIG5lZWRlZCAqL1xuICAgIGlmIChsZW4gPiByb290ICYmIChodWZmICYgbWFzaykgIT09IGxvdykge1xuICAgICAgLyogaWYgZmlyc3QgdGltZSwgdHJhbnNpdGlvbiB0byBzdWItdGFibGVzICovXG4gICAgICBpZiAoZHJvcCA9PT0gMCkge1xuICAgICAgICBkcm9wID0gcm9vdDtcbiAgICAgIH1cblxuICAgICAgLyogaW5jcmVtZW50IHBhc3QgbGFzdCB0YWJsZSAqL1xuICAgICAgbmV4dCArPSBtaW47ICAgICAgICAgICAgLyogaGVyZSBtaW4gaXMgMSA8PCBjdXJyICovXG5cbiAgICAgIC8qIGRldGVybWluZSBsZW5ndGggb2YgbmV4dCB0YWJsZSAqL1xuICAgICAgY3VyciA9IGxlbiAtIGRyb3A7XG4gICAgICBsZWZ0ID0gMSA8PCBjdXJyO1xuICAgICAgd2hpbGUgKGN1cnIgKyBkcm9wIDwgbWF4KSB7XG4gICAgICAgIGxlZnQgLT0gY291bnRbY3VyciArIGRyb3BdO1xuICAgICAgICBpZiAobGVmdCA8PSAwKSB7IGJyZWFrOyB9XG4gICAgICAgIGN1cnIrKztcbiAgICAgICAgbGVmdCA8PD0gMTtcbiAgICAgIH1cblxuICAgICAgLyogY2hlY2sgZm9yIGVub3VnaCBzcGFjZSAqL1xuICAgICAgdXNlZCArPSAxIDw8IGN1cnI7XG4gICAgICBpZiAoKHR5cGUgPT09IExFTlMgJiYgdXNlZCA+IEVOT1VHSF9MRU5TKSB8fFxuICAgICAgICAodHlwZSA9PT0gRElTVFMgJiYgdXNlZCA+IEVOT1VHSF9ESVNUUykpIHtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgICB9XG5cbiAgICAgIC8qIHBvaW50IGVudHJ5IGluIHJvb3QgdGFibGUgdG8gc3ViLXRhYmxlICovXG4gICAgICBsb3cgPSBodWZmICYgbWFzaztcbiAgICAgIC8qdGFibGUub3BbbG93XSA9IGN1cnI7XG4gICAgICB0YWJsZS5iaXRzW2xvd10gPSByb290O1xuICAgICAgdGFibGUudmFsW2xvd10gPSBuZXh0IC0gb3B0cy50YWJsZV9pbmRleDsqL1xuICAgICAgdGFibGVbbG93XSA9IChyb290IDw8IDI0KSB8IChjdXJyIDw8IDE2KSB8IChuZXh0IC0gdGFibGVfaW5kZXgpIHwwO1xuICAgIH1cbiAgfVxuXG4gIC8qIGZpbGwgaW4gcmVtYWluaW5nIHRhYmxlIGVudHJ5IGlmIGNvZGUgaXMgaW5jb21wbGV0ZSAoZ3VhcmFudGVlZCB0byBoYXZlXG4gICBhdCBtb3N0IG9uZSByZW1haW5pbmcgZW50cnksIHNpbmNlIGlmIHRoZSBjb2RlIGlzIGluY29tcGxldGUsIHRoZVxuICAgbWF4aW11bSBjb2RlIGxlbmd0aCB0aGF0IHdhcyBhbGxvd2VkIHRvIGdldCB0aGlzIGZhciBpcyBvbmUgYml0KSAqL1xuICBpZiAoaHVmZiAhPT0gMCkge1xuICAgIC8vdGFibGUub3BbbmV4dCArIGh1ZmZdID0gNjQ7ICAgICAgICAgICAgLyogaW52YWxpZCBjb2RlIG1hcmtlciAqL1xuICAgIC8vdGFibGUuYml0c1tuZXh0ICsgaHVmZl0gPSBsZW4gLSBkcm9wO1xuICAgIC8vdGFibGUudmFsW25leHQgKyBodWZmXSA9IDA7XG4gICAgdGFibGVbbmV4dCArIGh1ZmZdID0gKChsZW4gLSBkcm9wKSA8PCAyNCkgfCAoNjQgPDwgMTYpIHwwO1xuICB9XG5cbiAgLyogc2V0IHJldHVybiBwYXJhbWV0ZXJzICovXG4gIC8vb3B0cy50YWJsZV9pbmRleCArPSB1c2VkO1xuICBvcHRzLmJpdHMgPSByb290O1xuICByZXR1cm4gMDtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbi8vIChDKSAxOTk1LTIwMTMgSmVhbi1sb3VwIEdhaWxseSBhbmQgTWFyayBBZGxlclxuLy8gKEMpIDIwMTQtMjAxNyBWaXRhbHkgUHV6cmluIGFuZCBBbmRyZXkgVHVwaXRzaW5cbi8vXG4vLyBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZFxuLy8gd2FycmFudHkuIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzXG4vLyBhcmlzaW5nIGZyb20gdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byBhbnlvbmUgdG8gdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLFxuLy8gaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdFxuLy8gZnJlZWx5LCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOlxuLy9cbi8vIDEuIFRoZSBvcmlnaW4gb2YgdGhpcyBzb2Z0d2FyZSBtdXN0IG5vdCBiZSBtaXNyZXByZXNlbnRlZDsgeW91IG11c3Qgbm90XG4vLyAgIGNsYWltIHRoYXQgeW91IHdyb3RlIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4gSWYgeW91IHVzZSB0aGlzIHNvZnR3YXJlXG4vLyAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZVxuLy8gICBhcHByZWNpYXRlZCBidXQgaXMgbm90IHJlcXVpcmVkLlxuLy8gMi4gQWx0ZXJlZCBzb3VyY2UgdmVyc2lvbnMgbXVzdCBiZSBwbGFpbmx5IG1hcmtlZCBhcyBzdWNoLCBhbmQgbXVzdCBub3QgYmVcbi8vICAgbWlzcmVwcmVzZW50ZWQgYXMgYmVpbmcgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLlxuLy8gMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIDI6ICAgICAgJ25lZWQgZGljdGlvbmFyeScsICAgICAvKiBaX05FRURfRElDVCAgICAgICAyICAqL1xuICAxOiAgICAgICdzdHJlYW0gZW5kJywgICAgICAgICAgLyogWl9TVFJFQU1fRU5EICAgICAgMSAgKi9cbiAgMDogICAgICAnJywgICAgICAgICAgICAgICAgICAgIC8qIFpfT0sgICAgICAgICAgICAgIDAgICovXG4gICctMSc6ICAgJ2ZpbGUgZXJyb3InLCAgICAgICAgICAvKiBaX0VSUk5PICAgICAgICAgKC0xKSAqL1xuICAnLTInOiAgICdzdHJlYW0gZXJyb3InLCAgICAgICAgLyogWl9TVFJFQU1fRVJST1IgICgtMikgKi9cbiAgJy0zJzogICAnZGF0YSBlcnJvcicsICAgICAgICAgIC8qIFpfREFUQV9FUlJPUiAgICAoLTMpICovXG4gICctNCc6ICAgJ2luc3VmZmljaWVudCBtZW1vcnknLCAvKiBaX01FTV9FUlJPUiAgICAgKC00KSAqL1xuICAnLTUnOiAgICdidWZmZXIgZXJyb3InLCAgICAgICAgLyogWl9CVUZfRVJST1IgICAgICgtNSkgKi9cbiAgJy02JzogICAnaW5jb21wYXRpYmxlIHZlcnNpb24nIC8qIFpfVkVSU0lPTl9FUlJPUiAoLTYpICovXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vLyAoQykgMTk5NS0yMDEzIEplYW4tbG91cCBHYWlsbHkgYW5kIE1hcmsgQWRsZXJcbi8vIChDKSAyMDE0LTIwMTcgVml0YWx5IFB1enJpbiBhbmQgQW5kcmV5IFR1cGl0c2luXG4vL1xuLy8gVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWRcbi8vIHdhcnJhbnR5LiBJbiBubyBldmVudCB3aWxsIHRoZSBhdXRob3JzIGJlIGhlbGQgbGlhYmxlIGZvciBhbnkgZGFtYWdlc1xuLy8gYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGdyYW50ZWQgdG8gYW55b25lIHRvIHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZSxcbi8vIGluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXRcbi8vIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczpcbi8vXG4vLyAxLiBUaGUgb3JpZ2luIG9mIHRoaXMgc29mdHdhcmUgbXVzdCBub3QgYmUgbWlzcmVwcmVzZW50ZWQ7IHlvdSBtdXN0IG5vdFxuLy8gICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZVxuLy8gICBpbiBhIHByb2R1Y3QsIGFuIGFja25vd2xlZGdtZW50IGluIHRoZSBwcm9kdWN0IGRvY3VtZW50YXRpb24gd291bGQgYmVcbi8vICAgYXBwcmVjaWF0ZWQgYnV0IGlzIG5vdCByZXF1aXJlZC5cbi8vIDIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlXG4vLyAgIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS5cbi8vIDMuIFRoaXMgbm90aWNlIG1heSBub3QgYmUgcmVtb3ZlZCBvciBhbHRlcmVkIGZyb20gYW55IHNvdXJjZSBkaXN0cmlidXRpb24uXG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzL2NvbW1vbicpO1xuXG4vKiBQdWJsaWMgY29uc3RhbnRzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qL1xuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cblxuXG4vL3ZhciBaX0ZJTFRFUkVEICAgICAgICAgID0gMTtcbi8vdmFyIFpfSFVGRk1BTl9PTkxZICAgICAgPSAyO1xuLy92YXIgWl9STEUgICAgICAgICAgICAgICA9IDM7XG52YXIgWl9GSVhFRCAgICAgICAgICAgICAgID0gNDtcbi8vdmFyIFpfREVGQVVMVF9TVFJBVEVHWSAgPSAwO1xuXG4vKiBQb3NzaWJsZSB2YWx1ZXMgb2YgdGhlIGRhdGFfdHlwZSBmaWVsZCAodGhvdWdoIHNlZSBpbmZsYXRlKCkpICovXG52YXIgWl9CSU5BUlkgICAgICAgICAgICAgID0gMDtcbnZhciBaX1RFWFQgICAgICAgICAgICAgICAgPSAxO1xuLy92YXIgWl9BU0NJSSAgICAgICAgICAgICA9IDE7IC8vID0gWl9URVhUXG52YXIgWl9VTktOT1dOICAgICAgICAgICAgID0gMjtcblxuLyo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki9cblxuXG5mdW5jdGlvbiB6ZXJvKGJ1ZikgeyB2YXIgbGVuID0gYnVmLmxlbmd0aDsgd2hpbGUgKC0tbGVuID49IDApIHsgYnVmW2xlbl0gPSAwOyB9IH1cblxuLy8gRnJvbSB6dXRpbC5oXG5cbnZhciBTVE9SRURfQkxPQ0sgPSAwO1xudmFyIFNUQVRJQ19UUkVFUyA9IDE7XG52YXIgRFlOX1RSRUVTICAgID0gMjtcbi8qIFRoZSB0aHJlZSBraW5kcyBvZiBibG9jayB0eXBlICovXG5cbnZhciBNSU5fTUFUQ0ggICAgPSAzO1xudmFyIE1BWF9NQVRDSCAgICA9IDI1ODtcbi8qIFRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIG1hdGNoIGxlbmd0aHMgKi9cblxuLy8gRnJvbSBkZWZsYXRlLmhcbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogSW50ZXJuYWwgY29tcHJlc3Npb24gc3RhdGUuXG4gKi9cblxudmFyIExFTkdUSF9DT0RFUyAgPSAyOTtcbi8qIG51bWJlciBvZiBsZW5ndGggY29kZXMsIG5vdCBjb3VudGluZyB0aGUgc3BlY2lhbCBFTkRfQkxPQ0sgY29kZSAqL1xuXG52YXIgTElURVJBTFMgICAgICA9IDI1Njtcbi8qIG51bWJlciBvZiBsaXRlcmFsIGJ5dGVzIDAuLjI1NSAqL1xuXG52YXIgTF9DT0RFUyAgICAgICA9IExJVEVSQUxTICsgMSArIExFTkdUSF9DT0RFUztcbi8qIG51bWJlciBvZiBMaXRlcmFsIG9yIExlbmd0aCBjb2RlcywgaW5jbHVkaW5nIHRoZSBFTkRfQkxPQ0sgY29kZSAqL1xuXG52YXIgRF9DT0RFUyAgICAgICA9IDMwO1xuLyogbnVtYmVyIG9mIGRpc3RhbmNlIGNvZGVzICovXG5cbnZhciBCTF9DT0RFUyAgICAgID0gMTk7XG4vKiBudW1iZXIgb2YgY29kZXMgdXNlZCB0byB0cmFuc2ZlciB0aGUgYml0IGxlbmd0aHMgKi9cblxudmFyIEhFQVBfU0laRSAgICAgPSAyICogTF9DT0RFUyArIDE7XG4vKiBtYXhpbXVtIGhlYXAgc2l6ZSAqL1xuXG52YXIgTUFYX0JJVFMgICAgICA9IDE1O1xuLyogQWxsIGNvZGVzIG11c3Qgbm90IGV4Y2VlZCBNQVhfQklUUyBiaXRzICovXG5cbnZhciBCdWZfc2l6ZSAgICAgID0gMTY7XG4vKiBzaXplIG9mIGJpdCBidWZmZXIgaW4gYmlfYnVmICovXG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb25zdGFudHNcbiAqL1xuXG52YXIgTUFYX0JMX0JJVFMgPSA3O1xuLyogQml0IGxlbmd0aCBjb2RlcyBtdXN0IG5vdCBleGNlZWQgTUFYX0JMX0JJVFMgYml0cyAqL1xuXG52YXIgRU5EX0JMT0NLICAgPSAyNTY7XG4vKiBlbmQgb2YgYmxvY2sgbGl0ZXJhbCBjb2RlICovXG5cbnZhciBSRVBfM182ICAgICA9IDE2O1xuLyogcmVwZWF0IHByZXZpb3VzIGJpdCBsZW5ndGggMy02IHRpbWVzICgyIGJpdHMgb2YgcmVwZWF0IGNvdW50KSAqL1xuXG52YXIgUkVQWl8zXzEwICAgPSAxNztcbi8qIHJlcGVhdCBhIHplcm8gbGVuZ3RoIDMtMTAgdGltZXMgICgzIGJpdHMgb2YgcmVwZWF0IGNvdW50KSAqL1xuXG52YXIgUkVQWl8xMV8xMzggPSAxODtcbi8qIHJlcGVhdCBhIHplcm8gbGVuZ3RoIDExLTEzOCB0aW1lcyAgKDcgYml0cyBvZiByZXBlYXQgY291bnQpICovXG5cbi8qIGVzbGludC1kaXNhYmxlIGNvbW1hLXNwYWNpbmcsYXJyYXktYnJhY2tldC1zcGFjaW5nICovXG52YXIgZXh0cmFfbGJpdHMgPSAgIC8qIGV4dHJhIGJpdHMgZm9yIGVhY2ggbGVuZ3RoIGNvZGUgKi9cbiAgWzAsMCwwLDAsMCwwLDAsMCwxLDEsMSwxLDIsMiwyLDIsMywzLDMsMyw0LDQsNCw0LDUsNSw1LDUsMF07XG5cbnZhciBleHRyYV9kYml0cyA9ICAgLyogZXh0cmEgYml0cyBmb3IgZWFjaCBkaXN0YW5jZSBjb2RlICovXG4gIFswLDAsMCwwLDEsMSwyLDIsMywzLDQsNCw1LDUsNiw2LDcsNyw4LDgsOSw5LDEwLDEwLDExLDExLDEyLDEyLDEzLDEzXTtcblxudmFyIGV4dHJhX2JsYml0cyA9ICAvKiBleHRyYSBiaXRzIGZvciBlYWNoIGJpdCBsZW5ndGggY29kZSAqL1xuICBbMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwyLDMsN107XG5cbnZhciBibF9vcmRlciA9XG4gIFsxNiwxNywxOCwwLDgsNyw5LDYsMTAsNSwxMSw0LDEyLDMsMTMsMiwxNCwxLDE1XTtcbi8qIGVzbGludC1lbmFibGUgY29tbWEtc3BhY2luZyxhcnJheS1icmFja2V0LXNwYWNpbmcgKi9cblxuLyogVGhlIGxlbmd0aHMgb2YgdGhlIGJpdCBsZW5ndGggY29kZXMgYXJlIHNlbnQgaW4gb3JkZXIgb2YgZGVjcmVhc2luZ1xuICogcHJvYmFiaWxpdHksIHRvIGF2b2lkIHRyYW5zbWl0dGluZyB0aGUgbGVuZ3RocyBmb3IgdW51c2VkIGJpdCBsZW5ndGggY29kZXMuXG4gKi9cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBMb2NhbCBkYXRhLiBUaGVzZSBhcmUgaW5pdGlhbGl6ZWQgb25seSBvbmNlLlxuICovXG5cbi8vIFdlIHByZS1maWxsIGFycmF5cyB3aXRoIDAgdG8gYXZvaWQgdW5pbml0aWFsaXplZCBnYXBzXG5cbnZhciBESVNUX0NPREVfTEVOID0gNTEyOyAvKiBzZWUgZGVmaW5pdGlvbiBvZiBhcnJheSBkaXN0X2NvZGUgYmVsb3cgKi9cblxuLy8gISEhISBVc2UgZmxhdCBhcnJheSBpbnN0ZWFkIG9mIHN0cnVjdHVyZSwgRnJlcSA9IGkqMiwgTGVuID0gaSoyKzFcbnZhciBzdGF0aWNfbHRyZWUgID0gbmV3IEFycmF5KChMX0NPREVTICsgMikgKiAyKTtcbnplcm8oc3RhdGljX2x0cmVlKTtcbi8qIFRoZSBzdGF0aWMgbGl0ZXJhbCB0cmVlLiBTaW5jZSB0aGUgYml0IGxlbmd0aHMgYXJlIGltcG9zZWQsIHRoZXJlIGlzIG5vXG4gKiBuZWVkIGZvciB0aGUgTF9DT0RFUyBleHRyYSBjb2RlcyB1c2VkIGR1cmluZyBoZWFwIGNvbnN0cnVjdGlvbi4gSG93ZXZlclxuICogVGhlIGNvZGVzIDI4NiBhbmQgMjg3IGFyZSBuZWVkZWQgdG8gYnVpbGQgYSBjYW5vbmljYWwgdHJlZSAoc2VlIF90cl9pbml0XG4gKiBiZWxvdykuXG4gKi9cblxudmFyIHN0YXRpY19kdHJlZSAgPSBuZXcgQXJyYXkoRF9DT0RFUyAqIDIpO1xuemVybyhzdGF0aWNfZHRyZWUpO1xuLyogVGhlIHN0YXRpYyBkaXN0YW5jZSB0cmVlLiAoQWN0dWFsbHkgYSB0cml2aWFsIHRyZWUgc2luY2UgYWxsIGNvZGVzIHVzZVxuICogNSBiaXRzLilcbiAqL1xuXG52YXIgX2Rpc3RfY29kZSAgICA9IG5ldyBBcnJheShESVNUX0NPREVfTEVOKTtcbnplcm8oX2Rpc3RfY29kZSk7XG4vKiBEaXN0YW5jZSBjb2Rlcy4gVGhlIGZpcnN0IDI1NiB2YWx1ZXMgY29ycmVzcG9uZCB0byB0aGUgZGlzdGFuY2VzXG4gKiAzIC4uIDI1OCwgdGhlIGxhc3QgMjU2IHZhbHVlcyBjb3JyZXNwb25kIHRvIHRoZSB0b3AgOCBiaXRzIG9mXG4gKiB0aGUgMTUgYml0IGRpc3RhbmNlcy5cbiAqL1xuXG52YXIgX2xlbmd0aF9jb2RlICA9IG5ldyBBcnJheShNQVhfTUFUQ0ggLSBNSU5fTUFUQ0ggKyAxKTtcbnplcm8oX2xlbmd0aF9jb2RlKTtcbi8qIGxlbmd0aCBjb2RlIGZvciBlYWNoIG5vcm1hbGl6ZWQgbWF0Y2ggbGVuZ3RoICgwID09IE1JTl9NQVRDSCkgKi9cblxudmFyIGJhc2VfbGVuZ3RoICAgPSBuZXcgQXJyYXkoTEVOR1RIX0NPREVTKTtcbnplcm8oYmFzZV9sZW5ndGgpO1xuLyogRmlyc3Qgbm9ybWFsaXplZCBsZW5ndGggZm9yIGVhY2ggY29kZSAoMCA9IE1JTl9NQVRDSCkgKi9cblxudmFyIGJhc2VfZGlzdCAgICAgPSBuZXcgQXJyYXkoRF9DT0RFUyk7XG56ZXJvKGJhc2VfZGlzdCk7XG4vKiBGaXJzdCBub3JtYWxpemVkIGRpc3RhbmNlIGZvciBlYWNoIGNvZGUgKDAgPSBkaXN0YW5jZSBvZiAxKSAqL1xuXG5cbmZ1bmN0aW9uIFN0YXRpY1RyZWVEZXNjKHN0YXRpY190cmVlLCBleHRyYV9iaXRzLCBleHRyYV9iYXNlLCBlbGVtcywgbWF4X2xlbmd0aCkge1xuXG4gIHRoaXMuc3RhdGljX3RyZWUgID0gc3RhdGljX3RyZWU7ICAvKiBzdGF0aWMgdHJlZSBvciBOVUxMICovXG4gIHRoaXMuZXh0cmFfYml0cyAgID0gZXh0cmFfYml0czsgICAvKiBleHRyYSBiaXRzIGZvciBlYWNoIGNvZGUgb3IgTlVMTCAqL1xuICB0aGlzLmV4dHJhX2Jhc2UgICA9IGV4dHJhX2Jhc2U7ICAgLyogYmFzZSBpbmRleCBmb3IgZXh0cmFfYml0cyAqL1xuICB0aGlzLmVsZW1zICAgICAgICA9IGVsZW1zOyAgICAgICAgLyogbWF4IG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgdHJlZSAqL1xuICB0aGlzLm1heF9sZW5ndGggICA9IG1heF9sZW5ndGg7ICAgLyogbWF4IGJpdCBsZW5ndGggZm9yIHRoZSBjb2RlcyAqL1xuXG4gIC8vIHNob3cgaWYgYHN0YXRpY190cmVlYCBoYXMgZGF0YSBvciBkdW1teSAtIG5lZWRlZCBmb3IgbW9ub21vcnBoaWMgb2JqZWN0c1xuICB0aGlzLmhhc19zdHJlZSAgICA9IHN0YXRpY190cmVlICYmIHN0YXRpY190cmVlLmxlbmd0aDtcbn1cblxuXG52YXIgc3RhdGljX2xfZGVzYztcbnZhciBzdGF0aWNfZF9kZXNjO1xudmFyIHN0YXRpY19ibF9kZXNjO1xuXG5cbmZ1bmN0aW9uIFRyZWVEZXNjKGR5bl90cmVlLCBzdGF0X2Rlc2MpIHtcbiAgdGhpcy5keW5fdHJlZSA9IGR5bl90cmVlOyAgICAgLyogdGhlIGR5bmFtaWMgdHJlZSAqL1xuICB0aGlzLm1heF9jb2RlID0gMDsgICAgICAgICAgICAvKiBsYXJnZXN0IGNvZGUgd2l0aCBub24gemVybyBmcmVxdWVuY3kgKi9cbiAgdGhpcy5zdGF0X2Rlc2MgPSBzdGF0X2Rlc2M7ICAgLyogdGhlIGNvcnJlc3BvbmRpbmcgc3RhdGljIHRyZWUgKi9cbn1cblxuXG5cbmZ1bmN0aW9uIGRfY29kZShkaXN0KSB7XG4gIHJldHVybiBkaXN0IDwgMjU2ID8gX2Rpc3RfY29kZVtkaXN0XSA6IF9kaXN0X2NvZGVbMjU2ICsgKGRpc3QgPj4+IDcpXTtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIE91dHB1dCBhIHNob3J0IExTQiBmaXJzdCBvbiB0aGUgc3RyZWFtLlxuICogSU4gYXNzZXJ0aW9uOiB0aGVyZSBpcyBlbm91Z2ggcm9vbSBpbiBwZW5kaW5nQnVmLlxuICovXG5mdW5jdGlvbiBwdXRfc2hvcnQocywgdykge1xuLy8gICAgcHV0X2J5dGUocywgKHVjaCkoKHcpICYgMHhmZikpO1xuLy8gICAgcHV0X2J5dGUocywgKHVjaCkoKHVzaCkodykgPj4gOCkpO1xuICBzLnBlbmRpbmdfYnVmW3MucGVuZGluZysrXSA9ICh3KSAmIDB4ZmY7XG4gIHMucGVuZGluZ19idWZbcy5wZW5kaW5nKytdID0gKHcgPj4+IDgpICYgMHhmZjtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFNlbmQgYSB2YWx1ZSBvbiBhIGdpdmVuIG51bWJlciBvZiBiaXRzLlxuICogSU4gYXNzZXJ0aW9uOiBsZW5ndGggPD0gMTYgYW5kIHZhbHVlIGZpdHMgaW4gbGVuZ3RoIGJpdHMuXG4gKi9cbmZ1bmN0aW9uIHNlbmRfYml0cyhzLCB2YWx1ZSwgbGVuZ3RoKSB7XG4gIGlmIChzLmJpX3ZhbGlkID4gKEJ1Zl9zaXplIC0gbGVuZ3RoKSkge1xuICAgIHMuYmlfYnVmIHw9ICh2YWx1ZSA8PCBzLmJpX3ZhbGlkKSAmIDB4ZmZmZjtcbiAgICBwdXRfc2hvcnQocywgcy5iaV9idWYpO1xuICAgIHMuYmlfYnVmID0gdmFsdWUgPj4gKEJ1Zl9zaXplIC0gcy5iaV92YWxpZCk7XG4gICAgcy5iaV92YWxpZCArPSBsZW5ndGggLSBCdWZfc2l6ZTtcbiAgfSBlbHNlIHtcbiAgICBzLmJpX2J1ZiB8PSAodmFsdWUgPDwgcy5iaV92YWxpZCkgJiAweGZmZmY7XG4gICAgcy5iaV92YWxpZCArPSBsZW5ndGg7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBzZW5kX2NvZGUocywgYywgdHJlZSkge1xuICBzZW5kX2JpdHMocywgdHJlZVtjICogMl0vKi5Db2RlKi8sIHRyZWVbYyAqIDIgKyAxXS8qLkxlbiovKTtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFJldmVyc2UgdGhlIGZpcnN0IGxlbiBiaXRzIG9mIGEgY29kZSwgdXNpbmcgc3RyYWlnaHRmb3J3YXJkIGNvZGUgKGEgZmFzdGVyXG4gKiBtZXRob2Qgd291bGQgdXNlIGEgdGFibGUpXG4gKiBJTiBhc3NlcnRpb246IDEgPD0gbGVuIDw9IDE1XG4gKi9cbmZ1bmN0aW9uIGJpX3JldmVyc2UoY29kZSwgbGVuKSB7XG4gIHZhciByZXMgPSAwO1xuICBkbyB7XG4gICAgcmVzIHw9IGNvZGUgJiAxO1xuICAgIGNvZGUgPj4+PSAxO1xuICAgIHJlcyA8PD0gMTtcbiAgfSB3aGlsZSAoLS1sZW4gPiAwKTtcbiAgcmV0dXJuIHJlcyA+Pj4gMTtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEZsdXNoIHRoZSBiaXQgYnVmZmVyLCBrZWVwaW5nIGF0IG1vc3QgNyBiaXRzIGluIGl0LlxuICovXG5mdW5jdGlvbiBiaV9mbHVzaChzKSB7XG4gIGlmIChzLmJpX3ZhbGlkID09PSAxNikge1xuICAgIHB1dF9zaG9ydChzLCBzLmJpX2J1Zik7XG4gICAgcy5iaV9idWYgPSAwO1xuICAgIHMuYmlfdmFsaWQgPSAwO1xuXG4gIH0gZWxzZSBpZiAocy5iaV92YWxpZCA+PSA4KSB7XG4gICAgcy5wZW5kaW5nX2J1ZltzLnBlbmRpbmcrK10gPSBzLmJpX2J1ZiAmIDB4ZmY7XG4gICAgcy5iaV9idWYgPj49IDg7XG4gICAgcy5iaV92YWxpZCAtPSA4O1xuICB9XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb21wdXRlIHRoZSBvcHRpbWFsIGJpdCBsZW5ndGhzIGZvciBhIHRyZWUgYW5kIHVwZGF0ZSB0aGUgdG90YWwgYml0IGxlbmd0aFxuICogZm9yIHRoZSBjdXJyZW50IGJsb2NrLlxuICogSU4gYXNzZXJ0aW9uOiB0aGUgZmllbGRzIGZyZXEgYW5kIGRhZCBhcmUgc2V0LCBoZWFwW2hlYXBfbWF4XSBhbmRcbiAqICAgIGFib3ZlIGFyZSB0aGUgdHJlZSBub2RlcyBzb3J0ZWQgYnkgaW5jcmVhc2luZyBmcmVxdWVuY3kuXG4gKiBPVVQgYXNzZXJ0aW9uczogdGhlIGZpZWxkIGxlbiBpcyBzZXQgdG8gdGhlIG9wdGltYWwgYml0IGxlbmd0aCwgdGhlXG4gKiAgICAgYXJyYXkgYmxfY291bnQgY29udGFpbnMgdGhlIGZyZXF1ZW5jaWVzIGZvciBlYWNoIGJpdCBsZW5ndGguXG4gKiAgICAgVGhlIGxlbmd0aCBvcHRfbGVuIGlzIHVwZGF0ZWQ7IHN0YXRpY19sZW4gaXMgYWxzbyB1cGRhdGVkIGlmIHN0cmVlIGlzXG4gKiAgICAgbm90IG51bGwuXG4gKi9cbmZ1bmN0aW9uIGdlbl9iaXRsZW4ocywgZGVzYylcbi8vICAgIGRlZmxhdGVfc3RhdGUgKnM7XG4vLyAgICB0cmVlX2Rlc2MgKmRlc2M7ICAgIC8qIHRoZSB0cmVlIGRlc2NyaXB0b3IgKi9cbntcbiAgdmFyIHRyZWUgICAgICAgICAgICA9IGRlc2MuZHluX3RyZWU7XG4gIHZhciBtYXhfY29kZSAgICAgICAgPSBkZXNjLm1heF9jb2RlO1xuICB2YXIgc3RyZWUgICAgICAgICAgID0gZGVzYy5zdGF0X2Rlc2Muc3RhdGljX3RyZWU7XG4gIHZhciBoYXNfc3RyZWUgICAgICAgPSBkZXNjLnN0YXRfZGVzYy5oYXNfc3RyZWU7XG4gIHZhciBleHRyYSAgICAgICAgICAgPSBkZXNjLnN0YXRfZGVzYy5leHRyYV9iaXRzO1xuICB2YXIgYmFzZSAgICAgICAgICAgID0gZGVzYy5zdGF0X2Rlc2MuZXh0cmFfYmFzZTtcbiAgdmFyIG1heF9sZW5ndGggICAgICA9IGRlc2Muc3RhdF9kZXNjLm1heF9sZW5ndGg7XG4gIHZhciBoOyAgICAgICAgICAgICAgLyogaGVhcCBpbmRleCAqL1xuICB2YXIgbiwgbTsgICAgICAgICAgIC8qIGl0ZXJhdGUgb3ZlciB0aGUgdHJlZSBlbGVtZW50cyAqL1xuICB2YXIgYml0czsgICAgICAgICAgIC8qIGJpdCBsZW5ndGggKi9cbiAgdmFyIHhiaXRzOyAgICAgICAgICAvKiBleHRyYSBiaXRzICovXG4gIHZhciBmOyAgICAgICAgICAgICAgLyogZnJlcXVlbmN5ICovXG4gIHZhciBvdmVyZmxvdyA9IDA7ICAgLyogbnVtYmVyIG9mIGVsZW1lbnRzIHdpdGggYml0IGxlbmd0aCB0b28gbGFyZ2UgKi9cblxuICBmb3IgKGJpdHMgPSAwOyBiaXRzIDw9IE1BWF9CSVRTOyBiaXRzKyspIHtcbiAgICBzLmJsX2NvdW50W2JpdHNdID0gMDtcbiAgfVxuXG4gIC8qIEluIGEgZmlyc3QgcGFzcywgY29tcHV0ZSB0aGUgb3B0aW1hbCBiaXQgbGVuZ3RocyAod2hpY2ggbWF5XG4gICAqIG92ZXJmbG93IGluIHRoZSBjYXNlIG9mIHRoZSBiaXQgbGVuZ3RoIHRyZWUpLlxuICAgKi9cbiAgdHJlZVtzLmhlYXBbcy5oZWFwX21heF0gKiAyICsgMV0vKi5MZW4qLyA9IDA7IC8qIHJvb3Qgb2YgdGhlIGhlYXAgKi9cblxuICBmb3IgKGggPSBzLmhlYXBfbWF4ICsgMTsgaCA8IEhFQVBfU0laRTsgaCsrKSB7XG4gICAgbiA9IHMuaGVhcFtoXTtcbiAgICBiaXRzID0gdHJlZVt0cmVlW24gKiAyICsgMV0vKi5EYWQqLyAqIDIgKyAxXS8qLkxlbiovICsgMTtcbiAgICBpZiAoYml0cyA+IG1heF9sZW5ndGgpIHtcbiAgICAgIGJpdHMgPSBtYXhfbGVuZ3RoO1xuICAgICAgb3ZlcmZsb3crKztcbiAgICB9XG4gICAgdHJlZVtuICogMiArIDFdLyouTGVuKi8gPSBiaXRzO1xuICAgIC8qIFdlIG92ZXJ3cml0ZSB0cmVlW25dLkRhZCB3aGljaCBpcyBubyBsb25nZXIgbmVlZGVkICovXG5cbiAgICBpZiAobiA+IG1heF9jb2RlKSB7IGNvbnRpbnVlOyB9IC8qIG5vdCBhIGxlYWYgbm9kZSAqL1xuXG4gICAgcy5ibF9jb3VudFtiaXRzXSsrO1xuICAgIHhiaXRzID0gMDtcbiAgICBpZiAobiA+PSBiYXNlKSB7XG4gICAgICB4Yml0cyA9IGV4dHJhW24gLSBiYXNlXTtcbiAgICB9XG4gICAgZiA9IHRyZWVbbiAqIDJdLyouRnJlcSovO1xuICAgIHMub3B0X2xlbiArPSBmICogKGJpdHMgKyB4Yml0cyk7XG4gICAgaWYgKGhhc19zdHJlZSkge1xuICAgICAgcy5zdGF0aWNfbGVuICs9IGYgKiAoc3RyZWVbbiAqIDIgKyAxXS8qLkxlbiovICsgeGJpdHMpO1xuICAgIH1cbiAgfVxuICBpZiAob3ZlcmZsb3cgPT09IDApIHsgcmV0dXJuOyB9XG5cbiAgLy8gVHJhY2UoKHN0ZGVycixcIlxcbmJpdCBsZW5ndGggb3ZlcmZsb3dcXG5cIikpO1xuICAvKiBUaGlzIGhhcHBlbnMgZm9yIGV4YW1wbGUgb24gb2JqMiBhbmQgcGljIG9mIHRoZSBDYWxnYXJ5IGNvcnB1cyAqL1xuXG4gIC8qIEZpbmQgdGhlIGZpcnN0IGJpdCBsZW5ndGggd2hpY2ggY291bGQgaW5jcmVhc2U6ICovXG4gIGRvIHtcbiAgICBiaXRzID0gbWF4X2xlbmd0aCAtIDE7XG4gICAgd2hpbGUgKHMuYmxfY291bnRbYml0c10gPT09IDApIHsgYml0cy0tOyB9XG4gICAgcy5ibF9jb3VudFtiaXRzXS0tOyAgICAgIC8qIG1vdmUgb25lIGxlYWYgZG93biB0aGUgdHJlZSAqL1xuICAgIHMuYmxfY291bnRbYml0cyArIDFdICs9IDI7IC8qIG1vdmUgb25lIG92ZXJmbG93IGl0ZW0gYXMgaXRzIGJyb3RoZXIgKi9cbiAgICBzLmJsX2NvdW50W21heF9sZW5ndGhdLS07XG4gICAgLyogVGhlIGJyb3RoZXIgb2YgdGhlIG92ZXJmbG93IGl0ZW0gYWxzbyBtb3ZlcyBvbmUgc3RlcCB1cCxcbiAgICAgKiBidXQgdGhpcyBkb2VzIG5vdCBhZmZlY3QgYmxfY291bnRbbWF4X2xlbmd0aF1cbiAgICAgKi9cbiAgICBvdmVyZmxvdyAtPSAyO1xuICB9IHdoaWxlIChvdmVyZmxvdyA+IDApO1xuXG4gIC8qIE5vdyByZWNvbXB1dGUgYWxsIGJpdCBsZW5ndGhzLCBzY2FubmluZyBpbiBpbmNyZWFzaW5nIGZyZXF1ZW5jeS5cbiAgICogaCBpcyBzdGlsbCBlcXVhbCB0byBIRUFQX1NJWkUuIChJdCBpcyBzaW1wbGVyIHRvIHJlY29uc3RydWN0IGFsbFxuICAgKiBsZW5ndGhzIGluc3RlYWQgb2YgZml4aW5nIG9ubHkgdGhlIHdyb25nIG9uZXMuIFRoaXMgaWRlYSBpcyB0YWtlblxuICAgKiBmcm9tICdhcicgd3JpdHRlbiBieSBIYXJ1aGlrbyBPa3VtdXJhLilcbiAgICovXG4gIGZvciAoYml0cyA9IG1heF9sZW5ndGg7IGJpdHMgIT09IDA7IGJpdHMtLSkge1xuICAgIG4gPSBzLmJsX2NvdW50W2JpdHNdO1xuICAgIHdoaWxlIChuICE9PSAwKSB7XG4gICAgICBtID0gcy5oZWFwWy0taF07XG4gICAgICBpZiAobSA+IG1heF9jb2RlKSB7IGNvbnRpbnVlOyB9XG4gICAgICBpZiAodHJlZVttICogMiArIDFdLyouTGVuKi8gIT09IGJpdHMpIHtcbiAgICAgICAgLy8gVHJhY2UoKHN0ZGVycixcImNvZGUgJWQgYml0cyAlZC0+JWRcXG5cIiwgbSwgdHJlZVttXS5MZW4sIGJpdHMpKTtcbiAgICAgICAgcy5vcHRfbGVuICs9IChiaXRzIC0gdHJlZVttICogMiArIDFdLyouTGVuKi8pICogdHJlZVttICogMl0vKi5GcmVxKi87XG4gICAgICAgIHRyZWVbbSAqIDIgKyAxXS8qLkxlbiovID0gYml0cztcbiAgICAgIH1cbiAgICAgIG4tLTtcbiAgICB9XG4gIH1cbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEdlbmVyYXRlIHRoZSBjb2RlcyBmb3IgYSBnaXZlbiB0cmVlIGFuZCBiaXQgY291bnRzICh3aGljaCBuZWVkIG5vdCBiZVxuICogb3B0aW1hbCkuXG4gKiBJTiBhc3NlcnRpb246IHRoZSBhcnJheSBibF9jb3VudCBjb250YWlucyB0aGUgYml0IGxlbmd0aCBzdGF0aXN0aWNzIGZvclxuICogdGhlIGdpdmVuIHRyZWUgYW5kIHRoZSBmaWVsZCBsZW4gaXMgc2V0IGZvciBhbGwgdHJlZSBlbGVtZW50cy5cbiAqIE9VVCBhc3NlcnRpb246IHRoZSBmaWVsZCBjb2RlIGlzIHNldCBmb3IgYWxsIHRyZWUgZWxlbWVudHMgb2Ygbm9uXG4gKiAgICAgemVybyBjb2RlIGxlbmd0aC5cbiAqL1xuZnVuY3Rpb24gZ2VuX2NvZGVzKHRyZWUsIG1heF9jb2RlLCBibF9jb3VudClcbi8vICAgIGN0X2RhdGEgKnRyZWU7ICAgICAgICAgICAgIC8qIHRoZSB0cmVlIHRvIGRlY29yYXRlICovXG4vLyAgICBpbnQgbWF4X2NvZGU7ICAgICAgICAgICAgICAvKiBsYXJnZXN0IGNvZGUgd2l0aCBub24gemVybyBmcmVxdWVuY3kgKi9cbi8vICAgIHVzaGYgKmJsX2NvdW50OyAgICAgICAgICAgIC8qIG51bWJlciBvZiBjb2RlcyBhdCBlYWNoIGJpdCBsZW5ndGggKi9cbntcbiAgdmFyIG5leHRfY29kZSA9IG5ldyBBcnJheShNQVhfQklUUyArIDEpOyAvKiBuZXh0IGNvZGUgdmFsdWUgZm9yIGVhY2ggYml0IGxlbmd0aCAqL1xuICB2YXIgY29kZSA9IDA7ICAgICAgICAgICAgICAvKiBydW5uaW5nIGNvZGUgdmFsdWUgKi9cbiAgdmFyIGJpdHM7ICAgICAgICAgICAgICAgICAgLyogYml0IGluZGV4ICovXG4gIHZhciBuOyAgICAgICAgICAgICAgICAgICAgIC8qIGNvZGUgaW5kZXggKi9cblxuICAvKiBUaGUgZGlzdHJpYnV0aW9uIGNvdW50cyBhcmUgZmlyc3QgdXNlZCB0byBnZW5lcmF0ZSB0aGUgY29kZSB2YWx1ZXNcbiAgICogd2l0aG91dCBiaXQgcmV2ZXJzYWwuXG4gICAqL1xuICBmb3IgKGJpdHMgPSAxOyBiaXRzIDw9IE1BWF9CSVRTOyBiaXRzKyspIHtcbiAgICBuZXh0X2NvZGVbYml0c10gPSBjb2RlID0gKGNvZGUgKyBibF9jb3VudFtiaXRzIC0gMV0pIDw8IDE7XG4gIH1cbiAgLyogQ2hlY2sgdGhhdCB0aGUgYml0IGNvdW50cyBpbiBibF9jb3VudCBhcmUgY29uc2lzdGVudC4gVGhlIGxhc3QgY29kZVxuICAgKiBtdXN0IGJlIGFsbCBvbmVzLlxuICAgKi9cbiAgLy9Bc3NlcnQgKGNvZGUgKyBibF9jb3VudFtNQVhfQklUU10tMSA9PSAoMTw8TUFYX0JJVFMpLTEsXG4gIC8vICAgICAgICBcImluY29uc2lzdGVudCBiaXQgY291bnRzXCIpO1xuICAvL1RyYWNldigoc3RkZXJyLFwiXFxuZ2VuX2NvZGVzOiBtYXhfY29kZSAlZCBcIiwgbWF4X2NvZGUpKTtcblxuICBmb3IgKG4gPSAwOyAgbiA8PSBtYXhfY29kZTsgbisrKSB7XG4gICAgdmFyIGxlbiA9IHRyZWVbbiAqIDIgKyAxXS8qLkxlbiovO1xuICAgIGlmIChsZW4gPT09IDApIHsgY29udGludWU7IH1cbiAgICAvKiBOb3cgcmV2ZXJzZSB0aGUgYml0cyAqL1xuICAgIHRyZWVbbiAqIDJdLyouQ29kZSovID0gYmlfcmV2ZXJzZShuZXh0X2NvZGVbbGVuXSsrLCBsZW4pO1xuXG4gICAgLy9UcmFjZWN2KHRyZWUgIT0gc3RhdGljX2x0cmVlLCAoc3RkZXJyLFwiXFxubiAlM2QgJWMgbCAlMmQgYyAlNHggKCV4KSBcIixcbiAgICAvLyAgICAgbiwgKGlzZ3JhcGgobikgPyBuIDogJyAnKSwgbGVuLCB0cmVlW25dLkNvZGUsIG5leHRfY29kZVtsZW5dLTEpKTtcbiAgfVxufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogSW5pdGlhbGl6ZSB0aGUgdmFyaW91cyAnY29uc3RhbnQnIHRhYmxlcy5cbiAqL1xuZnVuY3Rpb24gdHJfc3RhdGljX2luaXQoKSB7XG4gIHZhciBuOyAgICAgICAgLyogaXRlcmF0ZXMgb3ZlciB0cmVlIGVsZW1lbnRzICovXG4gIHZhciBiaXRzOyAgICAgLyogYml0IGNvdW50ZXIgKi9cbiAgdmFyIGxlbmd0aDsgICAvKiBsZW5ndGggdmFsdWUgKi9cbiAgdmFyIGNvZGU7ICAgICAvKiBjb2RlIHZhbHVlICovXG4gIHZhciBkaXN0OyAgICAgLyogZGlzdGFuY2UgaW5kZXggKi9cbiAgdmFyIGJsX2NvdW50ID0gbmV3IEFycmF5KE1BWF9CSVRTICsgMSk7XG4gIC8qIG51bWJlciBvZiBjb2RlcyBhdCBlYWNoIGJpdCBsZW5ndGggZm9yIGFuIG9wdGltYWwgdHJlZSAqL1xuXG4gIC8vIGRvIGNoZWNrIGluIF90cl9pbml0KClcbiAgLy9pZiAoc3RhdGljX2luaXRfZG9uZSkgcmV0dXJuO1xuXG4gIC8qIEZvciBzb21lIGVtYmVkZGVkIHRhcmdldHMsIGdsb2JhbCB2YXJpYWJsZXMgYXJlIG5vdCBpbml0aWFsaXplZDogKi9cbi8qI2lmZGVmIE5PX0lOSVRfR0xPQkFMX1BPSU5URVJTXG4gIHN0YXRpY19sX2Rlc2Muc3RhdGljX3RyZWUgPSBzdGF0aWNfbHRyZWU7XG4gIHN0YXRpY19sX2Rlc2MuZXh0cmFfYml0cyA9IGV4dHJhX2xiaXRzO1xuICBzdGF0aWNfZF9kZXNjLnN0YXRpY190cmVlID0gc3RhdGljX2R0cmVlO1xuICBzdGF0aWNfZF9kZXNjLmV4dHJhX2JpdHMgPSBleHRyYV9kYml0cztcbiAgc3RhdGljX2JsX2Rlc2MuZXh0cmFfYml0cyA9IGV4dHJhX2JsYml0cztcbiNlbmRpZiovXG5cbiAgLyogSW5pdGlhbGl6ZSB0aGUgbWFwcGluZyBsZW5ndGggKDAuLjI1NSkgLT4gbGVuZ3RoIGNvZGUgKDAuLjI4KSAqL1xuICBsZW5ndGggPSAwO1xuICBmb3IgKGNvZGUgPSAwOyBjb2RlIDwgTEVOR1RIX0NPREVTIC0gMTsgY29kZSsrKSB7XG4gICAgYmFzZV9sZW5ndGhbY29kZV0gPSBsZW5ndGg7XG4gICAgZm9yIChuID0gMDsgbiA8ICgxIDw8IGV4dHJhX2xiaXRzW2NvZGVdKTsgbisrKSB7XG4gICAgICBfbGVuZ3RoX2NvZGVbbGVuZ3RoKytdID0gY29kZTtcbiAgICB9XG4gIH1cbiAgLy9Bc3NlcnQgKGxlbmd0aCA9PSAyNTYsIFwidHJfc3RhdGljX2luaXQ6IGxlbmd0aCAhPSAyNTZcIik7XG4gIC8qIE5vdGUgdGhhdCB0aGUgbGVuZ3RoIDI1NSAobWF0Y2ggbGVuZ3RoIDI1OCkgY2FuIGJlIHJlcHJlc2VudGVkXG4gICAqIGluIHR3byBkaWZmZXJlbnQgd2F5czogY29kZSAyODQgKyA1IGJpdHMgb3IgY29kZSAyODUsIHNvIHdlXG4gICAqIG92ZXJ3cml0ZSBsZW5ndGhfY29kZVsyNTVdIHRvIHVzZSB0aGUgYmVzdCBlbmNvZGluZzpcbiAgICovXG4gIF9sZW5ndGhfY29kZVtsZW5ndGggLSAxXSA9IGNvZGU7XG5cbiAgLyogSW5pdGlhbGl6ZSB0aGUgbWFwcGluZyBkaXN0ICgwLi4zMkspIC0+IGRpc3QgY29kZSAoMC4uMjkpICovXG4gIGRpc3QgPSAwO1xuICBmb3IgKGNvZGUgPSAwOyBjb2RlIDwgMTY7IGNvZGUrKykge1xuICAgIGJhc2VfZGlzdFtjb2RlXSA9IGRpc3Q7XG4gICAgZm9yIChuID0gMDsgbiA8ICgxIDw8IGV4dHJhX2RiaXRzW2NvZGVdKTsgbisrKSB7XG4gICAgICBfZGlzdF9jb2RlW2Rpc3QrK10gPSBjb2RlO1xuICAgIH1cbiAgfVxuICAvL0Fzc2VydCAoZGlzdCA9PSAyNTYsIFwidHJfc3RhdGljX2luaXQ6IGRpc3QgIT0gMjU2XCIpO1xuICBkaXN0ID4+PSA3OyAvKiBmcm9tIG5vdyBvbiwgYWxsIGRpc3RhbmNlcyBhcmUgZGl2aWRlZCBieSAxMjggKi9cbiAgZm9yICg7IGNvZGUgPCBEX0NPREVTOyBjb2RlKyspIHtcbiAgICBiYXNlX2Rpc3RbY29kZV0gPSBkaXN0IDw8IDc7XG4gICAgZm9yIChuID0gMDsgbiA8ICgxIDw8IChleHRyYV9kYml0c1tjb2RlXSAtIDcpKTsgbisrKSB7XG4gICAgICBfZGlzdF9jb2RlWzI1NiArIGRpc3QrK10gPSBjb2RlO1xuICAgIH1cbiAgfVxuICAvL0Fzc2VydCAoZGlzdCA9PSAyNTYsIFwidHJfc3RhdGljX2luaXQ6IDI1NitkaXN0ICE9IDUxMlwiKTtcblxuICAvKiBDb25zdHJ1Y3QgdGhlIGNvZGVzIG9mIHRoZSBzdGF0aWMgbGl0ZXJhbCB0cmVlICovXG4gIGZvciAoYml0cyA9IDA7IGJpdHMgPD0gTUFYX0JJVFM7IGJpdHMrKykge1xuICAgIGJsX2NvdW50W2JpdHNdID0gMDtcbiAgfVxuXG4gIG4gPSAwO1xuICB3aGlsZSAobiA8PSAxNDMpIHtcbiAgICBzdGF0aWNfbHRyZWVbbiAqIDIgKyAxXS8qLkxlbiovID0gODtcbiAgICBuKys7XG4gICAgYmxfY291bnRbOF0rKztcbiAgfVxuICB3aGlsZSAobiA8PSAyNTUpIHtcbiAgICBzdGF0aWNfbHRyZWVbbiAqIDIgKyAxXS8qLkxlbiovID0gOTtcbiAgICBuKys7XG4gICAgYmxfY291bnRbOV0rKztcbiAgfVxuICB3aGlsZSAobiA8PSAyNzkpIHtcbiAgICBzdGF0aWNfbHRyZWVbbiAqIDIgKyAxXS8qLkxlbiovID0gNztcbiAgICBuKys7XG4gICAgYmxfY291bnRbN10rKztcbiAgfVxuICB3aGlsZSAobiA8PSAyODcpIHtcbiAgICBzdGF0aWNfbHRyZWVbbiAqIDIgKyAxXS8qLkxlbiovID0gODtcbiAgICBuKys7XG4gICAgYmxfY291bnRbOF0rKztcbiAgfVxuICAvKiBDb2RlcyAyODYgYW5kIDI4NyBkbyBub3QgZXhpc3QsIGJ1dCB3ZSBtdXN0IGluY2x1ZGUgdGhlbSBpbiB0aGVcbiAgICogdHJlZSBjb25zdHJ1Y3Rpb24gdG8gZ2V0IGEgY2Fub25pY2FsIEh1ZmZtYW4gdHJlZSAobG9uZ2VzdCBjb2RlXG4gICAqIGFsbCBvbmVzKVxuICAgKi9cbiAgZ2VuX2NvZGVzKHN0YXRpY19sdHJlZSwgTF9DT0RFUyArIDEsIGJsX2NvdW50KTtcblxuICAvKiBUaGUgc3RhdGljIGRpc3RhbmNlIHRyZWUgaXMgdHJpdmlhbDogKi9cbiAgZm9yIChuID0gMDsgbiA8IERfQ09ERVM7IG4rKykge1xuICAgIHN0YXRpY19kdHJlZVtuICogMiArIDFdLyouTGVuKi8gPSA1O1xuICAgIHN0YXRpY19kdHJlZVtuICogMl0vKi5Db2RlKi8gPSBiaV9yZXZlcnNlKG4sIDUpO1xuICB9XG5cbiAgLy8gTm93IGRhdGEgcmVhZHkgYW5kIHdlIGNhbiBpbml0IHN0YXRpYyB0cmVlc1xuICBzdGF0aWNfbF9kZXNjID0gbmV3IFN0YXRpY1RyZWVEZXNjKHN0YXRpY19sdHJlZSwgZXh0cmFfbGJpdHMsIExJVEVSQUxTICsgMSwgTF9DT0RFUywgTUFYX0JJVFMpO1xuICBzdGF0aWNfZF9kZXNjID0gbmV3IFN0YXRpY1RyZWVEZXNjKHN0YXRpY19kdHJlZSwgZXh0cmFfZGJpdHMsIDAsICAgICAgICAgIERfQ09ERVMsIE1BWF9CSVRTKTtcbiAgc3RhdGljX2JsX2Rlc2MgPSBuZXcgU3RhdGljVHJlZURlc2MobmV3IEFycmF5KDApLCBleHRyYV9ibGJpdHMsIDAsICAgICAgICAgQkxfQ09ERVMsIE1BWF9CTF9CSVRTKTtcblxuICAvL3N0YXRpY19pbml0X2RvbmUgPSB0cnVlO1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogSW5pdGlhbGl6ZSBhIG5ldyBibG9jay5cbiAqL1xuZnVuY3Rpb24gaW5pdF9ibG9jayhzKSB7XG4gIHZhciBuOyAvKiBpdGVyYXRlcyBvdmVyIHRyZWUgZWxlbWVudHMgKi9cblxuICAvKiBJbml0aWFsaXplIHRoZSB0cmVlcy4gKi9cbiAgZm9yIChuID0gMDsgbiA8IExfQ09ERVM7ICBuKyspIHsgcy5keW5fbHRyZWVbbiAqIDJdLyouRnJlcSovID0gMDsgfVxuICBmb3IgKG4gPSAwOyBuIDwgRF9DT0RFUzsgIG4rKykgeyBzLmR5bl9kdHJlZVtuICogMl0vKi5GcmVxKi8gPSAwOyB9XG4gIGZvciAobiA9IDA7IG4gPCBCTF9DT0RFUzsgbisrKSB7IHMuYmxfdHJlZVtuICogMl0vKi5GcmVxKi8gPSAwOyB9XG5cbiAgcy5keW5fbHRyZWVbRU5EX0JMT0NLICogMl0vKi5GcmVxKi8gPSAxO1xuICBzLm9wdF9sZW4gPSBzLnN0YXRpY19sZW4gPSAwO1xuICBzLmxhc3RfbGl0ID0gcy5tYXRjaGVzID0gMDtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEZsdXNoIHRoZSBiaXQgYnVmZmVyIGFuZCBhbGlnbiB0aGUgb3V0cHV0IG9uIGEgYnl0ZSBib3VuZGFyeVxuICovXG5mdW5jdGlvbiBiaV93aW5kdXAocylcbntcbiAgaWYgKHMuYmlfdmFsaWQgPiA4KSB7XG4gICAgcHV0X3Nob3J0KHMsIHMuYmlfYnVmKTtcbiAgfSBlbHNlIGlmIChzLmJpX3ZhbGlkID4gMCkge1xuICAgIC8vcHV0X2J5dGUocywgKEJ5dGUpcy0+YmlfYnVmKTtcbiAgICBzLnBlbmRpbmdfYnVmW3MucGVuZGluZysrXSA9IHMuYmlfYnVmO1xuICB9XG4gIHMuYmlfYnVmID0gMDtcbiAgcy5iaV92YWxpZCA9IDA7XG59XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQ29weSBhIHN0b3JlZCBibG9jaywgc3RvcmluZyBmaXJzdCB0aGUgbGVuZ3RoIGFuZCBpdHNcbiAqIG9uZSdzIGNvbXBsZW1lbnQgaWYgcmVxdWVzdGVkLlxuICovXG5mdW5jdGlvbiBjb3B5X2Jsb2NrKHMsIGJ1ZiwgbGVuLCBoZWFkZXIpXG4vL0RlZmxhdGVTdGF0ZSAqcztcbi8vY2hhcmYgICAgKmJ1ZjsgICAgLyogdGhlIGlucHV0IGRhdGEgKi9cbi8vdW5zaWduZWQgbGVuOyAgICAgLyogaXRzIGxlbmd0aCAqL1xuLy9pbnQgICAgICBoZWFkZXI7ICAvKiB0cnVlIGlmIGJsb2NrIGhlYWRlciBtdXN0IGJlIHdyaXR0ZW4gKi9cbntcbiAgYmlfd2luZHVwKHMpOyAgICAgICAgLyogYWxpZ24gb24gYnl0ZSBib3VuZGFyeSAqL1xuXG4gIGlmIChoZWFkZXIpIHtcbiAgICBwdXRfc2hvcnQocywgbGVuKTtcbiAgICBwdXRfc2hvcnQocywgfmxlbik7XG4gIH1cbi8vICB3aGlsZSAobGVuLS0pIHtcbi8vICAgIHB1dF9ieXRlKHMsICpidWYrKyk7XG4vLyAgfVxuICB1dGlscy5hcnJheVNldChzLnBlbmRpbmdfYnVmLCBzLndpbmRvdywgYnVmLCBsZW4sIHMucGVuZGluZyk7XG4gIHMucGVuZGluZyArPSBsZW47XG59XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQ29tcGFyZXMgdG8gc3VidHJlZXMsIHVzaW5nIHRoZSB0cmVlIGRlcHRoIGFzIHRpZSBicmVha2VyIHdoZW5cbiAqIHRoZSBzdWJ0cmVlcyBoYXZlIGVxdWFsIGZyZXF1ZW5jeS4gVGhpcyBtaW5pbWl6ZXMgdGhlIHdvcnN0IGNhc2UgbGVuZ3RoLlxuICovXG5mdW5jdGlvbiBzbWFsbGVyKHRyZWUsIG4sIG0sIGRlcHRoKSB7XG4gIHZhciBfbjIgPSBuICogMjtcbiAgdmFyIF9tMiA9IG0gKiAyO1xuICByZXR1cm4gKHRyZWVbX24yXS8qLkZyZXEqLyA8IHRyZWVbX20yXS8qLkZyZXEqLyB8fFxuICAgICAgICAgKHRyZWVbX24yXS8qLkZyZXEqLyA9PT0gdHJlZVtfbTJdLyouRnJlcSovICYmIGRlcHRoW25dIDw9IGRlcHRoW21dKSk7XG59XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogUmVzdG9yZSB0aGUgaGVhcCBwcm9wZXJ0eSBieSBtb3ZpbmcgZG93biB0aGUgdHJlZSBzdGFydGluZyBhdCBub2RlIGssXG4gKiBleGNoYW5naW5nIGEgbm9kZSB3aXRoIHRoZSBzbWFsbGVzdCBvZiBpdHMgdHdvIHNvbnMgaWYgbmVjZXNzYXJ5LCBzdG9wcGluZ1xuICogd2hlbiB0aGUgaGVhcCBwcm9wZXJ0eSBpcyByZS1lc3RhYmxpc2hlZCAoZWFjaCBmYXRoZXIgc21hbGxlciB0aGFuIGl0c1xuICogdHdvIHNvbnMpLlxuICovXG5mdW5jdGlvbiBwcWRvd25oZWFwKHMsIHRyZWUsIGspXG4vLyAgICBkZWZsYXRlX3N0YXRlICpzO1xuLy8gICAgY3RfZGF0YSAqdHJlZTsgIC8qIHRoZSB0cmVlIHRvIHJlc3RvcmUgKi9cbi8vICAgIGludCBrOyAgICAgICAgICAgICAgIC8qIG5vZGUgdG8gbW92ZSBkb3duICovXG57XG4gIHZhciB2ID0gcy5oZWFwW2tdO1xuICB2YXIgaiA9IGsgPDwgMTsgIC8qIGxlZnQgc29uIG9mIGsgKi9cbiAgd2hpbGUgKGogPD0gcy5oZWFwX2xlbikge1xuICAgIC8qIFNldCBqIHRvIHRoZSBzbWFsbGVzdCBvZiB0aGUgdHdvIHNvbnM6ICovXG4gICAgaWYgKGogPCBzLmhlYXBfbGVuICYmXG4gICAgICBzbWFsbGVyKHRyZWUsIHMuaGVhcFtqICsgMV0sIHMuaGVhcFtqXSwgcy5kZXB0aCkpIHtcbiAgICAgIGorKztcbiAgICB9XG4gICAgLyogRXhpdCBpZiB2IGlzIHNtYWxsZXIgdGhhbiBib3RoIHNvbnMgKi9cbiAgICBpZiAoc21hbGxlcih0cmVlLCB2LCBzLmhlYXBbal0sIHMuZGVwdGgpKSB7IGJyZWFrOyB9XG5cbiAgICAvKiBFeGNoYW5nZSB2IHdpdGggdGhlIHNtYWxsZXN0IHNvbiAqL1xuICAgIHMuaGVhcFtrXSA9IHMuaGVhcFtqXTtcbiAgICBrID0gajtcblxuICAgIC8qIEFuZCBjb250aW51ZSBkb3duIHRoZSB0cmVlLCBzZXR0aW5nIGogdG8gdGhlIGxlZnQgc29uIG9mIGsgKi9cbiAgICBqIDw8PSAxO1xuICB9XG4gIHMuaGVhcFtrXSA9IHY7XG59XG5cblxuLy8gaW5saW5lZCBtYW51YWxseVxuLy8gdmFyIFNNQUxMRVNUID0gMTtcblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTZW5kIHRoZSBibG9jayBkYXRhIGNvbXByZXNzZWQgdXNpbmcgdGhlIGdpdmVuIEh1ZmZtYW4gdHJlZXNcbiAqL1xuZnVuY3Rpb24gY29tcHJlc3NfYmxvY2socywgbHRyZWUsIGR0cmVlKVxuLy8gICAgZGVmbGF0ZV9zdGF0ZSAqcztcbi8vICAgIGNvbnN0IGN0X2RhdGEgKmx0cmVlOyAvKiBsaXRlcmFsIHRyZWUgKi9cbi8vICAgIGNvbnN0IGN0X2RhdGEgKmR0cmVlOyAvKiBkaXN0YW5jZSB0cmVlICovXG57XG4gIHZhciBkaXN0OyAgICAgICAgICAgLyogZGlzdGFuY2Ugb2YgbWF0Y2hlZCBzdHJpbmcgKi9cbiAgdmFyIGxjOyAgICAgICAgICAgICAvKiBtYXRjaCBsZW5ndGggb3IgdW5tYXRjaGVkIGNoYXIgKGlmIGRpc3QgPT0gMCkgKi9cbiAgdmFyIGx4ID0gMDsgICAgICAgICAvKiBydW5uaW5nIGluZGV4IGluIGxfYnVmICovXG4gIHZhciBjb2RlOyAgICAgICAgICAgLyogdGhlIGNvZGUgdG8gc2VuZCAqL1xuICB2YXIgZXh0cmE7ICAgICAgICAgIC8qIG51bWJlciBvZiBleHRyYSBiaXRzIHRvIHNlbmQgKi9cblxuICBpZiAocy5sYXN0X2xpdCAhPT0gMCkge1xuICAgIGRvIHtcbiAgICAgIGRpc3QgPSAocy5wZW5kaW5nX2J1ZltzLmRfYnVmICsgbHggKiAyXSA8PCA4KSB8IChzLnBlbmRpbmdfYnVmW3MuZF9idWYgKyBseCAqIDIgKyAxXSk7XG4gICAgICBsYyA9IHMucGVuZGluZ19idWZbcy5sX2J1ZiArIGx4XTtcbiAgICAgIGx4Kys7XG5cbiAgICAgIGlmIChkaXN0ID09PSAwKSB7XG4gICAgICAgIHNlbmRfY29kZShzLCBsYywgbHRyZWUpOyAvKiBzZW5kIGEgbGl0ZXJhbCBieXRlICovXG4gICAgICAgIC8vVHJhY2Vjdihpc2dyYXBoKGxjKSwgKHN0ZGVycixcIiAnJWMnIFwiLCBsYykpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLyogSGVyZSwgbGMgaXMgdGhlIG1hdGNoIGxlbmd0aCAtIE1JTl9NQVRDSCAqL1xuICAgICAgICBjb2RlID0gX2xlbmd0aF9jb2RlW2xjXTtcbiAgICAgICAgc2VuZF9jb2RlKHMsIGNvZGUgKyBMSVRFUkFMUyArIDEsIGx0cmVlKTsgLyogc2VuZCB0aGUgbGVuZ3RoIGNvZGUgKi9cbiAgICAgICAgZXh0cmEgPSBleHRyYV9sYml0c1tjb2RlXTtcbiAgICAgICAgaWYgKGV4dHJhICE9PSAwKSB7XG4gICAgICAgICAgbGMgLT0gYmFzZV9sZW5ndGhbY29kZV07XG4gICAgICAgICAgc2VuZF9iaXRzKHMsIGxjLCBleHRyYSk7ICAgICAgIC8qIHNlbmQgdGhlIGV4dHJhIGxlbmd0aCBiaXRzICovXG4gICAgICAgIH1cbiAgICAgICAgZGlzdC0tOyAvKiBkaXN0IGlzIG5vdyB0aGUgbWF0Y2ggZGlzdGFuY2UgLSAxICovXG4gICAgICAgIGNvZGUgPSBkX2NvZGUoZGlzdCk7XG4gICAgICAgIC8vQXNzZXJ0IChjb2RlIDwgRF9DT0RFUywgXCJiYWQgZF9jb2RlXCIpO1xuXG4gICAgICAgIHNlbmRfY29kZShzLCBjb2RlLCBkdHJlZSk7ICAgICAgIC8qIHNlbmQgdGhlIGRpc3RhbmNlIGNvZGUgKi9cbiAgICAgICAgZXh0cmEgPSBleHRyYV9kYml0c1tjb2RlXTtcbiAgICAgICAgaWYgKGV4dHJhICE9PSAwKSB7XG4gICAgICAgICAgZGlzdCAtPSBiYXNlX2Rpc3RbY29kZV07XG4gICAgICAgICAgc2VuZF9iaXRzKHMsIGRpc3QsIGV4dHJhKTsgICAvKiBzZW5kIHRoZSBleHRyYSBkaXN0YW5jZSBiaXRzICovXG4gICAgICAgIH1cbiAgICAgIH0gLyogbGl0ZXJhbCBvciBtYXRjaCBwYWlyID8gKi9cblxuICAgICAgLyogQ2hlY2sgdGhhdCB0aGUgb3ZlcmxheSBiZXR3ZWVuIHBlbmRpbmdfYnVmIGFuZCBkX2J1ZitsX2J1ZiBpcyBvazogKi9cbiAgICAgIC8vQXNzZXJ0KCh1SW50KShzLT5wZW5kaW5nKSA8IHMtPmxpdF9idWZzaXplICsgMipseCxcbiAgICAgIC8vICAgICAgIFwicGVuZGluZ0J1ZiBvdmVyZmxvd1wiKTtcblxuICAgIH0gd2hpbGUgKGx4IDwgcy5sYXN0X2xpdCk7XG4gIH1cblxuICBzZW5kX2NvZGUocywgRU5EX0JMT0NLLCBsdHJlZSk7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBDb25zdHJ1Y3Qgb25lIEh1ZmZtYW4gdHJlZSBhbmQgYXNzaWducyB0aGUgY29kZSBiaXQgc3RyaW5ncyBhbmQgbGVuZ3Rocy5cbiAqIFVwZGF0ZSB0aGUgdG90YWwgYml0IGxlbmd0aCBmb3IgdGhlIGN1cnJlbnQgYmxvY2suXG4gKiBJTiBhc3NlcnRpb246IHRoZSBmaWVsZCBmcmVxIGlzIHNldCBmb3IgYWxsIHRyZWUgZWxlbWVudHMuXG4gKiBPVVQgYXNzZXJ0aW9uczogdGhlIGZpZWxkcyBsZW4gYW5kIGNvZGUgYXJlIHNldCB0byB0aGUgb3B0aW1hbCBiaXQgbGVuZ3RoXG4gKiAgICAgYW5kIGNvcnJlc3BvbmRpbmcgY29kZS4gVGhlIGxlbmd0aCBvcHRfbGVuIGlzIHVwZGF0ZWQ7IHN0YXRpY19sZW4gaXNcbiAqICAgICBhbHNvIHVwZGF0ZWQgaWYgc3RyZWUgaXMgbm90IG51bGwuIFRoZSBmaWVsZCBtYXhfY29kZSBpcyBzZXQuXG4gKi9cbmZ1bmN0aW9uIGJ1aWxkX3RyZWUocywgZGVzYylcbi8vICAgIGRlZmxhdGVfc3RhdGUgKnM7XG4vLyAgICB0cmVlX2Rlc2MgKmRlc2M7IC8qIHRoZSB0cmVlIGRlc2NyaXB0b3IgKi9cbntcbiAgdmFyIHRyZWUgICAgID0gZGVzYy5keW5fdHJlZTtcbiAgdmFyIHN0cmVlICAgID0gZGVzYy5zdGF0X2Rlc2Muc3RhdGljX3RyZWU7XG4gIHZhciBoYXNfc3RyZWUgPSBkZXNjLnN0YXRfZGVzYy5oYXNfc3RyZWU7XG4gIHZhciBlbGVtcyAgICA9IGRlc2Muc3RhdF9kZXNjLmVsZW1zO1xuICB2YXIgbiwgbTsgICAgICAgICAgLyogaXRlcmF0ZSBvdmVyIGhlYXAgZWxlbWVudHMgKi9cbiAgdmFyIG1heF9jb2RlID0gLTE7IC8qIGxhcmdlc3QgY29kZSB3aXRoIG5vbiB6ZXJvIGZyZXF1ZW5jeSAqL1xuICB2YXIgbm9kZTsgICAgICAgICAgLyogbmV3IG5vZGUgYmVpbmcgY3JlYXRlZCAqL1xuXG4gIC8qIENvbnN0cnVjdCB0aGUgaW5pdGlhbCBoZWFwLCB3aXRoIGxlYXN0IGZyZXF1ZW50IGVsZW1lbnQgaW5cbiAgICogaGVhcFtTTUFMTEVTVF0uIFRoZSBzb25zIG9mIGhlYXBbbl0gYXJlIGhlYXBbMipuXSBhbmQgaGVhcFsyKm4rMV0uXG4gICAqIGhlYXBbMF0gaXMgbm90IHVzZWQuXG4gICAqL1xuICBzLmhlYXBfbGVuID0gMDtcbiAgcy5oZWFwX21heCA9IEhFQVBfU0laRTtcblxuICBmb3IgKG4gPSAwOyBuIDwgZWxlbXM7IG4rKykge1xuICAgIGlmICh0cmVlW24gKiAyXS8qLkZyZXEqLyAhPT0gMCkge1xuICAgICAgcy5oZWFwWysrcy5oZWFwX2xlbl0gPSBtYXhfY29kZSA9IG47XG4gICAgICBzLmRlcHRoW25dID0gMDtcblxuICAgIH0gZWxzZSB7XG4gICAgICB0cmVlW24gKiAyICsgMV0vKi5MZW4qLyA9IDA7XG4gICAgfVxuICB9XG5cbiAgLyogVGhlIHBremlwIGZvcm1hdCByZXF1aXJlcyB0aGF0IGF0IGxlYXN0IG9uZSBkaXN0YW5jZSBjb2RlIGV4aXN0cyxcbiAgICogYW5kIHRoYXQgYXQgbGVhc3Qgb25lIGJpdCBzaG91bGQgYmUgc2VudCBldmVuIGlmIHRoZXJlIGlzIG9ubHkgb25lXG4gICAqIHBvc3NpYmxlIGNvZGUuIFNvIHRvIGF2b2lkIHNwZWNpYWwgY2hlY2tzIGxhdGVyIG9uIHdlIGZvcmNlIGF0IGxlYXN0XG4gICAqIHR3byBjb2RlcyBvZiBub24gemVybyBmcmVxdWVuY3kuXG4gICAqL1xuICB3aGlsZSAocy5oZWFwX2xlbiA8IDIpIHtcbiAgICBub2RlID0gcy5oZWFwWysrcy5oZWFwX2xlbl0gPSAobWF4X2NvZGUgPCAyID8gKyttYXhfY29kZSA6IDApO1xuICAgIHRyZWVbbm9kZSAqIDJdLyouRnJlcSovID0gMTtcbiAgICBzLmRlcHRoW25vZGVdID0gMDtcbiAgICBzLm9wdF9sZW4tLTtcblxuICAgIGlmIChoYXNfc3RyZWUpIHtcbiAgICAgIHMuc3RhdGljX2xlbiAtPSBzdHJlZVtub2RlICogMiArIDFdLyouTGVuKi87XG4gICAgfVxuICAgIC8qIG5vZGUgaXMgMCBvciAxIHNvIGl0IGRvZXMgbm90IGhhdmUgZXh0cmEgYml0cyAqL1xuICB9XG4gIGRlc2MubWF4X2NvZGUgPSBtYXhfY29kZTtcblxuICAvKiBUaGUgZWxlbWVudHMgaGVhcFtoZWFwX2xlbi8yKzEgLi4gaGVhcF9sZW5dIGFyZSBsZWF2ZXMgb2YgdGhlIHRyZWUsXG4gICAqIGVzdGFibGlzaCBzdWItaGVhcHMgb2YgaW5jcmVhc2luZyBsZW5ndGhzOlxuICAgKi9cbiAgZm9yIChuID0gKHMuaGVhcF9sZW4gPj4gMS8qaW50IC8yKi8pOyBuID49IDE7IG4tLSkgeyBwcWRvd25oZWFwKHMsIHRyZWUsIG4pOyB9XG5cbiAgLyogQ29uc3RydWN0IHRoZSBIdWZmbWFuIHRyZWUgYnkgcmVwZWF0ZWRseSBjb21iaW5pbmcgdGhlIGxlYXN0IHR3b1xuICAgKiBmcmVxdWVudCBub2Rlcy5cbiAgICovXG4gIG5vZGUgPSBlbGVtczsgICAgICAgICAgICAgIC8qIG5leHQgaW50ZXJuYWwgbm9kZSBvZiB0aGUgdHJlZSAqL1xuICBkbyB7XG4gICAgLy9wcXJlbW92ZShzLCB0cmVlLCBuKTsgIC8qIG4gPSBub2RlIG9mIGxlYXN0IGZyZXF1ZW5jeSAqL1xuICAgIC8qKiogcHFyZW1vdmUgKioqL1xuICAgIG4gPSBzLmhlYXBbMS8qU01BTExFU1QqL107XG4gICAgcy5oZWFwWzEvKlNNQUxMRVNUKi9dID0gcy5oZWFwW3MuaGVhcF9sZW4tLV07XG4gICAgcHFkb3duaGVhcChzLCB0cmVlLCAxLypTTUFMTEVTVCovKTtcbiAgICAvKioqL1xuXG4gICAgbSA9IHMuaGVhcFsxLypTTUFMTEVTVCovXTsgLyogbSA9IG5vZGUgb2YgbmV4dCBsZWFzdCBmcmVxdWVuY3kgKi9cblxuICAgIHMuaGVhcFstLXMuaGVhcF9tYXhdID0gbjsgLyoga2VlcCB0aGUgbm9kZXMgc29ydGVkIGJ5IGZyZXF1ZW5jeSAqL1xuICAgIHMuaGVhcFstLXMuaGVhcF9tYXhdID0gbTtcblxuICAgIC8qIENyZWF0ZSBhIG5ldyBub2RlIGZhdGhlciBvZiBuIGFuZCBtICovXG4gICAgdHJlZVtub2RlICogMl0vKi5GcmVxKi8gPSB0cmVlW24gKiAyXS8qLkZyZXEqLyArIHRyZWVbbSAqIDJdLyouRnJlcSovO1xuICAgIHMuZGVwdGhbbm9kZV0gPSAocy5kZXB0aFtuXSA+PSBzLmRlcHRoW21dID8gcy5kZXB0aFtuXSA6IHMuZGVwdGhbbV0pICsgMTtcbiAgICB0cmVlW24gKiAyICsgMV0vKi5EYWQqLyA9IHRyZWVbbSAqIDIgKyAxXS8qLkRhZCovID0gbm9kZTtcblxuICAgIC8qIGFuZCBpbnNlcnQgdGhlIG5ldyBub2RlIGluIHRoZSBoZWFwICovXG4gICAgcy5oZWFwWzEvKlNNQUxMRVNUKi9dID0gbm9kZSsrO1xuICAgIHBxZG93bmhlYXAocywgdHJlZSwgMS8qU01BTExFU1QqLyk7XG5cbiAgfSB3aGlsZSAocy5oZWFwX2xlbiA+PSAyKTtcblxuICBzLmhlYXBbLS1zLmhlYXBfbWF4XSA9IHMuaGVhcFsxLypTTUFMTEVTVCovXTtcblxuICAvKiBBdCB0aGlzIHBvaW50LCB0aGUgZmllbGRzIGZyZXEgYW5kIGRhZCBhcmUgc2V0LiBXZSBjYW4gbm93XG4gICAqIGdlbmVyYXRlIHRoZSBiaXQgbGVuZ3Rocy5cbiAgICovXG4gIGdlbl9iaXRsZW4ocywgZGVzYyk7XG5cbiAgLyogVGhlIGZpZWxkIGxlbiBpcyBub3cgc2V0LCB3ZSBjYW4gZ2VuZXJhdGUgdGhlIGJpdCBjb2RlcyAqL1xuICBnZW5fY29kZXModHJlZSwgbWF4X2NvZGUsIHMuYmxfY291bnQpO1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogU2NhbiBhIGxpdGVyYWwgb3IgZGlzdGFuY2UgdHJlZSB0byBkZXRlcm1pbmUgdGhlIGZyZXF1ZW5jaWVzIG9mIHRoZSBjb2Rlc1xuICogaW4gdGhlIGJpdCBsZW5ndGggdHJlZS5cbiAqL1xuZnVuY3Rpb24gc2Nhbl90cmVlKHMsIHRyZWUsIG1heF9jb2RlKVxuLy8gICAgZGVmbGF0ZV9zdGF0ZSAqcztcbi8vICAgIGN0X2RhdGEgKnRyZWU7ICAgLyogdGhlIHRyZWUgdG8gYmUgc2Nhbm5lZCAqL1xuLy8gICAgaW50IG1heF9jb2RlOyAgICAvKiBhbmQgaXRzIGxhcmdlc3QgY29kZSBvZiBub24gemVybyBmcmVxdWVuY3kgKi9cbntcbiAgdmFyIG47ICAgICAgICAgICAgICAgICAgICAgLyogaXRlcmF0ZXMgb3ZlciBhbGwgdHJlZSBlbGVtZW50cyAqL1xuICB2YXIgcHJldmxlbiA9IC0xOyAgICAgICAgICAvKiBsYXN0IGVtaXR0ZWQgbGVuZ3RoICovXG4gIHZhciBjdXJsZW47ICAgICAgICAgICAgICAgIC8qIGxlbmd0aCBvZiBjdXJyZW50IGNvZGUgKi9cblxuICB2YXIgbmV4dGxlbiA9IHRyZWVbMCAqIDIgKyAxXS8qLkxlbiovOyAvKiBsZW5ndGggb2YgbmV4dCBjb2RlICovXG5cbiAgdmFyIGNvdW50ID0gMDsgICAgICAgICAgICAgLyogcmVwZWF0IGNvdW50IG9mIHRoZSBjdXJyZW50IGNvZGUgKi9cbiAgdmFyIG1heF9jb3VudCA9IDc7ICAgICAgICAgLyogbWF4IHJlcGVhdCBjb3VudCAqL1xuICB2YXIgbWluX2NvdW50ID0gNDsgICAgICAgICAvKiBtaW4gcmVwZWF0IGNvdW50ICovXG5cbiAgaWYgKG5leHRsZW4gPT09IDApIHtcbiAgICBtYXhfY291bnQgPSAxMzg7XG4gICAgbWluX2NvdW50ID0gMztcbiAgfVxuICB0cmVlWyhtYXhfY29kZSArIDEpICogMiArIDFdLyouTGVuKi8gPSAweGZmZmY7IC8qIGd1YXJkICovXG5cbiAgZm9yIChuID0gMDsgbiA8PSBtYXhfY29kZTsgbisrKSB7XG4gICAgY3VybGVuID0gbmV4dGxlbjtcbiAgICBuZXh0bGVuID0gdHJlZVsobiArIDEpICogMiArIDFdLyouTGVuKi87XG5cbiAgICBpZiAoKytjb3VudCA8IG1heF9jb3VudCAmJiBjdXJsZW4gPT09IG5leHRsZW4pIHtcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgfSBlbHNlIGlmIChjb3VudCA8IG1pbl9jb3VudCkge1xuICAgICAgcy5ibF90cmVlW2N1cmxlbiAqIDJdLyouRnJlcSovICs9IGNvdW50O1xuXG4gICAgfSBlbHNlIGlmIChjdXJsZW4gIT09IDApIHtcblxuICAgICAgaWYgKGN1cmxlbiAhPT0gcHJldmxlbikgeyBzLmJsX3RyZWVbY3VybGVuICogMl0vKi5GcmVxKi8rKzsgfVxuICAgICAgcy5ibF90cmVlW1JFUF8zXzYgKiAyXS8qLkZyZXEqLysrO1xuXG4gICAgfSBlbHNlIGlmIChjb3VudCA8PSAxMCkge1xuICAgICAgcy5ibF90cmVlW1JFUFpfM18xMCAqIDJdLyouRnJlcSovKys7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgcy5ibF90cmVlW1JFUFpfMTFfMTM4ICogMl0vKi5GcmVxKi8rKztcbiAgICB9XG5cbiAgICBjb3VudCA9IDA7XG4gICAgcHJldmxlbiA9IGN1cmxlbjtcblxuICAgIGlmIChuZXh0bGVuID09PSAwKSB7XG4gICAgICBtYXhfY291bnQgPSAxMzg7XG4gICAgICBtaW5fY291bnQgPSAzO1xuXG4gICAgfSBlbHNlIGlmIChjdXJsZW4gPT09IG5leHRsZW4pIHtcbiAgICAgIG1heF9jb3VudCA9IDY7XG4gICAgICBtaW5fY291bnQgPSAzO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIG1heF9jb3VudCA9IDc7XG4gICAgICBtaW5fY291bnQgPSA0O1xuICAgIH1cbiAgfVxufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogU2VuZCBhIGxpdGVyYWwgb3IgZGlzdGFuY2UgdHJlZSBpbiBjb21wcmVzc2VkIGZvcm0sIHVzaW5nIHRoZSBjb2RlcyBpblxuICogYmxfdHJlZS5cbiAqL1xuZnVuY3Rpb24gc2VuZF90cmVlKHMsIHRyZWUsIG1heF9jb2RlKVxuLy8gICAgZGVmbGF0ZV9zdGF0ZSAqcztcbi8vICAgIGN0X2RhdGEgKnRyZWU7IC8qIHRoZSB0cmVlIHRvIGJlIHNjYW5uZWQgKi9cbi8vICAgIGludCBtYXhfY29kZTsgICAgICAgLyogYW5kIGl0cyBsYXJnZXN0IGNvZGUgb2Ygbm9uIHplcm8gZnJlcXVlbmN5ICovXG57XG4gIHZhciBuOyAgICAgICAgICAgICAgICAgICAgIC8qIGl0ZXJhdGVzIG92ZXIgYWxsIHRyZWUgZWxlbWVudHMgKi9cbiAgdmFyIHByZXZsZW4gPSAtMTsgICAgICAgICAgLyogbGFzdCBlbWl0dGVkIGxlbmd0aCAqL1xuICB2YXIgY3VybGVuOyAgICAgICAgICAgICAgICAvKiBsZW5ndGggb2YgY3VycmVudCBjb2RlICovXG5cbiAgdmFyIG5leHRsZW4gPSB0cmVlWzAgKiAyICsgMV0vKi5MZW4qLzsgLyogbGVuZ3RoIG9mIG5leHQgY29kZSAqL1xuXG4gIHZhciBjb3VudCA9IDA7ICAgICAgICAgICAgIC8qIHJlcGVhdCBjb3VudCBvZiB0aGUgY3VycmVudCBjb2RlICovXG4gIHZhciBtYXhfY291bnQgPSA3OyAgICAgICAgIC8qIG1heCByZXBlYXQgY291bnQgKi9cbiAgdmFyIG1pbl9jb3VudCA9IDQ7ICAgICAgICAgLyogbWluIHJlcGVhdCBjb3VudCAqL1xuXG4gIC8qIHRyZWVbbWF4X2NvZGUrMV0uTGVuID0gLTE7ICovICAvKiBndWFyZCBhbHJlYWR5IHNldCAqL1xuICBpZiAobmV4dGxlbiA9PT0gMCkge1xuICAgIG1heF9jb3VudCA9IDEzODtcbiAgICBtaW5fY291bnQgPSAzO1xuICB9XG5cbiAgZm9yIChuID0gMDsgbiA8PSBtYXhfY29kZTsgbisrKSB7XG4gICAgY3VybGVuID0gbmV4dGxlbjtcbiAgICBuZXh0bGVuID0gdHJlZVsobiArIDEpICogMiArIDFdLyouTGVuKi87XG5cbiAgICBpZiAoKytjb3VudCA8IG1heF9jb3VudCAmJiBjdXJsZW4gPT09IG5leHRsZW4pIHtcbiAgICAgIGNvbnRpbnVlO1xuXG4gICAgfSBlbHNlIGlmIChjb3VudCA8IG1pbl9jb3VudCkge1xuICAgICAgZG8geyBzZW5kX2NvZGUocywgY3VybGVuLCBzLmJsX3RyZWUpOyB9IHdoaWxlICgtLWNvdW50ICE9PSAwKTtcblxuICAgIH0gZWxzZSBpZiAoY3VybGVuICE9PSAwKSB7XG4gICAgICBpZiAoY3VybGVuICE9PSBwcmV2bGVuKSB7XG4gICAgICAgIHNlbmRfY29kZShzLCBjdXJsZW4sIHMuYmxfdHJlZSk7XG4gICAgICAgIGNvdW50LS07XG4gICAgICB9XG4gICAgICAvL0Fzc2VydChjb3VudCA+PSAzICYmIGNvdW50IDw9IDYsIFwiIDNfNj9cIik7XG4gICAgICBzZW5kX2NvZGUocywgUkVQXzNfNiwgcy5ibF90cmVlKTtcbiAgICAgIHNlbmRfYml0cyhzLCBjb3VudCAtIDMsIDIpO1xuXG4gICAgfSBlbHNlIGlmIChjb3VudCA8PSAxMCkge1xuICAgICAgc2VuZF9jb2RlKHMsIFJFUFpfM18xMCwgcy5ibF90cmVlKTtcbiAgICAgIHNlbmRfYml0cyhzLCBjb3VudCAtIDMsIDMpO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbmRfY29kZShzLCBSRVBaXzExXzEzOCwgcy5ibF90cmVlKTtcbiAgICAgIHNlbmRfYml0cyhzLCBjb3VudCAtIDExLCA3KTtcbiAgICB9XG5cbiAgICBjb3VudCA9IDA7XG4gICAgcHJldmxlbiA9IGN1cmxlbjtcbiAgICBpZiAobmV4dGxlbiA9PT0gMCkge1xuICAgICAgbWF4X2NvdW50ID0gMTM4O1xuICAgICAgbWluX2NvdW50ID0gMztcblxuICAgIH0gZWxzZSBpZiAoY3VybGVuID09PSBuZXh0bGVuKSB7XG4gICAgICBtYXhfY291bnQgPSA2O1xuICAgICAgbWluX2NvdW50ID0gMztcblxuICAgIH0gZWxzZSB7XG4gICAgICBtYXhfY291bnQgPSA3O1xuICAgICAgbWluX2NvdW50ID0gNDtcbiAgICB9XG4gIH1cbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvbnN0cnVjdCB0aGUgSHVmZm1hbiB0cmVlIGZvciB0aGUgYml0IGxlbmd0aHMgYW5kIHJldHVybiB0aGUgaW5kZXggaW5cbiAqIGJsX29yZGVyIG9mIHRoZSBsYXN0IGJpdCBsZW5ndGggY29kZSB0byBzZW5kLlxuICovXG5mdW5jdGlvbiBidWlsZF9ibF90cmVlKHMpIHtcbiAgdmFyIG1heF9ibGluZGV4OyAgLyogaW5kZXggb2YgbGFzdCBiaXQgbGVuZ3RoIGNvZGUgb2Ygbm9uIHplcm8gZnJlcSAqL1xuXG4gIC8qIERldGVybWluZSB0aGUgYml0IGxlbmd0aCBmcmVxdWVuY2llcyBmb3IgbGl0ZXJhbCBhbmQgZGlzdGFuY2UgdHJlZXMgKi9cbiAgc2Nhbl90cmVlKHMsIHMuZHluX2x0cmVlLCBzLmxfZGVzYy5tYXhfY29kZSk7XG4gIHNjYW5fdHJlZShzLCBzLmR5bl9kdHJlZSwgcy5kX2Rlc2MubWF4X2NvZGUpO1xuXG4gIC8qIEJ1aWxkIHRoZSBiaXQgbGVuZ3RoIHRyZWU6ICovXG4gIGJ1aWxkX3RyZWUocywgcy5ibF9kZXNjKTtcbiAgLyogb3B0X2xlbiBub3cgaW5jbHVkZXMgdGhlIGxlbmd0aCBvZiB0aGUgdHJlZSByZXByZXNlbnRhdGlvbnMsIGV4Y2VwdFxuICAgKiB0aGUgbGVuZ3RocyBvZiB0aGUgYml0IGxlbmd0aHMgY29kZXMgYW5kIHRoZSA1KzUrNCBiaXRzIGZvciB0aGUgY291bnRzLlxuICAgKi9cblxuICAvKiBEZXRlcm1pbmUgdGhlIG51bWJlciBvZiBiaXQgbGVuZ3RoIGNvZGVzIHRvIHNlbmQuIFRoZSBwa3ppcCBmb3JtYXRcbiAgICogcmVxdWlyZXMgdGhhdCBhdCBsZWFzdCA0IGJpdCBsZW5ndGggY29kZXMgYmUgc2VudC4gKGFwcG5vdGUudHh0IHNheXNcbiAgICogMyBidXQgdGhlIGFjdHVhbCB2YWx1ZSB1c2VkIGlzIDQuKVxuICAgKi9cbiAgZm9yIChtYXhfYmxpbmRleCA9IEJMX0NPREVTIC0gMTsgbWF4X2JsaW5kZXggPj0gMzsgbWF4X2JsaW5kZXgtLSkge1xuICAgIGlmIChzLmJsX3RyZWVbYmxfb3JkZXJbbWF4X2JsaW5kZXhdICogMiArIDFdLyouTGVuKi8gIT09IDApIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICAvKiBVcGRhdGUgb3B0X2xlbiB0byBpbmNsdWRlIHRoZSBiaXQgbGVuZ3RoIHRyZWUgYW5kIGNvdW50cyAqL1xuICBzLm9wdF9sZW4gKz0gMyAqIChtYXhfYmxpbmRleCArIDEpICsgNSArIDUgKyA0O1xuICAvL1RyYWNldigoc3RkZXJyLCBcIlxcbmR5biB0cmVlczogZHluICVsZCwgc3RhdCAlbGRcIixcbiAgLy8gICAgICAgIHMtPm9wdF9sZW4sIHMtPnN0YXRpY19sZW4pKTtcblxuICByZXR1cm4gbWF4X2JsaW5kZXg7XG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTZW5kIHRoZSBoZWFkZXIgZm9yIGEgYmxvY2sgdXNpbmcgZHluYW1pYyBIdWZmbWFuIHRyZWVzOiB0aGUgY291bnRzLCB0aGVcbiAqIGxlbmd0aHMgb2YgdGhlIGJpdCBsZW5ndGggY29kZXMsIHRoZSBsaXRlcmFsIHRyZWUgYW5kIHRoZSBkaXN0YW5jZSB0cmVlLlxuICogSU4gYXNzZXJ0aW9uOiBsY29kZXMgPj0gMjU3LCBkY29kZXMgPj0gMSwgYmxjb2RlcyA+PSA0LlxuICovXG5mdW5jdGlvbiBzZW5kX2FsbF90cmVlcyhzLCBsY29kZXMsIGRjb2RlcywgYmxjb2Rlcylcbi8vICAgIGRlZmxhdGVfc3RhdGUgKnM7XG4vLyAgICBpbnQgbGNvZGVzLCBkY29kZXMsIGJsY29kZXM7IC8qIG51bWJlciBvZiBjb2RlcyBmb3IgZWFjaCB0cmVlICovXG57XG4gIHZhciByYW5rOyAgICAgICAgICAgICAgICAgICAgLyogaW5kZXggaW4gYmxfb3JkZXIgKi9cblxuICAvL0Fzc2VydCAobGNvZGVzID49IDI1NyAmJiBkY29kZXMgPj0gMSAmJiBibGNvZGVzID49IDQsIFwibm90IGVub3VnaCBjb2Rlc1wiKTtcbiAgLy9Bc3NlcnQgKGxjb2RlcyA8PSBMX0NPREVTICYmIGRjb2RlcyA8PSBEX0NPREVTICYmIGJsY29kZXMgPD0gQkxfQ09ERVMsXG4gIC8vICAgICAgICBcInRvbyBtYW55IGNvZGVzXCIpO1xuICAvL1RyYWNldigoc3RkZXJyLCBcIlxcbmJsIGNvdW50czogXCIpKTtcbiAgc2VuZF9iaXRzKHMsIGxjb2RlcyAtIDI1NywgNSk7IC8qIG5vdCArMjU1IGFzIHN0YXRlZCBpbiBhcHBub3RlLnR4dCAqL1xuICBzZW5kX2JpdHMocywgZGNvZGVzIC0gMSwgICA1KTtcbiAgc2VuZF9iaXRzKHMsIGJsY29kZXMgLSA0LCAgNCk7IC8qIG5vdCAtMyBhcyBzdGF0ZWQgaW4gYXBwbm90ZS50eHQgKi9cbiAgZm9yIChyYW5rID0gMDsgcmFuayA8IGJsY29kZXM7IHJhbmsrKykge1xuICAgIC8vVHJhY2V2KChzdGRlcnIsIFwiXFxuYmwgY29kZSAlMmQgXCIsIGJsX29yZGVyW3JhbmtdKSk7XG4gICAgc2VuZF9iaXRzKHMsIHMuYmxfdHJlZVtibF9vcmRlcltyYW5rXSAqIDIgKyAxXS8qLkxlbiovLCAzKTtcbiAgfVxuICAvL1RyYWNldigoc3RkZXJyLCBcIlxcbmJsIHRyZWU6IHNlbnQgJWxkXCIsIHMtPmJpdHNfc2VudCkpO1xuXG4gIHNlbmRfdHJlZShzLCBzLmR5bl9sdHJlZSwgbGNvZGVzIC0gMSk7IC8qIGxpdGVyYWwgdHJlZSAqL1xuICAvL1RyYWNldigoc3RkZXJyLCBcIlxcbmxpdCB0cmVlOiBzZW50ICVsZFwiLCBzLT5iaXRzX3NlbnQpKTtcblxuICBzZW5kX3RyZWUocywgcy5keW5fZHRyZWUsIGRjb2RlcyAtIDEpOyAvKiBkaXN0YW5jZSB0cmVlICovXG4gIC8vVHJhY2V2KChzdGRlcnIsIFwiXFxuZGlzdCB0cmVlOiBzZW50ICVsZFwiLCBzLT5iaXRzX3NlbnQpKTtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENoZWNrIGlmIHRoZSBkYXRhIHR5cGUgaXMgVEVYVCBvciBCSU5BUlksIHVzaW5nIHRoZSBmb2xsb3dpbmcgYWxnb3JpdGhtOlxuICogLSBURVhUIGlmIHRoZSB0d28gY29uZGl0aW9ucyBiZWxvdyBhcmUgc2F0aXNmaWVkOlxuICogICAgYSkgVGhlcmUgYXJlIG5vIG5vbi1wb3J0YWJsZSBjb250cm9sIGNoYXJhY3RlcnMgYmVsb25naW5nIHRvIHRoZVxuICogICAgICAgXCJibGFjayBsaXN0XCIgKDAuLjYsIDE0Li4yNSwgMjguLjMxKS5cbiAqICAgIGIpIFRoZXJlIGlzIGF0IGxlYXN0IG9uZSBwcmludGFibGUgY2hhcmFjdGVyIGJlbG9uZ2luZyB0byB0aGVcbiAqICAgICAgIFwid2hpdGUgbGlzdFwiICg5IHtUQUJ9LCAxMCB7TEZ9LCAxMyB7Q1J9LCAzMi4uMjU1KS5cbiAqIC0gQklOQVJZIG90aGVyd2lzZS5cbiAqIC0gVGhlIGZvbGxvd2luZyBwYXJ0aWFsbHktcG9ydGFibGUgY29udHJvbCBjaGFyYWN0ZXJzIGZvcm0gYVxuICogICBcImdyYXkgbGlzdFwiIHRoYXQgaXMgaWdub3JlZCBpbiB0aGlzIGRldGVjdGlvbiBhbGdvcml0aG06XG4gKiAgICg3IHtCRUx9LCA4IHtCU30sIDExIHtWVH0sIDEyIHtGRn0sIDI2IHtTVUJ9LCAyNyB7RVNDfSkuXG4gKiBJTiBhc3NlcnRpb246IHRoZSBmaWVsZHMgRnJlcSBvZiBkeW5fbHRyZWUgYXJlIHNldC5cbiAqL1xuZnVuY3Rpb24gZGV0ZWN0X2RhdGFfdHlwZShzKSB7XG4gIC8qIGJsYWNrX21hc2sgaXMgdGhlIGJpdCBtYXNrIG9mIGJsYWNrLWxpc3RlZCBieXRlc1xuICAgKiBzZXQgYml0cyAwLi42LCAxNC4uMjUsIGFuZCAyOC4uMzFcbiAgICogMHhmM2ZmYzA3ZiA9IGJpbmFyeSAxMTExMDAxMTExMTExMTExMTEwMDAwMDAwMTExMTExMVxuICAgKi9cbiAgdmFyIGJsYWNrX21hc2sgPSAweGYzZmZjMDdmO1xuICB2YXIgbjtcblxuICAvKiBDaGVjayBmb3Igbm9uLXRleHR1YWwgKFwiYmxhY2stbGlzdGVkXCIpIGJ5dGVzLiAqL1xuICBmb3IgKG4gPSAwOyBuIDw9IDMxOyBuKyssIGJsYWNrX21hc2sgPj4+PSAxKSB7XG4gICAgaWYgKChibGFja19tYXNrICYgMSkgJiYgKHMuZHluX2x0cmVlW24gKiAyXS8qLkZyZXEqLyAhPT0gMCkpIHtcbiAgICAgIHJldHVybiBaX0JJTkFSWTtcbiAgICB9XG4gIH1cblxuICAvKiBDaGVjayBmb3IgdGV4dHVhbCAoXCJ3aGl0ZS1saXN0ZWRcIikgYnl0ZXMuICovXG4gIGlmIChzLmR5bl9sdHJlZVs5ICogMl0vKi5GcmVxKi8gIT09IDAgfHwgcy5keW5fbHRyZWVbMTAgKiAyXS8qLkZyZXEqLyAhPT0gMCB8fFxuICAgICAgcy5keW5fbHRyZWVbMTMgKiAyXS8qLkZyZXEqLyAhPT0gMCkge1xuICAgIHJldHVybiBaX1RFWFQ7XG4gIH1cbiAgZm9yIChuID0gMzI7IG4gPCBMSVRFUkFMUzsgbisrKSB7XG4gICAgaWYgKHMuZHluX2x0cmVlW24gKiAyXS8qLkZyZXEqLyAhPT0gMCkge1xuICAgICAgcmV0dXJuIFpfVEVYVDtcbiAgICB9XG4gIH1cblxuICAvKiBUaGVyZSBhcmUgbm8gXCJibGFjay1saXN0ZWRcIiBvciBcIndoaXRlLWxpc3RlZFwiIGJ5dGVzOlxuICAgKiB0aGlzIHN0cmVhbSBlaXRoZXIgaXMgZW1wdHkgb3IgaGFzIHRvbGVyYXRlZCAoXCJncmF5LWxpc3RlZFwiKSBieXRlcyBvbmx5LlxuICAgKi9cbiAgcmV0dXJuIFpfQklOQVJZO1xufVxuXG5cbnZhciBzdGF0aWNfaW5pdF9kb25lID0gZmFsc2U7XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogSW5pdGlhbGl6ZSB0aGUgdHJlZSBkYXRhIHN0cnVjdHVyZXMgZm9yIGEgbmV3IHpsaWIgc3RyZWFtLlxuICovXG5mdW5jdGlvbiBfdHJfaW5pdChzKVxue1xuXG4gIGlmICghc3RhdGljX2luaXRfZG9uZSkge1xuICAgIHRyX3N0YXRpY19pbml0KCk7XG4gICAgc3RhdGljX2luaXRfZG9uZSA9IHRydWU7XG4gIH1cblxuICBzLmxfZGVzYyAgPSBuZXcgVHJlZURlc2Mocy5keW5fbHRyZWUsIHN0YXRpY19sX2Rlc2MpO1xuICBzLmRfZGVzYyAgPSBuZXcgVHJlZURlc2Mocy5keW5fZHRyZWUsIHN0YXRpY19kX2Rlc2MpO1xuICBzLmJsX2Rlc2MgPSBuZXcgVHJlZURlc2Mocy5ibF90cmVlLCBzdGF0aWNfYmxfZGVzYyk7XG5cbiAgcy5iaV9idWYgPSAwO1xuICBzLmJpX3ZhbGlkID0gMDtcblxuICAvKiBJbml0aWFsaXplIHRoZSBmaXJzdCBibG9jayBvZiB0aGUgZmlyc3QgZmlsZTogKi9cbiAgaW5pdF9ibG9jayhzKTtcbn1cblxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFNlbmQgYSBzdG9yZWQgYmxvY2tcbiAqL1xuZnVuY3Rpb24gX3RyX3N0b3JlZF9ibG9jayhzLCBidWYsIHN0b3JlZF9sZW4sIGxhc3QpXG4vL0RlZmxhdGVTdGF0ZSAqcztcbi8vY2hhcmYgKmJ1ZjsgICAgICAgLyogaW5wdXQgYmxvY2sgKi9cbi8vdWxnIHN0b3JlZF9sZW47ICAgLyogbGVuZ3RoIG9mIGlucHV0IGJsb2NrICovXG4vL2ludCBsYXN0OyAgICAgICAgIC8qIG9uZSBpZiB0aGlzIGlzIHRoZSBsYXN0IGJsb2NrIGZvciBhIGZpbGUgKi9cbntcbiAgc2VuZF9iaXRzKHMsIChTVE9SRURfQkxPQ0sgPDwgMSkgKyAobGFzdCA/IDEgOiAwKSwgMyk7ICAgIC8qIHNlbmQgYmxvY2sgdHlwZSAqL1xuICBjb3B5X2Jsb2NrKHMsIGJ1Ziwgc3RvcmVkX2xlbiwgdHJ1ZSk7IC8qIHdpdGggaGVhZGVyICovXG59XG5cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBTZW5kIG9uZSBlbXB0eSBzdGF0aWMgYmxvY2sgdG8gZ2l2ZSBlbm91Z2ggbG9va2FoZWFkIGZvciBpbmZsYXRlLlxuICogVGhpcyB0YWtlcyAxMCBiaXRzLCBvZiB3aGljaCA3IG1heSByZW1haW4gaW4gdGhlIGJpdCBidWZmZXIuXG4gKi9cbmZ1bmN0aW9uIF90cl9hbGlnbihzKSB7XG4gIHNlbmRfYml0cyhzLCBTVEFUSUNfVFJFRVMgPDwgMSwgMyk7XG4gIHNlbmRfY29kZShzLCBFTkRfQkxPQ0ssIHN0YXRpY19sdHJlZSk7XG4gIGJpX2ZsdXNoKHMpO1xufVxuXG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogRGV0ZXJtaW5lIHRoZSBiZXN0IGVuY29kaW5nIGZvciB0aGUgY3VycmVudCBibG9jazogZHluYW1pYyB0cmVlcywgc3RhdGljXG4gKiB0cmVlcyBvciBzdG9yZSwgYW5kIG91dHB1dCB0aGUgZW5jb2RlZCBibG9jayB0byB0aGUgemlwIGZpbGUuXG4gKi9cbmZ1bmN0aW9uIF90cl9mbHVzaF9ibG9jayhzLCBidWYsIHN0b3JlZF9sZW4sIGxhc3QpXG4vL0RlZmxhdGVTdGF0ZSAqcztcbi8vY2hhcmYgKmJ1ZjsgICAgICAgLyogaW5wdXQgYmxvY2ssIG9yIE5VTEwgaWYgdG9vIG9sZCAqL1xuLy91bGcgc3RvcmVkX2xlbjsgICAvKiBsZW5ndGggb2YgaW5wdXQgYmxvY2sgKi9cbi8vaW50IGxhc3Q7ICAgICAgICAgLyogb25lIGlmIHRoaXMgaXMgdGhlIGxhc3QgYmxvY2sgZm9yIGEgZmlsZSAqL1xue1xuICB2YXIgb3B0X2xlbmIsIHN0YXRpY19sZW5iOyAgLyogb3B0X2xlbiBhbmQgc3RhdGljX2xlbiBpbiBieXRlcyAqL1xuICB2YXIgbWF4X2JsaW5kZXggPSAwOyAgICAgICAgLyogaW5kZXggb2YgbGFzdCBiaXQgbGVuZ3RoIGNvZGUgb2Ygbm9uIHplcm8gZnJlcSAqL1xuXG4gIC8qIEJ1aWxkIHRoZSBIdWZmbWFuIHRyZWVzIHVubGVzcyBhIHN0b3JlZCBibG9jayBpcyBmb3JjZWQgKi9cbiAgaWYgKHMubGV2ZWwgPiAwKSB7XG5cbiAgICAvKiBDaGVjayBpZiB0aGUgZmlsZSBpcyBiaW5hcnkgb3IgdGV4dCAqL1xuICAgIGlmIChzLnN0cm0uZGF0YV90eXBlID09PSBaX1VOS05PV04pIHtcbiAgICAgIHMuc3RybS5kYXRhX3R5cGUgPSBkZXRlY3RfZGF0YV90eXBlKHMpO1xuICAgIH1cblxuICAgIC8qIENvbnN0cnVjdCB0aGUgbGl0ZXJhbCBhbmQgZGlzdGFuY2UgdHJlZXMgKi9cbiAgICBidWlsZF90cmVlKHMsIHMubF9kZXNjKTtcbiAgICAvLyBUcmFjZXYoKHN0ZGVyciwgXCJcXG5saXQgZGF0YTogZHluICVsZCwgc3RhdCAlbGRcIiwgcy0+b3B0X2xlbixcbiAgICAvLyAgICAgICAgcy0+c3RhdGljX2xlbikpO1xuXG4gICAgYnVpbGRfdHJlZShzLCBzLmRfZGVzYyk7XG4gICAgLy8gVHJhY2V2KChzdGRlcnIsIFwiXFxuZGlzdCBkYXRhOiBkeW4gJWxkLCBzdGF0ICVsZFwiLCBzLT5vcHRfbGVuLFxuICAgIC8vICAgICAgICBzLT5zdGF0aWNfbGVuKSk7XG4gICAgLyogQXQgdGhpcyBwb2ludCwgb3B0X2xlbiBhbmQgc3RhdGljX2xlbiBhcmUgdGhlIHRvdGFsIGJpdCBsZW5ndGhzIG9mXG4gICAgICogdGhlIGNvbXByZXNzZWQgYmxvY2sgZGF0YSwgZXhjbHVkaW5nIHRoZSB0cmVlIHJlcHJlc2VudGF0aW9ucy5cbiAgICAgKi9cblxuICAgIC8qIEJ1aWxkIHRoZSBiaXQgbGVuZ3RoIHRyZWUgZm9yIHRoZSBhYm92ZSB0d28gdHJlZXMsIGFuZCBnZXQgdGhlIGluZGV4XG4gICAgICogaW4gYmxfb3JkZXIgb2YgdGhlIGxhc3QgYml0IGxlbmd0aCBjb2RlIHRvIHNlbmQuXG4gICAgICovXG4gICAgbWF4X2JsaW5kZXggPSBidWlsZF9ibF90cmVlKHMpO1xuXG4gICAgLyogRGV0ZXJtaW5lIHRoZSBiZXN0IGVuY29kaW5nLiBDb21wdXRlIHRoZSBibG9jayBsZW5ndGhzIGluIGJ5dGVzLiAqL1xuICAgIG9wdF9sZW5iID0gKHMub3B0X2xlbiArIDMgKyA3KSA+Pj4gMztcbiAgICBzdGF0aWNfbGVuYiA9IChzLnN0YXRpY19sZW4gKyAzICsgNykgPj4+IDM7XG5cbiAgICAvLyBUcmFjZXYoKHN0ZGVyciwgXCJcXG5vcHQgJWx1KCVsdSkgc3RhdCAlbHUoJWx1KSBzdG9yZWQgJWx1IGxpdCAldSBcIixcbiAgICAvLyAgICAgICAgb3B0X2xlbmIsIHMtPm9wdF9sZW4sIHN0YXRpY19sZW5iLCBzLT5zdGF0aWNfbGVuLCBzdG9yZWRfbGVuLFxuICAgIC8vICAgICAgICBzLT5sYXN0X2xpdCkpO1xuXG4gICAgaWYgKHN0YXRpY19sZW5iIDw9IG9wdF9sZW5iKSB7IG9wdF9sZW5iID0gc3RhdGljX2xlbmI7IH1cblxuICB9IGVsc2Uge1xuICAgIC8vIEFzc2VydChidWYgIT0gKGNoYXIqKTAsIFwibG9zdCBidWZcIik7XG4gICAgb3B0X2xlbmIgPSBzdGF0aWNfbGVuYiA9IHN0b3JlZF9sZW4gKyA1OyAvKiBmb3JjZSBhIHN0b3JlZCBibG9jayAqL1xuICB9XG5cbiAgaWYgKChzdG9yZWRfbGVuICsgNCA8PSBvcHRfbGVuYikgJiYgKGJ1ZiAhPT0gLTEpKSB7XG4gICAgLyogNDogdHdvIHdvcmRzIGZvciB0aGUgbGVuZ3RocyAqL1xuXG4gICAgLyogVGhlIHRlc3QgYnVmICE9IE5VTEwgaXMgb25seSBuZWNlc3NhcnkgaWYgTElUX0JVRlNJWkUgPiBXU0laRS5cbiAgICAgKiBPdGhlcndpc2Ugd2UgY2FuJ3QgaGF2ZSBwcm9jZXNzZWQgbW9yZSB0aGFuIFdTSVpFIGlucHV0IGJ5dGVzIHNpbmNlXG4gICAgICogdGhlIGxhc3QgYmxvY2sgZmx1c2gsIGJlY2F1c2UgY29tcHJlc3Npb24gd291bGQgaGF2ZSBiZWVuXG4gICAgICogc3VjY2Vzc2Z1bC4gSWYgTElUX0JVRlNJWkUgPD0gV1NJWkUsIGl0IGlzIG5ldmVyIHRvbyBsYXRlIHRvXG4gICAgICogdHJhbnNmb3JtIGEgYmxvY2sgaW50byBhIHN0b3JlZCBibG9jay5cbiAgICAgKi9cbiAgICBfdHJfc3RvcmVkX2Jsb2NrKHMsIGJ1Ziwgc3RvcmVkX2xlbiwgbGFzdCk7XG5cbiAgfSBlbHNlIGlmIChzLnN0cmF0ZWd5ID09PSBaX0ZJWEVEIHx8IHN0YXRpY19sZW5iID09PSBvcHRfbGVuYikge1xuXG4gICAgc2VuZF9iaXRzKHMsIChTVEFUSUNfVFJFRVMgPDwgMSkgKyAobGFzdCA/IDEgOiAwKSwgMyk7XG4gICAgY29tcHJlc3NfYmxvY2socywgc3RhdGljX2x0cmVlLCBzdGF0aWNfZHRyZWUpO1xuXG4gIH0gZWxzZSB7XG4gICAgc2VuZF9iaXRzKHMsIChEWU5fVFJFRVMgPDwgMSkgKyAobGFzdCA/IDEgOiAwKSwgMyk7XG4gICAgc2VuZF9hbGxfdHJlZXMocywgcy5sX2Rlc2MubWF4X2NvZGUgKyAxLCBzLmRfZGVzYy5tYXhfY29kZSArIDEsIG1heF9ibGluZGV4ICsgMSk7XG4gICAgY29tcHJlc3NfYmxvY2socywgcy5keW5fbHRyZWUsIHMuZHluX2R0cmVlKTtcbiAgfVxuICAvLyBBc3NlcnQgKHMtPmNvbXByZXNzZWRfbGVuID09IHMtPmJpdHNfc2VudCwgXCJiYWQgY29tcHJlc3NlZCBzaXplXCIpO1xuICAvKiBUaGUgYWJvdmUgY2hlY2sgaXMgbWFkZSBtb2QgMl4zMiwgZm9yIGZpbGVzIGxhcmdlciB0aGFuIDUxMiBNQlxuICAgKiBhbmQgdUxvbmcgaW1wbGVtZW50ZWQgb24gMzIgYml0cy5cbiAgICovXG4gIGluaXRfYmxvY2socyk7XG5cbiAgaWYgKGxhc3QpIHtcbiAgICBiaV93aW5kdXAocyk7XG4gIH1cbiAgLy8gVHJhY2V2KChzdGRlcnIsXCJcXG5jb21wcmxlbiAlbHUoJWx1KSBcIiwgcy0+Y29tcHJlc3NlZF9sZW4+PjMsXG4gIC8vICAgICAgIHMtPmNvbXByZXNzZWRfbGVuLTcqbGFzdCkpO1xufVxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFNhdmUgdGhlIG1hdGNoIGluZm8gYW5kIHRhbGx5IHRoZSBmcmVxdWVuY3kgY291bnRzLiBSZXR1cm4gdHJ1ZSBpZlxuICogdGhlIGN1cnJlbnQgYmxvY2sgbXVzdCBiZSBmbHVzaGVkLlxuICovXG5mdW5jdGlvbiBfdHJfdGFsbHkocywgZGlzdCwgbGMpXG4vLyAgICBkZWZsYXRlX3N0YXRlICpzO1xuLy8gICAgdW5zaWduZWQgZGlzdDsgIC8qIGRpc3RhbmNlIG9mIG1hdGNoZWQgc3RyaW5nICovXG4vLyAgICB1bnNpZ25lZCBsYzsgICAgLyogbWF0Y2ggbGVuZ3RoLU1JTl9NQVRDSCBvciB1bm1hdGNoZWQgY2hhciAoaWYgZGlzdD09MCkgKi9cbntcbiAgLy92YXIgb3V0X2xlbmd0aCwgaW5fbGVuZ3RoLCBkY29kZTtcblxuICBzLnBlbmRpbmdfYnVmW3MuZF9idWYgKyBzLmxhc3RfbGl0ICogMl0gICAgID0gKGRpc3QgPj4+IDgpICYgMHhmZjtcbiAgcy5wZW5kaW5nX2J1ZltzLmRfYnVmICsgcy5sYXN0X2xpdCAqIDIgKyAxXSA9IGRpc3QgJiAweGZmO1xuXG4gIHMucGVuZGluZ19idWZbcy5sX2J1ZiArIHMubGFzdF9saXRdID0gbGMgJiAweGZmO1xuICBzLmxhc3RfbGl0Kys7XG5cbiAgaWYgKGRpc3QgPT09IDApIHtcbiAgICAvKiBsYyBpcyB0aGUgdW5tYXRjaGVkIGNoYXIgKi9cbiAgICBzLmR5bl9sdHJlZVtsYyAqIDJdLyouRnJlcSovKys7XG4gIH0gZWxzZSB7XG4gICAgcy5tYXRjaGVzKys7XG4gICAgLyogSGVyZSwgbGMgaXMgdGhlIG1hdGNoIGxlbmd0aCAtIE1JTl9NQVRDSCAqL1xuICAgIGRpc3QtLTsgICAgICAgICAgICAgLyogZGlzdCA9IG1hdGNoIGRpc3RhbmNlIC0gMSAqL1xuICAgIC8vQXNzZXJ0KCh1c2gpZGlzdCA8ICh1c2gpTUFYX0RJU1QocykgJiZcbiAgICAvLyAgICAgICAodXNoKWxjIDw9ICh1c2gpKE1BWF9NQVRDSC1NSU5fTUFUQ0gpICYmXG4gICAgLy8gICAgICAgKHVzaClkX2NvZGUoZGlzdCkgPCAodXNoKURfQ09ERVMsICBcIl90cl90YWxseTogYmFkIG1hdGNoXCIpO1xuXG4gICAgcy5keW5fbHRyZWVbKF9sZW5ndGhfY29kZVtsY10gKyBMSVRFUkFMUyArIDEpICogMl0vKi5GcmVxKi8rKztcbiAgICBzLmR5bl9kdHJlZVtkX2NvZGUoZGlzdCkgKiAyXS8qLkZyZXEqLysrO1xuICB9XG5cbi8vICghKSBUaGlzIGJsb2NrIGlzIGRpc2FibGVkIGluIHpsaWIgZGVmYXVsdHMsXG4vLyBkb24ndCBlbmFibGUgaXQgZm9yIGJpbmFyeSBjb21wYXRpYmlsaXR5XG5cbi8vI2lmZGVmIFRSVU5DQVRFX0JMT0NLXG4vLyAgLyogVHJ5IHRvIGd1ZXNzIGlmIGl0IGlzIHByb2ZpdGFibGUgdG8gc3RvcCB0aGUgY3VycmVudCBibG9jayBoZXJlICovXG4vLyAgaWYgKChzLmxhc3RfbGl0ICYgMHgxZmZmKSA9PT0gMCAmJiBzLmxldmVsID4gMikge1xuLy8gICAgLyogQ29tcHV0ZSBhbiB1cHBlciBib3VuZCBmb3IgdGhlIGNvbXByZXNzZWQgbGVuZ3RoICovXG4vLyAgICBvdXRfbGVuZ3RoID0gcy5sYXN0X2xpdCo4O1xuLy8gICAgaW5fbGVuZ3RoID0gcy5zdHJzdGFydCAtIHMuYmxvY2tfc3RhcnQ7XG4vL1xuLy8gICAgZm9yIChkY29kZSA9IDA7IGRjb2RlIDwgRF9DT0RFUzsgZGNvZGUrKykge1xuLy8gICAgICBvdXRfbGVuZ3RoICs9IHMuZHluX2R0cmVlW2Rjb2RlKjJdLyouRnJlcSovICogKDUgKyBleHRyYV9kYml0c1tkY29kZV0pO1xuLy8gICAgfVxuLy8gICAgb3V0X2xlbmd0aCA+Pj49IDM7XG4vLyAgICAvL1RyYWNldigoc3RkZXJyLFwiXFxubGFzdF9saXQgJXUsIGluICVsZCwgb3V0IH4lbGQoJWxkJSUpIFwiLFxuLy8gICAgLy8gICAgICAgcy0+bGFzdF9saXQsIGluX2xlbmd0aCwgb3V0X2xlbmd0aCxcbi8vICAgIC8vICAgICAgIDEwMEwgLSBvdXRfbGVuZ3RoKjEwMEwvaW5fbGVuZ3RoKSk7XG4vLyAgICBpZiAocy5tYXRjaGVzIDwgKHMubGFzdF9saXQ+PjEpLyppbnQgLzIqLyAmJiBvdXRfbGVuZ3RoIDwgKGluX2xlbmd0aD4+MSkvKmludCAvMiovKSB7XG4vLyAgICAgIHJldHVybiB0cnVlO1xuLy8gICAgfVxuLy8gIH1cbi8vI2VuZGlmXG5cbiAgcmV0dXJuIChzLmxhc3RfbGl0ID09PSBzLmxpdF9idWZzaXplIC0gMSk7XG4gIC8qIFdlIGF2b2lkIGVxdWFsaXR5IHdpdGggbGl0X2J1ZnNpemUgYmVjYXVzZSBvZiB3cmFwYXJvdW5kIGF0IDY0S1xuICAgKiBvbiAxNiBiaXQgbWFjaGluZXMgYW5kIGJlY2F1c2Ugc3RvcmVkIGJsb2NrcyBhcmUgcmVzdHJpY3RlZCB0b1xuICAgKiA2NEstMSBieXRlcy5cbiAgICovXG59XG5cbmV4cG9ydHMuX3RyX2luaXQgID0gX3RyX2luaXQ7XG5leHBvcnRzLl90cl9zdG9yZWRfYmxvY2sgPSBfdHJfc3RvcmVkX2Jsb2NrO1xuZXhwb3J0cy5fdHJfZmx1c2hfYmxvY2sgID0gX3RyX2ZsdXNoX2Jsb2NrO1xuZXhwb3J0cy5fdHJfdGFsbHkgPSBfdHJfdGFsbHk7XG5leHBvcnRzLl90cl9hbGlnbiA9IF90cl9hbGlnbjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLy8gKEMpIDE5OTUtMjAxMyBKZWFuLWxvdXAgR2FpbGx5IGFuZCBNYXJrIEFkbGVyXG4vLyAoQykgMjAxNC0yMDE3IFZpdGFseSBQdXpyaW4gYW5kIEFuZHJleSBUdXBpdHNpblxuLy9cbi8vIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgJ2FzLWlzJywgd2l0aG91dCBhbnkgZXhwcmVzcyBvciBpbXBsaWVkXG4vLyB3YXJyYW50eS4gSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXNcbi8vIGFyaXNpbmcgZnJvbSB0aGUgdXNlIG9mIHRoaXMgc29mdHdhcmUuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsXG4vLyBpbmNsdWRpbmcgY29tbWVyY2lhbCBhcHBsaWNhdGlvbnMsIGFuZCB0byBhbHRlciBpdCBhbmQgcmVkaXN0cmlidXRlIGl0XG4vLyBmcmVlbHksIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyByZXN0cmljdGlvbnM6XG4vL1xuLy8gMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvZnR3YXJlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkOyB5b3UgbXVzdCBub3Rcbi8vICAgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmVcbi8vICAgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlXG4vLyAgIGFwcHJlY2lhdGVkIGJ1dCBpcyBub3QgcmVxdWlyZWQuXG4vLyAyLiBBbHRlcmVkIHNvdXJjZSB2ZXJzaW9ucyBtdXN0IGJlIHBsYWlubHkgbWFya2VkIGFzIHN1Y2gsIGFuZCBtdXN0IG5vdCBiZVxuLy8gICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuXG4vLyAzLiBUaGlzIG5vdGljZSBtYXkgbm90IGJlIHJlbW92ZWQgb3IgYWx0ZXJlZCBmcm9tIGFueSBzb3VyY2UgZGlzdHJpYnV0aW9uLlxuXG5mdW5jdGlvbiBaU3RyZWFtKCkge1xuICAvKiBuZXh0IGlucHV0IGJ5dGUgKi9cbiAgdGhpcy5pbnB1dCA9IG51bGw7IC8vIEpTIHNwZWNpZmljLCBiZWNhdXNlIHdlIGhhdmUgbm8gcG9pbnRlcnNcbiAgdGhpcy5uZXh0X2luID0gMDtcbiAgLyogbnVtYmVyIG9mIGJ5dGVzIGF2YWlsYWJsZSBhdCBpbnB1dCAqL1xuICB0aGlzLmF2YWlsX2luID0gMDtcbiAgLyogdG90YWwgbnVtYmVyIG9mIGlucHV0IGJ5dGVzIHJlYWQgc28gZmFyICovXG4gIHRoaXMudG90YWxfaW4gPSAwO1xuICAvKiBuZXh0IG91dHB1dCBieXRlIHNob3VsZCBiZSBwdXQgdGhlcmUgKi9cbiAgdGhpcy5vdXRwdXQgPSBudWxsOyAvLyBKUyBzcGVjaWZpYywgYmVjYXVzZSB3ZSBoYXZlIG5vIHBvaW50ZXJzXG4gIHRoaXMubmV4dF9vdXQgPSAwO1xuICAvKiByZW1haW5pbmcgZnJlZSBzcGFjZSBhdCBvdXRwdXQgKi9cbiAgdGhpcy5hdmFpbF9vdXQgPSAwO1xuICAvKiB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgb3V0cHV0IHNvIGZhciAqL1xuICB0aGlzLnRvdGFsX291dCA9IDA7XG4gIC8qIGxhc3QgZXJyb3IgbWVzc2FnZSwgTlVMTCBpZiBubyBlcnJvciAqL1xuICB0aGlzLm1zZyA9ICcnLypaX05VTEwqLztcbiAgLyogbm90IHZpc2libGUgYnkgYXBwbGljYXRpb25zICovXG4gIHRoaXMuc3RhdGUgPSBudWxsO1xuICAvKiBiZXN0IGd1ZXNzIGFib3V0IHRoZSBkYXRhIHR5cGU6IGJpbmFyeSBvciB0ZXh0ICovXG4gIHRoaXMuZGF0YV90eXBlID0gMi8qWl9VTktOT1dOKi87XG4gIC8qIGFkbGVyMzIgdmFsdWUgb2YgdGhlIHVuY29tcHJlc3NlZCBkYXRhICovXG4gIHRoaXMuYWRsZXIgPSAwO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFpTdHJlYW07XG4iLCJtb2R1bGUuZXhwb3J0cz17XCIyLjE2Ljg0MC4xLjEwMS4zLjQuMS4xXCI6IFwiYWVzLTEyOC1lY2JcIixcblwiMi4xNi44NDAuMS4xMDEuMy40LjEuMlwiOiBcImFlcy0xMjgtY2JjXCIsXG5cIjIuMTYuODQwLjEuMTAxLjMuNC4xLjNcIjogXCJhZXMtMTI4LW9mYlwiLFxuXCIyLjE2Ljg0MC4xLjEwMS4zLjQuMS40XCI6IFwiYWVzLTEyOC1jZmJcIixcblwiMi4xNi44NDAuMS4xMDEuMy40LjEuMjFcIjogXCJhZXMtMTkyLWVjYlwiLFxuXCIyLjE2Ljg0MC4xLjEwMS4zLjQuMS4yMlwiOiBcImFlcy0xOTItY2JjXCIsXG5cIjIuMTYuODQwLjEuMTAxLjMuNC4xLjIzXCI6IFwiYWVzLTE5Mi1vZmJcIixcblwiMi4xNi44NDAuMS4xMDEuMy40LjEuMjRcIjogXCJhZXMtMTkyLWNmYlwiLFxuXCIyLjE2Ljg0MC4xLjEwMS4zLjQuMS40MVwiOiBcImFlcy0yNTYtZWNiXCIsXG5cIjIuMTYuODQwLjEuMTAxLjMuNC4xLjQyXCI6IFwiYWVzLTI1Ni1jYmNcIixcblwiMi4xNi44NDAuMS4xMDEuMy40LjEuNDNcIjogXCJhZXMtMjU2LW9mYlwiLFxuXCIyLjE2Ljg0MC4xLjEwMS4zLjQuMS40NFwiOiBcImFlcy0yNTYtY2ZiXCJcbn0iLCIvLyBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9pbmR1dG55L3NlbGYtc2lnbmVkL2Jsb2IvZ2gtcGFnZXMvbGliL2FzbjEuanNcbi8vIEZlZG9yLCB5b3UgYXJlIGFtYXppbmcuXG4ndXNlIHN0cmljdCdcblxudmFyIGFzbjEgPSByZXF1aXJlKCdhc24xLmpzJylcblxuZXhwb3J0cy5jZXJ0aWZpY2F0ZSA9IHJlcXVpcmUoJy4vY2VydGlmaWNhdGUnKVxuXG52YXIgUlNBUHJpdmF0ZUtleSA9IGFzbjEuZGVmaW5lKCdSU0FQcml2YXRlS2V5JywgZnVuY3Rpb24gKCkge1xuICB0aGlzLnNlcSgpLm9iaihcbiAgICB0aGlzLmtleSgndmVyc2lvbicpLmludCgpLFxuICAgIHRoaXMua2V5KCdtb2R1bHVzJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3B1YmxpY0V4cG9uZW50JykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3ByaXZhdGVFeHBvbmVudCcpLmludCgpLFxuICAgIHRoaXMua2V5KCdwcmltZTEnKS5pbnQoKSxcbiAgICB0aGlzLmtleSgncHJpbWUyJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ2V4cG9uZW50MScpLmludCgpLFxuICAgIHRoaXMua2V5KCdleHBvbmVudDInKS5pbnQoKSxcbiAgICB0aGlzLmtleSgnY29lZmZpY2llbnQnKS5pbnQoKVxuICApXG59KVxuZXhwb3J0cy5SU0FQcml2YXRlS2V5ID0gUlNBUHJpdmF0ZUtleVxuXG52YXIgUlNBUHVibGljS2V5ID0gYXNuMS5kZWZpbmUoJ1JTQVB1YmxpY0tleScsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ21vZHVsdXMnKS5pbnQoKSxcbiAgICB0aGlzLmtleSgncHVibGljRXhwb25lbnQnKS5pbnQoKVxuICApXG59KVxuZXhwb3J0cy5SU0FQdWJsaWNLZXkgPSBSU0FQdWJsaWNLZXlcblxudmFyIFB1YmxpY0tleSA9IGFzbjEuZGVmaW5lKCdTdWJqZWN0UHVibGljS2V5SW5mbycsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ2FsZ29yaXRobScpLnVzZShBbGdvcml0aG1JZGVudGlmaWVyKSxcbiAgICB0aGlzLmtleSgnc3ViamVjdFB1YmxpY0tleScpLmJpdHN0cigpXG4gIClcbn0pXG5leHBvcnRzLlB1YmxpY0tleSA9IFB1YmxpY0tleVxuXG52YXIgQWxnb3JpdGhtSWRlbnRpZmllciA9IGFzbjEuZGVmaW5lKCdBbGdvcml0aG1JZGVudGlmaWVyJywgZnVuY3Rpb24gKCkge1xuICB0aGlzLnNlcSgpLm9iaihcbiAgICB0aGlzLmtleSgnYWxnb3JpdGhtJykub2JqaWQoKSxcbiAgICB0aGlzLmtleSgnbm9uZScpLm51bGxfKCkub3B0aW9uYWwoKSxcbiAgICB0aGlzLmtleSgnY3VydmUnKS5vYmppZCgpLm9wdGlvbmFsKCksXG4gICAgdGhpcy5rZXkoJ3BhcmFtcycpLnNlcSgpLm9iaihcbiAgICAgIHRoaXMua2V5KCdwJykuaW50KCksXG4gICAgICB0aGlzLmtleSgncScpLmludCgpLFxuICAgICAgdGhpcy5rZXkoJ2cnKS5pbnQoKVxuICAgICkub3B0aW9uYWwoKVxuICApXG59KVxuXG52YXIgUHJpdmF0ZUtleUluZm8gPSBhc24xLmRlZmluZSgnUHJpdmF0ZUtleUluZm8nLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCd2ZXJzaW9uJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ2FsZ29yaXRobScpLnVzZShBbGdvcml0aG1JZGVudGlmaWVyKSxcbiAgICB0aGlzLmtleSgnc3ViamVjdFByaXZhdGVLZXknKS5vY3RzdHIoKVxuICApXG59KVxuZXhwb3J0cy5Qcml2YXRlS2V5ID0gUHJpdmF0ZUtleUluZm9cbnZhciBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyA9IGFzbjEuZGVmaW5lKCdFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbycsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ2FsZ29yaXRobScpLnNlcSgpLm9iaihcbiAgICAgIHRoaXMua2V5KCdpZCcpLm9iamlkKCksXG4gICAgICB0aGlzLmtleSgnZGVjcnlwdCcpLnNlcSgpLm9iaihcbiAgICAgICAgdGhpcy5rZXkoJ2tkZScpLnNlcSgpLm9iaihcbiAgICAgICAgICB0aGlzLmtleSgnaWQnKS5vYmppZCgpLFxuICAgICAgICAgIHRoaXMua2V5KCdrZGVwYXJhbXMnKS5zZXEoKS5vYmooXG4gICAgICAgICAgICB0aGlzLmtleSgnc2FsdCcpLm9jdHN0cigpLFxuICAgICAgICAgICAgdGhpcy5rZXkoJ2l0ZXJzJykuaW50KClcbiAgICAgICAgICApXG4gICAgICAgICksXG4gICAgICAgIHRoaXMua2V5KCdjaXBoZXInKS5zZXEoKS5vYmooXG4gICAgICAgICAgdGhpcy5rZXkoJ2FsZ28nKS5vYmppZCgpLFxuICAgICAgICAgIHRoaXMua2V5KCdpdicpLm9jdHN0cigpXG4gICAgICAgIClcbiAgICAgIClcbiAgICApLFxuICAgIHRoaXMua2V5KCdzdWJqZWN0UHJpdmF0ZUtleScpLm9jdHN0cigpXG4gIClcbn0pXG5cbmV4cG9ydHMuRW5jcnlwdGVkUHJpdmF0ZUtleSA9IEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvXG5cbnZhciBEU0FQcml2YXRlS2V5ID0gYXNuMS5kZWZpbmUoJ0RTQVByaXZhdGVLZXknLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCd2ZXJzaW9uJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3AnKS5pbnQoKSxcbiAgICB0aGlzLmtleSgncScpLmludCgpLFxuICAgIHRoaXMua2V5KCdnJykuaW50KCksXG4gICAgdGhpcy5rZXkoJ3B1Yl9rZXknKS5pbnQoKSxcbiAgICB0aGlzLmtleSgncHJpdl9rZXknKS5pbnQoKVxuICApXG59KVxuZXhwb3J0cy5EU0FQcml2YXRlS2V5ID0gRFNBUHJpdmF0ZUtleVxuXG5leHBvcnRzLkRTQXBhcmFtID0gYXNuMS5kZWZpbmUoJ0RTQXBhcmFtJywgZnVuY3Rpb24gKCkge1xuICB0aGlzLmludCgpXG59KVxuXG52YXIgRUNQcml2YXRlS2V5ID0gYXNuMS5kZWZpbmUoJ0VDUHJpdmF0ZUtleScsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ3ZlcnNpb24nKS5pbnQoKSxcbiAgICB0aGlzLmtleSgncHJpdmF0ZUtleScpLm9jdHN0cigpLFxuICAgIHRoaXMua2V5KCdwYXJhbWV0ZXJzJykub3B0aW9uYWwoKS5leHBsaWNpdCgwKS51c2UoRUNQYXJhbWV0ZXJzKSxcbiAgICB0aGlzLmtleSgncHVibGljS2V5Jykub3B0aW9uYWwoKS5leHBsaWNpdCgxKS5iaXRzdHIoKVxuICApXG59KVxuZXhwb3J0cy5FQ1ByaXZhdGVLZXkgPSBFQ1ByaXZhdGVLZXlcblxudmFyIEVDUGFyYW1ldGVycyA9IGFzbjEuZGVmaW5lKCdFQ1BhcmFtZXRlcnMnLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuY2hvaWNlKHtcbiAgICBuYW1lZEN1cnZlOiB0aGlzLm9iamlkKClcbiAgfSlcbn0pXG5cbmV4cG9ydHMuc2lnbmF0dXJlID0gYXNuMS5kZWZpbmUoJ3NpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ3InKS5pbnQoKSxcbiAgICB0aGlzLmtleSgncycpLmludCgpXG4gIClcbn0pXG4iLCIvLyBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9SYW50YW5lbi9ub2RlLWR0bHMvYmxvYi8yNWE3ZGM4NjFiZGEzOGNmZWFjOTNhNzIzNTAwZWVhNGYwYWMyZTg2L0NlcnRpZmljYXRlLmpzXG4vLyB0aGFua3MgdG8gQFJhbnRhbmVuXG5cbid1c2Ugc3RyaWN0J1xuXG52YXIgYXNuID0gcmVxdWlyZSgnYXNuMS5qcycpXG5cbnZhciBUaW1lID0gYXNuLmRlZmluZSgnVGltZScsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5jaG9pY2Uoe1xuICAgIHV0Y1RpbWU6IHRoaXMudXRjdGltZSgpLFxuICAgIGdlbmVyYWxUaW1lOiB0aGlzLmdlbnRpbWUoKVxuICB9KVxufSlcblxudmFyIEF0dHJpYnV0ZVR5cGVWYWx1ZSA9IGFzbi5kZWZpbmUoJ0F0dHJpYnV0ZVR5cGVWYWx1ZScsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ3R5cGUnKS5vYmppZCgpLFxuICAgIHRoaXMua2V5KCd2YWx1ZScpLmFueSgpXG4gIClcbn0pXG5cbnZhciBBbGdvcml0aG1JZGVudGlmaWVyID0gYXNuLmRlZmluZSgnQWxnb3JpdGhtSWRlbnRpZmllcicsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ2FsZ29yaXRobScpLm9iamlkKCksXG4gICAgdGhpcy5rZXkoJ3BhcmFtZXRlcnMnKS5vcHRpb25hbCgpLFxuICAgIHRoaXMua2V5KCdjdXJ2ZScpLm9iamlkKCkub3B0aW9uYWwoKVxuICApXG59KVxuXG52YXIgU3ViamVjdFB1YmxpY0tleUluZm8gPSBhc24uZGVmaW5lKCdTdWJqZWN0UHVibGljS2V5SW5mbycsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ2FsZ29yaXRobScpLnVzZShBbGdvcml0aG1JZGVudGlmaWVyKSxcbiAgICB0aGlzLmtleSgnc3ViamVjdFB1YmxpY0tleScpLmJpdHN0cigpXG4gIClcbn0pXG5cbnZhciBSZWxhdGl2ZURpc3Rpbmd1aXNoZWROYW1lID0gYXNuLmRlZmluZSgnUmVsYXRpdmVEaXN0aW5ndWlzaGVkTmFtZScsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXRvZihBdHRyaWJ1dGVUeXBlVmFsdWUpXG59KVxuXG52YXIgUkROU2VxdWVuY2UgPSBhc24uZGVmaW5lKCdSRE5TZXF1ZW5jZScsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXFvZihSZWxhdGl2ZURpc3Rpbmd1aXNoZWROYW1lKVxufSlcblxudmFyIE5hbWUgPSBhc24uZGVmaW5lKCdOYW1lJywgZnVuY3Rpb24gKCkge1xuICB0aGlzLmNob2ljZSh7XG4gICAgcmRuU2VxdWVuY2U6IHRoaXMudXNlKFJETlNlcXVlbmNlKVxuICB9KVxufSlcblxudmFyIFZhbGlkaXR5ID0gYXNuLmRlZmluZSgnVmFsaWRpdHknLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCdub3RCZWZvcmUnKS51c2UoVGltZSksXG4gICAgdGhpcy5rZXkoJ25vdEFmdGVyJykudXNlKFRpbWUpXG4gIClcbn0pXG5cbnZhciBFeHRlbnNpb24gPSBhc24uZGVmaW5lKCdFeHRlbnNpb24nLCBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuc2VxKCkub2JqKFxuICAgIHRoaXMua2V5KCdleHRuSUQnKS5vYmppZCgpLFxuICAgIHRoaXMua2V5KCdjcml0aWNhbCcpLmJvb2woKS5kZWYoZmFsc2UpLFxuICAgIHRoaXMua2V5KCdleHRuVmFsdWUnKS5vY3RzdHIoKVxuICApXG59KVxuXG52YXIgVEJTQ2VydGlmaWNhdGUgPSBhc24uZGVmaW5lKCdUQlNDZXJ0aWZpY2F0ZScsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ3ZlcnNpb24nKS5leHBsaWNpdCgwKS5pbnQoKS5vcHRpb25hbCgpLFxuICAgIHRoaXMua2V5KCdzZXJpYWxOdW1iZXInKS5pbnQoKSxcbiAgICB0aGlzLmtleSgnc2lnbmF0dXJlJykudXNlKEFsZ29yaXRobUlkZW50aWZpZXIpLFxuICAgIHRoaXMua2V5KCdpc3N1ZXInKS51c2UoTmFtZSksXG4gICAgdGhpcy5rZXkoJ3ZhbGlkaXR5JykudXNlKFZhbGlkaXR5KSxcbiAgICB0aGlzLmtleSgnc3ViamVjdCcpLnVzZShOYW1lKSxcbiAgICB0aGlzLmtleSgnc3ViamVjdFB1YmxpY0tleUluZm8nKS51c2UoU3ViamVjdFB1YmxpY0tleUluZm8pLFxuICAgIHRoaXMua2V5KCdpc3N1ZXJVbmlxdWVJRCcpLmltcGxpY2l0KDEpLmJpdHN0cigpLm9wdGlvbmFsKCksXG4gICAgdGhpcy5rZXkoJ3N1YmplY3RVbmlxdWVJRCcpLmltcGxpY2l0KDIpLmJpdHN0cigpLm9wdGlvbmFsKCksXG4gICAgdGhpcy5rZXkoJ2V4dGVuc2lvbnMnKS5leHBsaWNpdCgzKS5zZXFvZihFeHRlbnNpb24pLm9wdGlvbmFsKClcbiAgKVxufSlcblxudmFyIFg1MDlDZXJ0aWZpY2F0ZSA9IGFzbi5kZWZpbmUoJ1g1MDlDZXJ0aWZpY2F0ZScsIGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZXEoKS5vYmooXG4gICAgdGhpcy5rZXkoJ3Ric0NlcnRpZmljYXRlJykudXNlKFRCU0NlcnRpZmljYXRlKSxcbiAgICB0aGlzLmtleSgnc2lnbmF0dXJlQWxnb3JpdGhtJykudXNlKEFsZ29yaXRobUlkZW50aWZpZXIpLFxuICAgIHRoaXMua2V5KCdzaWduYXR1cmVWYWx1ZScpLmJpdHN0cigpXG4gIClcbn0pXG5cbm1vZHVsZS5leHBvcnRzID0gWDUwOUNlcnRpZmljYXRlXG4iLCIvLyBhZGFwdGVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2FwYXRpbC9wZW1zdHJpcFxudmFyIGZpbmRQcm9jID0gL1Byb2MtVHlwZTogNCxFTkNSWVBURURbXFxuXFxyXStERUstSW5mbzogQUVTLSgoPzoxMjgpfCg/OjE5Mil8KD86MjU2KSktQ0JDLChbMC05QS1IXSspW1xcblxccl0rKFswLTlBLXpcXG5cXHJcXCtcXC9cXD1dKylbXFxuXFxyXSsvbVxudmFyIHN0YXJ0UmVnZXggPSAvXi0tLS0tQkVHSU4gKCg/Oi4qIEtFWSl8Q0VSVElGSUNBVEUpLS0tLS0vbVxudmFyIGZ1bGxSZWdleCA9IC9eLS0tLS1CRUdJTiAoKD86LiogS0VZKXxDRVJUSUZJQ0FURSktLS0tLShbMC05QS16XFxuXFxyXFwrXFwvXFw9XSspLS0tLS1FTkQgXFwxLS0tLS0kL21cbnZhciBldnAgPSByZXF1aXJlKCdldnBfYnl0ZXN0b2tleScpXG52YXIgY2lwaGVycyA9IHJlcXVpcmUoJ2Jyb3dzZXJpZnktYWVzJylcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9rZXksIHBhc3N3b3JkKSB7XG4gIHZhciBrZXkgPSBva2V5LnRvU3RyaW5nKClcbiAgdmFyIG1hdGNoID0ga2V5Lm1hdGNoKGZpbmRQcm9jKVxuICB2YXIgZGVjcnlwdGVkXG4gIGlmICghbWF0Y2gpIHtcbiAgICB2YXIgbWF0Y2gyID0ga2V5Lm1hdGNoKGZ1bGxSZWdleClcbiAgICBkZWNyeXB0ZWQgPSBuZXcgQnVmZmVyKG1hdGNoMlsyXS5yZXBsYWNlKC9bXFxyXFxuXS9nLCAnJyksICdiYXNlNjQnKVxuICB9IGVsc2Uge1xuICAgIHZhciBzdWl0ZSA9ICdhZXMnICsgbWF0Y2hbMV1cbiAgICB2YXIgaXYgPSBuZXcgQnVmZmVyKG1hdGNoWzJdLCAnaGV4JylcbiAgICB2YXIgY2lwaGVyVGV4dCA9IG5ldyBCdWZmZXIobWF0Y2hbM10ucmVwbGFjZSgvW1xcclxcbl0vZywgJycpLCAnYmFzZTY0JylcbiAgICB2YXIgY2lwaGVyS2V5ID0gZXZwKHBhc3N3b3JkLCBpdi5zbGljZSgwLCA4KSwgcGFyc2VJbnQobWF0Y2hbMV0sIDEwKSkua2V5XG4gICAgdmFyIG91dCA9IFtdXG4gICAgdmFyIGNpcGhlciA9IGNpcGhlcnMuY3JlYXRlRGVjaXBoZXJpdihzdWl0ZSwgY2lwaGVyS2V5LCBpdilcbiAgICBvdXQucHVzaChjaXBoZXIudXBkYXRlKGNpcGhlclRleHQpKVxuICAgIG91dC5wdXNoKGNpcGhlci5maW5hbCgpKVxuICAgIGRlY3J5cHRlZCA9IEJ1ZmZlci5jb25jYXQob3V0KVxuICB9XG4gIHZhciB0YWcgPSBrZXkubWF0Y2goc3RhcnRSZWdleClbMV1cbiAgcmV0dXJuIHtcbiAgICB0YWc6IHRhZyxcbiAgICBkYXRhOiBkZWNyeXB0ZWRcbiAgfVxufVxuIiwidmFyIGFzbjEgPSByZXF1aXJlKCcuL2FzbjEnKVxudmFyIGFlc2lkID0gcmVxdWlyZSgnLi9hZXNpZC5qc29uJylcbnZhciBmaXhQcm9jID0gcmVxdWlyZSgnLi9maXhQcm9jJylcbnZhciBjaXBoZXJzID0gcmVxdWlyZSgnYnJvd3NlcmlmeS1hZXMnKVxudmFyIGNvbXBhdCA9IHJlcXVpcmUoJ3Bia2RmMicpXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcbm1vZHVsZS5leHBvcnRzID0gcGFyc2VLZXlzXG5cbmZ1bmN0aW9uIHBhcnNlS2V5cyAoYnVmZmVyKSB7XG4gIHZhciBwYXNzd29yZFxuICBpZiAodHlwZW9mIGJ1ZmZlciA9PT0gJ29iamVjdCcgJiYgIUJ1ZmZlci5pc0J1ZmZlcihidWZmZXIpKSB7XG4gICAgcGFzc3dvcmQgPSBidWZmZXIucGFzc3BocmFzZVxuICAgIGJ1ZmZlciA9IGJ1ZmZlci5rZXlcbiAgfVxuICBpZiAodHlwZW9mIGJ1ZmZlciA9PT0gJ3N0cmluZycpIHtcbiAgICBidWZmZXIgPSBCdWZmZXIuZnJvbShidWZmZXIpXG4gIH1cblxuICB2YXIgc3RyaXBwZWQgPSBmaXhQcm9jKGJ1ZmZlciwgcGFzc3dvcmQpXG5cbiAgdmFyIHR5cGUgPSBzdHJpcHBlZC50YWdcbiAgdmFyIGRhdGEgPSBzdHJpcHBlZC5kYXRhXG4gIHZhciBzdWJ0eXBlLCBuZGF0YVxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdDRVJUSUZJQ0FURSc6XG4gICAgICBuZGF0YSA9IGFzbjEuY2VydGlmaWNhdGUuZGVjb2RlKGRhdGEsICdkZXInKS50YnNDZXJ0aWZpY2F0ZS5zdWJqZWN0UHVibGljS2V5SW5mb1xuICAgICAgLy8gZmFsbHMgdGhyb3VnaFxuICAgIGNhc2UgJ1BVQkxJQyBLRVknOlxuICAgICAgaWYgKCFuZGF0YSkge1xuICAgICAgICBuZGF0YSA9IGFzbjEuUHVibGljS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICAgIH1cbiAgICAgIHN1YnR5cGUgPSBuZGF0YS5hbGdvcml0aG0uYWxnb3JpdGhtLmpvaW4oJy4nKVxuICAgICAgc3dpdGNoIChzdWJ0eXBlKSB7XG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTEzNTQ5LjEuMS4xJzpcbiAgICAgICAgICByZXR1cm4gYXNuMS5SU0FQdWJsaWNLZXkuZGVjb2RlKG5kYXRhLnN1YmplY3RQdWJsaWNLZXkuZGF0YSwgJ2RlcicpXG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTAwNDUuMi4xJzpcbiAgICAgICAgICBuZGF0YS5zdWJqZWN0UHJpdmF0ZUtleSA9IG5kYXRhLnN1YmplY3RQdWJsaWNLZXlcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ2VjJyxcbiAgICAgICAgICAgIGRhdGE6IG5kYXRhXG4gICAgICAgICAgfVxuICAgICAgICBjYXNlICcxLjIuODQwLjEwMDQwLjQuMSc6XG4gICAgICAgICAgbmRhdGEuYWxnb3JpdGhtLnBhcmFtcy5wdWJfa2V5ID0gYXNuMS5EU0FwYXJhbS5kZWNvZGUobmRhdGEuc3ViamVjdFB1YmxpY0tleS5kYXRhLCAnZGVyJylcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ2RzYScsXG4gICAgICAgICAgICBkYXRhOiBuZGF0YS5hbGdvcml0aG0ucGFyYW1zXG4gICAgICAgICAgfVxuICAgICAgICBkZWZhdWx0OiB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24ga2V5IGlkICcgKyBzdWJ0eXBlKVxuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGtleSB0eXBlICcgKyB0eXBlKVxuICAgIGNhc2UgJ0VOQ1JZUFRFRCBQUklWQVRFIEtFWSc6XG4gICAgICBkYXRhID0gYXNuMS5FbmNyeXB0ZWRQcml2YXRlS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICAgIGRhdGEgPSBkZWNyeXB0KGRhdGEsIHBhc3N3b3JkKVxuICAgICAgLy8gZmFsbHMgdGhyb3VnaFxuICAgIGNhc2UgJ1BSSVZBVEUgS0VZJzpcbiAgICAgIG5kYXRhID0gYXNuMS5Qcml2YXRlS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICAgIHN1YnR5cGUgPSBuZGF0YS5hbGdvcml0aG0uYWxnb3JpdGhtLmpvaW4oJy4nKVxuICAgICAgc3dpdGNoIChzdWJ0eXBlKSB7XG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTEzNTQ5LjEuMS4xJzpcbiAgICAgICAgICByZXR1cm4gYXNuMS5SU0FQcml2YXRlS2V5LmRlY29kZShuZGF0YS5zdWJqZWN0UHJpdmF0ZUtleSwgJ2RlcicpXG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTAwNDUuMi4xJzpcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3VydmU6IG5kYXRhLmFsZ29yaXRobS5jdXJ2ZSxcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IGFzbjEuRUNQcml2YXRlS2V5LmRlY29kZShuZGF0YS5zdWJqZWN0UHJpdmF0ZUtleSwgJ2RlcicpLnByaXZhdGVLZXlcbiAgICAgICAgICB9XG4gICAgICAgIGNhc2UgJzEuMi44NDAuMTAwNDAuNC4xJzpcbiAgICAgICAgICBuZGF0YS5hbGdvcml0aG0ucGFyYW1zLnByaXZfa2V5ID0gYXNuMS5EU0FwYXJhbS5kZWNvZGUobmRhdGEuc3ViamVjdFByaXZhdGVLZXksICdkZXInKVxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiAnZHNhJyxcbiAgICAgICAgICAgIHBhcmFtczogbmRhdGEuYWxnb3JpdGhtLnBhcmFtc1xuICAgICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGtleSBpZCAnICsgc3VidHlwZSlcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBrZXkgdHlwZSAnICsgdHlwZSlcbiAgICBjYXNlICdSU0EgUFVCTElDIEtFWSc6XG4gICAgICByZXR1cm4gYXNuMS5SU0FQdWJsaWNLZXkuZGVjb2RlKGRhdGEsICdkZXInKVxuICAgIGNhc2UgJ1JTQSBQUklWQVRFIEtFWSc6XG4gICAgICByZXR1cm4gYXNuMS5SU0FQcml2YXRlS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICBjYXNlICdEU0EgUFJJVkFURSBLRVknOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ2RzYScsXG4gICAgICAgIHBhcmFtczogYXNuMS5EU0FQcml2YXRlS2V5LmRlY29kZShkYXRhLCAnZGVyJylcbiAgICAgIH1cbiAgICBjYXNlICdFQyBQUklWQVRFIEtFWSc6XG4gICAgICBkYXRhID0gYXNuMS5FQ1ByaXZhdGVLZXkuZGVjb2RlKGRhdGEsICdkZXInKVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY3VydmU6IGRhdGEucGFyYW1ldGVycy52YWx1ZSxcbiAgICAgICAgcHJpdmF0ZUtleTogZGF0YS5wcml2YXRlS2V5XG4gICAgICB9XG4gICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGtleSB0eXBlICcgKyB0eXBlKVxuICB9XG59XG5wYXJzZUtleXMuc2lnbmF0dXJlID0gYXNuMS5zaWduYXR1cmVcbmZ1bmN0aW9uIGRlY3J5cHQgKGRhdGEsIHBhc3N3b3JkKSB7XG4gIHZhciBzYWx0ID0gZGF0YS5hbGdvcml0aG0uZGVjcnlwdC5rZGUua2RlcGFyYW1zLnNhbHRcbiAgdmFyIGl0ZXJzID0gcGFyc2VJbnQoZGF0YS5hbGdvcml0aG0uZGVjcnlwdC5rZGUua2RlcGFyYW1zLml0ZXJzLnRvU3RyaW5nKCksIDEwKVxuICB2YXIgYWxnbyA9IGFlc2lkW2RhdGEuYWxnb3JpdGhtLmRlY3J5cHQuY2lwaGVyLmFsZ28uam9pbignLicpXVxuICB2YXIgaXYgPSBkYXRhLmFsZ29yaXRobS5kZWNyeXB0LmNpcGhlci5pdlxuICB2YXIgY2lwaGVyVGV4dCA9IGRhdGEuc3ViamVjdFByaXZhdGVLZXlcbiAgdmFyIGtleWxlbiA9IHBhcnNlSW50KGFsZ28uc3BsaXQoJy0nKVsxXSwgMTApIC8gOFxuICB2YXIga2V5ID0gY29tcGF0LnBia2RmMlN5bmMocGFzc3dvcmQsIHNhbHQsIGl0ZXJzLCBrZXlsZW4sICdzaGExJylcbiAgdmFyIGNpcGhlciA9IGNpcGhlcnMuY3JlYXRlRGVjaXBoZXJpdihhbGdvLCBrZXksIGl2KVxuICB2YXIgb3V0ID0gW11cbiAgb3V0LnB1c2goY2lwaGVyLnVwZGF0ZShjaXBoZXJUZXh0KSlcbiAgb3V0LnB1c2goY2lwaGVyLmZpbmFsKCkpXG4gIHJldHVybiBCdWZmZXIuY29uY2F0KG91dClcbn1cbiIsImV4cG9ydHMucGJrZGYyID0gcmVxdWlyZSgnLi9saWIvYXN5bmMnKVxuZXhwb3J0cy5wYmtkZjJTeW5jID0gcmVxdWlyZSgnLi9saWIvc3luYycpXG4iLCJ2YXIgY2hlY2tQYXJhbWV0ZXJzID0gcmVxdWlyZSgnLi9wcmVjb25kaXRpb24nKVxudmFyIGRlZmF1bHRFbmNvZGluZyA9IHJlcXVpcmUoJy4vZGVmYXVsdC1lbmNvZGluZycpXG52YXIgc3luYyA9IHJlcXVpcmUoJy4vc3luYycpXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcblxudmFyIFpFUk9fQlVGXG52YXIgc3VidGxlID0gZ2xvYmFsLmNyeXB0byAmJiBnbG9iYWwuY3J5cHRvLnN1YnRsZVxudmFyIHRvQnJvd3NlciA9IHtcbiAgJ3NoYSc6ICdTSEEtMScsXG4gICdzaGEtMSc6ICdTSEEtMScsXG4gICdzaGExJzogJ1NIQS0xJyxcbiAgJ3NoYTI1Nic6ICdTSEEtMjU2JyxcbiAgJ3NoYS0yNTYnOiAnU0hBLTI1NicsXG4gICdzaGEzODQnOiAnU0hBLTM4NCcsXG4gICdzaGEtMzg0JzogJ1NIQS0zODQnLFxuICAnc2hhLTUxMic6ICdTSEEtNTEyJyxcbiAgJ3NoYTUxMic6ICdTSEEtNTEyJ1xufVxudmFyIGNoZWNrcyA9IFtdXG5mdW5jdGlvbiBjaGVja05hdGl2ZSAoYWxnbykge1xuICBpZiAoZ2xvYmFsLnByb2Nlc3MgJiYgIWdsb2JhbC5wcm9jZXNzLmJyb3dzZXIpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKVxuICB9XG4gIGlmICghc3VidGxlIHx8ICFzdWJ0bGUuaW1wb3J0S2V5IHx8ICFzdWJ0bGUuZGVyaXZlQml0cykge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZmFsc2UpXG4gIH1cbiAgaWYgKGNoZWNrc1thbGdvXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGNoZWNrc1thbGdvXVxuICB9XG4gIFpFUk9fQlVGID0gWkVST19CVUYgfHwgQnVmZmVyLmFsbG9jKDgpXG4gIHZhciBwcm9tID0gYnJvd3NlclBia2RmMihaRVJPX0JVRiwgWkVST19CVUYsIDEwLCAxMjgsIGFsZ28pXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9KS5jYXRjaChmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9KVxuICBjaGVja3NbYWxnb10gPSBwcm9tXG4gIHJldHVybiBwcm9tXG59XG5cbmZ1bmN0aW9uIGJyb3dzZXJQYmtkZjIgKHBhc3N3b3JkLCBzYWx0LCBpdGVyYXRpb25zLCBsZW5ndGgsIGFsZ28pIHtcbiAgcmV0dXJuIHN1YnRsZS5pbXBvcnRLZXkoXG4gICAgJ3JhdycsIHBhc3N3b3JkLCB7bmFtZTogJ1BCS0RGMid9LCBmYWxzZSwgWydkZXJpdmVCaXRzJ11cbiAgKS50aGVuKGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gc3VidGxlLmRlcml2ZUJpdHMoe1xuICAgICAgbmFtZTogJ1BCS0RGMicsXG4gICAgICBzYWx0OiBzYWx0LFxuICAgICAgaXRlcmF0aW9uczogaXRlcmF0aW9ucyxcbiAgICAgIGhhc2g6IHtcbiAgICAgICAgbmFtZTogYWxnb1xuICAgICAgfVxuICAgIH0sIGtleSwgbGVuZ3RoIDw8IDMpXG4gIH0pLnRoZW4oZnVuY3Rpb24gKHJlcykge1xuICAgIHJldHVybiBCdWZmZXIuZnJvbShyZXMpXG4gIH0pXG59XG5cbmZ1bmN0aW9uIHJlc29sdmVQcm9taXNlIChwcm9taXNlLCBjYWxsYmFjaykge1xuICBwcm9taXNlLnRoZW4oZnVuY3Rpb24gKG91dCkge1xuICAgIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgY2FsbGJhY2sobnVsbCwgb3V0KVxuICAgIH0pXG4gIH0sIGZ1bmN0aW9uIChlKSB7XG4gICAgcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICBjYWxsYmFjayhlKVxuICAgIH0pXG4gIH0pXG59XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChwYXNzd29yZCwgc2FsdCwgaXRlcmF0aW9ucywga2V5bGVuLCBkaWdlc3QsIGNhbGxiYWNrKSB7XG4gIGlmICh0eXBlb2YgZGlnZXN0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBkaWdlc3RcbiAgICBkaWdlc3QgPSB1bmRlZmluZWRcbiAgfVxuXG4gIGRpZ2VzdCA9IGRpZ2VzdCB8fCAnc2hhMSdcbiAgdmFyIGFsZ28gPSB0b0Jyb3dzZXJbZGlnZXN0LnRvTG93ZXJDYXNlKCldXG5cbiAgaWYgKCFhbGdvIHx8IHR5cGVvZiBnbG9iYWwuUHJvbWlzZSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBvdXRcbiAgICAgIHRyeSB7XG4gICAgICAgIG91dCA9IHN5bmMocGFzc3dvcmQsIHNhbHQsIGl0ZXJhdGlvbnMsIGtleWxlbiwgZGlnZXN0KVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2soZSlcbiAgICAgIH1cbiAgICAgIGNhbGxiYWNrKG51bGwsIG91dClcbiAgICB9KVxuICB9XG5cbiAgY2hlY2tQYXJhbWV0ZXJzKHBhc3N3b3JkLCBzYWx0LCBpdGVyYXRpb25zLCBrZXlsZW4pXG4gIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09ICdmdW5jdGlvbicpIHRocm93IG5ldyBFcnJvcignTm8gY2FsbGJhY2sgcHJvdmlkZWQgdG8gcGJrZGYyJylcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIocGFzc3dvcmQpKSBwYXNzd29yZCA9IEJ1ZmZlci5mcm9tKHBhc3N3b3JkLCBkZWZhdWx0RW5jb2RpbmcpXG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHNhbHQpKSBzYWx0ID0gQnVmZmVyLmZyb20oc2FsdCwgZGVmYXVsdEVuY29kaW5nKVxuXG4gIHJlc29sdmVQcm9taXNlKGNoZWNrTmF0aXZlKGFsZ28pLnRoZW4oZnVuY3Rpb24gKHJlc3ApIHtcbiAgICBpZiAocmVzcCkgcmV0dXJuIGJyb3dzZXJQYmtkZjIocGFzc3dvcmQsIHNhbHQsIGl0ZXJhdGlvbnMsIGtleWxlbiwgYWxnbylcblxuICAgIHJldHVybiBzeW5jKHBhc3N3b3JkLCBzYWx0LCBpdGVyYXRpb25zLCBrZXlsZW4sIGRpZ2VzdClcbiAgfSksIGNhbGxiYWNrKVxufVxuIiwidmFyIGRlZmF1bHRFbmNvZGluZ1xuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmlmIChwcm9jZXNzLmJyb3dzZXIpIHtcbiAgZGVmYXVsdEVuY29kaW5nID0gJ3V0Zi04J1xufSBlbHNlIHtcbiAgdmFyIHBWZXJzaW9uTWFqb3IgPSBwYXJzZUludChwcm9jZXNzLnZlcnNpb24uc3BsaXQoJy4nKVswXS5zbGljZSgxKSwgMTApXG5cbiAgZGVmYXVsdEVuY29kaW5nID0gcFZlcnNpb25NYWpvciA+PSA2ID8gJ3V0Zi04JyA6ICdiaW5hcnknXG59XG5tb2R1bGUuZXhwb3J0cyA9IGRlZmF1bHRFbmNvZGluZ1xuIiwidmFyIE1BWF9BTExPQyA9IE1hdGgucG93KDIsIDMwKSAtIDEgLy8gZGVmYXVsdCBpbiBpb2pzXG5cbmZ1bmN0aW9uIGNoZWNrQnVmZmVyIChidWYsIG5hbWUpIHtcbiAgaWYgKHR5cGVvZiBidWYgIT09ICdzdHJpbmcnICYmICFCdWZmZXIuaXNCdWZmZXIoYnVmKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IobmFtZSArICcgbXVzdCBiZSBhIGJ1ZmZlciBvciBzdHJpbmcnKVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHBhc3N3b3JkLCBzYWx0LCBpdGVyYXRpb25zLCBrZXlsZW4pIHtcbiAgY2hlY2tCdWZmZXIocGFzc3dvcmQsICdQYXNzd29yZCcpXG4gIGNoZWNrQnVmZmVyKHNhbHQsICdTYWx0JylcblxuICBpZiAodHlwZW9mIGl0ZXJhdGlvbnMgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSXRlcmF0aW9ucyBub3QgYSBudW1iZXInKVxuICB9XG5cbiAgaWYgKGl0ZXJhdGlvbnMgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQmFkIGl0ZXJhdGlvbnMnKVxuICB9XG5cbiAgaWYgKHR5cGVvZiBrZXlsZW4gIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignS2V5IGxlbmd0aCBub3QgYSBudW1iZXInKVxuICB9XG5cbiAgaWYgKGtleWxlbiA8IDAgfHwga2V5bGVuID4gTUFYX0FMTE9DIHx8IGtleWxlbiAhPT0ga2V5bGVuKSB7IC8qIGVzbGludCBuby1zZWxmLWNvbXBhcmU6IDAgKi9cbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdCYWQga2V5IGxlbmd0aCcpXG4gIH1cbn1cbiIsInZhciBtZDUgPSByZXF1aXJlKCdjcmVhdGUtaGFzaC9tZDUnKVxudmFyIFJJUEVNRDE2MCA9IHJlcXVpcmUoJ3JpcGVtZDE2MCcpXG52YXIgc2hhID0gcmVxdWlyZSgnc2hhLmpzJylcblxudmFyIGNoZWNrUGFyYW1ldGVycyA9IHJlcXVpcmUoJy4vcHJlY29uZGl0aW9uJylcbnZhciBkZWZhdWx0RW5jb2RpbmcgPSByZXF1aXJlKCcuL2RlZmF1bHQtZW5jb2RpbmcnKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG52YXIgWkVST1MgPSBCdWZmZXIuYWxsb2MoMTI4KVxudmFyIHNpemVzID0ge1xuICBtZDU6IDE2LFxuICBzaGExOiAyMCxcbiAgc2hhMjI0OiAyOCxcbiAgc2hhMjU2OiAzMixcbiAgc2hhMzg0OiA0OCxcbiAgc2hhNTEyOiA2NCxcbiAgcm1kMTYwOiAyMCxcbiAgcmlwZW1kMTYwOiAyMFxufVxuXG5mdW5jdGlvbiBIbWFjIChhbGcsIGtleSwgc2FsdExlbikge1xuICB2YXIgaGFzaCA9IGdldERpZ2VzdChhbGcpXG4gIHZhciBibG9ja3NpemUgPSAoYWxnID09PSAnc2hhNTEyJyB8fCBhbGcgPT09ICdzaGEzODQnKSA/IDEyOCA6IDY0XG5cbiAgaWYgKGtleS5sZW5ndGggPiBibG9ja3NpemUpIHtcbiAgICBrZXkgPSBoYXNoKGtleSlcbiAgfSBlbHNlIGlmIChrZXkubGVuZ3RoIDwgYmxvY2tzaXplKSB7XG4gICAga2V5ID0gQnVmZmVyLmNvbmNhdChba2V5LCBaRVJPU10sIGJsb2Nrc2l6ZSlcbiAgfVxuXG4gIHZhciBpcGFkID0gQnVmZmVyLmFsbG9jVW5zYWZlKGJsb2Nrc2l6ZSArIHNpemVzW2FsZ10pXG4gIHZhciBvcGFkID0gQnVmZmVyLmFsbG9jVW5zYWZlKGJsb2Nrc2l6ZSArIHNpemVzW2FsZ10pXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tzaXplOyBpKyspIHtcbiAgICBpcGFkW2ldID0ga2V5W2ldIF4gMHgzNlxuICAgIG9wYWRbaV0gPSBrZXlbaV0gXiAweDVDXG4gIH1cblxuICB2YXIgaXBhZDEgPSBCdWZmZXIuYWxsb2NVbnNhZmUoYmxvY2tzaXplICsgc2FsdExlbiArIDQpXG4gIGlwYWQuY29weShpcGFkMSwgMCwgMCwgYmxvY2tzaXplKVxuICB0aGlzLmlwYWQxID0gaXBhZDFcbiAgdGhpcy5pcGFkMiA9IGlwYWRcbiAgdGhpcy5vcGFkID0gb3BhZFxuICB0aGlzLmFsZyA9IGFsZ1xuICB0aGlzLmJsb2Nrc2l6ZSA9IGJsb2Nrc2l6ZVxuICB0aGlzLmhhc2ggPSBoYXNoXG4gIHRoaXMuc2l6ZSA9IHNpemVzW2FsZ11cbn1cblxuSG1hYy5wcm90b3R5cGUucnVuID0gZnVuY3Rpb24gKGRhdGEsIGlwYWQpIHtcbiAgZGF0YS5jb3B5KGlwYWQsIHRoaXMuYmxvY2tzaXplKVxuICB2YXIgaCA9IHRoaXMuaGFzaChpcGFkKVxuICBoLmNvcHkodGhpcy5vcGFkLCB0aGlzLmJsb2Nrc2l6ZSlcbiAgcmV0dXJuIHRoaXMuaGFzaCh0aGlzLm9wYWQpXG59XG5cbmZ1bmN0aW9uIGdldERpZ2VzdCAoYWxnKSB7XG4gIGZ1bmN0aW9uIHNoYUZ1bmMgKGRhdGEpIHtcbiAgICByZXR1cm4gc2hhKGFsZykudXBkYXRlKGRhdGEpLmRpZ2VzdCgpXG4gIH1cbiAgZnVuY3Rpb24gcm1kMTYwRnVuYyAoZGF0YSkge1xuICAgIHJldHVybiBuZXcgUklQRU1EMTYwKCkudXBkYXRlKGRhdGEpLmRpZ2VzdCgpXG4gIH1cblxuICBpZiAoYWxnID09PSAncm1kMTYwJyB8fCBhbGcgPT09ICdyaXBlbWQxNjAnKSByZXR1cm4gcm1kMTYwRnVuY1xuICBpZiAoYWxnID09PSAnbWQ1JykgcmV0dXJuIG1kNVxuICByZXR1cm4gc2hhRnVuY1xufVxuXG5mdW5jdGlvbiBwYmtkZjIgKHBhc3N3b3JkLCBzYWx0LCBpdGVyYXRpb25zLCBrZXlsZW4sIGRpZ2VzdCkge1xuICBjaGVja1BhcmFtZXRlcnMocGFzc3dvcmQsIHNhbHQsIGl0ZXJhdGlvbnMsIGtleWxlbilcblxuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihwYXNzd29yZCkpIHBhc3N3b3JkID0gQnVmZmVyLmZyb20ocGFzc3dvcmQsIGRlZmF1bHRFbmNvZGluZylcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoc2FsdCkpIHNhbHQgPSBCdWZmZXIuZnJvbShzYWx0LCBkZWZhdWx0RW5jb2RpbmcpXG5cbiAgZGlnZXN0ID0gZGlnZXN0IHx8ICdzaGExJ1xuXG4gIHZhciBobWFjID0gbmV3IEhtYWMoZGlnZXN0LCBwYXNzd29yZCwgc2FsdC5sZW5ndGgpXG5cbiAgdmFyIERLID0gQnVmZmVyLmFsbG9jVW5zYWZlKGtleWxlbilcbiAgdmFyIGJsb2NrMSA9IEJ1ZmZlci5hbGxvY1Vuc2FmZShzYWx0Lmxlbmd0aCArIDQpXG4gIHNhbHQuY29weShibG9jazEsIDAsIDAsIHNhbHQubGVuZ3RoKVxuXG4gIHZhciBkZXN0UG9zID0gMFxuICB2YXIgaExlbiA9IHNpemVzW2RpZ2VzdF1cbiAgdmFyIGwgPSBNYXRoLmNlaWwoa2V5bGVuIC8gaExlbilcblxuICBmb3IgKHZhciBpID0gMTsgaSA8PSBsOyBpKyspIHtcbiAgICBibG9jazEud3JpdGVVSW50MzJCRShpLCBzYWx0Lmxlbmd0aClcblxuICAgIHZhciBUID0gaG1hYy5ydW4oYmxvY2sxLCBobWFjLmlwYWQxKVxuICAgIHZhciBVID0gVFxuXG4gICAgZm9yICh2YXIgaiA9IDE7IGogPCBpdGVyYXRpb25zOyBqKyspIHtcbiAgICAgIFUgPSBobWFjLnJ1bihVLCBobWFjLmlwYWQyKVxuICAgICAgZm9yICh2YXIgayA9IDA7IGsgPCBoTGVuOyBrKyspIFRba10gXj0gVVtrXVxuICAgIH1cblxuICAgIFQuY29weShESywgZGVzdFBvcylcbiAgICBkZXN0UG9zICs9IGhMZW5cbiAgfVxuXG4gIHJldHVybiBES1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHBia2RmMlxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5pZiAoIXByb2Nlc3MudmVyc2lvbiB8fFxuICAgIHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKCd2MC4nKSA9PT0gMCB8fFxuICAgIHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKCd2MS4nKSA9PT0gMCAmJiBwcm9jZXNzLnZlcnNpb24uaW5kZXhPZigndjEuOC4nKSAhPT0gMCkge1xuICBtb2R1bGUuZXhwb3J0cyA9IG5leHRUaWNrO1xufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBwcm9jZXNzLm5leHRUaWNrO1xufVxuXG5mdW5jdGlvbiBuZXh0VGljayhmbiwgYXJnMSwgYXJnMiwgYXJnMykge1xuICBpZiAodHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJjYWxsYmFja1wiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICB9XG4gIHZhciBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICB2YXIgYXJncywgaTtcbiAgc3dpdGNoIChsZW4pIHtcbiAgY2FzZSAwOlxuICBjYXNlIDE6XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZm4pO1xuICBjYXNlIDI6XG4gICAgcmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrT25lKCkge1xuICAgICAgZm4uY2FsbChudWxsLCBhcmcxKTtcbiAgICB9KTtcbiAgY2FzZSAzOlxuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGlja1R3bygpIHtcbiAgICAgIGZuLmNhbGwobnVsbCwgYXJnMSwgYXJnMik7XG4gICAgfSk7XG4gIGNhc2UgNDpcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiBhZnRlclRpY2tUaHJlZSgpIHtcbiAgICAgIGZuLmNhbGwobnVsbCwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gICAgfSk7XG4gIGRlZmF1bHQ6XG4gICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICBpID0gMDtcbiAgICB3aGlsZSAoaSA8IGFyZ3MubGVuZ3RoKSB7XG4gICAgICBhcmdzW2krK10gPSBhcmd1bWVudHNbaV07XG4gICAgfVxuICAgIHJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGljaygpIHtcbiAgICAgIGZuLmFwcGx5KG51bGwsIGFyZ3MpO1xuICAgIH0pO1xuICB9XG59XG4iLCIvLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLy8gY2FjaGVkIGZyb20gd2hhdGV2ZXIgZ2xvYmFsIGlzIHByZXNlbnQgc28gdGhhdCB0ZXN0IHJ1bm5lcnMgdGhhdCBzdHViIGl0XG4vLyBkb24ndCBicmVhayB0aGluZ3MuICBCdXQgd2UgbmVlZCB0byB3cmFwIGl0IGluIGEgdHJ5IGNhdGNoIGluIGNhc2UgaXQgaXNcbi8vIHdyYXBwZWQgaW4gc3RyaWN0IG1vZGUgY29kZSB3aGljaCBkb2Vzbid0IGRlZmluZSBhbnkgZ2xvYmFscy4gIEl0J3MgaW5zaWRlIGFcbi8vIGZ1bmN0aW9uIGJlY2F1c2UgdHJ5L2NhdGNoZXMgZGVvcHRpbWl6ZSBpbiBjZXJ0YWluIGVuZ2luZXMuXG5cbnZhciBjYWNoZWRTZXRUaW1lb3V0O1xudmFyIGNhY2hlZENsZWFyVGltZW91dDtcblxuZnVuY3Rpb24gZGVmYXVsdFNldFRpbW91dCgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NldFRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQgKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY2xlYXJUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG4oZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc2V0VGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2xlYXJUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBkZWZhdWx0Q2xlYXJUaW1lb3V0O1xuICAgIH1cbn0gKCkpXG5mdW5jdGlvbiBydW5UaW1lb3V0KGZ1bikge1xuICAgIGlmIChjYWNoZWRTZXRUaW1lb3V0ID09PSBzZXRUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICAvLyBpZiBzZXRUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkU2V0VGltZW91dCA9PT0gZGVmYXVsdFNldFRpbW91dCB8fCAhY2FjaGVkU2V0VGltZW91dCkgJiYgc2V0VGltZW91dCkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dChmdW4sIDApO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCwgZnVuLCAwKTtcbiAgICAgICAgfSBjYXRjaChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yXG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKHRoaXMsIGZ1biwgMCk7XG4gICAgICAgIH1cbiAgICB9XG5cblxufVxuZnVuY3Rpb24gcnVuQ2xlYXJUaW1lb3V0KG1hcmtlcikge1xuICAgIGlmIChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGNsZWFyVGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICAvLyBpZiBjbGVhclRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRDbGVhclRpbWVvdXQgPT09IGRlZmF1bHRDbGVhclRpbWVvdXQgfHwgIWNhY2hlZENsZWFyVGltZW91dCkgJiYgY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgcmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCAgdHJ1c3QgdGhlIGdsb2JhbCBvYmplY3Qgd2hlbiBjYWxsZWQgbm9ybWFsbHlcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbChudWxsLCBtYXJrZXIpO1xuICAgICAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgICAgIC8vIHNhbWUgYXMgYWJvdmUgYnV0IHdoZW4gaXQncyBhIHZlcnNpb24gb2YgSS5FLiB0aGF0IG11c3QgaGF2ZSB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgJ3RoaXMnLCBob3BmdWxseSBvdXIgY29udGV4dCBjb3JyZWN0IG90aGVyd2lzZSBpdCB3aWxsIHRocm93IGEgZ2xvYmFsIGVycm9yLlxuICAgICAgICAgICAgLy8gU29tZSB2ZXJzaW9ucyBvZiBJLkUuIGhhdmUgZGlmZmVyZW50IHJ1bGVzIGZvciBjbGVhclRpbWVvdXQgdnMgc2V0VGltZW91dFxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKHRoaXMsIG1hcmtlcik7XG4gICAgICAgIH1cbiAgICB9XG5cblxuXG59XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xudmFyIGN1cnJlbnRRdWV1ZTtcbnZhciBxdWV1ZUluZGV4ID0gLTE7XG5cbmZ1bmN0aW9uIGNsZWFuVXBOZXh0VGljaygpIHtcbiAgICBpZiAoIWRyYWluaW5nIHx8ICFjdXJyZW50UXVldWUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGlmIChjdXJyZW50UXVldWUubGVuZ3RoKSB7XG4gICAgICAgIHF1ZXVlID0gY3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgIH1cbiAgICBpZiAocXVldWUubGVuZ3RoKSB7XG4gICAgICAgIGRyYWluUXVldWUoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRyYWluUXVldWUoKSB7XG4gICAgaWYgKGRyYWluaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHRpbWVvdXQgPSBydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7XG4gICAgZHJhaW5pbmcgPSB0cnVlO1xuXG4gICAgdmFyIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB3aGlsZShsZW4pIHtcbiAgICAgICAgY3VycmVudFF1ZXVlID0gcXVldWU7XG4gICAgICAgIHF1ZXVlID0gW107XG4gICAgICAgIHdoaWxlICgrK3F1ZXVlSW5kZXggPCBsZW4pIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50UXVldWUpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UXVldWVbcXVldWVJbmRleF0ucnVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcXVldWVJbmRleCA9IC0xO1xuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGN1cnJlbnRRdWV1ZSA9IG51bGw7XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBydW5DbGVhclRpbWVvdXQodGltZW91dCk7XG59XG5cbnByb2Nlc3MubmV4dFRpY2sgPSBmdW5jdGlvbiAoZnVuKSB7XG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcXVldWUucHVzaChuZXcgSXRlbShmdW4sIGFyZ3MpKTtcbiAgICBpZiAocXVldWUubGVuZ3RoID09PSAxICYmICFkcmFpbmluZykge1xuICAgICAgICBydW5UaW1lb3V0KGRyYWluUXVldWUpO1xuICAgIH1cbn07XG5cbi8vIHY4IGxpa2VzIHByZWRpY3RpYmxlIG9iamVjdHNcbmZ1bmN0aW9uIEl0ZW0oZnVuLCBhcnJheSkge1xuICAgIHRoaXMuZnVuID0gZnVuO1xuICAgIHRoaXMuYXJyYXkgPSBhcnJheTtcbn1cbkl0ZW0ucHJvdG90eXBlLnJ1biA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmZ1bi5hcHBseShudWxsLCB0aGlzLmFycmF5KTtcbn07XG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcbnByb2Nlc3MudmVyc2lvbiA9ICcnOyAvLyBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgcmVnZXhwIGlzc3Vlc1xucHJvY2Vzcy52ZXJzaW9ucyA9IHt9O1xuXG5mdW5jdGlvbiBub29wKCkge31cblxucHJvY2Vzcy5vbiA9IG5vb3A7XG5wcm9jZXNzLmFkZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3Mub25jZSA9IG5vb3A7XG5wcm9jZXNzLm9mZiA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUxpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzID0gbm9vcDtcbnByb2Nlc3MuZW1pdCA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnByZXBlbmRPbmNlTGlzdGVuZXIgPSBub29wO1xuXG5wcm9jZXNzLmxpc3RlbmVycyA9IGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiBbXSB9XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcblxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5wcm9jZXNzLnVtYXNrID0gZnVuY3Rpb24oKSB7IHJldHVybiAwOyB9O1xuIiwiZXhwb3J0cy5wdWJsaWNFbmNyeXB0ID0gcmVxdWlyZSgnLi9wdWJsaWNFbmNyeXB0JylcbmV4cG9ydHMucHJpdmF0ZURlY3J5cHQgPSByZXF1aXJlKCcuL3ByaXZhdGVEZWNyeXB0JylcblxuZXhwb3J0cy5wcml2YXRlRW5jcnlwdCA9IGZ1bmN0aW9uIHByaXZhdGVFbmNyeXB0IChrZXksIGJ1Zikge1xuICByZXR1cm4gZXhwb3J0cy5wdWJsaWNFbmNyeXB0KGtleSwgYnVmLCB0cnVlKVxufVxuXG5leHBvcnRzLnB1YmxpY0RlY3J5cHQgPSBmdW5jdGlvbiBwdWJsaWNEZWNyeXB0IChrZXksIGJ1Zikge1xuICByZXR1cm4gZXhwb3J0cy5wcml2YXRlRGVjcnlwdChrZXksIGJ1ZiwgdHJ1ZSlcbn1cbiIsInZhciBjcmVhdGVIYXNoID0gcmVxdWlyZSgnY3JlYXRlLWhhc2gnKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHNlZWQsIGxlbikge1xuICB2YXIgdCA9IEJ1ZmZlci5hbGxvYygwKVxuICB2YXIgaSA9IDBcbiAgdmFyIGNcbiAgd2hpbGUgKHQubGVuZ3RoIDwgbGVuKSB7XG4gICAgYyA9IGkyb3BzKGkrKylcbiAgICB0ID0gQnVmZmVyLmNvbmNhdChbdCwgY3JlYXRlSGFzaCgnc2hhMScpLnVwZGF0ZShzZWVkKS51cGRhdGUoYykuZGlnZXN0KCldKVxuICB9XG4gIHJldHVybiB0LnNsaWNlKDAsIGxlbilcbn1cblxuZnVuY3Rpb24gaTJvcHMgKGMpIHtcbiAgdmFyIG91dCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSg0KVxuICBvdXQud3JpdGVVSW50MzJCRShjLCAwKVxuICByZXR1cm4gb3V0XG59XG4iLCJ2YXIgcGFyc2VLZXlzID0gcmVxdWlyZSgncGFyc2UtYXNuMScpXG52YXIgbWdmID0gcmVxdWlyZSgnLi9tZ2YnKVxudmFyIHhvciA9IHJlcXVpcmUoJy4veG9yJylcbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJylcbnZhciBjcnQgPSByZXF1aXJlKCdicm93c2VyaWZ5LXJzYScpXG52YXIgY3JlYXRlSGFzaCA9IHJlcXVpcmUoJ2NyZWF0ZS1oYXNoJylcbnZhciB3aXRoUHVibGljID0gcmVxdWlyZSgnLi93aXRoUHVibGljJylcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHByaXZhdGVEZWNyeXB0IChwcml2YXRlS2V5LCBlbmMsIHJldmVyc2UpIHtcbiAgdmFyIHBhZGRpbmdcbiAgaWYgKHByaXZhdGVLZXkucGFkZGluZykge1xuICAgIHBhZGRpbmcgPSBwcml2YXRlS2V5LnBhZGRpbmdcbiAgfSBlbHNlIGlmIChyZXZlcnNlKSB7XG4gICAgcGFkZGluZyA9IDFcbiAgfSBlbHNlIHtcbiAgICBwYWRkaW5nID0gNFxuICB9XG5cbiAgdmFyIGtleSA9IHBhcnNlS2V5cyhwcml2YXRlS2V5KVxuICB2YXIgayA9IGtleS5tb2R1bHVzLmJ5dGVMZW5ndGgoKVxuICBpZiAoZW5jLmxlbmd0aCA+IGsgfHwgbmV3IEJOKGVuYykuY21wKGtleS5tb2R1bHVzKSA+PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkZWNyeXB0aW9uIGVycm9yJylcbiAgfVxuICB2YXIgbXNnXG4gIGlmIChyZXZlcnNlKSB7XG4gICAgbXNnID0gd2l0aFB1YmxpYyhuZXcgQk4oZW5jKSwga2V5KVxuICB9IGVsc2Uge1xuICAgIG1zZyA9IGNydChlbmMsIGtleSlcbiAgfVxuICB2YXIgekJ1ZmZlciA9IEJ1ZmZlci5hbGxvYyhrIC0gbXNnLmxlbmd0aClcbiAgbXNnID0gQnVmZmVyLmNvbmNhdChbekJ1ZmZlciwgbXNnXSwgaylcbiAgaWYgKHBhZGRpbmcgPT09IDQpIHtcbiAgICByZXR1cm4gb2FlcChrZXksIG1zZylcbiAgfSBlbHNlIGlmIChwYWRkaW5nID09PSAxKSB7XG4gICAgcmV0dXJuIHBrY3MxKGtleSwgbXNnLCByZXZlcnNlKVxuICB9IGVsc2UgaWYgKHBhZGRpbmcgPT09IDMpIHtcbiAgICByZXR1cm4gbXNnXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIHBhZGRpbmcnKVxuICB9XG59XG5cbmZ1bmN0aW9uIG9hZXAgKGtleSwgbXNnKSB7XG4gIHZhciBrID0ga2V5Lm1vZHVsdXMuYnl0ZUxlbmd0aCgpXG4gIHZhciBpSGFzaCA9IGNyZWF0ZUhhc2goJ3NoYTEnKS51cGRhdGUoQnVmZmVyLmFsbG9jKDApKS5kaWdlc3QoKVxuICB2YXIgaExlbiA9IGlIYXNoLmxlbmd0aFxuICBpZiAobXNnWzBdICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkZWNyeXB0aW9uIGVycm9yJylcbiAgfVxuICB2YXIgbWFza2VkU2VlZCA9IG1zZy5zbGljZSgxLCBoTGVuICsgMSlcbiAgdmFyIG1hc2tlZERiID0gbXNnLnNsaWNlKGhMZW4gKyAxKVxuICB2YXIgc2VlZCA9IHhvcihtYXNrZWRTZWVkLCBtZ2YobWFza2VkRGIsIGhMZW4pKVxuICB2YXIgZGIgPSB4b3IobWFza2VkRGIsIG1nZihzZWVkLCBrIC0gaExlbiAtIDEpKVxuICBpZiAoY29tcGFyZShpSGFzaCwgZGIuc2xpY2UoMCwgaExlbikpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkZWNyeXB0aW9uIGVycm9yJylcbiAgfVxuICB2YXIgaSA9IGhMZW5cbiAgd2hpbGUgKGRiW2ldID09PSAwKSB7XG4gICAgaSsrXG4gIH1cbiAgaWYgKGRiW2krK10gIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RlY3J5cHRpb24gZXJyb3InKVxuICB9XG4gIHJldHVybiBkYi5zbGljZShpKVxufVxuXG5mdW5jdGlvbiBwa2NzMSAoa2V5LCBtc2csIHJldmVyc2UpIHtcbiAgdmFyIHAxID0gbXNnLnNsaWNlKDAsIDIpXG4gIHZhciBpID0gMlxuICB2YXIgc3RhdHVzID0gMFxuICB3aGlsZSAobXNnW2krK10gIT09IDApIHtcbiAgICBpZiAoaSA+PSBtc2cubGVuZ3RoKSB7XG4gICAgICBzdGF0dXMrK1xuICAgICAgYnJlYWtcbiAgICB9XG4gIH1cbiAgdmFyIHBzID0gbXNnLnNsaWNlKDIsIGkgLSAxKVxuXG4gIGlmICgocDEudG9TdHJpbmcoJ2hleCcpICE9PSAnMDAwMicgJiYgIXJldmVyc2UpIHx8IChwMS50b1N0cmluZygnaGV4JykgIT09ICcwMDAxJyAmJiByZXZlcnNlKSkge1xuICAgIHN0YXR1cysrXG4gIH1cbiAgaWYgKHBzLmxlbmd0aCA8IDgpIHtcbiAgICBzdGF0dXMrK1xuICB9XG4gIGlmIChzdGF0dXMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RlY3J5cHRpb24gZXJyb3InKVxuICB9XG4gIHJldHVybiBtc2cuc2xpY2UoaSlcbn1cbmZ1bmN0aW9uIGNvbXBhcmUgKGEsIGIpIHtcbiAgYSA9IEJ1ZmZlci5mcm9tKGEpXG4gIGIgPSBCdWZmZXIuZnJvbShiKVxuICB2YXIgZGlmID0gMFxuICB2YXIgbGVuID0gYS5sZW5ndGhcbiAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkge1xuICAgIGRpZisrXG4gICAgbGVuID0gTWF0aC5taW4oYS5sZW5ndGgsIGIubGVuZ3RoKVxuICB9XG4gIHZhciBpID0gLTFcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIGRpZiArPSAoYVtpXSBeIGJbaV0pXG4gIH1cbiAgcmV0dXJuIGRpZlxufVxuIiwidmFyIHBhcnNlS2V5cyA9IHJlcXVpcmUoJ3BhcnNlLWFzbjEnKVxudmFyIHJhbmRvbUJ5dGVzID0gcmVxdWlyZSgncmFuZG9tYnl0ZXMnKVxudmFyIGNyZWF0ZUhhc2ggPSByZXF1aXJlKCdjcmVhdGUtaGFzaCcpXG52YXIgbWdmID0gcmVxdWlyZSgnLi9tZ2YnKVxudmFyIHhvciA9IHJlcXVpcmUoJy4veG9yJylcbnZhciBCTiA9IHJlcXVpcmUoJ2JuLmpzJylcbnZhciB3aXRoUHVibGljID0gcmVxdWlyZSgnLi93aXRoUHVibGljJylcbnZhciBjcnQgPSByZXF1aXJlKCdicm93c2VyaWZ5LXJzYScpXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwdWJsaWNFbmNyeXB0IChwdWJsaWNLZXksIG1zZywgcmV2ZXJzZSkge1xuICB2YXIgcGFkZGluZ1xuICBpZiAocHVibGljS2V5LnBhZGRpbmcpIHtcbiAgICBwYWRkaW5nID0gcHVibGljS2V5LnBhZGRpbmdcbiAgfSBlbHNlIGlmIChyZXZlcnNlKSB7XG4gICAgcGFkZGluZyA9IDFcbiAgfSBlbHNlIHtcbiAgICBwYWRkaW5nID0gNFxuICB9XG4gIHZhciBrZXkgPSBwYXJzZUtleXMocHVibGljS2V5KVxuICB2YXIgcGFkZGVkTXNnXG4gIGlmIChwYWRkaW5nID09PSA0KSB7XG4gICAgcGFkZGVkTXNnID0gb2FlcChrZXksIG1zZylcbiAgfSBlbHNlIGlmIChwYWRkaW5nID09PSAxKSB7XG4gICAgcGFkZGVkTXNnID0gcGtjczEoa2V5LCBtc2csIHJldmVyc2UpXG4gIH0gZWxzZSBpZiAocGFkZGluZyA9PT0gMykge1xuICAgIHBhZGRlZE1zZyA9IG5ldyBCTihtc2cpXG4gICAgaWYgKHBhZGRlZE1zZy5jbXAoa2V5Lm1vZHVsdXMpID49IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZGF0YSB0b28gbG9uZyBmb3IgbW9kdWx1cycpXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBwYWRkaW5nJylcbiAgfVxuICBpZiAocmV2ZXJzZSkge1xuICAgIHJldHVybiBjcnQocGFkZGVkTXNnLCBrZXkpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHdpdGhQdWJsaWMocGFkZGVkTXNnLCBrZXkpXG4gIH1cbn1cblxuZnVuY3Rpb24gb2FlcCAoa2V5LCBtc2cpIHtcbiAgdmFyIGsgPSBrZXkubW9kdWx1cy5ieXRlTGVuZ3RoKClcbiAgdmFyIG1MZW4gPSBtc2cubGVuZ3RoXG4gIHZhciBpSGFzaCA9IGNyZWF0ZUhhc2goJ3NoYTEnKS51cGRhdGUoQnVmZmVyLmFsbG9jKDApKS5kaWdlc3QoKVxuICB2YXIgaExlbiA9IGlIYXNoLmxlbmd0aFxuICB2YXIgaExlbjIgPSAyICogaExlblxuICBpZiAobUxlbiA+IGsgLSBoTGVuMiAtIDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ21lc3NhZ2UgdG9vIGxvbmcnKVxuICB9XG4gIHZhciBwcyA9IEJ1ZmZlci5hbGxvYyhrIC0gbUxlbiAtIGhMZW4yIC0gMilcbiAgdmFyIGRibGVuID0gayAtIGhMZW4gLSAxXG4gIHZhciBzZWVkID0gcmFuZG9tQnl0ZXMoaExlbilcbiAgdmFyIG1hc2tlZERiID0geG9yKEJ1ZmZlci5jb25jYXQoW2lIYXNoLCBwcywgQnVmZmVyLmFsbG9jKDEsIDEpLCBtc2ddLCBkYmxlbiksIG1nZihzZWVkLCBkYmxlbikpXG4gIHZhciBtYXNrZWRTZWVkID0geG9yKHNlZWQsIG1nZihtYXNrZWREYiwgaExlbikpXG4gIHJldHVybiBuZXcgQk4oQnVmZmVyLmNvbmNhdChbQnVmZmVyLmFsbG9jKDEpLCBtYXNrZWRTZWVkLCBtYXNrZWREYl0sIGspKVxufVxuZnVuY3Rpb24gcGtjczEgKGtleSwgbXNnLCByZXZlcnNlKSB7XG4gIHZhciBtTGVuID0gbXNnLmxlbmd0aFxuICB2YXIgayA9IGtleS5tb2R1bHVzLmJ5dGVMZW5ndGgoKVxuICBpZiAobUxlbiA+IGsgLSAxMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignbWVzc2FnZSB0b28gbG9uZycpXG4gIH1cbiAgdmFyIHBzXG4gIGlmIChyZXZlcnNlKSB7XG4gICAgcHMgPSBCdWZmZXIuYWxsb2MoayAtIG1MZW4gLSAzLCAweGZmKVxuICB9IGVsc2Uge1xuICAgIHBzID0gbm9uWmVybyhrIC0gbUxlbiAtIDMpXG4gIH1cbiAgcmV0dXJuIG5ldyBCTihCdWZmZXIuY29uY2F0KFtCdWZmZXIuZnJvbShbMCwgcmV2ZXJzZSA/IDEgOiAyXSksIHBzLCBCdWZmZXIuYWxsb2MoMSksIG1zZ10sIGspKVxufVxuZnVuY3Rpb24gbm9uWmVybyAobGVuKSB7XG4gIHZhciBvdXQgPSBCdWZmZXIuYWxsb2NVbnNhZmUobGVuKVxuICB2YXIgaSA9IDBcbiAgdmFyIGNhY2hlID0gcmFuZG9tQnl0ZXMobGVuICogMilcbiAgdmFyIGN1ciA9IDBcbiAgdmFyIG51bVxuICB3aGlsZSAoaSA8IGxlbikge1xuICAgIGlmIChjdXIgPT09IGNhY2hlLmxlbmd0aCkge1xuICAgICAgY2FjaGUgPSByYW5kb21CeXRlcyhsZW4gKiAyKVxuICAgICAgY3VyID0gMFxuICAgIH1cbiAgICBudW0gPSBjYWNoZVtjdXIrK11cbiAgICBpZiAobnVtKSB7XG4gICAgICBvdXRbaSsrXSA9IG51bVxuICAgIH1cbiAgfVxuICByZXR1cm4gb3V0XG59XG4iLCJ2YXIgQk4gPSByZXF1aXJlKCdibi5qcycpXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcblxuZnVuY3Rpb24gd2l0aFB1YmxpYyAocGFkZGVkTXNnLCBrZXkpIHtcbiAgcmV0dXJuIEJ1ZmZlci5mcm9tKHBhZGRlZE1zZ1xuICAgIC50b1JlZChCTi5tb250KGtleS5tb2R1bHVzKSlcbiAgICAucmVkUG93KG5ldyBCTihrZXkucHVibGljRXhwb25lbnQpKVxuICAgIC5mcm9tUmVkKClcbiAgICAudG9BcnJheSgpKVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHdpdGhQdWJsaWNcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24geG9yIChhLCBiKSB7XG4gIHZhciBsZW4gPSBhLmxlbmd0aFxuICB2YXIgaSA9IC0xXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBhW2ldIF49IGJbaV1cbiAgfVxuICByZXR1cm4gYVxufVxuIiwiJ3VzZSBzdHJpY3QnXG5cbmZ1bmN0aW9uIG9sZEJyb3dzZXIgKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ1NlY3VyZSByYW5kb20gbnVtYmVyIGdlbmVyYXRpb24gaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIGJyb3dzZXIuXFxuVXNlIENocm9tZSwgRmlyZWZveCBvciBJbnRlcm5ldCBFeHBsb3JlciAxMScpXG59XG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxudmFyIGNyeXB0byA9IGdsb2JhbC5jcnlwdG8gfHwgZ2xvYmFsLm1zQ3J5cHRvXG5cbmlmIChjcnlwdG8gJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcykge1xuICBtb2R1bGUuZXhwb3J0cyA9IHJhbmRvbUJ5dGVzXG59IGVsc2Uge1xuICBtb2R1bGUuZXhwb3J0cyA9IG9sZEJyb3dzZXJcbn1cblxuZnVuY3Rpb24gcmFuZG9tQnl0ZXMgKHNpemUsIGNiKSB7XG4gIC8vIHBoYW50b21qcyBuZWVkcyB0byB0aHJvd1xuICBpZiAoc2l6ZSA+IDY1NTM2KSB0aHJvdyBuZXcgRXJyb3IoJ3JlcXVlc3RlZCB0b28gbWFueSByYW5kb20gYnl0ZXMnKVxuICAvLyBpbiBjYXNlIGJyb3dzZXJpZnkgIGlzbid0IHVzaW5nIHRoZSBVaW50OEFycmF5IHZlcnNpb25cbiAgdmFyIHJhd0J5dGVzID0gbmV3IGdsb2JhbC5VaW50OEFycmF5KHNpemUpXG5cbiAgLy8gVGhpcyB3aWxsIG5vdCB3b3JrIGluIG9sZGVyIGJyb3dzZXJzLlxuICAvLyBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL3dpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzXG4gIGlmIChzaXplID4gMCkgeyAgLy8gZ2V0UmFuZG9tVmFsdWVzIGZhaWxzIG9uIElFIGlmIHNpemUgPT0gMFxuICAgIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMocmF3Qnl0ZXMpXG4gIH1cblxuICAvLyBYWFg6IHBoYW50b21qcyBkb2Vzbid0IGxpa2UgYSBidWZmZXIgYmVpbmcgcGFzc2VkIGhlcmVcbiAgdmFyIGJ5dGVzID0gQnVmZmVyLmZyb20ocmF3Qnl0ZXMuYnVmZmVyKVxuXG4gIGlmICh0eXBlb2YgY2IgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICBjYihudWxsLCBieXRlcylcbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG4iLCIndXNlIHN0cmljdCdcblxuZnVuY3Rpb24gb2xkQnJvd3NlciAoKSB7XG4gIHRocm93IG5ldyBFcnJvcignc2VjdXJlIHJhbmRvbSBudW1iZXIgZ2VuZXJhdGlvbiBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgYnJvd3NlclxcbnVzZSBjaHJvbWUsIEZpcmVGb3ggb3IgSW50ZXJuZXQgRXhwbG9yZXIgMTEnKVxufVxudmFyIHNhZmVCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpXG52YXIgcmFuZG9tYnl0ZXMgPSByZXF1aXJlKCdyYW5kb21ieXRlcycpXG52YXIgQnVmZmVyID0gc2FmZUJ1ZmZlci5CdWZmZXJcbnZhciBrQnVmZmVyTWF4TGVuZ3RoID0gc2FmZUJ1ZmZlci5rTWF4TGVuZ3RoXG52YXIgY3J5cHRvID0gZ2xvYmFsLmNyeXB0byB8fCBnbG9iYWwubXNDcnlwdG9cbnZhciBrTWF4VWludDMyID0gTWF0aC5wb3coMiwgMzIpIC0gMVxuZnVuY3Rpb24gYXNzZXJ0T2Zmc2V0IChvZmZzZXQsIGxlbmd0aCkge1xuICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0ICE9PSBvZmZzZXQpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvZmZzZXQgbXVzdCBiZSBhIG51bWJlcicpXG4gIH1cblxuICBpZiAob2Zmc2V0ID4ga01heFVpbnQzMiB8fCBvZmZzZXQgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb2Zmc2V0IG11c3QgYmUgYSB1aW50MzInKVxuICB9XG5cbiAgaWYgKG9mZnNldCA+IGtCdWZmZXJNYXhMZW5ndGggfHwgb2Zmc2V0ID4gbGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ29mZnNldCBvdXQgb2YgcmFuZ2UnKVxuICB9XG59XG5cbmZ1bmN0aW9uIGFzc2VydFNpemUgKHNpemUsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICh0eXBlb2Ygc2l6ZSAhPT0gJ251bWJlcicgfHwgc2l6ZSAhPT0gc2l6ZSkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNlbGYtY29tcGFyZVxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3NpemUgbXVzdCBiZSBhIG51bWJlcicpXG4gIH1cblxuICBpZiAoc2l6ZSA+IGtNYXhVaW50MzIgfHwgc2l6ZSA8IDApIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdzaXplIG11c3QgYmUgYSB1aW50MzInKVxuICB9XG5cbiAgaWYgKHNpemUgKyBvZmZzZXQgPiBsZW5ndGggfHwgc2l6ZSA+IGtCdWZmZXJNYXhMZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignYnVmZmVyIHRvbyBzbWFsbCcpXG4gIH1cbn1cbmlmICgoY3J5cHRvICYmIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMpIHx8ICFwcm9jZXNzLmJyb3dzZXIpIHtcbiAgZXhwb3J0cy5yYW5kb21GaWxsID0gcmFuZG9tRmlsbFxuICBleHBvcnRzLnJhbmRvbUZpbGxTeW5jID0gcmFuZG9tRmlsbFN5bmNcbn0gZWxzZSB7XG4gIGV4cG9ydHMucmFuZG9tRmlsbCA9IG9sZEJyb3dzZXJcbiAgZXhwb3J0cy5yYW5kb21GaWxsU3luYyA9IG9sZEJyb3dzZXJcbn1cbmZ1bmN0aW9uIHJhbmRvbUZpbGwgKGJ1Ziwgb2Zmc2V0LCBzaXplLCBjYikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpICYmICEoYnVmIGluc3RhbmNlb2YgZ2xvYmFsLlVpbnQ4QXJyYXkpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJidWZcIiBhcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyIG9yIFVpbnQ4QXJyYXknKVxuICB9XG5cbiAgaWYgKHR5cGVvZiBvZmZzZXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IG9mZnNldFxuICAgIG9mZnNldCA9IDBcbiAgICBzaXplID0gYnVmLmxlbmd0aFxuICB9IGVsc2UgaWYgKHR5cGVvZiBzaXplID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBzaXplXG4gICAgc2l6ZSA9IGJ1Zi5sZW5ndGggLSBvZmZzZXRcbiAgfSBlbHNlIGlmICh0eXBlb2YgY2IgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImNiXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJylcbiAgfVxuICBhc3NlcnRPZmZzZXQob2Zmc2V0LCBidWYubGVuZ3RoKVxuICBhc3NlcnRTaXplKHNpemUsIG9mZnNldCwgYnVmLmxlbmd0aClcbiAgcmV0dXJuIGFjdHVhbEZpbGwoYnVmLCBvZmZzZXQsIHNpemUsIGNiKVxufVxuXG5mdW5jdGlvbiBhY3R1YWxGaWxsIChidWYsIG9mZnNldCwgc2l6ZSwgY2IpIHtcbiAgaWYgKHByb2Nlc3MuYnJvd3Nlcikge1xuICAgIHZhciBvdXJCdWYgPSBidWYuYnVmZmVyXG4gICAgdmFyIHVpbnQgPSBuZXcgVWludDhBcnJheShvdXJCdWYsIG9mZnNldCwgc2l6ZSlcbiAgICBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKHVpbnQpXG4gICAgaWYgKGNiKSB7XG4gICAgICBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY2IobnVsbCwgYnVmKVxuICAgICAgfSlcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICByZXR1cm4gYnVmXG4gIH1cbiAgaWYgKGNiKSB7XG4gICAgcmFuZG9tYnl0ZXMoc2l6ZSwgZnVuY3Rpb24gKGVyciwgYnl0ZXMpIHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgcmV0dXJuIGNiKGVycilcbiAgICAgIH1cbiAgICAgIGJ5dGVzLmNvcHkoYnVmLCBvZmZzZXQpXG4gICAgICBjYihudWxsLCBidWYpXG4gICAgfSlcbiAgICByZXR1cm5cbiAgfVxuICB2YXIgYnl0ZXMgPSByYW5kb21ieXRlcyhzaXplKVxuICBieXRlcy5jb3B5KGJ1Ziwgb2Zmc2V0KVxuICByZXR1cm4gYnVmXG59XG5mdW5jdGlvbiByYW5kb21GaWxsU3luYyAoYnVmLCBvZmZzZXQsIHNpemUpIHtcbiAgaWYgKHR5cGVvZiBvZmZzZXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgb2Zmc2V0ID0gMFxuICB9XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikgJiYgIShidWYgaW5zdGFuY2VvZiBnbG9iYWwuVWludDhBcnJheSkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImJ1ZlwiIGFyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXIgb3IgVWludDhBcnJheScpXG4gIH1cblxuICBhc3NlcnRPZmZzZXQob2Zmc2V0LCBidWYubGVuZ3RoKVxuXG4gIGlmIChzaXplID09PSB1bmRlZmluZWQpIHNpemUgPSBidWYubGVuZ3RoIC0gb2Zmc2V0XG5cbiAgYXNzZXJ0U2l6ZShzaXplLCBvZmZzZXQsIGJ1Zi5sZW5ndGgpXG5cbiAgcmV0dXJuIGFjdHVhbEZpbGwoYnVmLCBvZmZzZXQsIHNpemUpXG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX2R1cGxleC5qc1wiKVxuIiwiLy8gYSBkdXBsZXggc3RyZWFtIGlzIGp1c3QgYSBzdHJlYW0gdGhhdCBpcyBib3RoIHJlYWRhYmxlIGFuZCB3cml0YWJsZS5cbi8vIFNpbmNlIEpTIGRvZXNuJ3QgaGF2ZSBtdWx0aXBsZSBwcm90b3R5cGFsIGluaGVyaXRhbmNlLCB0aGlzIGNsYXNzXG4vLyBwcm90b3R5cGFsbHkgaW5oZXJpdHMgZnJvbSBSZWFkYWJsZSwgYW5kIHRoZW4gcGFyYXNpdGljYWxseSBmcm9tXG4vLyBXcml0YWJsZS5cblxuJ3VzZSBzdHJpY3QnO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xuXG52YXIgb2JqZWN0S2V5cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGtleXMucHVzaChrZXkpO1xuICB9cmV0dXJuIGtleXM7XG59O1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbm1vZHVsZS5leHBvcnRzID0gRHVwbGV4O1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHByb2Nlc3NOZXh0VGljayA9IHJlcXVpcmUoJ3Byb2Nlc3MtbmV4dGljay1hcmdzJyk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gcmVxdWlyZSgnY29yZS11dGlsLWlzJyk7XG51dGlsLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG52YXIgUmVhZGFibGUgPSByZXF1aXJlKCcuL19zdHJlYW1fcmVhZGFibGUnKTtcbnZhciBXcml0YWJsZSA9IHJlcXVpcmUoJy4vX3N0cmVhbV93cml0YWJsZScpO1xuXG51dGlsLmluaGVyaXRzKER1cGxleCwgUmVhZGFibGUpO1xuXG52YXIga2V5cyA9IG9iamVjdEtleXMoV3JpdGFibGUucHJvdG90eXBlKTtcbmZvciAodmFyIHYgPSAwOyB2IDwga2V5cy5sZW5ndGg7IHYrKykge1xuICB2YXIgbWV0aG9kID0ga2V5c1t2XTtcbiAgaWYgKCFEdXBsZXgucHJvdG90eXBlW21ldGhvZF0pIER1cGxleC5wcm90b3R5cGVbbWV0aG9kXSA9IFdyaXRhYmxlLnByb3RvdHlwZVttZXRob2RdO1xufVxuXG5mdW5jdGlvbiBEdXBsZXgob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgRHVwbGV4KSkgcmV0dXJuIG5ldyBEdXBsZXgob3B0aW9ucyk7XG5cbiAgUmVhZGFibGUuY2FsbCh0aGlzLCBvcHRpb25zKTtcbiAgV3JpdGFibGUuY2FsbCh0aGlzLCBvcHRpb25zKTtcblxuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLnJlYWRhYmxlID09PSBmYWxzZSkgdGhpcy5yZWFkYWJsZSA9IGZhbHNlO1xuXG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMud3JpdGFibGUgPT09IGZhbHNlKSB0aGlzLndyaXRhYmxlID0gZmFsc2U7XG5cbiAgdGhpcy5hbGxvd0hhbGZPcGVuID0gdHJ1ZTtcbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5hbGxvd0hhbGZPcGVuID09PSBmYWxzZSkgdGhpcy5hbGxvd0hhbGZPcGVuID0gZmFsc2U7XG5cbiAgdGhpcy5vbmNlKCdlbmQnLCBvbmVuZCk7XG59XG5cbi8vIHRoZSBuby1oYWxmLW9wZW4gZW5mb3JjZXJcbmZ1bmN0aW9uIG9uZW5kKCkge1xuICAvLyBpZiB3ZSBhbGxvdyBoYWxmLW9wZW4gc3RhdGUsIG9yIGlmIHRoZSB3cml0YWJsZSBzaWRlIGVuZGVkLFxuICAvLyB0aGVuIHdlJ3JlIG9rLlxuICBpZiAodGhpcy5hbGxvd0hhbGZPcGVuIHx8IHRoaXMuX3dyaXRhYmxlU3RhdGUuZW5kZWQpIHJldHVybjtcblxuICAvLyBubyBtb3JlIGRhdGEgY2FuIGJlIHdyaXR0ZW4uXG4gIC8vIEJ1dCBhbGxvdyBtb3JlIHdyaXRlcyB0byBoYXBwZW4gaW4gdGhpcyB0aWNrLlxuICBwcm9jZXNzTmV4dFRpY2sob25FbmROVCwgdGhpcyk7XG59XG5cbmZ1bmN0aW9uIG9uRW5kTlQoc2VsZikge1xuICBzZWxmLmVuZCgpO1xufVxuXG5mdW5jdGlvbiBmb3JFYWNoKHhzLCBmKSB7XG4gIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgZih4c1tpXSwgaSk7XG4gIH1cbn0iLCIvLyBhIHBhc3N0aHJvdWdoIHN0cmVhbS5cbi8vIGJhc2ljYWxseSBqdXN0IHRoZSBtb3N0IG1pbmltYWwgc29ydCBvZiBUcmFuc2Zvcm0gc3RyZWFtLlxuLy8gRXZlcnkgd3JpdHRlbiBjaHVuayBnZXRzIG91dHB1dCBhcy1pcy5cblxuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBhc3NUaHJvdWdoO1xuXG52YXIgVHJhbnNmb3JtID0gcmVxdWlyZSgnLi9fc3RyZWFtX3RyYW5zZm9ybScpO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHV0aWwgPSByZXF1aXJlKCdjb3JlLXV0aWwtaXMnKTtcbnV0aWwuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbnV0aWwuaW5oZXJpdHMoUGFzc1Rocm91Z2gsIFRyYW5zZm9ybSk7XG5cbmZ1bmN0aW9uIFBhc3NUaHJvdWdoKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFBhc3NUaHJvdWdoKSkgcmV0dXJuIG5ldyBQYXNzVGhyb3VnaChvcHRpb25zKTtcblxuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBvcHRpb25zKTtcbn1cblxuUGFzc1Rocm91Z2gucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBjYihudWxsLCBjaHVuayk7XG59OyIsIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBSZWFkYWJsZTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBwcm9jZXNzTmV4dFRpY2sgPSByZXF1aXJlKCdwcm9jZXNzLW5leHRpY2stYXJncycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG5SZWFkYWJsZS5SZWFkYWJsZVN0YXRlID0gUmVhZGFibGVTdGF0ZTtcblxudmFyIEVFID0gcmVxdWlyZSgnZXZlbnRzJyk7XG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgRUVsaXN0ZW5lckNvdW50ID0gZnVuY3Rpb24gKGVtaXR0ZXIsIHR5cGUpIHtcbiAgcmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJzKHR5cGUpLmxlbmd0aDtcbn07XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBTdHJlYW07XG4oZnVuY3Rpb24gKCkge1xuICB0cnkge1xuICAgIFN0cmVhbSA9IHJlcXVpcmUoJ3N0JyArICdyZWFtJyk7XG4gIH0gY2F0Y2ggKF8pIHt9IGZpbmFsbHkge1xuICAgIGlmICghU3RyZWFtKSBTdHJlYW0gPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG4gIH1cbn0pKCk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gcmVxdWlyZSgnY29yZS11dGlsLWlzJyk7XG51dGlsLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIGRlYnVnVXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnZhciBkZWJ1ZyA9IHVuZGVmaW5lZDtcbmlmIChkZWJ1Z1V0aWwgJiYgZGVidWdVdGlsLmRlYnVnbG9nKSB7XG4gIGRlYnVnID0gZGVidWdVdGlsLmRlYnVnbG9nKCdzdHJlYW0nKTtcbn0gZWxzZSB7XG4gIGRlYnVnID0gZnVuY3Rpb24gKCkge307XG59XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIFN0cmluZ0RlY29kZXI7XG5cbnV0aWwuaW5oZXJpdHMoUmVhZGFibGUsIFN0cmVhbSk7XG5cbnZhciBEdXBsZXg7XG5mdW5jdGlvbiBSZWFkYWJsZVN0YXRlKG9wdGlvbnMsIHN0cmVhbSkge1xuICBEdXBsZXggPSBEdXBsZXggfHwgcmVxdWlyZSgnLi9fc3RyZWFtX2R1cGxleCcpO1xuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIG9iamVjdCBzdHJlYW0gZmxhZy4gVXNlZCB0byBtYWtlIHJlYWQobikgaWdub3JlIG4gYW5kIHRvXG4gIC8vIG1ha2UgYWxsIHRoZSBidWZmZXIgbWVyZ2luZyBhbmQgbGVuZ3RoIGNoZWNrcyBnbyBhd2F5XG4gIHRoaXMub2JqZWN0TW9kZSA9ICEhb3B0aW9ucy5vYmplY3RNb2RlO1xuXG4gIGlmIChzdHJlYW0gaW5zdGFuY2VvZiBEdXBsZXgpIHRoaXMub2JqZWN0TW9kZSA9IHRoaXMub2JqZWN0TW9kZSB8fCAhIW9wdGlvbnMucmVhZGFibGVPYmplY3RNb2RlO1xuXG4gIC8vIHRoZSBwb2ludCBhdCB3aGljaCBpdCBzdG9wcyBjYWxsaW5nIF9yZWFkKCkgdG8gZmlsbCB0aGUgYnVmZmVyXG4gIC8vIE5vdGU6IDAgaXMgYSB2YWxpZCB2YWx1ZSwgbWVhbnMgXCJkb24ndCBjYWxsIF9yZWFkIHByZWVtcHRpdmVseSBldmVyXCJcbiAgdmFyIGh3bSA9IG9wdGlvbnMuaGlnaFdhdGVyTWFyaztcbiAgdmFyIGRlZmF1bHRId20gPSB0aGlzLm9iamVjdE1vZGUgPyAxNiA6IDE2ICogMTAyNDtcbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gaHdtIHx8IGh3bSA9PT0gMCA/IGh3bSA6IGRlZmF1bHRId207XG5cbiAgLy8gY2FzdCB0byBpbnRzLlxuICB0aGlzLmhpZ2hXYXRlck1hcmsgPSB+IH50aGlzLmhpZ2hXYXRlck1hcms7XG5cbiAgdGhpcy5idWZmZXIgPSBbXTtcbiAgdGhpcy5sZW5ndGggPSAwO1xuICB0aGlzLnBpcGVzID0gbnVsbDtcbiAgdGhpcy5waXBlc0NvdW50ID0gMDtcbiAgdGhpcy5mbG93aW5nID0gbnVsbDtcbiAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICB0aGlzLmVuZEVtaXR0ZWQgPSBmYWxzZTtcbiAgdGhpcy5yZWFkaW5nID0gZmFsc2U7XG5cbiAgLy8gYSBmbGFnIHRvIGJlIGFibGUgdG8gdGVsbCBpZiB0aGUgb253cml0ZSBjYiBpcyBjYWxsZWQgaW1tZWRpYXRlbHksXG4gIC8vIG9yIG9uIGEgbGF0ZXIgdGljay4gIFdlIHNldCB0aGlzIHRvIHRydWUgYXQgZmlyc3QsIGJlY2F1c2UgYW55XG4gIC8vIGFjdGlvbnMgdGhhdCBzaG91bGRuJ3QgaGFwcGVuIHVudGlsIFwibGF0ZXJcIiBzaG91bGQgZ2VuZXJhbGx5IGFsc29cbiAgLy8gbm90IGhhcHBlbiBiZWZvcmUgdGhlIGZpcnN0IHdyaXRlIGNhbGwuXG4gIHRoaXMuc3luYyA9IHRydWU7XG5cbiAgLy8gd2hlbmV2ZXIgd2UgcmV0dXJuIG51bGwsIHRoZW4gd2Ugc2V0IGEgZmxhZyB0byBzYXlcbiAgLy8gdGhhdCB3ZSdyZSBhd2FpdGluZyBhICdyZWFkYWJsZScgZXZlbnQgZW1pc3Npb24uXG4gIHRoaXMubmVlZFJlYWRhYmxlID0gZmFsc2U7XG4gIHRoaXMuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG4gIHRoaXMucmVhZGFibGVMaXN0ZW5pbmcgPSBmYWxzZTtcbiAgdGhpcy5yZXN1bWVTY2hlZHVsZWQgPSBmYWxzZTtcblxuICAvLyBDcnlwdG8gaXMga2luZCBvZiBvbGQgYW5kIGNydXN0eS4gIEhpc3RvcmljYWxseSwgaXRzIGRlZmF1bHQgc3RyaW5nXG4gIC8vIGVuY29kaW5nIGlzICdiaW5hcnknIHNvIHdlIGhhdmUgdG8gbWFrZSB0aGlzIGNvbmZpZ3VyYWJsZS5cbiAgLy8gRXZlcnl0aGluZyBlbHNlIGluIHRoZSB1bml2ZXJzZSB1c2VzICd1dGY4JywgdGhvdWdoLlxuICB0aGlzLmRlZmF1bHRFbmNvZGluZyA9IG9wdGlvbnMuZGVmYXVsdEVuY29kaW5nIHx8ICd1dGY4JztcblxuICAvLyB3aGVuIHBpcGluZywgd2Ugb25seSBjYXJlIGFib3V0ICdyZWFkYWJsZScgZXZlbnRzIHRoYXQgaGFwcGVuXG4gIC8vIGFmdGVyIHJlYWQoKWluZyBhbGwgdGhlIGJ5dGVzIGFuZCBub3QgZ2V0dGluZyBhbnkgcHVzaGJhY2suXG4gIHRoaXMucmFuT3V0ID0gZmFsc2U7XG5cbiAgLy8gdGhlIG51bWJlciBvZiB3cml0ZXJzIHRoYXQgYXJlIGF3YWl0aW5nIGEgZHJhaW4gZXZlbnQgaW4gLnBpcGUoKXNcbiAgdGhpcy5hd2FpdERyYWluID0gMDtcblxuICAvLyBpZiB0cnVlLCBhIG1heWJlUmVhZE1vcmUgaGFzIGJlZW4gc2NoZWR1bGVkXG4gIHRoaXMucmVhZGluZ01vcmUgPSBmYWxzZTtcblxuICB0aGlzLmRlY29kZXIgPSBudWxsO1xuICB0aGlzLmVuY29kaW5nID0gbnVsbDtcbiAgaWYgKG9wdGlvbnMuZW5jb2RpbmcpIHtcbiAgICBpZiAoIVN0cmluZ0RlY29kZXIpIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2Rlci8nKS5TdHJpbmdEZWNvZGVyO1xuICAgIHRoaXMuZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKG9wdGlvbnMuZW5jb2RpbmcpO1xuICAgIHRoaXMuZW5jb2RpbmcgPSBvcHRpb25zLmVuY29kaW5nO1xuICB9XG59XG5cbnZhciBEdXBsZXg7XG5mdW5jdGlvbiBSZWFkYWJsZShvcHRpb25zKSB7XG4gIER1cGxleCA9IER1cGxleCB8fCByZXF1aXJlKCcuL19zdHJlYW1fZHVwbGV4Jyk7XG5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJlYWRhYmxlKSkgcmV0dXJuIG5ldyBSZWFkYWJsZShvcHRpb25zKTtcblxuICB0aGlzLl9yZWFkYWJsZVN0YXRlID0gbmV3IFJlYWRhYmxlU3RhdGUob3B0aW9ucywgdGhpcyk7XG5cbiAgLy8gbGVnYWN5XG4gIHRoaXMucmVhZGFibGUgPSB0cnVlO1xuXG4gIGlmIChvcHRpb25zICYmIHR5cGVvZiBvcHRpb25zLnJlYWQgPT09ICdmdW5jdGlvbicpIHRoaXMuX3JlYWQgPSBvcHRpb25zLnJlYWQ7XG5cbiAgU3RyZWFtLmNhbGwodGhpcyk7XG59XG5cbi8vIE1hbnVhbGx5IHNob3ZlIHNvbWV0aGluZyBpbnRvIHRoZSByZWFkKCkgYnVmZmVyLlxuLy8gVGhpcyByZXR1cm5zIHRydWUgaWYgdGhlIGhpZ2hXYXRlck1hcmsgaGFzIG5vdCBiZWVuIGhpdCB5ZXQsXG4vLyBzaW1pbGFyIHRvIGhvdyBXcml0YWJsZS53cml0ZSgpIHJldHVybnMgdHJ1ZSBpZiB5b3Ugc2hvdWxkXG4vLyB3cml0ZSgpIHNvbWUgbW9yZS5cblJlYWRhYmxlLnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZykge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuXG4gIGlmICghc3RhdGUub2JqZWN0TW9kZSAmJiB0eXBlb2YgY2h1bmsgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBlbmNvZGluZyB8fCBzdGF0ZS5kZWZhdWx0RW5jb2Rpbmc7XG4gICAgaWYgKGVuY29kaW5nICE9PSBzdGF0ZS5lbmNvZGluZykge1xuICAgICAgY2h1bmsgPSBuZXcgQnVmZmVyKGNodW5rLCBlbmNvZGluZyk7XG4gICAgICBlbmNvZGluZyA9ICcnO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZWFkYWJsZUFkZENodW5rKHRoaXMsIHN0YXRlLCBjaHVuaywgZW5jb2RpbmcsIGZhbHNlKTtcbn07XG5cbi8vIFVuc2hpZnQgc2hvdWxkICphbHdheXMqIGJlIHNvbWV0aGluZyBkaXJlY3RseSBvdXQgb2YgcmVhZCgpXG5SZWFkYWJsZS5wcm90b3R5cGUudW5zaGlmdCA9IGZ1bmN0aW9uIChjaHVuaykge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICByZXR1cm4gcmVhZGFibGVBZGRDaHVuayh0aGlzLCBzdGF0ZSwgY2h1bmssICcnLCB0cnVlKTtcbn07XG5cblJlYWRhYmxlLnByb3RvdHlwZS5pc1BhdXNlZCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyA9PT0gZmFsc2U7XG59O1xuXG5mdW5jdGlvbiByZWFkYWJsZUFkZENodW5rKHN0cmVhbSwgc3RhdGUsIGNodW5rLCBlbmNvZGluZywgYWRkVG9Gcm9udCkge1xuICB2YXIgZXIgPSBjaHVua0ludmFsaWQoc3RhdGUsIGNodW5rKTtcbiAgaWYgKGVyKSB7XG4gICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuICB9IGVsc2UgaWYgKGNodW5rID09PSBudWxsKSB7XG4gICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICAgIG9uRW9mQ2h1bmsoc3RyZWFtLCBzdGF0ZSk7XG4gIH0gZWxzZSBpZiAoc3RhdGUub2JqZWN0TW9kZSB8fCBjaHVuayAmJiBjaHVuay5sZW5ndGggPiAwKSB7XG4gICAgaWYgKHN0YXRlLmVuZGVkICYmICFhZGRUb0Zyb250KSB7XG4gICAgICB2YXIgZSA9IG5ldyBFcnJvcignc3RyZWFtLnB1c2goKSBhZnRlciBFT0YnKTtcbiAgICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIGUpO1xuICAgIH0gZWxzZSBpZiAoc3RhdGUuZW5kRW1pdHRlZCAmJiBhZGRUb0Zyb250KSB7XG4gICAgICB2YXIgZSA9IG5ldyBFcnJvcignc3RyZWFtLnVuc2hpZnQoKSBhZnRlciBlbmQgZXZlbnQnKTtcbiAgICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgc2tpcEFkZDtcbiAgICAgIGlmIChzdGF0ZS5kZWNvZGVyICYmICFhZGRUb0Zyb250ICYmICFlbmNvZGluZykge1xuICAgICAgICBjaHVuayA9IHN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO1xuICAgICAgICBza2lwQWRkID0gIXN0YXRlLm9iamVjdE1vZGUgJiYgY2h1bmsubGVuZ3RoID09PSAwO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWFkZFRvRnJvbnQpIHN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcblxuICAgICAgLy8gRG9uJ3QgYWRkIHRvIHRoZSBidWZmZXIgaWYgd2UndmUgZGVjb2RlZCB0byBhbiBlbXB0eSBzdHJpbmcgY2h1bmsgYW5kXG4gICAgICAvLyB3ZSdyZSBub3QgaW4gb2JqZWN0IG1vZGVcbiAgICAgIGlmICghc2tpcEFkZCkge1xuICAgICAgICAvLyBpZiB3ZSB3YW50IHRoZSBkYXRhIG5vdywganVzdCBlbWl0IGl0LlxuICAgICAgICBpZiAoc3RhdGUuZmxvd2luZyAmJiBzdGF0ZS5sZW5ndGggPT09IDAgJiYgIXN0YXRlLnN5bmMpIHtcbiAgICAgICAgICBzdHJlYW0uZW1pdCgnZGF0YScsIGNodW5rKTtcbiAgICAgICAgICBzdHJlYW0ucmVhZCgwKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyB1cGRhdGUgdGhlIGJ1ZmZlciBpbmZvLlxuICAgICAgICAgIHN0YXRlLmxlbmd0aCArPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcbiAgICAgICAgICBpZiAoYWRkVG9Gcm9udCkgc3RhdGUuYnVmZmVyLnVuc2hpZnQoY2h1bmspO2Vsc2Ugc3RhdGUuYnVmZmVyLnB1c2goY2h1bmspO1xuXG4gICAgICAgICAgaWYgKHN0YXRlLm5lZWRSZWFkYWJsZSkgZW1pdFJlYWRhYmxlKHN0cmVhbSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoIWFkZFRvRnJvbnQpIHtcbiAgICBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gbmVlZE1vcmVEYXRhKHN0YXRlKTtcbn1cblxuLy8gaWYgaXQncyBwYXN0IHRoZSBoaWdoIHdhdGVyIG1hcmssIHdlIGNhbiBwdXNoIGluIHNvbWUgbW9yZS5cbi8vIEFsc28sIGlmIHdlIGhhdmUgbm8gZGF0YSB5ZXQsIHdlIGNhbiBzdGFuZCBzb21lXG4vLyBtb3JlIGJ5dGVzLiAgVGhpcyBpcyB0byB3b3JrIGFyb3VuZCBjYXNlcyB3aGVyZSBod209MCxcbi8vIHN1Y2ggYXMgdGhlIHJlcGwuICBBbHNvLCBpZiB0aGUgcHVzaCgpIHRyaWdnZXJlZCBhXG4vLyByZWFkYWJsZSBldmVudCwgYW5kIHRoZSB1c2VyIGNhbGxlZCByZWFkKGxhcmdlTnVtYmVyKSBzdWNoIHRoYXRcbi8vIG5lZWRSZWFkYWJsZSB3YXMgc2V0LCB0aGVuIHdlIG91Z2h0IHRvIHB1c2ggbW9yZSwgc28gdGhhdCBhbm90aGVyXG4vLyAncmVhZGFibGUnIGV2ZW50IHdpbGwgYmUgdHJpZ2dlcmVkLlxuZnVuY3Rpb24gbmVlZE1vcmVEYXRhKHN0YXRlKSB7XG4gIHJldHVybiAhc3RhdGUuZW5kZWQgJiYgKHN0YXRlLm5lZWRSZWFkYWJsZSB8fCBzdGF0ZS5sZW5ndGggPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrIHx8IHN0YXRlLmxlbmd0aCA9PT0gMCk7XG59XG5cbi8vIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LlxuUmVhZGFibGUucHJvdG90eXBlLnNldEVuY29kaW5nID0gZnVuY3Rpb24gKGVuYykge1xuICBpZiAoIVN0cmluZ0RlY29kZXIpIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2Rlci8nKS5TdHJpbmdEZWNvZGVyO1xuICB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlY29kZXIgPSBuZXcgU3RyaW5nRGVjb2RlcihlbmMpO1xuICB0aGlzLl9yZWFkYWJsZVN0YXRlLmVuY29kaW5nID0gZW5jO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIERvbid0IHJhaXNlIHRoZSBod20gPiA4TUJcbnZhciBNQVhfSFdNID0gMHg4MDAwMDA7XG5mdW5jdGlvbiBjb21wdXRlTmV3SGlnaFdhdGVyTWFyayhuKSB7XG4gIGlmIChuID49IE1BWF9IV00pIHtcbiAgICBuID0gTUFYX0hXTTtcbiAgfSBlbHNlIHtcbiAgICAvLyBHZXQgdGhlIG5leHQgaGlnaGVzdCBwb3dlciBvZiAyXG4gICAgbi0tO1xuICAgIG4gfD0gbiA+Pj4gMTtcbiAgICBuIHw9IG4gPj4+IDI7XG4gICAgbiB8PSBuID4+PiA0O1xuICAgIG4gfD0gbiA+Pj4gODtcbiAgICBuIHw9IG4gPj4+IDE2O1xuICAgIG4rKztcbiAgfVxuICByZXR1cm4gbjtcbn1cblxuZnVuY3Rpb24gaG93TXVjaFRvUmVhZChuLCBzdGF0ZSkge1xuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLmVuZGVkKSByZXR1cm4gMDtcblxuICBpZiAoc3RhdGUub2JqZWN0TW9kZSkgcmV0dXJuIG4gPT09IDAgPyAwIDogMTtcblxuICBpZiAobiA9PT0gbnVsbCB8fCBpc05hTihuKSkge1xuICAgIC8vIG9ubHkgZmxvdyBvbmUgYnVmZmVyIGF0IGEgdGltZVxuICAgIGlmIChzdGF0ZS5mbG93aW5nICYmIHN0YXRlLmJ1ZmZlci5sZW5ndGgpIHJldHVybiBzdGF0ZS5idWZmZXJbMF0ubGVuZ3RoO2Vsc2UgcmV0dXJuIHN0YXRlLmxlbmd0aDtcbiAgfVxuXG4gIGlmIChuIDw9IDApIHJldHVybiAwO1xuXG4gIC8vIElmIHdlJ3JlIGFza2luZyBmb3IgbW9yZSB0aGFuIHRoZSB0YXJnZXQgYnVmZmVyIGxldmVsLFxuICAvLyB0aGVuIHJhaXNlIHRoZSB3YXRlciBtYXJrLiAgQnVtcCB1cCB0byB0aGUgbmV4dCBoaWdoZXN0XG4gIC8vIHBvd2VyIG9mIDIsIHRvIHByZXZlbnQgaW5jcmVhc2luZyBpdCBleGNlc3NpdmVseSBpbiB0aW55XG4gIC8vIGFtb3VudHMuXG4gIGlmIChuID4gc3RhdGUuaGlnaFdhdGVyTWFyaykgc3RhdGUuaGlnaFdhdGVyTWFyayA9IGNvbXB1dGVOZXdIaWdoV2F0ZXJNYXJrKG4pO1xuXG4gIC8vIGRvbid0IGhhdmUgdGhhdCBtdWNoLiAgcmV0dXJuIG51bGwsIHVubGVzcyB3ZSd2ZSBlbmRlZC5cbiAgaWYgKG4gPiBzdGF0ZS5sZW5ndGgpIHtcbiAgICBpZiAoIXN0YXRlLmVuZGVkKSB7XG4gICAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgICAgcmV0dXJuIDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzdGF0ZS5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG47XG59XG5cbi8vIHlvdSBjYW4gb3ZlcnJpZGUgZWl0aGVyIHRoaXMgbWV0aG9kLCBvciB0aGUgYXN5bmMgX3JlYWQobikgYmVsb3cuXG5SZWFkYWJsZS5wcm90b3R5cGUucmVhZCA9IGZ1bmN0aW9uIChuKSB7XG4gIGRlYnVnKCdyZWFkJywgbik7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHZhciBuT3JpZyA9IG47XG5cbiAgaWYgKHR5cGVvZiBuICE9PSAnbnVtYmVyJyB8fCBuID4gMCkgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG5cbiAgLy8gaWYgd2UncmUgZG9pbmcgcmVhZCgwKSB0byB0cmlnZ2VyIGEgcmVhZGFibGUgZXZlbnQsIGJ1dCB3ZVxuICAvLyBhbHJlYWR5IGhhdmUgYSBidW5jaCBvZiBkYXRhIGluIHRoZSBidWZmZXIsIHRoZW4ganVzdCB0cmlnZ2VyXG4gIC8vIHRoZSAncmVhZGFibGUnIGV2ZW50IGFuZCBtb3ZlIG9uLlxuICBpZiAobiA9PT0gMCAmJiBzdGF0ZS5uZWVkUmVhZGFibGUgJiYgKHN0YXRlLmxlbmd0aCA+PSBzdGF0ZS5oaWdoV2F0ZXJNYXJrIHx8IHN0YXRlLmVuZGVkKSkge1xuICAgIGRlYnVnKCdyZWFkOiBlbWl0UmVhZGFibGUnLCBzdGF0ZS5sZW5ndGgsIHN0YXRlLmVuZGVkKTtcbiAgICBpZiAoc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLmVuZGVkKSBlbmRSZWFkYWJsZSh0aGlzKTtlbHNlIGVtaXRSZWFkYWJsZSh0aGlzKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIG4gPSBob3dNdWNoVG9SZWFkKG4sIHN0YXRlKTtcblxuICAvLyBpZiB3ZSd2ZSBlbmRlZCwgYW5kIHdlJ3JlIG5vdyBjbGVhciwgdGhlbiBmaW5pc2ggaXQgdXAuXG4gIGlmIChuID09PSAwICYmIHN0YXRlLmVuZGVkKSB7XG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkgZW5kUmVhZGFibGUodGhpcyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBBbGwgdGhlIGFjdHVhbCBjaHVuayBnZW5lcmF0aW9uIGxvZ2ljIG5lZWRzIHRvIGJlXG4gIC8vICpiZWxvdyogdGhlIGNhbGwgdG8gX3JlYWQuICBUaGUgcmVhc29uIGlzIHRoYXQgaW4gY2VydGFpblxuICAvLyBzeW50aGV0aWMgc3RyZWFtIGNhc2VzLCBzdWNoIGFzIHBhc3N0aHJvdWdoIHN0cmVhbXMsIF9yZWFkXG4gIC8vIG1heSBiZSBhIGNvbXBsZXRlbHkgc3luY2hyb25vdXMgb3BlcmF0aW9uIHdoaWNoIG1heSBjaGFuZ2VcbiAgLy8gdGhlIHN0YXRlIG9mIHRoZSByZWFkIGJ1ZmZlciwgcHJvdmlkaW5nIGVub3VnaCBkYXRhIHdoZW5cbiAgLy8gYmVmb3JlIHRoZXJlIHdhcyAqbm90KiBlbm91Z2guXG4gIC8vXG4gIC8vIFNvLCB0aGUgc3RlcHMgYXJlOlxuICAvLyAxLiBGaWd1cmUgb3V0IHdoYXQgdGhlIHN0YXRlIG9mIHRoaW5ncyB3aWxsIGJlIGFmdGVyIHdlIGRvXG4gIC8vIGEgcmVhZCBmcm9tIHRoZSBidWZmZXIuXG4gIC8vXG4gIC8vIDIuIElmIHRoYXQgcmVzdWx0aW5nIHN0YXRlIHdpbGwgdHJpZ2dlciBhIF9yZWFkLCB0aGVuIGNhbGwgX3JlYWQuXG4gIC8vIE5vdGUgdGhhdCB0aGlzIG1heSBiZSBhc3luY2hyb25vdXMsIG9yIHN5bmNocm9ub3VzLiAgWWVzLCBpdCBpc1xuICAvLyBkZWVwbHkgdWdseSB0byB3cml0ZSBBUElzIHRoaXMgd2F5LCBidXQgdGhhdCBzdGlsbCBkb2Vzbid0IG1lYW5cbiAgLy8gdGhhdCB0aGUgUmVhZGFibGUgY2xhc3Mgc2hvdWxkIGJlaGF2ZSBpbXByb3Blcmx5LCBhcyBzdHJlYW1zIGFyZVxuICAvLyBkZXNpZ25lZCB0byBiZSBzeW5jL2FzeW5jIGFnbm9zdGljLlxuICAvLyBUYWtlIG5vdGUgaWYgdGhlIF9yZWFkIGNhbGwgaXMgc3luYyBvciBhc3luYyAoaWUsIGlmIHRoZSByZWFkIGNhbGxcbiAgLy8gaGFzIHJldHVybmVkIHlldCksIHNvIHRoYXQgd2Uga25vdyB3aGV0aGVyIG9yIG5vdCBpdCdzIHNhZmUgdG8gZW1pdFxuICAvLyAncmVhZGFibGUnIGV0Yy5cbiAgLy9cbiAgLy8gMy4gQWN0dWFsbHkgcHVsbCB0aGUgcmVxdWVzdGVkIGNodW5rcyBvdXQgb2YgdGhlIGJ1ZmZlciBhbmQgcmV0dXJuLlxuXG4gIC8vIGlmIHdlIG5lZWQgYSByZWFkYWJsZSBldmVudCwgdGhlbiB3ZSBuZWVkIHRvIGRvIHNvbWUgcmVhZGluZy5cbiAgdmFyIGRvUmVhZCA9IHN0YXRlLm5lZWRSZWFkYWJsZTtcbiAgZGVidWcoJ25lZWQgcmVhZGFibGUnLCBkb1JlYWQpO1xuXG4gIC8vIGlmIHdlIGN1cnJlbnRseSBoYXZlIGxlc3MgdGhhbiB0aGUgaGlnaFdhdGVyTWFyaywgdGhlbiBhbHNvIHJlYWQgc29tZVxuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwIHx8IHN0YXRlLmxlbmd0aCAtIG4gPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrKSB7XG4gICAgZG9SZWFkID0gdHJ1ZTtcbiAgICBkZWJ1ZygnbGVuZ3RoIGxlc3MgdGhhbiB3YXRlcm1hcmsnLCBkb1JlYWQpO1xuICB9XG5cbiAgLy8gaG93ZXZlciwgaWYgd2UndmUgZW5kZWQsIHRoZW4gdGhlcmUncyBubyBwb2ludCwgYW5kIGlmIHdlJ3JlIGFscmVhZHlcbiAgLy8gcmVhZGluZywgdGhlbiBpdCdzIHVubmVjZXNzYXJ5LlxuICBpZiAoc3RhdGUuZW5kZWQgfHwgc3RhdGUucmVhZGluZykge1xuICAgIGRvUmVhZCA9IGZhbHNlO1xuICAgIGRlYnVnKCdyZWFkaW5nIG9yIGVuZGVkJywgZG9SZWFkKTtcbiAgfVxuXG4gIGlmIChkb1JlYWQpIHtcbiAgICBkZWJ1ZygnZG8gcmVhZCcpO1xuICAgIHN0YXRlLnJlYWRpbmcgPSB0cnVlO1xuICAgIHN0YXRlLnN5bmMgPSB0cnVlO1xuICAgIC8vIGlmIHRoZSBsZW5ndGggaXMgY3VycmVudGx5IHplcm8sIHRoZW4gd2UgKm5lZWQqIGEgcmVhZGFibGUgZXZlbnQuXG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCkgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICAvLyBjYWxsIGludGVybmFsIHJlYWQgbWV0aG9kXG4gICAgdGhpcy5fcmVhZChzdGF0ZS5oaWdoV2F0ZXJNYXJrKTtcbiAgICBzdGF0ZS5zeW5jID0gZmFsc2U7XG4gIH1cblxuICAvLyBJZiBfcmVhZCBwdXNoZWQgZGF0YSBzeW5jaHJvbm91c2x5LCB0aGVuIGByZWFkaW5nYCB3aWxsIGJlIGZhbHNlLFxuICAvLyBhbmQgd2UgbmVlZCB0byByZS1ldmFsdWF0ZSBob3cgbXVjaCBkYXRhIHdlIGNhbiByZXR1cm4gdG8gdGhlIHVzZXIuXG4gIGlmIChkb1JlYWQgJiYgIXN0YXRlLnJlYWRpbmcpIG4gPSBob3dNdWNoVG9SZWFkKG5PcmlnLCBzdGF0ZSk7XG5cbiAgdmFyIHJldDtcbiAgaWYgKG4gPiAwKSByZXQgPSBmcm9tTGlzdChuLCBzdGF0ZSk7ZWxzZSByZXQgPSBudWxsO1xuXG4gIGlmIChyZXQgPT09IG51bGwpIHtcbiAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgIG4gPSAwO1xuICB9XG5cbiAgc3RhdGUubGVuZ3RoIC09IG47XG5cbiAgLy8gSWYgd2UgaGF2ZSBub3RoaW5nIGluIHRoZSBidWZmZXIsIHRoZW4gd2Ugd2FudCB0byBrbm93XG4gIC8vIGFzIHNvb24gYXMgd2UgKmRvKiBnZXQgc29tZXRoaW5nIGludG8gdGhlIGJ1ZmZlci5cbiAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMCAmJiAhc3RhdGUuZW5kZWQpIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG5cbiAgLy8gSWYgd2UgdHJpZWQgdG8gcmVhZCgpIHBhc3QgdGhlIEVPRiwgdGhlbiBlbWl0IGVuZCBvbiB0aGUgbmV4dCB0aWNrLlxuICBpZiAobk9yaWcgIT09IG4gJiYgc3RhdGUuZW5kZWQgJiYgc3RhdGUubGVuZ3RoID09PSAwKSBlbmRSZWFkYWJsZSh0aGlzKTtcblxuICBpZiAocmV0ICE9PSBudWxsKSB0aGlzLmVtaXQoJ2RhdGEnLCByZXQpO1xuXG4gIHJldHVybiByZXQ7XG59O1xuXG5mdW5jdGlvbiBjaHVua0ludmFsaWQoc3RhdGUsIGNodW5rKSB7XG4gIHZhciBlciA9IG51bGw7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGNodW5rKSAmJiB0eXBlb2YgY2h1bmsgIT09ICdzdHJpbmcnICYmIGNodW5rICE9PSBudWxsICYmIGNodW5rICE9PSB1bmRlZmluZWQgJiYgIXN0YXRlLm9iamVjdE1vZGUpIHtcbiAgICBlciA9IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgbm9uLXN0cmluZy9idWZmZXIgY2h1bmsnKTtcbiAgfVxuICByZXR1cm4gZXI7XG59XG5cbmZ1bmN0aW9uIG9uRW9mQ2h1bmsoc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoc3RhdGUuZW5kZWQpIHJldHVybjtcbiAgaWYgKHN0YXRlLmRlY29kZXIpIHtcbiAgICB2YXIgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLmVuZCgpO1xuICAgIGlmIChjaHVuayAmJiBjaHVuay5sZW5ndGgpIHtcbiAgICAgIHN0YXRlLmJ1ZmZlci5wdXNoKGNodW5rKTtcbiAgICAgIHN0YXRlLmxlbmd0aCArPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcbiAgICB9XG4gIH1cbiAgc3RhdGUuZW5kZWQgPSB0cnVlO1xuXG4gIC8vIGVtaXQgJ3JlYWRhYmxlJyBub3cgdG8gbWFrZSBzdXJlIGl0IGdldHMgcGlja2VkIHVwLlxuICBlbWl0UmVhZGFibGUoc3RyZWFtKTtcbn1cblxuLy8gRG9uJ3QgZW1pdCByZWFkYWJsZSByaWdodCBhd2F5IGluIHN5bmMgbW9kZSwgYmVjYXVzZSB0aGlzIGNhbiB0cmlnZ2VyXG4vLyBhbm90aGVyIHJlYWQoKSBjYWxsID0+IHN0YWNrIG92ZXJmbG93LiAgVGhpcyB3YXksIGl0IG1pZ2h0IHRyaWdnZXJcbi8vIGEgbmV4dFRpY2sgcmVjdXJzaW9uIHdhcm5pbmcsIGJ1dCB0aGF0J3Mgbm90IHNvIGJhZC5cbmZ1bmN0aW9uIGVtaXRSZWFkYWJsZShzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICBzdGF0ZS5uZWVkUmVhZGFibGUgPSBmYWxzZTtcbiAgaWYgKCFzdGF0ZS5lbWl0dGVkUmVhZGFibGUpIHtcbiAgICBkZWJ1ZygnZW1pdFJlYWRhYmxlJywgc3RhdGUuZmxvd2luZyk7XG4gICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICBpZiAoc3RhdGUuc3luYykgcHJvY2Vzc05leHRUaWNrKGVtaXRSZWFkYWJsZV8sIHN0cmVhbSk7ZWxzZSBlbWl0UmVhZGFibGVfKHN0cmVhbSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW1pdFJlYWRhYmxlXyhzdHJlYW0pIHtcbiAgZGVidWcoJ2VtaXQgcmVhZGFibGUnKTtcbiAgc3RyZWFtLmVtaXQoJ3JlYWRhYmxlJyk7XG4gIGZsb3coc3RyZWFtKTtcbn1cblxuLy8gYXQgdGhpcyBwb2ludCwgdGhlIHVzZXIgaGFzIHByZXN1bWFibHkgc2VlbiB0aGUgJ3JlYWRhYmxlJyBldmVudCxcbi8vIGFuZCBjYWxsZWQgcmVhZCgpIHRvIGNvbnN1bWUgc29tZSBkYXRhLiAgdGhhdCBtYXkgaGF2ZSB0cmlnZ2VyZWRcbi8vIGluIHR1cm4gYW5vdGhlciBfcmVhZChuKSBjYWxsLCBpbiB3aGljaCBjYXNlIHJlYWRpbmcgPSB0cnVlIGlmXG4vLyBpdCdzIGluIHByb2dyZXNzLlxuLy8gSG93ZXZlciwgaWYgd2UncmUgbm90IGVuZGVkLCBvciByZWFkaW5nLCBhbmQgdGhlIGxlbmd0aCA8IGh3bSxcbi8vIHRoZW4gZ28gYWhlYWQgYW5kIHRyeSB0byByZWFkIHNvbWUgbW9yZSBwcmVlbXB0aXZlbHkuXG5mdW5jdGlvbiBtYXliZVJlYWRNb3JlKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5yZWFkaW5nTW9yZSkge1xuICAgIHN0YXRlLnJlYWRpbmdNb3JlID0gdHJ1ZTtcbiAgICBwcm9jZXNzTmV4dFRpY2sobWF5YmVSZWFkTW9yZV8sIHN0cmVhbSwgc3RhdGUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1heWJlUmVhZE1vcmVfKHN0cmVhbSwgc3RhdGUpIHtcbiAgdmFyIGxlbiA9IHN0YXRlLmxlbmd0aDtcbiAgd2hpbGUgKCFzdGF0ZS5yZWFkaW5nICYmICFzdGF0ZS5mbG93aW5nICYmICFzdGF0ZS5lbmRlZCAmJiBzdGF0ZS5sZW5ndGggPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrKSB7XG4gICAgZGVidWcoJ21heWJlUmVhZE1vcmUgcmVhZCAwJyk7XG4gICAgc3RyZWFtLnJlYWQoMCk7XG4gICAgaWYgKGxlbiA9PT0gc3RhdGUubGVuZ3RoKVxuICAgICAgLy8gZGlkbid0IGdldCBhbnkgZGF0YSwgc3RvcCBzcGlubmluZy5cbiAgICAgIGJyZWFrO2Vsc2UgbGVuID0gc3RhdGUubGVuZ3RoO1xuICB9XG4gIHN0YXRlLnJlYWRpbmdNb3JlID0gZmFsc2U7XG59XG5cbi8vIGFic3RyYWN0IG1ldGhvZC4gIHRvIGJlIG92ZXJyaWRkZW4gaW4gc3BlY2lmaWMgaW1wbGVtZW50YXRpb24gY2xhc3Nlcy5cbi8vIGNhbGwgY2IoZXIsIGRhdGEpIHdoZXJlIGRhdGEgaXMgPD0gbiBpbiBsZW5ndGguXG4vLyBmb3IgdmlydHVhbCAobm9uLXN0cmluZywgbm9uLWJ1ZmZlcikgc3RyZWFtcywgXCJsZW5ndGhcIiBpcyBzb21ld2hhdFxuLy8gYXJiaXRyYXJ5LCBhbmQgcGVyaGFwcyBub3QgdmVyeSBtZWFuaW5nZnVsLlxuUmVhZGFibGUucHJvdG90eXBlLl9yZWFkID0gZnVuY3Rpb24gKG4pIHtcbiAgdGhpcy5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignbm90IGltcGxlbWVudGVkJykpO1xufTtcblxuUmVhZGFibGUucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbiAoZGVzdCwgcGlwZU9wdHMpIHtcbiAgdmFyIHNyYyA9IHRoaXM7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG5cbiAgc3dpdGNoIChzdGF0ZS5waXBlc0NvdW50KSB7XG4gICAgY2FzZSAwOlxuICAgICAgc3RhdGUucGlwZXMgPSBkZXN0O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAxOlxuICAgICAgc3RhdGUucGlwZXMgPSBbc3RhdGUucGlwZXMsIGRlc3RdO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHN0YXRlLnBpcGVzLnB1c2goZGVzdCk7XG4gICAgICBicmVhaztcbiAgfVxuICBzdGF0ZS5waXBlc0NvdW50ICs9IDE7XG4gIGRlYnVnKCdwaXBlIGNvdW50PSVkIG9wdHM9JWonLCBzdGF0ZS5waXBlc0NvdW50LCBwaXBlT3B0cyk7XG5cbiAgdmFyIGRvRW5kID0gKCFwaXBlT3B0cyB8fCBwaXBlT3B0cy5lbmQgIT09IGZhbHNlKSAmJiBkZXN0ICE9PSBwcm9jZXNzLnN0ZG91dCAmJiBkZXN0ICE9PSBwcm9jZXNzLnN0ZGVycjtcblxuICB2YXIgZW5kRm4gPSBkb0VuZCA/IG9uZW5kIDogY2xlYW51cDtcbiAgaWYgKHN0YXRlLmVuZEVtaXR0ZWQpIHByb2Nlc3NOZXh0VGljayhlbmRGbik7ZWxzZSBzcmMub25jZSgnZW5kJywgZW5kRm4pO1xuXG4gIGRlc3Qub24oJ3VucGlwZScsIG9udW5waXBlKTtcbiAgZnVuY3Rpb24gb251bnBpcGUocmVhZGFibGUpIHtcbiAgICBkZWJ1Zygnb251bnBpcGUnKTtcbiAgICBpZiAocmVhZGFibGUgPT09IHNyYykge1xuICAgICAgY2xlYW51cCgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG9uZW5kKCkge1xuICAgIGRlYnVnKCdvbmVuZCcpO1xuICAgIGRlc3QuZW5kKCk7XG4gIH1cblxuICAvLyB3aGVuIHRoZSBkZXN0IGRyYWlucywgaXQgcmVkdWNlcyB0aGUgYXdhaXREcmFpbiBjb3VudGVyXG4gIC8vIG9uIHRoZSBzb3VyY2UuICBUaGlzIHdvdWxkIGJlIG1vcmUgZWxlZ2FudCB3aXRoIGEgLm9uY2UoKVxuICAvLyBoYW5kbGVyIGluIGZsb3coKSwgYnV0IGFkZGluZyBhbmQgcmVtb3ZpbmcgcmVwZWF0ZWRseSBpc1xuICAvLyB0b28gc2xvdy5cbiAgdmFyIG9uZHJhaW4gPSBwaXBlT25EcmFpbihzcmMpO1xuICBkZXN0Lm9uKCdkcmFpbicsIG9uZHJhaW4pO1xuXG4gIHZhciBjbGVhbmVkVXAgPSBmYWxzZTtcbiAgZnVuY3Rpb24gY2xlYW51cCgpIHtcbiAgICBkZWJ1ZygnY2xlYW51cCcpO1xuICAgIC8vIGNsZWFudXAgZXZlbnQgaGFuZGxlcnMgb25jZSB0aGUgcGlwZSBpcyBicm9rZW5cbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2ZpbmlzaCcsIG9uZmluaXNoKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdkcmFpbicsIG9uZHJhaW4pO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcigndW5waXBlJywgb251bnBpcGUpO1xuICAgIHNyYy5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25lbmQpO1xuICAgIHNyYy5yZW1vdmVMaXN0ZW5lcignZW5kJywgY2xlYW51cCk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgb25kYXRhKTtcblxuICAgIGNsZWFuZWRVcCA9IHRydWU7XG5cbiAgICAvLyBpZiB0aGUgcmVhZGVyIGlzIHdhaXRpbmcgZm9yIGEgZHJhaW4gZXZlbnQgZnJvbSB0aGlzXG4gICAgLy8gc3BlY2lmaWMgd3JpdGVyLCB0aGVuIGl0IHdvdWxkIGNhdXNlIGl0IHRvIG5ldmVyIHN0YXJ0XG4gICAgLy8gZmxvd2luZyBhZ2Fpbi5cbiAgICAvLyBTbywgaWYgdGhpcyBpcyBhd2FpdGluZyBhIGRyYWluLCB0aGVuIHdlIGp1c3QgY2FsbCBpdCBub3cuXG4gICAgLy8gSWYgd2UgZG9uJ3Qga25vdywgdGhlbiBhc3N1bWUgdGhhdCB3ZSBhcmUgd2FpdGluZyBmb3Igb25lLlxuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluICYmICghZGVzdC5fd3JpdGFibGVTdGF0ZSB8fCBkZXN0Ll93cml0YWJsZVN0YXRlLm5lZWREcmFpbikpIG9uZHJhaW4oKTtcbiAgfVxuXG4gIHNyYy5vbignZGF0YScsIG9uZGF0YSk7XG4gIGZ1bmN0aW9uIG9uZGF0YShjaHVuaykge1xuICAgIGRlYnVnKCdvbmRhdGEnKTtcbiAgICB2YXIgcmV0ID0gZGVzdC53cml0ZShjaHVuayk7XG4gICAgaWYgKGZhbHNlID09PSByZXQpIHtcbiAgICAgIC8vIElmIHRoZSB1c2VyIHVucGlwZWQgZHVyaW5nIGBkZXN0LndyaXRlKClgLCBpdCBpcyBwb3NzaWJsZVxuICAgICAgLy8gdG8gZ2V0IHN0dWNrIGluIGEgcGVybWFuZW50bHkgcGF1c2VkIHN0YXRlIGlmIHRoYXQgd3JpdGVcbiAgICAgIC8vIGFsc28gcmV0dXJuZWQgZmFsc2UuXG4gICAgICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMSAmJiBzdGF0ZS5waXBlc1swXSA9PT0gZGVzdCAmJiBzcmMubGlzdGVuZXJDb3VudCgnZGF0YScpID09PSAxICYmICFjbGVhbmVkVXApIHtcbiAgICAgICAgZGVidWcoJ2ZhbHNlIHdyaXRlIHJlc3BvbnNlLCBwYXVzZScsIHNyYy5fcmVhZGFibGVTdGF0ZS5hd2FpdERyYWluKTtcbiAgICAgICAgc3JjLl9yZWFkYWJsZVN0YXRlLmF3YWl0RHJhaW4rKztcbiAgICAgIH1cbiAgICAgIHNyYy5wYXVzZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGlmIHRoZSBkZXN0IGhhcyBhbiBlcnJvciwgdGhlbiBzdG9wIHBpcGluZyBpbnRvIGl0LlxuICAvLyBob3dldmVyLCBkb24ndCBzdXBwcmVzcyB0aGUgdGhyb3dpbmcgYmVoYXZpb3IgZm9yIHRoaXMuXG4gIGZ1bmN0aW9uIG9uZXJyb3IoZXIpIHtcbiAgICBkZWJ1Zygnb25lcnJvcicsIGVyKTtcbiAgICB1bnBpcGUoKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIGlmIChFRWxpc3RlbmVyQ291bnQoZGVzdCwgJ2Vycm9yJykgPT09IDApIGRlc3QuZW1pdCgnZXJyb3InLCBlcik7XG4gIH1cbiAgLy8gVGhpcyBpcyBhIGJydXRhbGx5IHVnbHkgaGFjayB0byBtYWtlIHN1cmUgdGhhdCBvdXIgZXJyb3IgaGFuZGxlclxuICAvLyBpcyBhdHRhY2hlZCBiZWZvcmUgYW55IHVzZXJsYW5kIG9uZXMuICBORVZFUiBETyBUSElTLlxuICBpZiAoIWRlc3QuX2V2ZW50cyB8fCAhZGVzdC5fZXZlbnRzLmVycm9yKSBkZXN0Lm9uKCdlcnJvcicsIG9uZXJyb3IpO2Vsc2UgaWYgKGlzQXJyYXkoZGVzdC5fZXZlbnRzLmVycm9yKSkgZGVzdC5fZXZlbnRzLmVycm9yLnVuc2hpZnQob25lcnJvcik7ZWxzZSBkZXN0Ll9ldmVudHMuZXJyb3IgPSBbb25lcnJvciwgZGVzdC5fZXZlbnRzLmVycm9yXTtcblxuICAvLyBCb3RoIGNsb3NlIGFuZCBmaW5pc2ggc2hvdWxkIHRyaWdnZXIgdW5waXBlLCBidXQgb25seSBvbmNlLlxuICBmdW5jdGlvbiBvbmNsb3NlKCkge1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2ZpbmlzaCcsIG9uZmluaXNoKTtcbiAgICB1bnBpcGUoKTtcbiAgfVxuICBkZXN0Lm9uY2UoJ2Nsb3NlJywgb25jbG9zZSk7XG4gIGZ1bmN0aW9uIG9uZmluaXNoKCkge1xuICAgIGRlYnVnKCdvbmZpbmlzaCcpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG4gICAgdW5waXBlKCk7XG4gIH1cbiAgZGVzdC5vbmNlKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG5cbiAgZnVuY3Rpb24gdW5waXBlKCkge1xuICAgIGRlYnVnKCd1bnBpcGUnKTtcbiAgICBzcmMudW5waXBlKGRlc3QpO1xuICB9XG5cbiAgLy8gdGVsbCB0aGUgZGVzdCB0aGF0IGl0J3MgYmVpbmcgcGlwZWQgdG9cbiAgZGVzdC5lbWl0KCdwaXBlJywgc3JjKTtcblxuICAvLyBzdGFydCB0aGUgZmxvdyBpZiBpdCBoYXNuJ3QgYmVlbiBzdGFydGVkIGFscmVhZHkuXG4gIGlmICghc3RhdGUuZmxvd2luZykge1xuICAgIGRlYnVnKCdwaXBlIHJlc3VtZScpO1xuICAgIHNyYy5yZXN1bWUoKTtcbiAgfVxuXG4gIHJldHVybiBkZXN0O1xufTtcblxuZnVuY3Rpb24gcGlwZU9uRHJhaW4oc3JjKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHN0YXRlID0gc3JjLl9yZWFkYWJsZVN0YXRlO1xuICAgIGRlYnVnKCdwaXBlT25EcmFpbicsIHN0YXRlLmF3YWl0RHJhaW4pO1xuICAgIGlmIChzdGF0ZS5hd2FpdERyYWluKSBzdGF0ZS5hd2FpdERyYWluLS07XG4gICAgaWYgKHN0YXRlLmF3YWl0RHJhaW4gPT09IDAgJiYgRUVsaXN0ZW5lckNvdW50KHNyYywgJ2RhdGEnKSkge1xuICAgICAgc3RhdGUuZmxvd2luZyA9IHRydWU7XG4gICAgICBmbG93KHNyYyk7XG4gICAgfVxuICB9O1xufVxuXG5SZWFkYWJsZS5wcm90b3R5cGUudW5waXBlID0gZnVuY3Rpb24gKGRlc3QpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcblxuICAvLyBpZiB3ZSdyZSBub3QgcGlwaW5nIGFueXdoZXJlLCB0aGVuIGRvIG5vdGhpbmcuXG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAwKSByZXR1cm4gdGhpcztcblxuICAvLyBqdXN0IG9uZSBkZXN0aW5hdGlvbi4gIG1vc3QgY29tbW9uIGNhc2UuXG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAxKSB7XG4gICAgLy8gcGFzc2VkIGluIG9uZSwgYnV0IGl0J3Mgbm90IHRoZSByaWdodCBvbmUuXG4gICAgaWYgKGRlc3QgJiYgZGVzdCAhPT0gc3RhdGUucGlwZXMpIHJldHVybiB0aGlzO1xuXG4gICAgaWYgKCFkZXN0KSBkZXN0ID0gc3RhdGUucGlwZXM7XG5cbiAgICAvLyBnb3QgYSBtYXRjaC5cbiAgICBzdGF0ZS5waXBlcyA9IG51bGw7XG4gICAgc3RhdGUucGlwZXNDb3VudCA9IDA7XG4gICAgc3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuICAgIGlmIChkZXN0KSBkZXN0LmVtaXQoJ3VucGlwZScsIHRoaXMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gc2xvdyBjYXNlLiBtdWx0aXBsZSBwaXBlIGRlc3RpbmF0aW9ucy5cblxuICBpZiAoIWRlc3QpIHtcbiAgICAvLyByZW1vdmUgYWxsLlxuICAgIHZhciBkZXN0cyA9IHN0YXRlLnBpcGVzO1xuICAgIHZhciBsZW4gPSBzdGF0ZS5waXBlc0NvdW50O1xuICAgIHN0YXRlLnBpcGVzID0gbnVsbDtcbiAgICBzdGF0ZS5waXBlc0NvdW50ID0gMDtcbiAgICBzdGF0ZS5mbG93aW5nID0gZmFsc2U7XG5cbiAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgbGVuOyBfaSsrKSB7XG4gICAgICBkZXN0c1tfaV0uZW1pdCgndW5waXBlJywgdGhpcyk7XG4gICAgfXJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gdHJ5IHRvIGZpbmQgdGhlIHJpZ2h0IG9uZS5cbiAgdmFyIGkgPSBpbmRleE9mKHN0YXRlLnBpcGVzLCBkZXN0KTtcbiAgaWYgKGkgPT09IC0xKSByZXR1cm4gdGhpcztcblxuICBzdGF0ZS5waXBlcy5zcGxpY2UoaSwgMSk7XG4gIHN0YXRlLnBpcGVzQ291bnQgLT0gMTtcbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDEpIHN0YXRlLnBpcGVzID0gc3RhdGUucGlwZXNbMF07XG5cbiAgZGVzdC5lbWl0KCd1bnBpcGUnLCB0aGlzKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIHNldCB1cCBkYXRhIGV2ZW50cyBpZiB0aGV5IGFyZSBhc2tlZCBmb3Jcbi8vIEVuc3VyZSByZWFkYWJsZSBsaXN0ZW5lcnMgZXZlbnR1YWxseSBnZXQgc29tZXRoaW5nXG5SZWFkYWJsZS5wcm90b3R5cGUub24gPSBmdW5jdGlvbiAoZXYsIGZuKSB7XG4gIHZhciByZXMgPSBTdHJlYW0ucHJvdG90eXBlLm9uLmNhbGwodGhpcywgZXYsIGZuKTtcblxuICAvLyBJZiBsaXN0ZW5pbmcgdG8gZGF0YSwgYW5kIGl0IGhhcyBub3QgZXhwbGljaXRseSBiZWVuIHBhdXNlZCxcbiAgLy8gdGhlbiBjYWxsIHJlc3VtZSB0byBzdGFydCB0aGUgZmxvdyBvZiBkYXRhIG9uIHRoZSBuZXh0IHRpY2suXG4gIGlmIChldiA9PT0gJ2RhdGEnICYmIGZhbHNlICE9PSB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcpIHtcbiAgICB0aGlzLnJlc3VtZSgpO1xuICB9XG5cbiAgaWYgKGV2ID09PSAncmVhZGFibGUnICYmICF0aGlzLl9yZWFkYWJsZVN0YXRlLmVuZEVtaXR0ZWQpIHtcbiAgICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICAgIGlmICghc3RhdGUucmVhZGFibGVMaXN0ZW5pbmcpIHtcbiAgICAgIHN0YXRlLnJlYWRhYmxlTGlzdGVuaW5nID0gdHJ1ZTtcbiAgICAgIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuICAgICAgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICAgIGlmICghc3RhdGUucmVhZGluZykge1xuICAgICAgICBwcm9jZXNzTmV4dFRpY2soblJlYWRpbmdOZXh0VGljaywgdGhpcyk7XG4gICAgICB9IGVsc2UgaWYgKHN0YXRlLmxlbmd0aCkge1xuICAgICAgICBlbWl0UmVhZGFibGUodGhpcywgc3RhdGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXM7XG59O1xuUmVhZGFibGUucHJvdG90eXBlLmFkZExpc3RlbmVyID0gUmVhZGFibGUucHJvdG90eXBlLm9uO1xuXG5mdW5jdGlvbiBuUmVhZGluZ05leHRUaWNrKHNlbGYpIHtcbiAgZGVidWcoJ3JlYWRhYmxlIG5leHR0aWNrIHJlYWQgMCcpO1xuICBzZWxmLnJlYWQoMCk7XG59XG5cbi8vIHBhdXNlKCkgYW5kIHJlc3VtZSgpIGFyZSByZW1uYW50cyBvZiB0aGUgbGVnYWN5IHJlYWRhYmxlIHN0cmVhbSBBUElcbi8vIElmIHRoZSB1c2VyIHVzZXMgdGhlbSwgdGhlbiBzd2l0Y2ggaW50byBvbGQgbW9kZS5cblJlYWRhYmxlLnByb3RvdHlwZS5yZXN1bWUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIGlmICghc3RhdGUuZmxvd2luZykge1xuICAgIGRlYnVnKCdyZXN1bWUnKTtcbiAgICBzdGF0ZS5mbG93aW5nID0gdHJ1ZTtcbiAgICByZXN1bWUodGhpcywgc3RhdGUpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gcmVzdW1lKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5yZXN1bWVTY2hlZHVsZWQpIHtcbiAgICBzdGF0ZS5yZXN1bWVTY2hlZHVsZWQgPSB0cnVlO1xuICAgIHByb2Nlc3NOZXh0VGljayhyZXN1bWVfLCBzdHJlYW0sIHN0YXRlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZXN1bWVfKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5yZWFkaW5nKSB7XG4gICAgZGVidWcoJ3Jlc3VtZSByZWFkIDAnKTtcbiAgICBzdHJlYW0ucmVhZCgwKTtcbiAgfVxuXG4gIHN0YXRlLnJlc3VtZVNjaGVkdWxlZCA9IGZhbHNlO1xuICBzdHJlYW0uZW1pdCgncmVzdW1lJyk7XG4gIGZsb3coc3RyZWFtKTtcbiAgaWYgKHN0YXRlLmZsb3dpbmcgJiYgIXN0YXRlLnJlYWRpbmcpIHN0cmVhbS5yZWFkKDApO1xufVxuXG5SZWFkYWJsZS5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbiAoKSB7XG4gIGRlYnVnKCdjYWxsIHBhdXNlIGZsb3dpbmc9JWonLCB0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcpO1xuICBpZiAoZmFsc2UgIT09IHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZykge1xuICAgIGRlYnVnKCdwYXVzZScpO1xuICAgIHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuICAgIHRoaXMuZW1pdCgncGF1c2UnKTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIGZsb3coc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgZGVidWcoJ2Zsb3cnLCBzdGF0ZS5mbG93aW5nKTtcbiAgaWYgKHN0YXRlLmZsb3dpbmcpIHtcbiAgICBkbyB7XG4gICAgICB2YXIgY2h1bmsgPSBzdHJlYW0ucmVhZCgpO1xuICAgIH0gd2hpbGUgKG51bGwgIT09IGNodW5rICYmIHN0YXRlLmZsb3dpbmcpO1xuICB9XG59XG5cbi8vIHdyYXAgYW4gb2xkLXN0eWxlIHN0cmVhbSBhcyB0aGUgYXN5bmMgZGF0YSBzb3VyY2UuXG4vLyBUaGlzIGlzICpub3QqIHBhcnQgb2YgdGhlIHJlYWRhYmxlIHN0cmVhbSBpbnRlcmZhY2UuXG4vLyBJdCBpcyBhbiB1Z2x5IHVuZm9ydHVuYXRlIG1lc3Mgb2YgaGlzdG9yeS5cblJlYWRhYmxlLnByb3RvdHlwZS53cmFwID0gZnVuY3Rpb24gKHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICB2YXIgcGF1c2VkID0gZmFsc2U7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBzdHJlYW0ub24oJ2VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBkZWJ1Zygnd3JhcHBlZCBlbmQnKTtcbiAgICBpZiAoc3RhdGUuZGVjb2RlciAmJiAhc3RhdGUuZW5kZWQpIHtcbiAgICAgIHZhciBjaHVuayA9IHN0YXRlLmRlY29kZXIuZW5kKCk7XG4gICAgICBpZiAoY2h1bmsgJiYgY2h1bmsubGVuZ3RoKSBzZWxmLnB1c2goY2h1bmspO1xuICAgIH1cblxuICAgIHNlbGYucHVzaChudWxsKTtcbiAgfSk7XG5cbiAgc3RyZWFtLm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgZGVidWcoJ3dyYXBwZWQgZGF0YScpO1xuICAgIGlmIChzdGF0ZS5kZWNvZGVyKSBjaHVuayA9IHN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO1xuXG4gICAgLy8gZG9uJ3Qgc2tpcCBvdmVyIGZhbHN5IHZhbHVlcyBpbiBvYmplY3RNb2RlXG4gICAgaWYgKHN0YXRlLm9iamVjdE1vZGUgJiYgKGNodW5rID09PSBudWxsIHx8IGNodW5rID09PSB1bmRlZmluZWQpKSByZXR1cm47ZWxzZSBpZiAoIXN0YXRlLm9iamVjdE1vZGUgJiYgKCFjaHVuayB8fCAhY2h1bmsubGVuZ3RoKSkgcmV0dXJuO1xuXG4gICAgdmFyIHJldCA9IHNlbGYucHVzaChjaHVuayk7XG4gICAgaWYgKCFyZXQpIHtcbiAgICAgIHBhdXNlZCA9IHRydWU7XG4gICAgICBzdHJlYW0ucGF1c2UoKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIHByb3h5IGFsbCB0aGUgb3RoZXIgbWV0aG9kcy5cbiAgLy8gaW1wb3J0YW50IHdoZW4gd3JhcHBpbmcgZmlsdGVycyBhbmQgZHVwbGV4ZXMuXG4gIGZvciAodmFyIGkgaW4gc3RyZWFtKSB7XG4gICAgaWYgKHRoaXNbaV0gPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygc3RyZWFtW2ldID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzW2ldID0gZnVuY3Rpb24gKG1ldGhvZCkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiBzdHJlYW1bbWV0aG9kXS5hcHBseShzdHJlYW0sIGFyZ3VtZW50cyk7XG4gICAgICAgIH07XG4gICAgICB9KGkpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHByb3h5IGNlcnRhaW4gaW1wb3J0YW50IGV2ZW50cy5cbiAgdmFyIGV2ZW50cyA9IFsnZXJyb3InLCAnY2xvc2UnLCAnZGVzdHJveScsICdwYXVzZScsICdyZXN1bWUnXTtcbiAgZm9yRWFjaChldmVudHMsIGZ1bmN0aW9uIChldikge1xuICAgIHN0cmVhbS5vbihldiwgc2VsZi5lbWl0LmJpbmQoc2VsZiwgZXYpKTtcbiAgfSk7XG5cbiAgLy8gd2hlbiB3ZSB0cnkgdG8gY29uc3VtZSBzb21lIG1vcmUgYnl0ZXMsIHNpbXBseSB1bnBhdXNlIHRoZVxuICAvLyB1bmRlcmx5aW5nIHN0cmVhbS5cbiAgc2VsZi5fcmVhZCA9IGZ1bmN0aW9uIChuKSB7XG4gICAgZGVidWcoJ3dyYXBwZWQgX3JlYWQnLCBuKTtcbiAgICBpZiAocGF1c2VkKSB7XG4gICAgICBwYXVzZWQgPSBmYWxzZTtcbiAgICAgIHN0cmVhbS5yZXN1bWUoKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHNlbGY7XG59O1xuXG4vLyBleHBvc2VkIGZvciB0ZXN0aW5nIHB1cnBvc2VzIG9ubHkuXG5SZWFkYWJsZS5fZnJvbUxpc3QgPSBmcm9tTGlzdDtcblxuLy8gUGx1Y2sgb2ZmIG4gYnl0ZXMgZnJvbSBhbiBhcnJheSBvZiBidWZmZXJzLlxuLy8gTGVuZ3RoIGlzIHRoZSBjb21iaW5lZCBsZW5ndGhzIG9mIGFsbCB0aGUgYnVmZmVycyBpbiB0aGUgbGlzdC5cbmZ1bmN0aW9uIGZyb21MaXN0KG4sIHN0YXRlKSB7XG4gIHZhciBsaXN0ID0gc3RhdGUuYnVmZmVyO1xuICB2YXIgbGVuZ3RoID0gc3RhdGUubGVuZ3RoO1xuICB2YXIgc3RyaW5nTW9kZSA9ICEhc3RhdGUuZGVjb2RlcjtcbiAgdmFyIG9iamVjdE1vZGUgPSAhIXN0YXRlLm9iamVjdE1vZGU7XG4gIHZhciByZXQ7XG5cbiAgLy8gbm90aGluZyBpbiB0aGUgbGlzdCwgZGVmaW5pdGVseSBlbXB0eS5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcblxuICBpZiAobGVuZ3RoID09PSAwKSByZXQgPSBudWxsO2Vsc2UgaWYgKG9iamVjdE1vZGUpIHJldCA9IGxpc3Quc2hpZnQoKTtlbHNlIGlmICghbiB8fCBuID49IGxlbmd0aCkge1xuICAgIC8vIHJlYWQgaXQgYWxsLCB0cnVuY2F0ZSB0aGUgYXJyYXkuXG4gICAgaWYgKHN0cmluZ01vZGUpIHJldCA9IGxpc3Quam9pbignJyk7ZWxzZSBpZiAobGlzdC5sZW5ndGggPT09IDEpIHJldCA9IGxpc3RbMF07ZWxzZSByZXQgPSBCdWZmZXIuY29uY2F0KGxpc3QsIGxlbmd0aCk7XG4gICAgbGlzdC5sZW5ndGggPSAwO1xuICB9IGVsc2Uge1xuICAgIC8vIHJlYWQganVzdCBzb21lIG9mIGl0LlxuICAgIGlmIChuIDwgbGlzdFswXS5sZW5ndGgpIHtcbiAgICAgIC8vIGp1c3QgdGFrZSBhIHBhcnQgb2YgdGhlIGZpcnN0IGxpc3QgaXRlbS5cbiAgICAgIC8vIHNsaWNlIGlzIHRoZSBzYW1lIGZvciBidWZmZXJzIGFuZCBzdHJpbmdzLlxuICAgICAgdmFyIGJ1ZiA9IGxpc3RbMF07XG4gICAgICByZXQgPSBidWYuc2xpY2UoMCwgbik7XG4gICAgICBsaXN0WzBdID0gYnVmLnNsaWNlKG4pO1xuICAgIH0gZWxzZSBpZiAobiA9PT0gbGlzdFswXS5sZW5ndGgpIHtcbiAgICAgIC8vIGZpcnN0IGxpc3QgaXMgYSBwZXJmZWN0IG1hdGNoXG4gICAgICByZXQgPSBsaXN0LnNoaWZ0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGNvbXBsZXggY2FzZS5cbiAgICAgIC8vIHdlIGhhdmUgZW5vdWdoIHRvIGNvdmVyIGl0LCBidXQgaXQgc3BhbnMgcGFzdCB0aGUgZmlyc3QgYnVmZmVyLlxuICAgICAgaWYgKHN0cmluZ01vZGUpIHJldCA9ICcnO2Vsc2UgcmV0ID0gbmV3IEJ1ZmZlcihuKTtcblxuICAgICAgdmFyIGMgPSAwO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBsaXN0Lmxlbmd0aDsgaSA8IGwgJiYgYyA8IG47IGkrKykge1xuICAgICAgICB2YXIgYnVmID0gbGlzdFswXTtcbiAgICAgICAgdmFyIGNweSA9IE1hdGgubWluKG4gLSBjLCBidWYubGVuZ3RoKTtcblxuICAgICAgICBpZiAoc3RyaW5nTW9kZSkgcmV0ICs9IGJ1Zi5zbGljZSgwLCBjcHkpO2Vsc2UgYnVmLmNvcHkocmV0LCBjLCAwLCBjcHkpO1xuXG4gICAgICAgIGlmIChjcHkgPCBidWYubGVuZ3RoKSBsaXN0WzBdID0gYnVmLnNsaWNlKGNweSk7ZWxzZSBsaXN0LnNoaWZ0KCk7XG5cbiAgICAgICAgYyArPSBjcHk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gZW5kUmVhZGFibGUoc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcblxuICAvLyBJZiB3ZSBnZXQgaGVyZSBiZWZvcmUgY29uc3VtaW5nIGFsbCB0aGUgYnl0ZXMsIHRoZW4gdGhhdCBpcyBhXG4gIC8vIGJ1ZyBpbiBub2RlLiAgU2hvdWxkIG5ldmVyIGhhcHBlbi5cbiAgaWYgKHN0YXRlLmxlbmd0aCA+IDApIHRocm93IG5ldyBFcnJvcignZW5kUmVhZGFibGUgY2FsbGVkIG9uIG5vbi1lbXB0eSBzdHJlYW0nKTtcblxuICBpZiAoIXN0YXRlLmVuZEVtaXR0ZWQpIHtcbiAgICBzdGF0ZS5lbmRlZCA9IHRydWU7XG4gICAgcHJvY2Vzc05leHRUaWNrKGVuZFJlYWRhYmxlTlQsIHN0YXRlLCBzdHJlYW0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVuZFJlYWRhYmxlTlQoc3RhdGUsIHN0cmVhbSkge1xuICAvLyBDaGVjayB0aGF0IHdlIGRpZG4ndCBnZXQgb25lIGxhc3QgdW5zaGlmdC5cbiAgaWYgKCFzdGF0ZS5lbmRFbWl0dGVkICYmIHN0YXRlLmxlbmd0aCA9PT0gMCkge1xuICAgIHN0YXRlLmVuZEVtaXR0ZWQgPSB0cnVlO1xuICAgIHN0cmVhbS5yZWFkYWJsZSA9IGZhbHNlO1xuICAgIHN0cmVhbS5lbWl0KCdlbmQnKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBmb3JFYWNoKHhzLCBmKSB7XG4gIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgZih4c1tpXSwgaSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5kZXhPZih4cywgeCkge1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHhzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGlmICh4c1tpXSA9PT0geCkgcmV0dXJuIGk7XG4gIH1cbiAgcmV0dXJuIC0xO1xufSIsIi8vIGEgdHJhbnNmb3JtIHN0cmVhbSBpcyBhIHJlYWRhYmxlL3dyaXRhYmxlIHN0cmVhbSB3aGVyZSB5b3UgZG9cbi8vIHNvbWV0aGluZyB3aXRoIHRoZSBkYXRhLiAgU29tZXRpbWVzIGl0J3MgY2FsbGVkIGEgXCJmaWx0ZXJcIixcbi8vIGJ1dCB0aGF0J3Mgbm90IGEgZ3JlYXQgbmFtZSBmb3IgaXQsIHNpbmNlIHRoYXQgaW1wbGllcyBhIHRoaW5nIHdoZXJlXG4vLyBzb21lIGJpdHMgcGFzcyB0aHJvdWdoLCBhbmQgb3RoZXJzIGFyZSBzaW1wbHkgaWdub3JlZC4gIChUaGF0IHdvdWxkXG4vLyBiZSBhIHZhbGlkIGV4YW1wbGUgb2YgYSB0cmFuc2Zvcm0sIG9mIGNvdXJzZS4pXG4vL1xuLy8gV2hpbGUgdGhlIG91dHB1dCBpcyBjYXVzYWxseSByZWxhdGVkIHRvIHRoZSBpbnB1dCwgaXQncyBub3QgYVxuLy8gbmVjZXNzYXJpbHkgc3ltbWV0cmljIG9yIHN5bmNocm9ub3VzIHRyYW5zZm9ybWF0aW9uLiAgRm9yIGV4YW1wbGUsXG4vLyBhIHpsaWIgc3RyZWFtIG1pZ2h0IHRha2UgbXVsdGlwbGUgcGxhaW4tdGV4dCB3cml0ZXMoKSwgYW5kIHRoZW5cbi8vIGVtaXQgYSBzaW5nbGUgY29tcHJlc3NlZCBjaHVuayBzb21lIHRpbWUgaW4gdGhlIGZ1dHVyZS5cbi8vXG4vLyBIZXJlJ3MgaG93IHRoaXMgd29ya3M6XG4vL1xuLy8gVGhlIFRyYW5zZm9ybSBzdHJlYW0gaGFzIGFsbCB0aGUgYXNwZWN0cyBvZiB0aGUgcmVhZGFibGUgYW5kIHdyaXRhYmxlXG4vLyBzdHJlYW0gY2xhc3Nlcy4gIFdoZW4geW91IHdyaXRlKGNodW5rKSwgdGhhdCBjYWxscyBfd3JpdGUoY2h1bmssY2IpXG4vLyBpbnRlcm5hbGx5LCBhbmQgcmV0dXJucyBmYWxzZSBpZiB0aGVyZSdzIGEgbG90IG9mIHBlbmRpbmcgd3JpdGVzXG4vLyBidWZmZXJlZCB1cC4gIFdoZW4geW91IGNhbGwgcmVhZCgpLCB0aGF0IGNhbGxzIF9yZWFkKG4pIHVudGlsXG4vLyB0aGVyZSdzIGVub3VnaCBwZW5kaW5nIHJlYWRhYmxlIGRhdGEgYnVmZmVyZWQgdXAuXG4vL1xuLy8gSW4gYSB0cmFuc2Zvcm0gc3RyZWFtLCB0aGUgd3JpdHRlbiBkYXRhIGlzIHBsYWNlZCBpbiBhIGJ1ZmZlci4gIFdoZW5cbi8vIF9yZWFkKG4pIGlzIGNhbGxlZCwgaXQgdHJhbnNmb3JtcyB0aGUgcXVldWVkIHVwIGRhdGEsIGNhbGxpbmcgdGhlXG4vLyBidWZmZXJlZCBfd3JpdGUgY2IncyBhcyBpdCBjb25zdW1lcyBjaHVua3MuICBJZiBjb25zdW1pbmcgYSBzaW5nbGVcbi8vIHdyaXR0ZW4gY2h1bmsgd291bGQgcmVzdWx0IGluIG11bHRpcGxlIG91dHB1dCBjaHVua3MsIHRoZW4gdGhlIGZpcnN0XG4vLyBvdXRwdXR0ZWQgYml0IGNhbGxzIHRoZSByZWFkY2IsIGFuZCBzdWJzZXF1ZW50IGNodW5rcyBqdXN0IGdvIGludG9cbi8vIHRoZSByZWFkIGJ1ZmZlciwgYW5kIHdpbGwgY2F1c2UgaXQgdG8gZW1pdCAncmVhZGFibGUnIGlmIG5lY2Vzc2FyeS5cbi8vXG4vLyBUaGlzIHdheSwgYmFjay1wcmVzc3VyZSBpcyBhY3R1YWxseSBkZXRlcm1pbmVkIGJ5IHRoZSByZWFkaW5nIHNpZGUsXG4vLyBzaW5jZSBfcmVhZCBoYXMgdG8gYmUgY2FsbGVkIHRvIHN0YXJ0IHByb2Nlc3NpbmcgYSBuZXcgY2h1bmsuICBIb3dldmVyLFxuLy8gYSBwYXRob2xvZ2ljYWwgaW5mbGF0ZSB0eXBlIG9mIHRyYW5zZm9ybSBjYW4gY2F1c2UgZXhjZXNzaXZlIGJ1ZmZlcmluZ1xuLy8gaGVyZS4gIEZvciBleGFtcGxlLCBpbWFnaW5lIGEgc3RyZWFtIHdoZXJlIGV2ZXJ5IGJ5dGUgb2YgaW5wdXQgaXNcbi8vIGludGVycHJldGVkIGFzIGFuIGludGVnZXIgZnJvbSAwLTI1NSwgYW5kIHRoZW4gcmVzdWx0cyBpbiB0aGF0IG1hbnlcbi8vIGJ5dGVzIG9mIG91dHB1dC4gIFdyaXRpbmcgdGhlIDQgYnl0ZXMge2ZmLGZmLGZmLGZmfSB3b3VsZCByZXN1bHQgaW5cbi8vIDFrYiBvZiBkYXRhIGJlaW5nIG91dHB1dC4gIEluIHRoaXMgY2FzZSwgeW91IGNvdWxkIHdyaXRlIGEgdmVyeSBzbWFsbFxuLy8gYW1vdW50IG9mIGlucHV0LCBhbmQgZW5kIHVwIHdpdGggYSB2ZXJ5IGxhcmdlIGFtb3VudCBvZiBvdXRwdXQuICBJblxuLy8gc3VjaCBhIHBhdGhvbG9naWNhbCBpbmZsYXRpbmcgbWVjaGFuaXNtLCB0aGVyZSdkIGJlIG5vIHdheSB0byB0ZWxsXG4vLyB0aGUgc3lzdGVtIHRvIHN0b3AgZG9pbmcgdGhlIHRyYW5zZm9ybS4gIEEgc2luZ2xlIDRNQiB3cml0ZSBjb3VsZFxuLy8gY2F1c2UgdGhlIHN5c3RlbSB0byBydW4gb3V0IG9mIG1lbW9yeS5cbi8vXG4vLyBIb3dldmVyLCBldmVuIGluIHN1Y2ggYSBwYXRob2xvZ2ljYWwgY2FzZSwgb25seSBhIHNpbmdsZSB3cml0dGVuIGNodW5rXG4vLyB3b3VsZCBiZSBjb25zdW1lZCwgYW5kIHRoZW4gdGhlIHJlc3Qgd291bGQgd2FpdCAodW4tdHJhbnNmb3JtZWQpIHVudGlsXG4vLyB0aGUgcmVzdWx0cyBvZiB0aGUgcHJldmlvdXMgdHJhbnNmb3JtZWQgY2h1bmsgd2VyZSBjb25zdW1lZC5cblxuJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFRyYW5zZm9ybTtcblxudmFyIER1cGxleCA9IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciB1dGlsID0gcmVxdWlyZSgnY29yZS11dGlsLWlzJyk7XG51dGlsLmluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcbi8qPC9yZXBsYWNlbWVudD4qL1xuXG51dGlsLmluaGVyaXRzKFRyYW5zZm9ybSwgRHVwbGV4KTtcblxuZnVuY3Rpb24gVHJhbnNmb3JtU3RhdGUoc3RyZWFtKSB7XG4gIHRoaXMuYWZ0ZXJUcmFuc2Zvcm0gPSBmdW5jdGlvbiAoZXIsIGRhdGEpIHtcbiAgICByZXR1cm4gYWZ0ZXJUcmFuc2Zvcm0oc3RyZWFtLCBlciwgZGF0YSk7XG4gIH07XG5cbiAgdGhpcy5uZWVkVHJhbnNmb3JtID0gZmFsc2U7XG4gIHRoaXMudHJhbnNmb3JtaW5nID0gZmFsc2U7XG4gIHRoaXMud3JpdGVjYiA9IG51bGw7XG4gIHRoaXMud3JpdGVjaHVuayA9IG51bGw7XG4gIHRoaXMud3JpdGVlbmNvZGluZyA9IG51bGw7XG59XG5cbmZ1bmN0aW9uIGFmdGVyVHJhbnNmb3JtKHN0cmVhbSwgZXIsIGRhdGEpIHtcbiAgdmFyIHRzID0gc3RyZWFtLl90cmFuc2Zvcm1TdGF0ZTtcbiAgdHMudHJhbnNmb3JtaW5nID0gZmFsc2U7XG5cbiAgdmFyIGNiID0gdHMud3JpdGVjYjtcblxuICBpZiAoIWNiKSByZXR1cm4gc3RyZWFtLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdubyB3cml0ZWNiIGluIFRyYW5zZm9ybSBjbGFzcycpKTtcblxuICB0cy53cml0ZWNodW5rID0gbnVsbDtcbiAgdHMud3JpdGVjYiA9IG51bGw7XG5cbiAgaWYgKGRhdGEgIT09IG51bGwgJiYgZGF0YSAhPT0gdW5kZWZpbmVkKSBzdHJlYW0ucHVzaChkYXRhKTtcblxuICBjYihlcik7XG5cbiAgdmFyIHJzID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICBycy5yZWFkaW5nID0gZmFsc2U7XG4gIGlmIChycy5uZWVkUmVhZGFibGUgfHwgcnMubGVuZ3RoIDwgcnMuaGlnaFdhdGVyTWFyaykge1xuICAgIHN0cmVhbS5fcmVhZChycy5oaWdoV2F0ZXJNYXJrKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBUcmFuc2Zvcm0ob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVHJhbnNmb3JtKSkgcmV0dXJuIG5ldyBUcmFuc2Zvcm0ob3B0aW9ucyk7XG5cbiAgRHVwbGV4LmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgdGhpcy5fdHJhbnNmb3JtU3RhdGUgPSBuZXcgVHJhbnNmb3JtU3RhdGUodGhpcyk7XG5cbiAgLy8gd2hlbiB0aGUgd3JpdGFibGUgc2lkZSBmaW5pc2hlcywgdGhlbiBmbHVzaCBvdXQgYW55dGhpbmcgcmVtYWluaW5nLlxuICB2YXIgc3RyZWFtID0gdGhpcztcblxuICAvLyBzdGFydCBvdXQgYXNraW5nIGZvciBhIHJlYWRhYmxlIGV2ZW50IG9uY2UgZGF0YSBpcyB0cmFuc2Zvcm1lZC5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuXG4gIC8vIHdlIGhhdmUgaW1wbGVtZW50ZWQgdGhlIF9yZWFkIG1ldGhvZCwgYW5kIGRvbmUgdGhlIG90aGVyIHRoaW5nc1xuICAvLyB0aGF0IFJlYWRhYmxlIHdhbnRzIGJlZm9yZSB0aGUgZmlyc3QgX3JlYWQgY2FsbCwgc28gdW5zZXQgdGhlXG4gIC8vIHN5bmMgZ3VhcmQgZmxhZy5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5zeW5jID0gZmFsc2U7XG5cbiAgaWYgKG9wdGlvbnMpIHtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMudHJhbnNmb3JtID09PSAnZnVuY3Rpb24nKSB0aGlzLl90cmFuc2Zvcm0gPSBvcHRpb25zLnRyYW5zZm9ybTtcblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5mbHVzaCA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fZmx1c2ggPSBvcHRpb25zLmZsdXNoO1xuICB9XG5cbiAgdGhpcy5vbmNlKCdwcmVmaW5pc2gnLCBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLl9mbHVzaCA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fZmx1c2goZnVuY3Rpb24gKGVyKSB7XG4gICAgICBkb25lKHN0cmVhbSwgZXIpO1xuICAgIH0pO2Vsc2UgZG9uZShzdHJlYW0pO1xuICB9KTtcbn1cblxuVHJhbnNmb3JtLnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZykge1xuICB0aGlzLl90cmFuc2Zvcm1TdGF0ZS5uZWVkVHJhbnNmb3JtID0gZmFsc2U7XG4gIHJldHVybiBEdXBsZXgucHJvdG90eXBlLnB1c2guY2FsbCh0aGlzLCBjaHVuaywgZW5jb2RpbmcpO1xufTtcblxuLy8gVGhpcyBpcyB0aGUgcGFydCB3aGVyZSB5b3UgZG8gc3R1ZmYhXG4vLyBvdmVycmlkZSB0aGlzIGZ1bmN0aW9uIGluIGltcGxlbWVudGF0aW9uIGNsYXNzZXMuXG4vLyAnY2h1bmsnIGlzIGFuIGlucHV0IGNodW5rLlxuLy9cbi8vIENhbGwgYHB1c2gobmV3Q2h1bmspYCB0byBwYXNzIGFsb25nIHRyYW5zZm9ybWVkIG91dHB1dFxuLy8gdG8gdGhlIHJlYWRhYmxlIHNpZGUuICBZb3UgbWF5IGNhbGwgJ3B1c2gnIHplcm8gb3IgbW9yZSB0aW1lcy5cbi8vXG4vLyBDYWxsIGBjYihlcnIpYCB3aGVuIHlvdSBhcmUgZG9uZSB3aXRoIHRoaXMgY2h1bmsuICBJZiB5b3UgcGFzc1xuLy8gYW4gZXJyb3IsIHRoZW4gdGhhdCdsbCBwdXQgdGhlIGh1cnQgb24gdGhlIHdob2xlIG9wZXJhdGlvbi4gIElmIHlvdVxuLy8gbmV2ZXIgY2FsbCBjYigpLCB0aGVuIHlvdSdsbCBuZXZlciBnZXQgYW5vdGhlciBjaHVuay5cblRyYW5zZm9ybS5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHRocm93IG5ldyBFcnJvcignbm90IGltcGxlbWVudGVkJyk7XG59O1xuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uIChjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciB0cyA9IHRoaXMuX3RyYW5zZm9ybVN0YXRlO1xuICB0cy53cml0ZWNiID0gY2I7XG4gIHRzLndyaXRlY2h1bmsgPSBjaHVuaztcbiAgdHMud3JpdGVlbmNvZGluZyA9IGVuY29kaW5nO1xuICBpZiAoIXRzLnRyYW5zZm9ybWluZykge1xuICAgIHZhciBycyA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gICAgaWYgKHRzLm5lZWRUcmFuc2Zvcm0gfHwgcnMubmVlZFJlYWRhYmxlIHx8IHJzLmxlbmd0aCA8IHJzLmhpZ2hXYXRlck1hcmspIHRoaXMuX3JlYWQocnMuaGlnaFdhdGVyTWFyayk7XG4gIH1cbn07XG5cbi8vIERvZXNuJ3QgbWF0dGVyIHdoYXQgdGhlIGFyZ3MgYXJlIGhlcmUuXG4vLyBfdHJhbnNmb3JtIGRvZXMgYWxsIHRoZSB3b3JrLlxuLy8gVGhhdCB3ZSBnb3QgaGVyZSBtZWFucyB0aGF0IHRoZSByZWFkYWJsZSBzaWRlIHdhbnRzIG1vcmUgZGF0YS5cblRyYW5zZm9ybS5wcm90b3R5cGUuX3JlYWQgPSBmdW5jdGlvbiAobikge1xuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZTtcblxuICBpZiAodHMud3JpdGVjaHVuayAhPT0gbnVsbCAmJiB0cy53cml0ZWNiICYmICF0cy50cmFuc2Zvcm1pbmcpIHtcbiAgICB0cy50cmFuc2Zvcm1pbmcgPSB0cnVlO1xuICAgIHRoaXMuX3RyYW5zZm9ybSh0cy53cml0ZWNodW5rLCB0cy53cml0ZWVuY29kaW5nLCB0cy5hZnRlclRyYW5zZm9ybSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gbWFyayB0aGF0IHdlIG5lZWQgYSB0cmFuc2Zvcm0sIHNvIHRoYXQgYW55IGRhdGEgdGhhdCBjb21lcyBpblxuICAgIC8vIHdpbGwgZ2V0IHByb2Nlc3NlZCwgbm93IHRoYXQgd2UndmUgYXNrZWQgZm9yIGl0LlxuICAgIHRzLm5lZWRUcmFuc2Zvcm0gPSB0cnVlO1xuICB9XG59O1xuXG5mdW5jdGlvbiBkb25lKHN0cmVhbSwgZXIpIHtcbiAgaWYgKGVyKSByZXR1cm4gc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuXG4gIC8vIGlmIHRoZXJlJ3Mgbm90aGluZyBpbiB0aGUgd3JpdGUgYnVmZmVyLCB0aGVuIHRoYXQgbWVhbnNcbiAgLy8gdGhhdCBub3RoaW5nIG1vcmUgd2lsbCBldmVyIGJlIHByb3ZpZGVkXG4gIHZhciB3cyA9IHN0cmVhbS5fd3JpdGFibGVTdGF0ZTtcbiAgdmFyIHRzID0gc3RyZWFtLl90cmFuc2Zvcm1TdGF0ZTtcblxuICBpZiAod3MubGVuZ3RoKSB0aHJvdyBuZXcgRXJyb3IoJ2NhbGxpbmcgdHJhbnNmb3JtIGRvbmUgd2hlbiB3cy5sZW5ndGggIT0gMCcpO1xuXG4gIGlmICh0cy50cmFuc2Zvcm1pbmcpIHRocm93IG5ldyBFcnJvcignY2FsbGluZyB0cmFuc2Zvcm0gZG9uZSB3aGVuIHN0aWxsIHRyYW5zZm9ybWluZycpO1xuXG4gIHJldHVybiBzdHJlYW0ucHVzaChudWxsKTtcbn0iLCIvLyBBIGJpdCBzaW1wbGVyIHRoYW4gcmVhZGFibGUgc3RyZWFtcy5cbi8vIEltcGxlbWVudCBhbiBhc3luYyAuX3dyaXRlKGNodW5rLCBlbmNvZGluZywgY2IpLCBhbmQgaXQnbGwgaGFuZGxlIGFsbFxuLy8gdGhlIGRyYWluIGV2ZW50IGVtaXNzaW9uIGFuZCBidWZmZXJpbmcuXG5cbid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBXcml0YWJsZTtcblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBwcm9jZXNzTmV4dFRpY2sgPSByZXF1aXJlKCdwcm9jZXNzLW5leHRpY2stYXJncycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgYXN5bmNXcml0ZSA9ICFwcm9jZXNzLmJyb3dzZXIgJiYgWyd2MC4xMCcsICd2MC45LiddLmluZGV4T2YocHJvY2Vzcy52ZXJzaW9uLnNsaWNlKDAsIDUpKSA+IC0xID8gc2V0SW1tZWRpYXRlIDogcHJvY2Vzc05leHRUaWNrO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbldyaXRhYmxlLldyaXRhYmxlU3RhdGUgPSBXcml0YWJsZVN0YXRlO1xuXG4vKjxyZXBsYWNlbWVudD4qL1xudmFyIHV0aWwgPSByZXF1aXJlKCdjb3JlLXV0aWwtaXMnKTtcbnV0aWwuaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuLyo8L3JlcGxhY2VtZW50PiovXG5cbi8qPHJlcGxhY2VtZW50PiovXG52YXIgaW50ZXJuYWxVdGlsID0ge1xuICBkZXByZWNhdGU6IHJlcXVpcmUoJ3V0aWwtZGVwcmVjYXRlJylcbn07XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxuLyo8cmVwbGFjZW1lbnQ+Ki9cbnZhciBTdHJlYW07XG4oZnVuY3Rpb24gKCkge1xuICB0cnkge1xuICAgIFN0cmVhbSA9IHJlcXVpcmUoJ3N0JyArICdyZWFtJyk7XG4gIH0gY2F0Y2ggKF8pIHt9IGZpbmFsbHkge1xuICAgIGlmICghU3RyZWFtKSBTdHJlYW0gPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG4gIH1cbn0pKCk7XG4vKjwvcmVwbGFjZW1lbnQ+Ki9cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcblxudXRpbC5pbmhlcml0cyhXcml0YWJsZSwgU3RyZWFtKTtcblxuZnVuY3Rpb24gbm9wKCkge31cblxuZnVuY3Rpb24gV3JpdGVSZXEoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB0aGlzLmNodW5rID0gY2h1bms7XG4gIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZztcbiAgdGhpcy5jYWxsYmFjayA9IGNiO1xuICB0aGlzLm5leHQgPSBudWxsO1xufVxuXG52YXIgRHVwbGV4O1xuZnVuY3Rpb24gV3JpdGFibGVTdGF0ZShvcHRpb25zLCBzdHJlYW0pIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAvLyBvYmplY3Qgc3RyZWFtIGZsYWcgdG8gaW5kaWNhdGUgd2hldGhlciBvciBub3QgdGhpcyBzdHJlYW1cbiAgLy8gY29udGFpbnMgYnVmZmVycyBvciBvYmplY3RzLlxuICB0aGlzLm9iamVjdE1vZGUgPSAhIW9wdGlvbnMub2JqZWN0TW9kZTtcblxuICBpZiAoc3RyZWFtIGluc3RhbmNlb2YgRHVwbGV4KSB0aGlzLm9iamVjdE1vZGUgPSB0aGlzLm9iamVjdE1vZGUgfHwgISFvcHRpb25zLndyaXRhYmxlT2JqZWN0TW9kZTtcblxuICAvLyB0aGUgcG9pbnQgYXQgd2hpY2ggd3JpdGUoKSBzdGFydHMgcmV0dXJuaW5nIGZhbHNlXG4gIC8vIE5vdGU6IDAgaXMgYSB2YWxpZCB2YWx1ZSwgbWVhbnMgdGhhdCB3ZSBhbHdheXMgcmV0dXJuIGZhbHNlIGlmXG4gIC8vIHRoZSBlbnRpcmUgYnVmZmVyIGlzIG5vdCBmbHVzaGVkIGltbWVkaWF0ZWx5IG9uIHdyaXRlKClcbiAgdmFyIGh3bSA9IG9wdGlvbnMuaGlnaFdhdGVyTWFyaztcbiAgdmFyIGRlZmF1bHRId20gPSB0aGlzLm9iamVjdE1vZGUgPyAxNiA6IDE2ICogMTAyNDtcbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gaHdtIHx8IGh3bSA9PT0gMCA/IGh3bSA6IGRlZmF1bHRId207XG5cbiAgLy8gY2FzdCB0byBpbnRzLlxuICB0aGlzLmhpZ2hXYXRlck1hcmsgPSB+IH50aGlzLmhpZ2hXYXRlck1hcms7XG5cbiAgdGhpcy5uZWVkRHJhaW4gPSBmYWxzZTtcbiAgLy8gYXQgdGhlIHN0YXJ0IG9mIGNhbGxpbmcgZW5kKClcbiAgdGhpcy5lbmRpbmcgPSBmYWxzZTtcbiAgLy8gd2hlbiBlbmQoKSBoYXMgYmVlbiBjYWxsZWQsIGFuZCByZXR1cm5lZFxuICB0aGlzLmVuZGVkID0gZmFsc2U7XG4gIC8vIHdoZW4gJ2ZpbmlzaCcgaXMgZW1pdHRlZFxuICB0aGlzLmZpbmlzaGVkID0gZmFsc2U7XG5cbiAgLy8gc2hvdWxkIHdlIGRlY29kZSBzdHJpbmdzIGludG8gYnVmZmVycyBiZWZvcmUgcGFzc2luZyB0byBfd3JpdGU/XG4gIC8vIHRoaXMgaXMgaGVyZSBzbyB0aGF0IHNvbWUgbm9kZS1jb3JlIHN0cmVhbXMgY2FuIG9wdGltaXplIHN0cmluZ1xuICAvLyBoYW5kbGluZyBhdCBhIGxvd2VyIGxldmVsLlxuICB2YXIgbm9EZWNvZGUgPSBvcHRpb25zLmRlY29kZVN0cmluZ3MgPT09IGZhbHNlO1xuICB0aGlzLmRlY29kZVN0cmluZ3MgPSAhbm9EZWNvZGU7XG5cbiAgLy8gQ3J5cHRvIGlzIGtpbmQgb2Ygb2xkIGFuZCBjcnVzdHkuICBIaXN0b3JpY2FsbHksIGl0cyBkZWZhdWx0IHN0cmluZ1xuICAvLyBlbmNvZGluZyBpcyAnYmluYXJ5JyBzbyB3ZSBoYXZlIHRvIG1ha2UgdGhpcyBjb25maWd1cmFibGUuXG4gIC8vIEV2ZXJ5dGhpbmcgZWxzZSBpbiB0aGUgdW5pdmVyc2UgdXNlcyAndXRmOCcsIHRob3VnaC5cbiAgdGhpcy5kZWZhdWx0RW5jb2RpbmcgPSBvcHRpb25zLmRlZmF1bHRFbmNvZGluZyB8fCAndXRmOCc7XG5cbiAgLy8gbm90IGFuIGFjdHVhbCBidWZmZXIgd2Uga2VlcCB0cmFjayBvZiwgYnV0IGEgbWVhc3VyZW1lbnRcbiAgLy8gb2YgaG93IG11Y2ggd2UncmUgd2FpdGluZyB0byBnZXQgcHVzaGVkIHRvIHNvbWUgdW5kZXJseWluZ1xuICAvLyBzb2NrZXQgb3IgZmlsZS5cbiAgdGhpcy5sZW5ndGggPSAwO1xuXG4gIC8vIGEgZmxhZyB0byBzZWUgd2hlbiB3ZSdyZSBpbiB0aGUgbWlkZGxlIG9mIGEgd3JpdGUuXG4gIHRoaXMud3JpdGluZyA9IGZhbHNlO1xuXG4gIC8vIHdoZW4gdHJ1ZSBhbGwgd3JpdGVzIHdpbGwgYmUgYnVmZmVyZWQgdW50aWwgLnVuY29yaygpIGNhbGxcbiAgdGhpcy5jb3JrZWQgPSAwO1xuXG4gIC8vIGEgZmxhZyB0byBiZSBhYmxlIHRvIHRlbGwgaWYgdGhlIG9ud3JpdGUgY2IgaXMgY2FsbGVkIGltbWVkaWF0ZWx5LFxuICAvLyBvciBvbiBhIGxhdGVyIHRpY2suICBXZSBzZXQgdGhpcyB0byB0cnVlIGF0IGZpcnN0LCBiZWNhdXNlIGFueVxuICAvLyBhY3Rpb25zIHRoYXQgc2hvdWxkbid0IGhhcHBlbiB1bnRpbCBcImxhdGVyXCIgc2hvdWxkIGdlbmVyYWxseSBhbHNvXG4gIC8vIG5vdCBoYXBwZW4gYmVmb3JlIHRoZSBmaXJzdCB3cml0ZSBjYWxsLlxuICB0aGlzLnN5bmMgPSB0cnVlO1xuXG4gIC8vIGEgZmxhZyB0byBrbm93IGlmIHdlJ3JlIHByb2Nlc3NpbmcgcHJldmlvdXNseSBidWZmZXJlZCBpdGVtcywgd2hpY2hcbiAgLy8gbWF5IGNhbGwgdGhlIF93cml0ZSgpIGNhbGxiYWNrIGluIHRoZSBzYW1lIHRpY2ssIHNvIHRoYXQgd2UgZG9uJ3RcbiAgLy8gZW5kIHVwIGluIGFuIG92ZXJsYXBwZWQgb253cml0ZSBzaXR1YXRpb24uXG4gIHRoaXMuYnVmZmVyUHJvY2Vzc2luZyA9IGZhbHNlO1xuXG4gIC8vIHRoZSBjYWxsYmFjayB0aGF0J3MgcGFzc2VkIHRvIF93cml0ZShjaHVuayxjYilcbiAgdGhpcy5vbndyaXRlID0gZnVuY3Rpb24gKGVyKSB7XG4gICAgb253cml0ZShzdHJlYW0sIGVyKTtcbiAgfTtcblxuICAvLyB0aGUgY2FsbGJhY2sgdGhhdCB0aGUgdXNlciBzdXBwbGllcyB0byB3cml0ZShjaHVuayxlbmNvZGluZyxjYilcbiAgdGhpcy53cml0ZWNiID0gbnVsbDtcblxuICAvLyB0aGUgYW1vdW50IHRoYXQgaXMgYmVpbmcgd3JpdHRlbiB3aGVuIF93cml0ZSBpcyBjYWxsZWQuXG4gIHRoaXMud3JpdGVsZW4gPSAwO1xuXG4gIHRoaXMuYnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcbiAgdGhpcy5sYXN0QnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcblxuICAvLyBudW1iZXIgb2YgcGVuZGluZyB1c2VyLXN1cHBsaWVkIHdyaXRlIGNhbGxiYWNrc1xuICAvLyB0aGlzIG11c3QgYmUgMCBiZWZvcmUgJ2ZpbmlzaCcgY2FuIGJlIGVtaXR0ZWRcbiAgdGhpcy5wZW5kaW5nY2IgPSAwO1xuXG4gIC8vIGVtaXQgcHJlZmluaXNoIGlmIHRoZSBvbmx5IHRoaW5nIHdlJ3JlIHdhaXRpbmcgZm9yIGlzIF93cml0ZSBjYnNcbiAgLy8gVGhpcyBpcyByZWxldmFudCBmb3Igc3luY2hyb25vdXMgVHJhbnNmb3JtIHN0cmVhbXNcbiAgdGhpcy5wcmVmaW5pc2hlZCA9IGZhbHNlO1xuXG4gIC8vIFRydWUgaWYgdGhlIGVycm9yIHdhcyBhbHJlYWR5IGVtaXR0ZWQgYW5kIHNob3VsZCBub3QgYmUgdGhyb3duIGFnYWluXG4gIHRoaXMuZXJyb3JFbWl0dGVkID0gZmFsc2U7XG5cbiAgLy8gY291bnQgYnVmZmVyZWQgcmVxdWVzdHNcbiAgdGhpcy5idWZmZXJlZFJlcXVlc3RDb3VudCA9IDA7XG5cbiAgLy8gY3JlYXRlIHRoZSB0d28gb2JqZWN0cyBuZWVkZWQgdG8gc3RvcmUgdGhlIGNvcmtlZCByZXF1ZXN0c1xuICAvLyB0aGV5IGFyZSBub3QgYSBsaW5rZWQgbGlzdCwgYXMgbm8gbmV3IGVsZW1lbnRzIGFyZSBpbnNlcnRlZCBpbiB0aGVyZVxuICB0aGlzLmNvcmtlZFJlcXVlc3RzRnJlZSA9IG5ldyBDb3JrZWRSZXF1ZXN0KHRoaXMpO1xuICB0aGlzLmNvcmtlZFJlcXVlc3RzRnJlZS5uZXh0ID0gbmV3IENvcmtlZFJlcXVlc3QodGhpcyk7XG59XG5cbldyaXRhYmxlU3RhdGUucHJvdG90eXBlLmdldEJ1ZmZlciA9IGZ1bmN0aW9uIHdyaXRhYmxlU3RhdGVHZXRCdWZmZXIoKSB7XG4gIHZhciBjdXJyZW50ID0gdGhpcy5idWZmZXJlZFJlcXVlc3Q7XG4gIHZhciBvdXQgPSBbXTtcbiAgd2hpbGUgKGN1cnJlbnQpIHtcbiAgICBvdXQucHVzaChjdXJyZW50KTtcbiAgICBjdXJyZW50ID0gY3VycmVudC5uZXh0O1xuICB9XG4gIHJldHVybiBvdXQ7XG59O1xuXG4oZnVuY3Rpb24gKCkge1xuICB0cnkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShXcml0YWJsZVN0YXRlLnByb3RvdHlwZSwgJ2J1ZmZlcicsIHtcbiAgICAgIGdldDogaW50ZXJuYWxVdGlsLmRlcHJlY2F0ZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEJ1ZmZlcigpO1xuICAgICAgfSwgJ193cml0YWJsZVN0YXRlLmJ1ZmZlciBpcyBkZXByZWNhdGVkLiBVc2UgX3dyaXRhYmxlU3RhdGUuZ2V0QnVmZmVyICcgKyAnaW5zdGVhZC4nKVxuICAgIH0pO1xuICB9IGNhdGNoIChfKSB7fVxufSkoKTtcblxudmFyIER1cGxleDtcbmZ1bmN0aW9uIFdyaXRhYmxlKG9wdGlvbnMpIHtcbiAgRHVwbGV4ID0gRHVwbGV4IHx8IHJlcXVpcmUoJy4vX3N0cmVhbV9kdXBsZXgnKTtcblxuICAvLyBXcml0YWJsZSBjdG9yIGlzIGFwcGxpZWQgdG8gRHVwbGV4ZXMsIHRob3VnaCB0aGV5J3JlIG5vdFxuICAvLyBpbnN0YW5jZW9mIFdyaXRhYmxlLCB0aGV5J3JlIGluc3RhbmNlb2YgUmVhZGFibGUuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBXcml0YWJsZSkgJiYgISh0aGlzIGluc3RhbmNlb2YgRHVwbGV4KSkgcmV0dXJuIG5ldyBXcml0YWJsZShvcHRpb25zKTtcblxuICB0aGlzLl93cml0YWJsZVN0YXRlID0gbmV3IFdyaXRhYmxlU3RhdGUob3B0aW9ucywgdGhpcyk7XG5cbiAgLy8gbGVnYWN5LlxuICB0aGlzLndyaXRhYmxlID0gdHJ1ZTtcblxuICBpZiAob3B0aW9ucykge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy53cml0ZSA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fd3JpdGUgPSBvcHRpb25zLndyaXRlO1xuXG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLndyaXRldiA9PT0gJ2Z1bmN0aW9uJykgdGhpcy5fd3JpdGV2ID0gb3B0aW9ucy53cml0ZXY7XG4gIH1cblxuICBTdHJlYW0uY2FsbCh0aGlzKTtcbn1cblxuLy8gT3RoZXJ3aXNlIHBlb3BsZSBjYW4gcGlwZSBXcml0YWJsZSBzdHJlYW1zLCB3aGljaCBpcyBqdXN0IHdyb25nLlxuV3JpdGFibGUucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ0Nhbm5vdCBwaXBlLiBOb3QgcmVhZGFibGUuJykpO1xufTtcblxuZnVuY3Rpb24gd3JpdGVBZnRlckVuZChzdHJlYW0sIGNiKSB7XG4gIHZhciBlciA9IG5ldyBFcnJvcignd3JpdGUgYWZ0ZXIgZW5kJyk7XG4gIC8vIFRPRE86IGRlZmVyIGVycm9yIGV2ZW50cyBjb25zaXN0ZW50bHkgZXZlcnl3aGVyZSwgbm90IGp1c3QgdGhlIGNiXG4gIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbiAgcHJvY2Vzc05leHRUaWNrKGNiLCBlcik7XG59XG5cbi8vIElmIHdlIGdldCBzb21ldGhpbmcgdGhhdCBpcyBub3QgYSBidWZmZXIsIHN0cmluZywgbnVsbCwgb3IgdW5kZWZpbmVkLFxuLy8gYW5kIHdlJ3JlIG5vdCBpbiBvYmplY3RNb2RlLCB0aGVuIHRoYXQncyBhbiBlcnJvci5cbi8vIE90aGVyd2lzZSBzdHJlYW0gY2h1bmtzIGFyZSBhbGwgY29uc2lkZXJlZCB0byBiZSBvZiBsZW5ndGg9MSwgYW5kIHRoZVxuLy8gd2F0ZXJtYXJrcyBkZXRlcm1pbmUgaG93IG1hbnkgb2JqZWN0cyB0byBrZWVwIGluIHRoZSBidWZmZXIsIHJhdGhlciB0aGFuXG4vLyBob3cgbWFueSBieXRlcyBvciBjaGFyYWN0ZXJzLlxuZnVuY3Rpb24gdmFsaWRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgY2IpIHtcbiAgdmFyIHZhbGlkID0gdHJ1ZTtcblxuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihjaHVuaykgJiYgdHlwZW9mIGNodW5rICE9PSAnc3RyaW5nJyAmJiBjaHVuayAhPT0gbnVsbCAmJiBjaHVuayAhPT0gdW5kZWZpbmVkICYmICFzdGF0ZS5vYmplY3RNb2RlKSB7XG4gICAgdmFyIGVyID0gbmV3IFR5cGVFcnJvcignSW52YWxpZCBub24tc3RyaW5nL2J1ZmZlciBjaHVuaycpO1xuICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbiAgICBwcm9jZXNzTmV4dFRpY2soY2IsIGVyKTtcbiAgICB2YWxpZCA9IGZhbHNlO1xuICB9XG4gIHJldHVybiB2YWxpZDtcbn1cblxuV3JpdGFibGUucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcbiAgdmFyIHJldCA9IGZhbHNlO1xuXG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGVuY29kaW5nO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfVxuXG4gIGlmIChCdWZmZXIuaXNCdWZmZXIoY2h1bmspKSBlbmNvZGluZyA9ICdidWZmZXInO2Vsc2UgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSBzdGF0ZS5kZWZhdWx0RW5jb2Rpbmc7XG5cbiAgaWYgKHR5cGVvZiBjYiAhPT0gJ2Z1bmN0aW9uJykgY2IgPSBub3A7XG5cbiAgaWYgKHN0YXRlLmVuZGVkKSB3cml0ZUFmdGVyRW5kKHRoaXMsIGNiKTtlbHNlIGlmICh2YWxpZENodW5rKHRoaXMsIHN0YXRlLCBjaHVuaywgY2IpKSB7XG4gICAgc3RhdGUucGVuZGluZ2NiKys7XG4gICAgcmV0ID0gd3JpdGVPckJ1ZmZlcih0aGlzLCBzdGF0ZSwgY2h1bmssIGVuY29kaW5nLCBjYik7XG4gIH1cblxuICByZXR1cm4gcmV0O1xufTtcblxuV3JpdGFibGUucHJvdG90eXBlLmNvcmsgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3dyaXRhYmxlU3RhdGU7XG5cbiAgc3RhdGUuY29ya2VkKys7XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUudW5jb3JrID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuXG4gIGlmIChzdGF0ZS5jb3JrZWQpIHtcbiAgICBzdGF0ZS5jb3JrZWQtLTtcblxuICAgIGlmICghc3RhdGUud3JpdGluZyAmJiAhc3RhdGUuY29ya2VkICYmICFzdGF0ZS5maW5pc2hlZCAmJiAhc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyAmJiBzdGF0ZS5idWZmZXJlZFJlcXVlc3QpIGNsZWFyQnVmZmVyKHRoaXMsIHN0YXRlKTtcbiAgfVxufTtcblxuV3JpdGFibGUucHJvdG90eXBlLnNldERlZmF1bHRFbmNvZGluZyA9IGZ1bmN0aW9uIHNldERlZmF1bHRFbmNvZGluZyhlbmNvZGluZykge1xuICAvLyBub2RlOjpQYXJzZUVuY29kaW5nKCkgcmVxdWlyZXMgbG93ZXIgY2FzZS5cbiAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZycpIGVuY29kaW5nID0gZW5jb2RpbmcudG9Mb3dlckNhc2UoKTtcbiAgaWYgKCEoWydoZXgnLCAndXRmOCcsICd1dGYtOCcsICdhc2NpaScsICdiaW5hcnknLCAnYmFzZTY0JywgJ3VjczInLCAndWNzLTInLCAndXRmMTZsZScsICd1dGYtMTZsZScsICdyYXcnXS5pbmRleE9mKChlbmNvZGluZyArICcnKS50b0xvd2VyQ2FzZSgpKSA+IC0xKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKTtcbiAgdGhpcy5fd3JpdGFibGVTdGF0ZS5kZWZhdWx0RW5jb2RpbmcgPSBlbmNvZGluZztcbn07XG5cbmZ1bmN0aW9uIGRlY29kZUNodW5rKHN0YXRlLCBjaHVuaywgZW5jb2RpbmcpIHtcbiAgaWYgKCFzdGF0ZS5vYmplY3RNb2RlICYmIHN0YXRlLmRlY29kZVN0cmluZ3MgIT09IGZhbHNlICYmIHR5cGVvZiBjaHVuayA9PT0gJ3N0cmluZycpIHtcbiAgICBjaHVuayA9IG5ldyBCdWZmZXIoY2h1bmssIGVuY29kaW5nKTtcbiAgfVxuICByZXR1cm4gY2h1bms7XG59XG5cbi8vIGlmIHdlJ3JlIGFscmVhZHkgd3JpdGluZyBzb21ldGhpbmcsIHRoZW4ganVzdCBwdXQgdGhpc1xuLy8gaW4gdGhlIHF1ZXVlLCBhbmQgd2FpdCBvdXIgdHVybi4gIE90aGVyd2lzZSwgY2FsbCBfd3JpdGVcbi8vIElmIHdlIHJldHVybiBmYWxzZSwgdGhlbiB3ZSBuZWVkIGEgZHJhaW4gZXZlbnQsIHNvIHNldCB0aGF0IGZsYWcuXG5mdW5jdGlvbiB3cml0ZU9yQnVmZmVyKHN0cmVhbSwgc3RhdGUsIGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgY2h1bmsgPSBkZWNvZGVDaHVuayhzdGF0ZSwgY2h1bmssIGVuY29kaW5nKTtcblxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKGNodW5rKSkgZW5jb2RpbmcgPSAnYnVmZmVyJztcbiAgdmFyIGxlbiA9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuXG4gIHN0YXRlLmxlbmd0aCArPSBsZW47XG5cbiAgdmFyIHJldCA9IHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcms7XG4gIC8vIHdlIG11c3QgZW5zdXJlIHRoYXQgcHJldmlvdXMgbmVlZERyYWluIHdpbGwgbm90IGJlIHJlc2V0IHRvIGZhbHNlLlxuICBpZiAoIXJldCkgc3RhdGUubmVlZERyYWluID0gdHJ1ZTtcblxuICBpZiAoc3RhdGUud3JpdGluZyB8fCBzdGF0ZS5jb3JrZWQpIHtcbiAgICB2YXIgbGFzdCA9IHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7XG4gICAgc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG5ldyBXcml0ZVJlcShjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgICBpZiAobGFzdCkge1xuICAgICAgbGFzdC5uZXh0ID0gc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdDtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0ID0gc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdDtcbiAgICB9XG4gICAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQgKz0gMTtcbiAgfSBlbHNlIHtcbiAgICBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIGZhbHNlLCBsZW4sIGNodW5rLCBlbmNvZGluZywgY2IpO1xuICB9XG5cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCB3cml0ZXYsIGxlbiwgY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBzdGF0ZS53cml0ZWxlbiA9IGxlbjtcbiAgc3RhdGUud3JpdGVjYiA9IGNiO1xuICBzdGF0ZS53cml0aW5nID0gdHJ1ZTtcbiAgc3RhdGUuc3luYyA9IHRydWU7XG4gIGlmICh3cml0ZXYpIHN0cmVhbS5fd3JpdGV2KGNodW5rLCBzdGF0ZS5vbndyaXRlKTtlbHNlIHN0cmVhbS5fd3JpdGUoY2h1bmssIGVuY29kaW5nLCBzdGF0ZS5vbndyaXRlKTtcbiAgc3RhdGUuc3luYyA9IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBvbndyaXRlRXJyb3Ioc3RyZWFtLCBzdGF0ZSwgc3luYywgZXIsIGNiKSB7XG4gIC0tc3RhdGUucGVuZGluZ2NiO1xuICBpZiAoc3luYykgcHJvY2Vzc05leHRUaWNrKGNiLCBlcik7ZWxzZSBjYihlcik7XG5cbiAgc3RyZWFtLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZCA9IHRydWU7XG4gIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcbn1cblxuZnVuY3Rpb24gb253cml0ZVN0YXRlVXBkYXRlKHN0YXRlKSB7XG4gIHN0YXRlLndyaXRpbmcgPSBmYWxzZTtcbiAgc3RhdGUud3JpdGVjYiA9IG51bGw7XG4gIHN0YXRlLmxlbmd0aCAtPSBzdGF0ZS53cml0ZWxlbjtcbiAgc3RhdGUud3JpdGVsZW4gPSAwO1xufVxuXG5mdW5jdGlvbiBvbndyaXRlKHN0cmVhbSwgZXIpIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl93cml0YWJsZVN0YXRlO1xuICB2YXIgc3luYyA9IHN0YXRlLnN5bmM7XG4gIHZhciBjYiA9IHN0YXRlLndyaXRlY2I7XG5cbiAgb253cml0ZVN0YXRlVXBkYXRlKHN0YXRlKTtcblxuICBpZiAoZXIpIG9ud3JpdGVFcnJvcihzdHJlYW0sIHN0YXRlLCBzeW5jLCBlciwgY2IpO2Vsc2Uge1xuICAgIC8vIENoZWNrIGlmIHdlJ3JlIGFjdHVhbGx5IHJlYWR5IHRvIGZpbmlzaCwgYnV0IGRvbid0IGVtaXQgeWV0XG4gICAgdmFyIGZpbmlzaGVkID0gbmVlZEZpbmlzaChzdGF0ZSk7XG5cbiAgICBpZiAoIWZpbmlzaGVkICYmICFzdGF0ZS5jb3JrZWQgJiYgIXN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgJiYgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0KSB7XG4gICAgICBjbGVhckJ1ZmZlcihzdHJlYW0sIHN0YXRlKTtcbiAgICB9XG5cbiAgICBpZiAoc3luYykge1xuICAgICAgLyo8cmVwbGFjZW1lbnQ+Ki9cbiAgICAgIGFzeW5jV3JpdGUoYWZ0ZXJXcml0ZSwgc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKTtcbiAgICAgIC8qPC9yZXBsYWNlbWVudD4qL1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGFmdGVyV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKTtcbiAgICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhZnRlcldyaXRlKHN0cmVhbSwgc3RhdGUsIGZpbmlzaGVkLCBjYikge1xuICBpZiAoIWZpbmlzaGVkKSBvbndyaXRlRHJhaW4oc3RyZWFtLCBzdGF0ZSk7XG4gIHN0YXRlLnBlbmRpbmdjYi0tO1xuICBjYigpO1xuICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbn1cblxuLy8gTXVzdCBmb3JjZSBjYWxsYmFjayB0byBiZSBjYWxsZWQgb24gbmV4dFRpY2ssIHNvIHRoYXQgd2UgZG9uJ3Rcbi8vIGVtaXQgJ2RyYWluJyBiZWZvcmUgdGhlIHdyaXRlKCkgY29uc3VtZXIgZ2V0cyB0aGUgJ2ZhbHNlJyByZXR1cm5cbi8vIHZhbHVlLCBhbmQgaGFzIGEgY2hhbmNlIHRvIGF0dGFjaCBhICdkcmFpbicgbGlzdGVuZXIuXG5mdW5jdGlvbiBvbndyaXRlRHJhaW4oc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLm5lZWREcmFpbikge1xuICAgIHN0YXRlLm5lZWREcmFpbiA9IGZhbHNlO1xuICAgIHN0cmVhbS5lbWl0KCdkcmFpbicpO1xuICB9XG59XG5cbi8vIGlmIHRoZXJlJ3Mgc29tZXRoaW5nIGluIHRoZSBidWZmZXIgd2FpdGluZywgdGhlbiBwcm9jZXNzIGl0XG5mdW5jdGlvbiBjbGVhckJ1ZmZlcihzdHJlYW0sIHN0YXRlKSB7XG4gIHN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcgPSB0cnVlO1xuICB2YXIgZW50cnkgPSBzdGF0ZS5idWZmZXJlZFJlcXVlc3Q7XG5cbiAgaWYgKHN0cmVhbS5fd3JpdGV2ICYmIGVudHJ5ICYmIGVudHJ5Lm5leHQpIHtcbiAgICAvLyBGYXN0IGNhc2UsIHdyaXRlIGV2ZXJ5dGhpbmcgdXNpbmcgX3dyaXRldigpXG4gICAgdmFyIGwgPSBzdGF0ZS5idWZmZXJlZFJlcXVlc3RDb3VudDtcbiAgICB2YXIgYnVmZmVyID0gbmV3IEFycmF5KGwpO1xuICAgIHZhciBob2xkZXIgPSBzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWU7XG4gICAgaG9sZGVyLmVudHJ5ID0gZW50cnk7XG5cbiAgICB2YXIgY291bnQgPSAwO1xuICAgIHdoaWxlIChlbnRyeSkge1xuICAgICAgYnVmZmVyW2NvdW50XSA9IGVudHJ5O1xuICAgICAgZW50cnkgPSBlbnRyeS5uZXh0O1xuICAgICAgY291bnQgKz0gMTtcbiAgICB9XG5cbiAgICBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIHRydWUsIHN0YXRlLmxlbmd0aCwgYnVmZmVyLCAnJywgaG9sZGVyLmZpbmlzaCk7XG5cbiAgICAvLyBkb1dyaXRlIGlzIGFsd2F5cyBhc3luYywgZGVmZXIgdGhlc2UgdG8gc2F2ZSBhIGJpdCBvZiB0aW1lXG4gICAgLy8gYXMgdGhlIGhvdCBwYXRoIGVuZHMgd2l0aCBkb1dyaXRlXG4gICAgc3RhdGUucGVuZGluZ2NiKys7XG4gICAgc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdCA9IG51bGw7XG4gICAgc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlID0gaG9sZGVyLm5leHQ7XG4gICAgaG9sZGVyLm5leHQgPSBudWxsO1xuICB9IGVsc2Uge1xuICAgIC8vIFNsb3cgY2FzZSwgd3JpdGUgY2h1bmtzIG9uZS1ieS1vbmVcbiAgICB3aGlsZSAoZW50cnkpIHtcbiAgICAgIHZhciBjaHVuayA9IGVudHJ5LmNodW5rO1xuICAgICAgdmFyIGVuY29kaW5nID0gZW50cnkuZW5jb2Rpbmc7XG4gICAgICB2YXIgY2IgPSBlbnRyeS5jYWxsYmFjaztcbiAgICAgIHZhciBsZW4gPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcblxuICAgICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBmYWxzZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcbiAgICAgIGVudHJ5ID0gZW50cnkubmV4dDtcbiAgICAgIC8vIGlmIHdlIGRpZG4ndCBjYWxsIHRoZSBvbndyaXRlIGltbWVkaWF0ZWx5LCB0aGVuXG4gICAgICAvLyBpdCBtZWFucyB0aGF0IHdlIG5lZWQgdG8gd2FpdCB1bnRpbCBpdCBkb2VzLlxuICAgICAgLy8gYWxzbywgdGhhdCBtZWFucyB0aGF0IHRoZSBjaHVuayBhbmQgY2IgYXJlIGN1cnJlbnRseVxuICAgICAgLy8gYmVpbmcgcHJvY2Vzc2VkLCBzbyBtb3ZlIHRoZSBidWZmZXIgY291bnRlciBwYXN0IHRoZW0uXG4gICAgICBpZiAoc3RhdGUud3JpdGluZykge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZW50cnkgPT09IG51bGwpIHN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3QgPSBudWxsO1xuICB9XG5cbiAgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQgPSAwO1xuICBzdGF0ZS5idWZmZXJlZFJlcXVlc3QgPSBlbnRyeTtcbiAgc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyA9IGZhbHNlO1xufVxuXG5Xcml0YWJsZS5wcm90b3R5cGUuX3dyaXRlID0gZnVuY3Rpb24gKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgY2IobmV3IEVycm9yKCdub3QgaW1wbGVtZW50ZWQnKSk7XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuX3dyaXRldiA9IG51bGw7XG5cbldyaXRhYmxlLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbiAoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuXG4gIGlmICh0eXBlb2YgY2h1bmsgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGNodW5rO1xuICAgIGNodW5rID0gbnVsbDtcbiAgICBlbmNvZGluZyA9IG51bGw7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBlbmNvZGluZztcbiAgICBlbmNvZGluZyA9IG51bGw7XG4gIH1cblxuICBpZiAoY2h1bmsgIT09IG51bGwgJiYgY2h1bmsgIT09IHVuZGVmaW5lZCkgdGhpcy53cml0ZShjaHVuaywgZW5jb2RpbmcpO1xuXG4gIC8vIC5lbmQoKSBmdWxseSB1bmNvcmtzXG4gIGlmIChzdGF0ZS5jb3JrZWQpIHtcbiAgICBzdGF0ZS5jb3JrZWQgPSAxO1xuICAgIHRoaXMudW5jb3JrKCk7XG4gIH1cblxuICAvLyBpZ25vcmUgdW5uZWNlc3NhcnkgZW5kKCkgY2FsbHMuXG4gIGlmICghc3RhdGUuZW5kaW5nICYmICFzdGF0ZS5maW5pc2hlZCkgZW5kV3JpdGFibGUodGhpcywgc3RhdGUsIGNiKTtcbn07XG5cbmZ1bmN0aW9uIG5lZWRGaW5pc2goc3RhdGUpIHtcbiAgcmV0dXJuIHN0YXRlLmVuZGluZyAmJiBzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUuYnVmZmVyZWRSZXF1ZXN0ID09PSBudWxsICYmICFzdGF0ZS5maW5pc2hlZCAmJiAhc3RhdGUud3JpdGluZztcbn1cblxuZnVuY3Rpb24gcHJlZmluaXNoKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5wcmVmaW5pc2hlZCkge1xuICAgIHN0YXRlLnByZWZpbmlzaGVkID0gdHJ1ZTtcbiAgICBzdHJlYW0uZW1pdCgncHJlZmluaXNoJyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSkge1xuICB2YXIgbmVlZCA9IG5lZWRGaW5pc2goc3RhdGUpO1xuICBpZiAobmVlZCkge1xuICAgIGlmIChzdGF0ZS5wZW5kaW5nY2IgPT09IDApIHtcbiAgICAgIHByZWZpbmlzaChzdHJlYW0sIHN0YXRlKTtcbiAgICAgIHN0YXRlLmZpbmlzaGVkID0gdHJ1ZTtcbiAgICAgIHN0cmVhbS5lbWl0KCdmaW5pc2gnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJlZmluaXNoKHN0cmVhbSwgc3RhdGUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbmVlZDtcbn1cblxuZnVuY3Rpb24gZW5kV3JpdGFibGUoc3RyZWFtLCBzdGF0ZSwgY2IpIHtcbiAgc3RhdGUuZW5kaW5nID0gdHJ1ZTtcbiAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG4gIGlmIChjYikge1xuICAgIGlmIChzdGF0ZS5maW5pc2hlZCkgcHJvY2Vzc05leHRUaWNrKGNiKTtlbHNlIHN0cmVhbS5vbmNlKCdmaW5pc2gnLCBjYik7XG4gIH1cbiAgc3RhdGUuZW5kZWQgPSB0cnVlO1xuICBzdHJlYW0ud3JpdGFibGUgPSBmYWxzZTtcbn1cblxuLy8gSXQgc2VlbXMgYSBsaW5rZWQgbGlzdCBidXQgaXQgaXMgbm90XG4vLyB0aGVyZSB3aWxsIGJlIG9ubHkgMiBvZiB0aGVzZSBmb3IgZWFjaCBzdHJlYW1cbmZ1bmN0aW9uIENvcmtlZFJlcXVlc3Qoc3RhdGUpIHtcbiAgdmFyIF90aGlzID0gdGhpcztcblxuICB0aGlzLm5leHQgPSBudWxsO1xuICB0aGlzLmVudHJ5ID0gbnVsbDtcblxuICB0aGlzLmZpbmlzaCA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgICB2YXIgZW50cnkgPSBfdGhpcy5lbnRyeTtcbiAgICBfdGhpcy5lbnRyeSA9IG51bGw7XG4gICAgd2hpbGUgKGVudHJ5KSB7XG4gICAgICB2YXIgY2IgPSBlbnRyeS5jYWxsYmFjaztcbiAgICAgIHN0YXRlLnBlbmRpbmdjYi0tO1xuICAgICAgY2IoZXJyKTtcbiAgICAgIGVudHJ5ID0gZW50cnkubmV4dDtcbiAgICB9XG4gICAgaWYgKHN0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZSkge1xuICAgICAgc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlLm5leHQgPSBfdGhpcztcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlID0gX3RoaXM7XG4gICAgfVxuICB9O1xufSIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanNcIilcbiIsInZhciBTdHJlYW0gPSAoZnVuY3Rpb24gKCl7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHJlcXVpcmUoJ3N0JyArICdyZWFtJyk7IC8vIGhhY2sgdG8gZml4IGEgY2lyY3VsYXIgZGVwZW5kZW5jeSBpc3N1ZSB3aGVuIHVzZWQgd2l0aCBicm93c2VyaWZ5XG4gIH0gY2F0Y2goXyl7fVxufSgpKTtcbmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fcmVhZGFibGUuanMnKTtcbmV4cG9ydHMuU3RyZWFtID0gU3RyZWFtIHx8IGV4cG9ydHM7XG5leHBvcnRzLlJlYWRhYmxlID0gZXhwb3J0cztcbmV4cG9ydHMuV3JpdGFibGUgPSByZXF1aXJlKCcuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzJyk7XG5leHBvcnRzLkR1cGxleCA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fZHVwbGV4LmpzJyk7XG5leHBvcnRzLlRyYW5zZm9ybSA9IHJlcXVpcmUoJy4vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzJyk7XG5leHBvcnRzLlBhc3NUaHJvdWdoID0gcmVxdWlyZSgnLi9saWIvX3N0cmVhbV9wYXNzdGhyb3VnaC5qcycpO1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi9saWIvX3N0cmVhbV90cmFuc2Zvcm0uanNcIilcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vbGliL19zdHJlYW1fd3JpdGFibGUuanNcIilcbiIsIid1c2Ugc3RyaWN0J1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlclxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEhhc2hCYXNlID0gcmVxdWlyZSgnaGFzaC1iYXNlJylcblxudmFyIEFSUkFZMTYgPSBuZXcgQXJyYXkoMTYpXG5cbnZhciB6bCA9IFtcbiAgMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSxcbiAgNywgNCwgMTMsIDEsIDEwLCA2LCAxNSwgMywgMTIsIDAsIDksIDUsIDIsIDE0LCAxMSwgOCxcbiAgMywgMTAsIDE0LCA0LCA5LCAxNSwgOCwgMSwgMiwgNywgMCwgNiwgMTMsIDExLCA1LCAxMixcbiAgMSwgOSwgMTEsIDEwLCAwLCA4LCAxMiwgNCwgMTMsIDMsIDcsIDE1LCAxNCwgNSwgNiwgMixcbiAgNCwgMCwgNSwgOSwgNywgMTIsIDIsIDEwLCAxNCwgMSwgMywgOCwgMTEsIDYsIDE1LCAxM1xuXVxuXG52YXIgenIgPSBbXG4gIDUsIDE0LCA3LCAwLCA5LCAyLCAxMSwgNCwgMTMsIDYsIDE1LCA4LCAxLCAxMCwgMywgMTIsXG4gIDYsIDExLCAzLCA3LCAwLCAxMywgNSwgMTAsIDE0LCAxNSwgOCwgMTIsIDQsIDksIDEsIDIsXG4gIDE1LCA1LCAxLCAzLCA3LCAxNCwgNiwgOSwgMTEsIDgsIDEyLCAyLCAxMCwgMCwgNCwgMTMsXG4gIDgsIDYsIDQsIDEsIDMsIDExLCAxNSwgMCwgNSwgMTIsIDIsIDEzLCA5LCA3LCAxMCwgMTQsXG4gIDEyLCAxNSwgMTAsIDQsIDEsIDUsIDgsIDcsIDYsIDIsIDEzLCAxNCwgMCwgMywgOSwgMTFcbl1cblxudmFyIHNsID0gW1xuICAxMSwgMTQsIDE1LCAxMiwgNSwgOCwgNywgOSwgMTEsIDEzLCAxNCwgMTUsIDYsIDcsIDksIDgsXG4gIDcsIDYsIDgsIDEzLCAxMSwgOSwgNywgMTUsIDcsIDEyLCAxNSwgOSwgMTEsIDcsIDEzLCAxMixcbiAgMTEsIDEzLCA2LCA3LCAxNCwgOSwgMTMsIDE1LCAxNCwgOCwgMTMsIDYsIDUsIDEyLCA3LCA1LFxuICAxMSwgMTIsIDE0LCAxNSwgMTQsIDE1LCA5LCA4LCA5LCAxNCwgNSwgNiwgOCwgNiwgNSwgMTIsXG4gIDksIDE1LCA1LCAxMSwgNiwgOCwgMTMsIDEyLCA1LCAxMiwgMTMsIDE0LCAxMSwgOCwgNSwgNlxuXVxuXG52YXIgc3IgPSBbXG4gIDgsIDksIDksIDExLCAxMywgMTUsIDE1LCA1LCA3LCA3LCA4LCAxMSwgMTQsIDE0LCAxMiwgNixcbiAgOSwgMTMsIDE1LCA3LCAxMiwgOCwgOSwgMTEsIDcsIDcsIDEyLCA3LCA2LCAxNSwgMTMsIDExLFxuICA5LCA3LCAxNSwgMTEsIDgsIDYsIDYsIDE0LCAxMiwgMTMsIDUsIDE0LCAxMywgMTMsIDcsIDUsXG4gIDE1LCA1LCA4LCAxMSwgMTQsIDE0LCA2LCAxNCwgNiwgOSwgMTIsIDksIDEyLCA1LCAxNSwgOCxcbiAgOCwgNSwgMTIsIDksIDEyLCA1LCAxNCwgNiwgOCwgMTMsIDYsIDUsIDE1LCAxMywgMTEsIDExXG5dXG5cbnZhciBobCA9IFsweDAwMDAwMDAwLCAweDVhODI3OTk5LCAweDZlZDllYmExLCAweDhmMWJiY2RjLCAweGE5NTNmZDRlXVxudmFyIGhyID0gWzB4NTBhMjhiZTYsIDB4NWM0ZGQxMjQsIDB4NmQ3MDNlZjMsIDB4N2E2ZDc2ZTksIDB4MDAwMDAwMDBdXG5cbmZ1bmN0aW9uIFJJUEVNRDE2MCAoKSB7XG4gIEhhc2hCYXNlLmNhbGwodGhpcywgNjQpXG5cbiAgLy8gc3RhdGVcbiAgdGhpcy5fYSA9IDB4Njc0NTIzMDFcbiAgdGhpcy5fYiA9IDB4ZWZjZGFiODlcbiAgdGhpcy5fYyA9IDB4OThiYWRjZmVcbiAgdGhpcy5fZCA9IDB4MTAzMjU0NzZcbiAgdGhpcy5fZSA9IDB4YzNkMmUxZjBcbn1cblxuaW5oZXJpdHMoUklQRU1EMTYwLCBIYXNoQmFzZSlcblxuUklQRU1EMTYwLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgd29yZHMgPSBBUlJBWTE2XG4gIGZvciAodmFyIGogPSAwOyBqIDwgMTY7ICsraikgd29yZHNbal0gPSB0aGlzLl9ibG9jay5yZWFkSW50MzJMRShqICogNClcblxuICB2YXIgYWwgPSB0aGlzLl9hIHwgMFxuICB2YXIgYmwgPSB0aGlzLl9iIHwgMFxuICB2YXIgY2wgPSB0aGlzLl9jIHwgMFxuICB2YXIgZGwgPSB0aGlzLl9kIHwgMFxuICB2YXIgZWwgPSB0aGlzLl9lIHwgMFxuXG4gIHZhciBhciA9IHRoaXMuX2EgfCAwXG4gIHZhciBiciA9IHRoaXMuX2IgfCAwXG4gIHZhciBjciA9IHRoaXMuX2MgfCAwXG4gIHZhciBkciA9IHRoaXMuX2QgfCAwXG4gIHZhciBlciA9IHRoaXMuX2UgfCAwXG5cbiAgLy8gY29tcHV0YXRpb25cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA4MDsgaSArPSAxKSB7XG4gICAgdmFyIHRsXG4gICAgdmFyIHRyXG4gICAgaWYgKGkgPCAxNikge1xuICAgICAgdGwgPSBmbjEoYWwsIGJsLCBjbCwgZGwsIGVsLCB3b3Jkc1t6bFtpXV0sIGhsWzBdLCBzbFtpXSlcbiAgICAgIHRyID0gZm41KGFyLCBiciwgY3IsIGRyLCBlciwgd29yZHNbenJbaV1dLCBoclswXSwgc3JbaV0pXG4gICAgfSBlbHNlIGlmIChpIDwgMzIpIHtcbiAgICAgIHRsID0gZm4yKGFsLCBibCwgY2wsIGRsLCBlbCwgd29yZHNbemxbaV1dLCBobFsxXSwgc2xbaV0pXG4gICAgICB0ciA9IGZuNChhciwgYnIsIGNyLCBkciwgZXIsIHdvcmRzW3pyW2ldXSwgaHJbMV0sIHNyW2ldKVxuICAgIH0gZWxzZSBpZiAoaSA8IDQ4KSB7XG4gICAgICB0bCA9IGZuMyhhbCwgYmwsIGNsLCBkbCwgZWwsIHdvcmRzW3psW2ldXSwgaGxbMl0sIHNsW2ldKVxuICAgICAgdHIgPSBmbjMoYXIsIGJyLCBjciwgZHIsIGVyLCB3b3Jkc1t6cltpXV0sIGhyWzJdLCBzcltpXSlcbiAgICB9IGVsc2UgaWYgKGkgPCA2NCkge1xuICAgICAgdGwgPSBmbjQoYWwsIGJsLCBjbCwgZGwsIGVsLCB3b3Jkc1t6bFtpXV0sIGhsWzNdLCBzbFtpXSlcbiAgICAgIHRyID0gZm4yKGFyLCBiciwgY3IsIGRyLCBlciwgd29yZHNbenJbaV1dLCBoclszXSwgc3JbaV0pXG4gICAgfSBlbHNlIHsgLy8gaWYgKGk8ODApIHtcbiAgICAgIHRsID0gZm41KGFsLCBibCwgY2wsIGRsLCBlbCwgd29yZHNbemxbaV1dLCBobFs0XSwgc2xbaV0pXG4gICAgICB0ciA9IGZuMShhciwgYnIsIGNyLCBkciwgZXIsIHdvcmRzW3pyW2ldXSwgaHJbNF0sIHNyW2ldKVxuICAgIH1cblxuICAgIGFsID0gZWxcbiAgICBlbCA9IGRsXG4gICAgZGwgPSByb3RsKGNsLCAxMClcbiAgICBjbCA9IGJsXG4gICAgYmwgPSB0bFxuXG4gICAgYXIgPSBlclxuICAgIGVyID0gZHJcbiAgICBkciA9IHJvdGwoY3IsIDEwKVxuICAgIGNyID0gYnJcbiAgICBiciA9IHRyXG4gIH1cblxuICAvLyB1cGRhdGUgc3RhdGVcbiAgdmFyIHQgPSAodGhpcy5fYiArIGNsICsgZHIpIHwgMFxuICB0aGlzLl9iID0gKHRoaXMuX2MgKyBkbCArIGVyKSB8IDBcbiAgdGhpcy5fYyA9ICh0aGlzLl9kICsgZWwgKyBhcikgfCAwXG4gIHRoaXMuX2QgPSAodGhpcy5fZSArIGFsICsgYnIpIHwgMFxuICB0aGlzLl9lID0gKHRoaXMuX2EgKyBibCArIGNyKSB8IDBcbiAgdGhpcy5fYSA9IHRcbn1cblxuUklQRU1EMTYwLnByb3RvdHlwZS5fZGlnZXN0ID0gZnVuY3Rpb24gKCkge1xuICAvLyBjcmVhdGUgcGFkZGluZyBhbmQgaGFuZGxlIGJsb2Nrc1xuICB0aGlzLl9ibG9ja1t0aGlzLl9ibG9ja09mZnNldCsrXSA9IDB4ODBcbiAgaWYgKHRoaXMuX2Jsb2NrT2Zmc2V0ID4gNTYpIHtcbiAgICB0aGlzLl9ibG9jay5maWxsKDAsIHRoaXMuX2Jsb2NrT2Zmc2V0LCA2NClcbiAgICB0aGlzLl91cGRhdGUoKVxuICAgIHRoaXMuX2Jsb2NrT2Zmc2V0ID0gMFxuICB9XG5cbiAgdGhpcy5fYmxvY2suZmlsbCgwLCB0aGlzLl9ibG9ja09mZnNldCwgNTYpXG4gIHRoaXMuX2Jsb2NrLndyaXRlVUludDMyTEUodGhpcy5fbGVuZ3RoWzBdLCA1NilcbiAgdGhpcy5fYmxvY2sud3JpdGVVSW50MzJMRSh0aGlzLl9sZW5ndGhbMV0sIDYwKVxuICB0aGlzLl91cGRhdGUoKVxuXG4gIC8vIHByb2R1Y2UgcmVzdWx0XG4gIHZhciBidWZmZXIgPSBCdWZmZXIuYWxsb2MgPyBCdWZmZXIuYWxsb2MoMjApIDogbmV3IEJ1ZmZlcigyMClcbiAgYnVmZmVyLndyaXRlSW50MzJMRSh0aGlzLl9hLCAwKVxuICBidWZmZXIud3JpdGVJbnQzMkxFKHRoaXMuX2IsIDQpXG4gIGJ1ZmZlci53cml0ZUludDMyTEUodGhpcy5fYywgOClcbiAgYnVmZmVyLndyaXRlSW50MzJMRSh0aGlzLl9kLCAxMilcbiAgYnVmZmVyLndyaXRlSW50MzJMRSh0aGlzLl9lLCAxNilcbiAgcmV0dXJuIGJ1ZmZlclxufVxuXG5mdW5jdGlvbiByb3RsICh4LCBuKSB7XG4gIHJldHVybiAoeCA8PCBuKSB8ICh4ID4+PiAoMzIgLSBuKSlcbn1cblxuZnVuY3Rpb24gZm4xIChhLCBiLCBjLCBkLCBlLCBtLCBrLCBzKSB7XG4gIHJldHVybiAocm90bCgoYSArIChiIF4gYyBeIGQpICsgbSArIGspIHwgMCwgcykgKyBlKSB8IDBcbn1cblxuZnVuY3Rpb24gZm4yIChhLCBiLCBjLCBkLCBlLCBtLCBrLCBzKSB7XG4gIHJldHVybiAocm90bCgoYSArICgoYiAmIGMpIHwgKCh+YikgJiBkKSkgKyBtICsgaykgfCAwLCBzKSArIGUpIHwgMFxufVxuXG5mdW5jdGlvbiBmbjMgKGEsIGIsIGMsIGQsIGUsIG0sIGssIHMpIHtcbiAgcmV0dXJuIChyb3RsKChhICsgKChiIHwgKH5jKSkgXiBkKSArIG0gKyBrKSB8IDAsIHMpICsgZSkgfCAwXG59XG5cbmZ1bmN0aW9uIGZuNCAoYSwgYiwgYywgZCwgZSwgbSwgaywgcykge1xuICByZXR1cm4gKHJvdGwoKGEgKyAoKGIgJiBkKSB8IChjICYgKH5kKSkpICsgbSArIGspIHwgMCwgcykgKyBlKSB8IDBcbn1cblxuZnVuY3Rpb24gZm41IChhLCBiLCBjLCBkLCBlLCBtLCBrLCBzKSB7XG4gIHJldHVybiAocm90bCgoYSArIChiIF4gKGMgfCAofmQpKSkgKyBtICsgaykgfCAwLCBzKSArIGUpIHwgMFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFJJUEVNRDE2MFxuIiwiOyhmdW5jdGlvbiAoc2F4KSB7IC8vIHdyYXBwZXIgZm9yIG5vbi1ub2RlIGVudnNcbiAgc2F4LnBhcnNlciA9IGZ1bmN0aW9uIChzdHJpY3QsIG9wdCkgeyByZXR1cm4gbmV3IFNBWFBhcnNlcihzdHJpY3QsIG9wdCkgfVxuICBzYXguU0FYUGFyc2VyID0gU0FYUGFyc2VyXG4gIHNheC5TQVhTdHJlYW0gPSBTQVhTdHJlYW1cbiAgc2F4LmNyZWF0ZVN0cmVhbSA9IGNyZWF0ZVN0cmVhbVxuXG4gIC8vIFdoZW4gd2UgcGFzcyB0aGUgTUFYX0JVRkZFUl9MRU5HVEggcG9zaXRpb24sIHN0YXJ0IGNoZWNraW5nIGZvciBidWZmZXIgb3ZlcnJ1bnMuXG4gIC8vIFdoZW4gd2UgY2hlY2ssIHNjaGVkdWxlIHRoZSBuZXh0IGNoZWNrIGZvciBNQVhfQlVGRkVSX0xFTkdUSCAtIChtYXgoYnVmZmVyIGxlbmd0aHMpKSxcbiAgLy8gc2luY2UgdGhhdCdzIHRoZSBlYXJsaWVzdCB0aGF0IGEgYnVmZmVyIG92ZXJydW4gY291bGQgb2NjdXIuICBUaGlzIHdheSwgY2hlY2tzIGFyZVxuICAvLyBhcyByYXJlIGFzIHJlcXVpcmVkLCBidXQgYXMgb2Z0ZW4gYXMgbmVjZXNzYXJ5IHRvIGVuc3VyZSBuZXZlciBjcm9zc2luZyB0aGlzIGJvdW5kLlxuICAvLyBGdXJ0aGVybW9yZSwgYnVmZmVycyBhcmUgb25seSB0ZXN0ZWQgYXQgbW9zdCBvbmNlIHBlciB3cml0ZSgpLCBzbyBwYXNzaW5nIGEgdmVyeVxuICAvLyBsYXJnZSBzdHJpbmcgaW50byB3cml0ZSgpIG1pZ2h0IGhhdmUgdW5kZXNpcmFibGUgZWZmZWN0cywgYnV0IHRoaXMgaXMgbWFuYWdlYWJsZSBieVxuICAvLyB0aGUgY2FsbGVyLCBzbyBpdCBpcyBhc3N1bWVkIHRvIGJlIHNhZmUuICBUaHVzLCBhIGNhbGwgdG8gd3JpdGUoKSBtYXksIGluIHRoZSBleHRyZW1lXG4gIC8vIGVkZ2UgY2FzZSwgcmVzdWx0IGluIGNyZWF0aW5nIGF0IG1vc3Qgb25lIGNvbXBsZXRlIGNvcHkgb2YgdGhlIHN0cmluZyBwYXNzZWQgaW4uXG4gIC8vIFNldCB0byBJbmZpbml0eSB0byBoYXZlIHVubGltaXRlZCBidWZmZXJzLlxuICBzYXguTUFYX0JVRkZFUl9MRU5HVEggPSA2NCAqIDEwMjRcblxuICB2YXIgYnVmZmVycyA9IFtcbiAgICAnY29tbWVudCcsICdzZ21sRGVjbCcsICd0ZXh0Tm9kZScsICd0YWdOYW1lJywgJ2RvY3R5cGUnLFxuICAgICdwcm9jSW5zdE5hbWUnLCAncHJvY0luc3RCb2R5JywgJ2VudGl0eScsICdhdHRyaWJOYW1lJyxcbiAgICAnYXR0cmliVmFsdWUnLCAnY2RhdGEnLCAnc2NyaXB0J1xuICBdXG5cbiAgc2F4LkVWRU5UUyA9IFtcbiAgICAndGV4dCcsXG4gICAgJ3Byb2Nlc3NpbmdpbnN0cnVjdGlvbicsXG4gICAgJ3NnbWxkZWNsYXJhdGlvbicsXG4gICAgJ2RvY3R5cGUnLFxuICAgICdjb21tZW50JyxcbiAgICAnb3BlbnRhZ3N0YXJ0JyxcbiAgICAnYXR0cmlidXRlJyxcbiAgICAnb3BlbnRhZycsXG4gICAgJ2Nsb3NldGFnJyxcbiAgICAnb3BlbmNkYXRhJyxcbiAgICAnY2RhdGEnLFxuICAgICdjbG9zZWNkYXRhJyxcbiAgICAnZXJyb3InLFxuICAgICdlbmQnLFxuICAgICdyZWFkeScsXG4gICAgJ3NjcmlwdCcsXG4gICAgJ29wZW5uYW1lc3BhY2UnLFxuICAgICdjbG9zZW5hbWVzcGFjZSdcbiAgXVxuXG4gIGZ1bmN0aW9uIFNBWFBhcnNlciAoc3RyaWN0LCBvcHQpIHtcbiAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0FYUGFyc2VyKSkge1xuICAgICAgcmV0dXJuIG5ldyBTQVhQYXJzZXIoc3RyaWN0LCBvcHQpXG4gICAgfVxuXG4gICAgdmFyIHBhcnNlciA9IHRoaXNcbiAgICBjbGVhckJ1ZmZlcnMocGFyc2VyKVxuICAgIHBhcnNlci5xID0gcGFyc2VyLmMgPSAnJ1xuICAgIHBhcnNlci5idWZmZXJDaGVja1Bvc2l0aW9uID0gc2F4Lk1BWF9CVUZGRVJfTEVOR1RIXG4gICAgcGFyc2VyLm9wdCA9IG9wdCB8fCB7fVxuICAgIHBhcnNlci5vcHQubG93ZXJjYXNlID0gcGFyc2VyLm9wdC5sb3dlcmNhc2UgfHwgcGFyc2VyLm9wdC5sb3dlcmNhc2V0YWdzXG4gICAgcGFyc2VyLmxvb3NlQ2FzZSA9IHBhcnNlci5vcHQubG93ZXJjYXNlID8gJ3RvTG93ZXJDYXNlJyA6ICd0b1VwcGVyQ2FzZSdcbiAgICBwYXJzZXIudGFncyA9IFtdXG4gICAgcGFyc2VyLmNsb3NlZCA9IHBhcnNlci5jbG9zZWRSb290ID0gcGFyc2VyLnNhd1Jvb3QgPSBmYWxzZVxuICAgIHBhcnNlci50YWcgPSBwYXJzZXIuZXJyb3IgPSBudWxsXG4gICAgcGFyc2VyLnN0cmljdCA9ICEhc3RyaWN0XG4gICAgcGFyc2VyLm5vc2NyaXB0ID0gISEoc3RyaWN0IHx8IHBhcnNlci5vcHQubm9zY3JpcHQpXG4gICAgcGFyc2VyLnN0YXRlID0gUy5CRUdJTlxuICAgIHBhcnNlci5zdHJpY3RFbnRpdGllcyA9IHBhcnNlci5vcHQuc3RyaWN0RW50aXRpZXNcbiAgICBwYXJzZXIuRU5USVRJRVMgPSBwYXJzZXIuc3RyaWN0RW50aXRpZXMgPyBPYmplY3QuY3JlYXRlKHNheC5YTUxfRU5USVRJRVMpIDogT2JqZWN0LmNyZWF0ZShzYXguRU5USVRJRVMpXG4gICAgcGFyc2VyLmF0dHJpYkxpc3QgPSBbXVxuXG4gICAgLy8gbmFtZXNwYWNlcyBmb3JtIGEgcHJvdG90eXBlIGNoYWluLlxuICAgIC8vIGl0IGFsd2F5cyBwb2ludHMgYXQgdGhlIGN1cnJlbnQgdGFnLFxuICAgIC8vIHdoaWNoIHByb3RvcyB0byBpdHMgcGFyZW50IHRhZy5cbiAgICBpZiAocGFyc2VyLm9wdC54bWxucykge1xuICAgICAgcGFyc2VyLm5zID0gT2JqZWN0LmNyZWF0ZShyb290TlMpXG4gICAgfVxuXG4gICAgLy8gbW9zdGx5IGp1c3QgZm9yIGVycm9yIHJlcG9ydGluZ1xuICAgIHBhcnNlci50cmFja1Bvc2l0aW9uID0gcGFyc2VyLm9wdC5wb3NpdGlvbiAhPT0gZmFsc2VcbiAgICBpZiAocGFyc2VyLnRyYWNrUG9zaXRpb24pIHtcbiAgICAgIHBhcnNlci5wb3NpdGlvbiA9IHBhcnNlci5saW5lID0gcGFyc2VyLmNvbHVtbiA9IDBcbiAgICB9XG4gICAgZW1pdChwYXJzZXIsICdvbnJlYWR5JylcbiAgfVxuXG4gIGlmICghT2JqZWN0LmNyZWF0ZSkge1xuICAgIE9iamVjdC5jcmVhdGUgPSBmdW5jdGlvbiAobykge1xuICAgICAgZnVuY3Rpb24gRiAoKSB7fVxuICAgICAgRi5wcm90b3R5cGUgPSBvXG4gICAgICB2YXIgbmV3ZiA9IG5ldyBGKClcbiAgICAgIHJldHVybiBuZXdmXG4gICAgfVxuICB9XG5cbiAgaWYgKCFPYmplY3Qua2V5cykge1xuICAgIE9iamVjdC5rZXlzID0gZnVuY3Rpb24gKG8pIHtcbiAgICAgIHZhciBhID0gW11cbiAgICAgIGZvciAodmFyIGkgaW4gbykgaWYgKG8uaGFzT3duUHJvcGVydHkoaSkpIGEucHVzaChpKVxuICAgICAgcmV0dXJuIGFcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjaGVja0J1ZmZlckxlbmd0aCAocGFyc2VyKSB7XG4gICAgdmFyIG1heEFsbG93ZWQgPSBNYXRoLm1heChzYXguTUFYX0JVRkZFUl9MRU5HVEgsIDEwKVxuICAgIHZhciBtYXhBY3R1YWwgPSAwXG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSBidWZmZXJzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgdmFyIGxlbiA9IHBhcnNlcltidWZmZXJzW2ldXS5sZW5ndGhcbiAgICAgIGlmIChsZW4gPiBtYXhBbGxvd2VkKSB7XG4gICAgICAgIC8vIFRleHQvY2RhdGEgbm9kZXMgY2FuIGdldCBiaWcsIGFuZCBzaW5jZSB0aGV5J3JlIGJ1ZmZlcmVkLFxuICAgICAgICAvLyB3ZSBjYW4gZ2V0IGhlcmUgdW5kZXIgbm9ybWFsIGNvbmRpdGlvbnMuXG4gICAgICAgIC8vIEF2b2lkIGlzc3VlcyBieSBlbWl0dGluZyB0aGUgdGV4dCBub2RlIG5vdyxcbiAgICAgICAgLy8gc28gYXQgbGVhc3QgaXQgd29uJ3QgZ2V0IGFueSBiaWdnZXIuXG4gICAgICAgIHN3aXRjaCAoYnVmZmVyc1tpXSkge1xuICAgICAgICAgIGNhc2UgJ3RleHROb2RlJzpcbiAgICAgICAgICAgIGNsb3NlVGV4dChwYXJzZXIpXG4gICAgICAgICAgICBicmVha1xuXG4gICAgICAgICAgY2FzZSAnY2RhdGEnOlxuICAgICAgICAgICAgZW1pdE5vZGUocGFyc2VyLCAnb25jZGF0YScsIHBhcnNlci5jZGF0YSlcbiAgICAgICAgICAgIHBhcnNlci5jZGF0YSA9ICcnXG4gICAgICAgICAgICBicmVha1xuXG4gICAgICAgICAgY2FzZSAnc2NyaXB0JzpcbiAgICAgICAgICAgIGVtaXROb2RlKHBhcnNlciwgJ29uc2NyaXB0JywgcGFyc2VyLnNjcmlwdClcbiAgICAgICAgICAgIHBhcnNlci5zY3JpcHQgPSAnJ1xuICAgICAgICAgICAgYnJlYWtcblxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBlcnJvcihwYXJzZXIsICdNYXggYnVmZmVyIGxlbmd0aCBleGNlZWRlZDogJyArIGJ1ZmZlcnNbaV0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIG1heEFjdHVhbCA9IE1hdGgubWF4KG1heEFjdHVhbCwgbGVuKVxuICAgIH1cbiAgICAvLyBzY2hlZHVsZSB0aGUgbmV4dCBjaGVjayBmb3IgdGhlIGVhcmxpZXN0IHBvc3NpYmxlIGJ1ZmZlciBvdmVycnVuLlxuICAgIHZhciBtID0gc2F4Lk1BWF9CVUZGRVJfTEVOR1RIIC0gbWF4QWN0dWFsXG4gICAgcGFyc2VyLmJ1ZmZlckNoZWNrUG9zaXRpb24gPSBtICsgcGFyc2VyLnBvc2l0aW9uXG4gIH1cblxuICBmdW5jdGlvbiBjbGVhckJ1ZmZlcnMgKHBhcnNlcikge1xuICAgIGZvciAodmFyIGkgPSAwLCBsID0gYnVmZmVycy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIHBhcnNlcltidWZmZXJzW2ldXSA9ICcnXG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZmx1c2hCdWZmZXJzIChwYXJzZXIpIHtcbiAgICBjbG9zZVRleHQocGFyc2VyKVxuICAgIGlmIChwYXJzZXIuY2RhdGEgIT09ICcnKSB7XG4gICAgICBlbWl0Tm9kZShwYXJzZXIsICdvbmNkYXRhJywgcGFyc2VyLmNkYXRhKVxuICAgICAgcGFyc2VyLmNkYXRhID0gJydcbiAgICB9XG4gICAgaWYgKHBhcnNlci5zY3JpcHQgIT09ICcnKSB7XG4gICAgICBlbWl0Tm9kZShwYXJzZXIsICdvbnNjcmlwdCcsIHBhcnNlci5zY3JpcHQpXG4gICAgICBwYXJzZXIuc2NyaXB0ID0gJydcbiAgICB9XG4gIH1cblxuICBTQVhQYXJzZXIucHJvdG90eXBlID0ge1xuICAgIGVuZDogZnVuY3Rpb24gKCkgeyBlbmQodGhpcykgfSxcbiAgICB3cml0ZTogd3JpdGUsXG4gICAgcmVzdW1lOiBmdW5jdGlvbiAoKSB7IHRoaXMuZXJyb3IgPSBudWxsOyByZXR1cm4gdGhpcyB9LFxuICAgIGNsb3NlOiBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLndyaXRlKG51bGwpIH0sXG4gICAgZmx1c2g6IGZ1bmN0aW9uICgpIHsgZmx1c2hCdWZmZXJzKHRoaXMpIH1cbiAgfVxuXG4gIHZhciBTdHJlYW1cbiAgdHJ5IHtcbiAgICBTdHJlYW0gPSByZXF1aXJlKCdzdHJlYW0nKS5TdHJlYW1cbiAgfSBjYXRjaCAoZXgpIHtcbiAgICBTdHJlYW0gPSBmdW5jdGlvbiAoKSB7fVxuICB9XG5cbiAgdmFyIHN0cmVhbVdyYXBzID0gc2F4LkVWRU5UUy5maWx0ZXIoZnVuY3Rpb24gKGV2KSB7XG4gICAgcmV0dXJuIGV2ICE9PSAnZXJyb3InICYmIGV2ICE9PSAnZW5kJ1xuICB9KVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZVN0cmVhbSAoc3RyaWN0LCBvcHQpIHtcbiAgICByZXR1cm4gbmV3IFNBWFN0cmVhbShzdHJpY3QsIG9wdClcbiAgfVxuXG4gIGZ1bmN0aW9uIFNBWFN0cmVhbSAoc3RyaWN0LCBvcHQpIHtcbiAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU0FYU3RyZWFtKSkge1xuICAgICAgcmV0dXJuIG5ldyBTQVhTdHJlYW0oc3RyaWN0LCBvcHQpXG4gICAgfVxuXG4gICAgU3RyZWFtLmFwcGx5KHRoaXMpXG5cbiAgICB0aGlzLl9wYXJzZXIgPSBuZXcgU0FYUGFyc2VyKHN0cmljdCwgb3B0KVxuICAgIHRoaXMud3JpdGFibGUgPSB0cnVlXG4gICAgdGhpcy5yZWFkYWJsZSA9IHRydWVcblxuICAgIHZhciBtZSA9IHRoaXNcblxuICAgIHRoaXMuX3BhcnNlci5vbmVuZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIG1lLmVtaXQoJ2VuZCcpXG4gICAgfVxuXG4gICAgdGhpcy5fcGFyc2VyLm9uZXJyb3IgPSBmdW5jdGlvbiAoZXIpIHtcbiAgICAgIG1lLmVtaXQoJ2Vycm9yJywgZXIpXG5cbiAgICAgIC8vIGlmIGRpZG4ndCB0aHJvdywgdGhlbiBtZWFucyBlcnJvciB3YXMgaGFuZGxlZC5cbiAgICAgIC8vIGdvIGFoZWFkIGFuZCBjbGVhciBlcnJvciwgc28gd2UgY2FuIHdyaXRlIGFnYWluLlxuICAgICAgbWUuX3BhcnNlci5lcnJvciA9IG51bGxcbiAgICB9XG5cbiAgICB0aGlzLl9kZWNvZGVyID0gbnVsbFxuXG4gICAgc3RyZWFtV3JhcHMuZm9yRWFjaChmdW5jdGlvbiAoZXYpIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtZSwgJ29uJyArIGV2LCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiBtZS5fcGFyc2VyWydvbicgKyBldl1cbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbiAoaCkge1xuICAgICAgICAgIGlmICghaCkge1xuICAgICAgICAgICAgbWUucmVtb3ZlQWxsTGlzdGVuZXJzKGV2KVxuICAgICAgICAgICAgbWUuX3BhcnNlclsnb24nICsgZXZdID0gaFxuICAgICAgICAgICAgcmV0dXJuIGhcbiAgICAgICAgICB9XG4gICAgICAgICAgbWUub24oZXYsIGgpXG4gICAgICAgIH0sXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2VcbiAgICAgIH0pXG4gICAgfSlcbiAgfVxuXG4gIFNBWFN0cmVhbS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKFN0cmVhbS5wcm90b3R5cGUsIHtcbiAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgdmFsdWU6IFNBWFN0cmVhbVxuICAgIH1cbiAgfSlcblxuICBTQVhTdHJlYW0ucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICBpZiAodHlwZW9mIEJ1ZmZlciA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgdHlwZW9mIEJ1ZmZlci5pc0J1ZmZlciA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgQnVmZmVyLmlzQnVmZmVyKGRhdGEpKSB7XG4gICAgICBpZiAoIXRoaXMuX2RlY29kZXIpIHtcbiAgICAgICAgdmFyIFNEID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXInKS5TdHJpbmdEZWNvZGVyXG4gICAgICAgIHRoaXMuX2RlY29kZXIgPSBuZXcgU0QoJ3V0ZjgnKVxuICAgICAgfVxuICAgICAgZGF0YSA9IHRoaXMuX2RlY29kZXIud3JpdGUoZGF0YSlcbiAgICB9XG5cbiAgICB0aGlzLl9wYXJzZXIud3JpdGUoZGF0YS50b1N0cmluZygpKVxuICAgIHRoaXMuZW1pdCgnZGF0YScsIGRhdGEpXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIFNBWFN0cmVhbS5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgaWYgKGNodW5rICYmIGNodW5rLmxlbmd0aCkge1xuICAgICAgdGhpcy53cml0ZShjaHVuaylcbiAgICB9XG4gICAgdGhpcy5fcGFyc2VyLmVuZCgpXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIFNBWFN0cmVhbS5wcm90b3R5cGUub24gPSBmdW5jdGlvbiAoZXYsIGhhbmRsZXIpIHtcbiAgICB2YXIgbWUgPSB0aGlzXG4gICAgaWYgKCFtZS5fcGFyc2VyWydvbicgKyBldl0gJiYgc3RyZWFtV3JhcHMuaW5kZXhPZihldikgIT09IC0xKSB7XG4gICAgICBtZS5fcGFyc2VyWydvbicgKyBldl0gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzLmxlbmd0aCA9PT0gMSA/IFthcmd1bWVudHNbMF1dIDogQXJyYXkuYXBwbHkobnVsbCwgYXJndW1lbnRzKVxuICAgICAgICBhcmdzLnNwbGljZSgwLCAwLCBldilcbiAgICAgICAgbWUuZW1pdC5hcHBseShtZSwgYXJncylcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gU3RyZWFtLnByb3RvdHlwZS5vbi5jYWxsKG1lLCBldiwgaGFuZGxlcilcbiAgfVxuXG4gIC8vIHRoaXMgcmVhbGx5IG5lZWRzIHRvIGJlIHJlcGxhY2VkIHdpdGggY2hhcmFjdGVyIGNsYXNzZXMuXG4gIC8vIFhNTCBhbGxvd3MgYWxsIG1hbm5lciBvZiByaWRpY3Vsb3VzIG51bWJlcnMgYW5kIGRpZ2l0cy5cbiAgdmFyIENEQVRBID0gJ1tDREFUQVsnXG4gIHZhciBET0NUWVBFID0gJ0RPQ1RZUEUnXG4gIHZhciBYTUxfTkFNRVNQQUNFID0gJ2h0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZSdcbiAgdmFyIFhNTE5TX05BTUVTUEFDRSA9ICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLydcbiAgdmFyIHJvb3ROUyA9IHsgeG1sOiBYTUxfTkFNRVNQQUNFLCB4bWxuczogWE1MTlNfTkFNRVNQQUNFIH1cblxuICAvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLyNOVC1OYW1lU3RhcnRDaGFyXG4gIC8vIFRoaXMgaW1wbGVtZW50YXRpb24gd29ya3Mgb24gc3RyaW5ncywgYSBzaW5nbGUgY2hhcmFjdGVyIGF0IGEgdGltZVxuICAvLyBhcyBzdWNoLCBpdCBjYW5ub3QgZXZlciBzdXBwb3J0IGFzdHJhbC1wbGFuZSBjaGFyYWN0ZXJzICgxMDAwMC1FRkZGRilcbiAgLy8gd2l0aG91dCBhIHNpZ25pZmljYW50IGJyZWFraW5nIGNoYW5nZSB0byBlaXRoZXIgdGhpcyAgcGFyc2VyLCBvciB0aGVcbiAgLy8gSmF2YVNjcmlwdCBsYW5ndWFnZS4gIEltcGxlbWVudGF0aW9uIG9mIGFuIGVtb2ppLWNhcGFibGUgeG1sIHBhcnNlclxuICAvLyBpcyBsZWZ0IGFzIGFuIGV4ZXJjaXNlIGZvciB0aGUgcmVhZGVyLlxuICB2YXIgbmFtZVN0YXJ0ID0gL1s6X0EtWmEtelxcdTAwQzAtXFx1MDBENlxcdTAwRDgtXFx1MDBGNlxcdTAwRjgtXFx1MDJGRlxcdTAzNzAtXFx1MDM3RFxcdTAzN0YtXFx1MUZGRlxcdTIwMEMtXFx1MjAwRFxcdTIwNzAtXFx1MjE4RlxcdTJDMDAtXFx1MkZFRlxcdTMwMDEtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZGRF0vXG5cbiAgdmFyIG5hbWVCb2R5ID0gL1s6X0EtWmEtelxcdTAwQzAtXFx1MDBENlxcdTAwRDgtXFx1MDBGNlxcdTAwRjgtXFx1MDJGRlxcdTAzNzAtXFx1MDM3RFxcdTAzN0YtXFx1MUZGRlxcdTIwMEMtXFx1MjAwRFxcdTIwNzAtXFx1MjE4RlxcdTJDMDAtXFx1MkZFRlxcdTMwMDEtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZGRFxcdTAwQjdcXHUwMzAwLVxcdTAzNkZcXHUyMDNGLVxcdTIwNDAuXFxkLV0vXG5cbiAgdmFyIGVudGl0eVN0YXJ0ID0gL1sjOl9BLVphLXpcXHUwMEMwLVxcdTAwRDZcXHUwMEQ4LVxcdTAwRjZcXHUwMEY4LVxcdTAyRkZcXHUwMzcwLVxcdTAzN0RcXHUwMzdGLVxcdTFGRkZcXHUyMDBDLVxcdTIwMERcXHUyMDcwLVxcdTIxOEZcXHUyQzAwLVxcdTJGRUZcXHUzMDAxLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRkRdL1xuICB2YXIgZW50aXR5Qm9keSA9IC9bIzpfQS1aYS16XFx1MDBDMC1cXHUwMEQ2XFx1MDBEOC1cXHUwMEY2XFx1MDBGOC1cXHUwMkZGXFx1MDM3MC1cXHUwMzdEXFx1MDM3Ri1cXHUxRkZGXFx1MjAwQy1cXHUyMDBEXFx1MjA3MC1cXHUyMThGXFx1MkMwMC1cXHUyRkVGXFx1MzAwMS1cXHVEN0ZGXFx1RjkwMC1cXHVGRENGXFx1RkRGMC1cXHVGRkZEXFx1MDBCN1xcdTAzMDAtXFx1MDM2RlxcdTIwM0YtXFx1MjA0MC5cXGQtXS9cblxuICBmdW5jdGlvbiBpc1doaXRlc3BhY2UgKGMpIHtcbiAgICByZXR1cm4gYyA9PT0gJyAnIHx8IGMgPT09ICdcXG4nIHx8IGMgPT09ICdcXHInIHx8IGMgPT09ICdcXHQnXG4gIH1cblxuICBmdW5jdGlvbiBpc1F1b3RlIChjKSB7XG4gICAgcmV0dXJuIGMgPT09ICdcIicgfHwgYyA9PT0gJ1xcJydcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzQXR0cmliRW5kIChjKSB7XG4gICAgcmV0dXJuIGMgPT09ICc+JyB8fCBpc1doaXRlc3BhY2UoYylcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzTWF0Y2ggKHJlZ2V4LCBjKSB7XG4gICAgcmV0dXJuIHJlZ2V4LnRlc3QoYylcbiAgfVxuXG4gIGZ1bmN0aW9uIG5vdE1hdGNoIChyZWdleCwgYykge1xuICAgIHJldHVybiAhaXNNYXRjaChyZWdleCwgYylcbiAgfVxuXG4gIHZhciBTID0gMFxuICBzYXguU1RBVEUgPSB7XG4gICAgQkVHSU46IFMrKywgLy8gbGVhZGluZyBieXRlIG9yZGVyIG1hcmsgb3Igd2hpdGVzcGFjZVxuICAgIEJFR0lOX1dISVRFU1BBQ0U6IFMrKywgLy8gbGVhZGluZyB3aGl0ZXNwYWNlXG4gICAgVEVYVDogUysrLCAvLyBnZW5lcmFsIHN0dWZmXG4gICAgVEVYVF9FTlRJVFk6IFMrKywgLy8gJmFtcCBhbmQgc3VjaC5cbiAgICBPUEVOX1dBS0E6IFMrKywgLy8gPFxuICAgIFNHTUxfREVDTDogUysrLCAvLyA8IUJMQVJHXG4gICAgU0dNTF9ERUNMX1FVT1RFRDogUysrLCAvLyA8IUJMQVJHIGZvbyBcImJhclxuICAgIERPQ1RZUEU6IFMrKywgLy8gPCFET0NUWVBFXG4gICAgRE9DVFlQRV9RVU9URUQ6IFMrKywgLy8gPCFET0NUWVBFIFwiLy9ibGFoXG4gICAgRE9DVFlQRV9EVEQ6IFMrKywgLy8gPCFET0NUWVBFIFwiLy9ibGFoXCIgWyAuLi5cbiAgICBET0NUWVBFX0RURF9RVU9URUQ6IFMrKywgLy8gPCFET0NUWVBFIFwiLy9ibGFoXCIgWyBcImZvb1xuICAgIENPTU1FTlRfU1RBUlRJTkc6IFMrKywgLy8gPCEtXG4gICAgQ09NTUVOVDogUysrLCAvLyA8IS0tXG4gICAgQ09NTUVOVF9FTkRJTkc6IFMrKywgLy8gPCEtLSBibGFoIC1cbiAgICBDT01NRU5UX0VOREVEOiBTKyssIC8vIDwhLS0gYmxhaCAtLVxuICAgIENEQVRBOiBTKyssIC8vIDwhW0NEQVRBWyBzb21ldGhpbmdcbiAgICBDREFUQV9FTkRJTkc6IFMrKywgLy8gXVxuICAgIENEQVRBX0VORElOR18yOiBTKyssIC8vIF1dXG4gICAgUFJPQ19JTlNUOiBTKyssIC8vIDw/aGlcbiAgICBQUk9DX0lOU1RfQk9EWTogUysrLCAvLyA8P2hpIHRoZXJlXG4gICAgUFJPQ19JTlNUX0VORElORzogUysrLCAvLyA8P2hpIFwidGhlcmVcIiA/XG4gICAgT1BFTl9UQUc6IFMrKywgLy8gPHN0cm9uZ1xuICAgIE9QRU5fVEFHX1NMQVNIOiBTKyssIC8vIDxzdHJvbmcgL1xuICAgIEFUVFJJQjogUysrLCAvLyA8YVxuICAgIEFUVFJJQl9OQU1FOiBTKyssIC8vIDxhIGZvb1xuICAgIEFUVFJJQl9OQU1FX1NBV19XSElURTogUysrLCAvLyA8YSBmb28gX1xuICAgIEFUVFJJQl9WQUxVRTogUysrLCAvLyA8YSBmb289XG4gICAgQVRUUklCX1ZBTFVFX1FVT1RFRDogUysrLCAvLyA8YSBmb289XCJiYXJcbiAgICBBVFRSSUJfVkFMVUVfQ0xPU0VEOiBTKyssIC8vIDxhIGZvbz1cImJhclwiXG4gICAgQVRUUklCX1ZBTFVFX1VOUVVPVEVEOiBTKyssIC8vIDxhIGZvbz1iYXJcbiAgICBBVFRSSUJfVkFMVUVfRU5USVRZX1E6IFMrKywgLy8gPGZvbyBiYXI9XCImcXVvdDtcIlxuICAgIEFUVFJJQl9WQUxVRV9FTlRJVFlfVTogUysrLCAvLyA8Zm9vIGJhcj0mcXVvdFxuICAgIENMT1NFX1RBRzogUysrLCAvLyA8L2FcbiAgICBDTE9TRV9UQUdfU0FXX1dISVRFOiBTKyssIC8vIDwvYSAgID5cbiAgICBTQ1JJUFQ6IFMrKywgLy8gPHNjcmlwdD4gLi4uXG4gICAgU0NSSVBUX0VORElORzogUysrIC8vIDxzY3JpcHQ+IC4uLiA8XG4gIH1cblxuICBzYXguWE1MX0VOVElUSUVTID0ge1xuICAgICdhbXAnOiAnJicsXG4gICAgJ2d0JzogJz4nLFxuICAgICdsdCc6ICc8JyxcbiAgICAncXVvdCc6ICdcIicsXG4gICAgJ2Fwb3MnOiBcIidcIlxuICB9XG5cbiAgc2F4LkVOVElUSUVTID0ge1xuICAgICdhbXAnOiAnJicsXG4gICAgJ2d0JzogJz4nLFxuICAgICdsdCc6ICc8JyxcbiAgICAncXVvdCc6ICdcIicsXG4gICAgJ2Fwb3MnOiBcIidcIixcbiAgICAnQUVsaWcnOiAxOTgsXG4gICAgJ0FhY3V0ZSc6IDE5MyxcbiAgICAnQWNpcmMnOiAxOTQsXG4gICAgJ0FncmF2ZSc6IDE5MixcbiAgICAnQXJpbmcnOiAxOTcsXG4gICAgJ0F0aWxkZSc6IDE5NSxcbiAgICAnQXVtbCc6IDE5NixcbiAgICAnQ2NlZGlsJzogMTk5LFxuICAgICdFVEgnOiAyMDgsXG4gICAgJ0VhY3V0ZSc6IDIwMSxcbiAgICAnRWNpcmMnOiAyMDIsXG4gICAgJ0VncmF2ZSc6IDIwMCxcbiAgICAnRXVtbCc6IDIwMyxcbiAgICAnSWFjdXRlJzogMjA1LFxuICAgICdJY2lyYyc6IDIwNixcbiAgICAnSWdyYXZlJzogMjA0LFxuICAgICdJdW1sJzogMjA3LFxuICAgICdOdGlsZGUnOiAyMDksXG4gICAgJ09hY3V0ZSc6IDIxMSxcbiAgICAnT2NpcmMnOiAyMTIsXG4gICAgJ09ncmF2ZSc6IDIxMCxcbiAgICAnT3NsYXNoJzogMjE2LFxuICAgICdPdGlsZGUnOiAyMTMsXG4gICAgJ091bWwnOiAyMTQsXG4gICAgJ1RIT1JOJzogMjIyLFxuICAgICdVYWN1dGUnOiAyMTgsXG4gICAgJ1VjaXJjJzogMjE5LFxuICAgICdVZ3JhdmUnOiAyMTcsXG4gICAgJ1V1bWwnOiAyMjAsXG4gICAgJ1lhY3V0ZSc6IDIyMSxcbiAgICAnYWFjdXRlJzogMjI1LFxuICAgICdhY2lyYyc6IDIyNixcbiAgICAnYWVsaWcnOiAyMzAsXG4gICAgJ2FncmF2ZSc6IDIyNCxcbiAgICAnYXJpbmcnOiAyMjksXG4gICAgJ2F0aWxkZSc6IDIyNyxcbiAgICAnYXVtbCc6IDIyOCxcbiAgICAnY2NlZGlsJzogMjMxLFxuICAgICdlYWN1dGUnOiAyMzMsXG4gICAgJ2VjaXJjJzogMjM0LFxuICAgICdlZ3JhdmUnOiAyMzIsXG4gICAgJ2V0aCc6IDI0MCxcbiAgICAnZXVtbCc6IDIzNSxcbiAgICAnaWFjdXRlJzogMjM3LFxuICAgICdpY2lyYyc6IDIzOCxcbiAgICAnaWdyYXZlJzogMjM2LFxuICAgICdpdW1sJzogMjM5LFxuICAgICdudGlsZGUnOiAyNDEsXG4gICAgJ29hY3V0ZSc6IDI0MyxcbiAgICAnb2NpcmMnOiAyNDQsXG4gICAgJ29ncmF2ZSc6IDI0MixcbiAgICAnb3NsYXNoJzogMjQ4LFxuICAgICdvdGlsZGUnOiAyNDUsXG4gICAgJ291bWwnOiAyNDYsXG4gICAgJ3N6bGlnJzogMjIzLFxuICAgICd0aG9ybic6IDI1NCxcbiAgICAndWFjdXRlJzogMjUwLFxuICAgICd1Y2lyYyc6IDI1MSxcbiAgICAndWdyYXZlJzogMjQ5LFxuICAgICd1dW1sJzogMjUyLFxuICAgICd5YWN1dGUnOiAyNTMsXG4gICAgJ3l1bWwnOiAyNTUsXG4gICAgJ2NvcHknOiAxNjksXG4gICAgJ3JlZyc6IDE3NCxcbiAgICAnbmJzcCc6IDE2MCxcbiAgICAnaWV4Y2wnOiAxNjEsXG4gICAgJ2NlbnQnOiAxNjIsXG4gICAgJ3BvdW5kJzogMTYzLFxuICAgICdjdXJyZW4nOiAxNjQsXG4gICAgJ3llbic6IDE2NSxcbiAgICAnYnJ2YmFyJzogMTY2LFxuICAgICdzZWN0JzogMTY3LFxuICAgICd1bWwnOiAxNjgsXG4gICAgJ29yZGYnOiAxNzAsXG4gICAgJ2xhcXVvJzogMTcxLFxuICAgICdub3QnOiAxNzIsXG4gICAgJ3NoeSc6IDE3MyxcbiAgICAnbWFjcic6IDE3NSxcbiAgICAnZGVnJzogMTc2LFxuICAgICdwbHVzbW4nOiAxNzcsXG4gICAgJ3N1cDEnOiAxODUsXG4gICAgJ3N1cDInOiAxNzgsXG4gICAgJ3N1cDMnOiAxNzksXG4gICAgJ2FjdXRlJzogMTgwLFxuICAgICdtaWNybyc6IDE4MSxcbiAgICAncGFyYSc6IDE4MixcbiAgICAnbWlkZG90JzogMTgzLFxuICAgICdjZWRpbCc6IDE4NCxcbiAgICAnb3JkbSc6IDE4NixcbiAgICAncmFxdW8nOiAxODcsXG4gICAgJ2ZyYWMxNCc6IDE4OCxcbiAgICAnZnJhYzEyJzogMTg5LFxuICAgICdmcmFjMzQnOiAxOTAsXG4gICAgJ2lxdWVzdCc6IDE5MSxcbiAgICAndGltZXMnOiAyMTUsXG4gICAgJ2RpdmlkZSc6IDI0NyxcbiAgICAnT0VsaWcnOiAzMzgsXG4gICAgJ29lbGlnJzogMzM5LFxuICAgICdTY2Fyb24nOiAzNTIsXG4gICAgJ3NjYXJvbic6IDM1MyxcbiAgICAnWXVtbCc6IDM3NixcbiAgICAnZm5vZic6IDQwMixcbiAgICAnY2lyYyc6IDcxMCxcbiAgICAndGlsZGUnOiA3MzIsXG4gICAgJ0FscGhhJzogOTEzLFxuICAgICdCZXRhJzogOTE0LFxuICAgICdHYW1tYSc6IDkxNSxcbiAgICAnRGVsdGEnOiA5MTYsXG4gICAgJ0Vwc2lsb24nOiA5MTcsXG4gICAgJ1pldGEnOiA5MTgsXG4gICAgJ0V0YSc6IDkxOSxcbiAgICAnVGhldGEnOiA5MjAsXG4gICAgJ0lvdGEnOiA5MjEsXG4gICAgJ0thcHBhJzogOTIyLFxuICAgICdMYW1iZGEnOiA5MjMsXG4gICAgJ011JzogOTI0LFxuICAgICdOdSc6IDkyNSxcbiAgICAnWGknOiA5MjYsXG4gICAgJ09taWNyb24nOiA5MjcsXG4gICAgJ1BpJzogOTI4LFxuICAgICdSaG8nOiA5MjksXG4gICAgJ1NpZ21hJzogOTMxLFxuICAgICdUYXUnOiA5MzIsXG4gICAgJ1Vwc2lsb24nOiA5MzMsXG4gICAgJ1BoaSc6IDkzNCxcbiAgICAnQ2hpJzogOTM1LFxuICAgICdQc2knOiA5MzYsXG4gICAgJ09tZWdhJzogOTM3LFxuICAgICdhbHBoYSc6IDk0NSxcbiAgICAnYmV0YSc6IDk0NixcbiAgICAnZ2FtbWEnOiA5NDcsXG4gICAgJ2RlbHRhJzogOTQ4LFxuICAgICdlcHNpbG9uJzogOTQ5LFxuICAgICd6ZXRhJzogOTUwLFxuICAgICdldGEnOiA5NTEsXG4gICAgJ3RoZXRhJzogOTUyLFxuICAgICdpb3RhJzogOTUzLFxuICAgICdrYXBwYSc6IDk1NCxcbiAgICAnbGFtYmRhJzogOTU1LFxuICAgICdtdSc6IDk1NixcbiAgICAnbnUnOiA5NTcsXG4gICAgJ3hpJzogOTU4LFxuICAgICdvbWljcm9uJzogOTU5LFxuICAgICdwaSc6IDk2MCxcbiAgICAncmhvJzogOTYxLFxuICAgICdzaWdtYWYnOiA5NjIsXG4gICAgJ3NpZ21hJzogOTYzLFxuICAgICd0YXUnOiA5NjQsXG4gICAgJ3Vwc2lsb24nOiA5NjUsXG4gICAgJ3BoaSc6IDk2NixcbiAgICAnY2hpJzogOTY3LFxuICAgICdwc2knOiA5NjgsXG4gICAgJ29tZWdhJzogOTY5LFxuICAgICd0aGV0YXN5bSc6IDk3NyxcbiAgICAndXBzaWgnOiA5NzgsXG4gICAgJ3Bpdic6IDk4MixcbiAgICAnZW5zcCc6IDgxOTQsXG4gICAgJ2Vtc3AnOiA4MTk1LFxuICAgICd0aGluc3AnOiA4MjAxLFxuICAgICd6d25qJzogODIwNCxcbiAgICAnendqJzogODIwNSxcbiAgICAnbHJtJzogODIwNixcbiAgICAncmxtJzogODIwNyxcbiAgICAnbmRhc2gnOiA4MjExLFxuICAgICdtZGFzaCc6IDgyMTIsXG4gICAgJ2xzcXVvJzogODIxNixcbiAgICAncnNxdW8nOiA4MjE3LFxuICAgICdzYnF1byc6IDgyMTgsXG4gICAgJ2xkcXVvJzogODIyMCxcbiAgICAncmRxdW8nOiA4MjIxLFxuICAgICdiZHF1byc6IDgyMjIsXG4gICAgJ2RhZ2dlcic6IDgyMjQsXG4gICAgJ0RhZ2dlcic6IDgyMjUsXG4gICAgJ2J1bGwnOiA4MjI2LFxuICAgICdoZWxsaXAnOiA4MjMwLFxuICAgICdwZXJtaWwnOiA4MjQwLFxuICAgICdwcmltZSc6IDgyNDIsXG4gICAgJ1ByaW1lJzogODI0MyxcbiAgICAnbHNhcXVvJzogODI0OSxcbiAgICAncnNhcXVvJzogODI1MCxcbiAgICAnb2xpbmUnOiA4MjU0LFxuICAgICdmcmFzbCc6IDgyNjAsXG4gICAgJ2V1cm8nOiA4MzY0LFxuICAgICdpbWFnZSc6IDg0NjUsXG4gICAgJ3dlaWVycCc6IDg0NzIsXG4gICAgJ3JlYWwnOiA4NDc2LFxuICAgICd0cmFkZSc6IDg0ODIsXG4gICAgJ2FsZWZzeW0nOiA4NTAxLFxuICAgICdsYXJyJzogODU5MixcbiAgICAndWFycic6IDg1OTMsXG4gICAgJ3JhcnInOiA4NTk0LFxuICAgICdkYXJyJzogODU5NSxcbiAgICAnaGFycic6IDg1OTYsXG4gICAgJ2NyYXJyJzogODYyOSxcbiAgICAnbEFycic6IDg2NTYsXG4gICAgJ3VBcnInOiA4NjU3LFxuICAgICdyQXJyJzogODY1OCxcbiAgICAnZEFycic6IDg2NTksXG4gICAgJ2hBcnInOiA4NjYwLFxuICAgICdmb3JhbGwnOiA4NzA0LFxuICAgICdwYXJ0JzogODcwNixcbiAgICAnZXhpc3QnOiA4NzA3LFxuICAgICdlbXB0eSc6IDg3MDksXG4gICAgJ25hYmxhJzogODcxMSxcbiAgICAnaXNpbic6IDg3MTIsXG4gICAgJ25vdGluJzogODcxMyxcbiAgICAnbmknOiA4NzE1LFxuICAgICdwcm9kJzogODcxOSxcbiAgICAnc3VtJzogODcyMSxcbiAgICAnbWludXMnOiA4NzIyLFxuICAgICdsb3dhc3QnOiA4NzI3LFxuICAgICdyYWRpYyc6IDg3MzAsXG4gICAgJ3Byb3AnOiA4NzMzLFxuICAgICdpbmZpbic6IDg3MzQsXG4gICAgJ2FuZyc6IDg3MzYsXG4gICAgJ2FuZCc6IDg3NDMsXG4gICAgJ29yJzogODc0NCxcbiAgICAnY2FwJzogODc0NSxcbiAgICAnY3VwJzogODc0NixcbiAgICAnaW50JzogODc0NyxcbiAgICAndGhlcmU0JzogODc1NixcbiAgICAnc2ltJzogODc2NCxcbiAgICAnY29uZyc6IDg3NzMsXG4gICAgJ2FzeW1wJzogODc3NixcbiAgICAnbmUnOiA4ODAwLFxuICAgICdlcXVpdic6IDg4MDEsXG4gICAgJ2xlJzogODgwNCxcbiAgICAnZ2UnOiA4ODA1LFxuICAgICdzdWInOiA4ODM0LFxuICAgICdzdXAnOiA4ODM1LFxuICAgICduc3ViJzogODgzNixcbiAgICAnc3ViZSc6IDg4MzgsXG4gICAgJ3N1cGUnOiA4ODM5LFxuICAgICdvcGx1cyc6IDg4NTMsXG4gICAgJ290aW1lcyc6IDg4NTUsXG4gICAgJ3BlcnAnOiA4ODY5LFxuICAgICdzZG90JzogODkwMSxcbiAgICAnbGNlaWwnOiA4OTY4LFxuICAgICdyY2VpbCc6IDg5NjksXG4gICAgJ2xmbG9vcic6IDg5NzAsXG4gICAgJ3JmbG9vcic6IDg5NzEsXG4gICAgJ2xhbmcnOiA5MDAxLFxuICAgICdyYW5nJzogOTAwMixcbiAgICAnbG96JzogOTY3NCxcbiAgICAnc3BhZGVzJzogOTgyNCxcbiAgICAnY2x1YnMnOiA5ODI3LFxuICAgICdoZWFydHMnOiA5ODI5LFxuICAgICdkaWFtcyc6IDk4MzBcbiAgfVxuXG4gIE9iamVjdC5rZXlzKHNheC5FTlRJVElFUykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgdmFyIGUgPSBzYXguRU5USVRJRVNba2V5XVxuICAgIHZhciBzID0gdHlwZW9mIGUgPT09ICdudW1iZXInID8gU3RyaW5nLmZyb21DaGFyQ29kZShlKSA6IGVcbiAgICBzYXguRU5USVRJRVNba2V5XSA9IHNcbiAgfSlcblxuICBmb3IgKHZhciBzIGluIHNheC5TVEFURSkge1xuICAgIHNheC5TVEFURVtzYXguU1RBVEVbc11dID0gc1xuICB9XG5cbiAgLy8gc2hvcnRoYW5kXG4gIFMgPSBzYXguU1RBVEVcblxuICBmdW5jdGlvbiBlbWl0IChwYXJzZXIsIGV2ZW50LCBkYXRhKSB7XG4gICAgcGFyc2VyW2V2ZW50XSAmJiBwYXJzZXJbZXZlbnRdKGRhdGEpXG4gIH1cblxuICBmdW5jdGlvbiBlbWl0Tm9kZSAocGFyc2VyLCBub2RlVHlwZSwgZGF0YSkge1xuICAgIGlmIChwYXJzZXIudGV4dE5vZGUpIGNsb3NlVGV4dChwYXJzZXIpXG4gICAgZW1pdChwYXJzZXIsIG5vZGVUeXBlLCBkYXRhKVxuICB9XG5cbiAgZnVuY3Rpb24gY2xvc2VUZXh0IChwYXJzZXIpIHtcbiAgICBwYXJzZXIudGV4dE5vZGUgPSB0ZXh0b3B0cyhwYXJzZXIub3B0LCBwYXJzZXIudGV4dE5vZGUpXG4gICAgaWYgKHBhcnNlci50ZXh0Tm9kZSkgZW1pdChwYXJzZXIsICdvbnRleHQnLCBwYXJzZXIudGV4dE5vZGUpXG4gICAgcGFyc2VyLnRleHROb2RlID0gJydcbiAgfVxuXG4gIGZ1bmN0aW9uIHRleHRvcHRzIChvcHQsIHRleHQpIHtcbiAgICBpZiAob3B0LnRyaW0pIHRleHQgPSB0ZXh0LnRyaW0oKVxuICAgIGlmIChvcHQubm9ybWFsaXplKSB0ZXh0ID0gdGV4dC5yZXBsYWNlKC9cXHMrL2csICcgJylcbiAgICByZXR1cm4gdGV4dFxuICB9XG5cbiAgZnVuY3Rpb24gZXJyb3IgKHBhcnNlciwgZXIpIHtcbiAgICBjbG9zZVRleHQocGFyc2VyKVxuICAgIGlmIChwYXJzZXIudHJhY2tQb3NpdGlvbikge1xuICAgICAgZXIgKz0gJ1xcbkxpbmU6ICcgKyBwYXJzZXIubGluZSArXG4gICAgICAgICdcXG5Db2x1bW46ICcgKyBwYXJzZXIuY29sdW1uICtcbiAgICAgICAgJ1xcbkNoYXI6ICcgKyBwYXJzZXIuY1xuICAgIH1cbiAgICBlciA9IG5ldyBFcnJvcihlcilcbiAgICBwYXJzZXIuZXJyb3IgPSBlclxuICAgIGVtaXQocGFyc2VyLCAnb25lcnJvcicsIGVyKVxuICAgIHJldHVybiBwYXJzZXJcbiAgfVxuXG4gIGZ1bmN0aW9uIGVuZCAocGFyc2VyKSB7XG4gICAgaWYgKHBhcnNlci5zYXdSb290ICYmICFwYXJzZXIuY2xvc2VkUm9vdCkgc3RyaWN0RmFpbChwYXJzZXIsICdVbmNsb3NlZCByb290IHRhZycpXG4gICAgaWYgKChwYXJzZXIuc3RhdGUgIT09IFMuQkVHSU4pICYmXG4gICAgICAocGFyc2VyLnN0YXRlICE9PSBTLkJFR0lOX1dISVRFU1BBQ0UpICYmXG4gICAgICAocGFyc2VyLnN0YXRlICE9PSBTLlRFWFQpKSB7XG4gICAgICBlcnJvcihwYXJzZXIsICdVbmV4cGVjdGVkIGVuZCcpXG4gICAgfVxuICAgIGNsb3NlVGV4dChwYXJzZXIpXG4gICAgcGFyc2VyLmMgPSAnJ1xuICAgIHBhcnNlci5jbG9zZWQgPSB0cnVlXG4gICAgZW1pdChwYXJzZXIsICdvbmVuZCcpXG4gICAgU0FYUGFyc2VyLmNhbGwocGFyc2VyLCBwYXJzZXIuc3RyaWN0LCBwYXJzZXIub3B0KVxuICAgIHJldHVybiBwYXJzZXJcbiAgfVxuXG4gIGZ1bmN0aW9uIHN0cmljdEZhaWwgKHBhcnNlciwgbWVzc2FnZSkge1xuICAgIGlmICh0eXBlb2YgcGFyc2VyICE9PSAnb2JqZWN0JyB8fCAhKHBhcnNlciBpbnN0YW5jZW9mIFNBWFBhcnNlcikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYmFkIGNhbGwgdG8gc3RyaWN0RmFpbCcpXG4gICAgfVxuICAgIGlmIChwYXJzZXIuc3RyaWN0KSB7XG4gICAgICBlcnJvcihwYXJzZXIsIG1lc3NhZ2UpXG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gbmV3VGFnIChwYXJzZXIpIHtcbiAgICBpZiAoIXBhcnNlci5zdHJpY3QpIHBhcnNlci50YWdOYW1lID0gcGFyc2VyLnRhZ05hbWVbcGFyc2VyLmxvb3NlQ2FzZV0oKVxuICAgIHZhciBwYXJlbnQgPSBwYXJzZXIudGFnc1twYXJzZXIudGFncy5sZW5ndGggLSAxXSB8fCBwYXJzZXJcbiAgICB2YXIgdGFnID0gcGFyc2VyLnRhZyA9IHsgbmFtZTogcGFyc2VyLnRhZ05hbWUsIGF0dHJpYnV0ZXM6IHt9IH1cblxuICAgIC8vIHdpbGwgYmUgb3ZlcnJpZGRlbiBpZiB0YWcgY29udGFpbHMgYW4geG1sbnM9XCJmb29cIiBvciB4bWxuczpmb289XCJiYXJcIlxuICAgIGlmIChwYXJzZXIub3B0LnhtbG5zKSB7XG4gICAgICB0YWcubnMgPSBwYXJlbnQubnNcbiAgICB9XG4gICAgcGFyc2VyLmF0dHJpYkxpc3QubGVuZ3RoID0gMFxuICAgIGVtaXROb2RlKHBhcnNlciwgJ29ub3BlbnRhZ3N0YXJ0JywgdGFnKVxuICB9XG5cbiAgZnVuY3Rpb24gcW5hbWUgKG5hbWUsIGF0dHJpYnV0ZSkge1xuICAgIHZhciBpID0gbmFtZS5pbmRleE9mKCc6JylcbiAgICB2YXIgcXVhbE5hbWUgPSBpIDwgMCA/IFsgJycsIG5hbWUgXSA6IG5hbWUuc3BsaXQoJzonKVxuICAgIHZhciBwcmVmaXggPSBxdWFsTmFtZVswXVxuICAgIHZhciBsb2NhbCA9IHF1YWxOYW1lWzFdXG5cbiAgICAvLyA8eCBcInhtbG5zXCI9XCJodHRwOi8vZm9vXCI+XG4gICAgaWYgKGF0dHJpYnV0ZSAmJiBuYW1lID09PSAneG1sbnMnKSB7XG4gICAgICBwcmVmaXggPSAneG1sbnMnXG4gICAgICBsb2NhbCA9ICcnXG4gICAgfVxuXG4gICAgcmV0dXJuIHsgcHJlZml4OiBwcmVmaXgsIGxvY2FsOiBsb2NhbCB9XG4gIH1cblxuICBmdW5jdGlvbiBhdHRyaWIgKHBhcnNlcikge1xuICAgIGlmICghcGFyc2VyLnN0cmljdCkge1xuICAgICAgcGFyc2VyLmF0dHJpYk5hbWUgPSBwYXJzZXIuYXR0cmliTmFtZVtwYXJzZXIubG9vc2VDYXNlXSgpXG4gICAgfVxuXG4gICAgaWYgKHBhcnNlci5hdHRyaWJMaXN0LmluZGV4T2YocGFyc2VyLmF0dHJpYk5hbWUpICE9PSAtMSB8fFxuICAgICAgcGFyc2VyLnRhZy5hdHRyaWJ1dGVzLmhhc093blByb3BlcnR5KHBhcnNlci5hdHRyaWJOYW1lKSkge1xuICAgICAgcGFyc2VyLmF0dHJpYk5hbWUgPSBwYXJzZXIuYXR0cmliVmFsdWUgPSAnJ1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHBhcnNlci5vcHQueG1sbnMpIHtcbiAgICAgIHZhciBxbiA9IHFuYW1lKHBhcnNlci5hdHRyaWJOYW1lLCB0cnVlKVxuICAgICAgdmFyIHByZWZpeCA9IHFuLnByZWZpeFxuICAgICAgdmFyIGxvY2FsID0gcW4ubG9jYWxcblxuICAgICAgaWYgKHByZWZpeCA9PT0gJ3htbG5zJykge1xuICAgICAgICAvLyBuYW1lc3BhY2UgYmluZGluZyBhdHRyaWJ1dGUuIHB1c2ggdGhlIGJpbmRpbmcgaW50byBzY29wZVxuICAgICAgICBpZiAobG9jYWwgPT09ICd4bWwnICYmIHBhcnNlci5hdHRyaWJWYWx1ZSAhPT0gWE1MX05BTUVTUEFDRSkge1xuICAgICAgICAgIHN0cmljdEZhaWwocGFyc2VyLFxuICAgICAgICAgICAgJ3htbDogcHJlZml4IG11c3QgYmUgYm91bmQgdG8gJyArIFhNTF9OQU1FU1BBQ0UgKyAnXFxuJyArXG4gICAgICAgICAgICAnQWN0dWFsOiAnICsgcGFyc2VyLmF0dHJpYlZhbHVlKVxuICAgICAgICB9IGVsc2UgaWYgKGxvY2FsID09PSAneG1sbnMnICYmIHBhcnNlci5hdHRyaWJWYWx1ZSAhPT0gWE1MTlNfTkFNRVNQQUNFKSB7XG4gICAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsXG4gICAgICAgICAgICAneG1sbnM6IHByZWZpeCBtdXN0IGJlIGJvdW5kIHRvICcgKyBYTUxOU19OQU1FU1BBQ0UgKyAnXFxuJyArXG4gICAgICAgICAgICAnQWN0dWFsOiAnICsgcGFyc2VyLmF0dHJpYlZhbHVlKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciB0YWcgPSBwYXJzZXIudGFnXG4gICAgICAgICAgdmFyIHBhcmVudCA9IHBhcnNlci50YWdzW3BhcnNlci50YWdzLmxlbmd0aCAtIDFdIHx8IHBhcnNlclxuICAgICAgICAgIGlmICh0YWcubnMgPT09IHBhcmVudC5ucykge1xuICAgICAgICAgICAgdGFnLm5zID0gT2JqZWN0LmNyZWF0ZShwYXJlbnQubnMpXG4gICAgICAgICAgfVxuICAgICAgICAgIHRhZy5uc1tsb2NhbF0gPSBwYXJzZXIuYXR0cmliVmFsdWVcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBkZWZlciBvbmF0dHJpYnV0ZSBldmVudHMgdW50aWwgYWxsIGF0dHJpYnV0ZXMgaGF2ZSBiZWVuIHNlZW5cbiAgICAgIC8vIHNvIGFueSBuZXcgYmluZGluZ3MgY2FuIHRha2UgZWZmZWN0LiBwcmVzZXJ2ZSBhdHRyaWJ1dGUgb3JkZXJcbiAgICAgIC8vIHNvIGRlZmVycmVkIGV2ZW50cyBjYW4gYmUgZW1pdHRlZCBpbiBkb2N1bWVudCBvcmRlclxuICAgICAgcGFyc2VyLmF0dHJpYkxpc3QucHVzaChbcGFyc2VyLmF0dHJpYk5hbWUsIHBhcnNlci5hdHRyaWJWYWx1ZV0pXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGluIG5vbi14bWxucyBtb2RlLCB3ZSBjYW4gZW1pdCB0aGUgZXZlbnQgcmlnaHQgYXdheVxuICAgICAgcGFyc2VyLnRhZy5hdHRyaWJ1dGVzW3BhcnNlci5hdHRyaWJOYW1lXSA9IHBhcnNlci5hdHRyaWJWYWx1ZVxuICAgICAgZW1pdE5vZGUocGFyc2VyLCAnb25hdHRyaWJ1dGUnLCB7XG4gICAgICAgIG5hbWU6IHBhcnNlci5hdHRyaWJOYW1lLFxuICAgICAgICB2YWx1ZTogcGFyc2VyLmF0dHJpYlZhbHVlXG4gICAgICB9KVxuICAgIH1cblxuICAgIHBhcnNlci5hdHRyaWJOYW1lID0gcGFyc2VyLmF0dHJpYlZhbHVlID0gJydcbiAgfVxuXG4gIGZ1bmN0aW9uIG9wZW5UYWcgKHBhcnNlciwgc2VsZkNsb3NpbmcpIHtcbiAgICBpZiAocGFyc2VyLm9wdC54bWxucykge1xuICAgICAgLy8gZW1pdCBuYW1lc3BhY2UgYmluZGluZyBldmVudHNcbiAgICAgIHZhciB0YWcgPSBwYXJzZXIudGFnXG5cbiAgICAgIC8vIGFkZCBuYW1lc3BhY2UgaW5mbyB0byB0YWdcbiAgICAgIHZhciBxbiA9IHFuYW1lKHBhcnNlci50YWdOYW1lKVxuICAgICAgdGFnLnByZWZpeCA9IHFuLnByZWZpeFxuICAgICAgdGFnLmxvY2FsID0gcW4ubG9jYWxcbiAgICAgIHRhZy51cmkgPSB0YWcubnNbcW4ucHJlZml4XSB8fCAnJ1xuXG4gICAgICBpZiAodGFnLnByZWZpeCAmJiAhdGFnLnVyaSkge1xuICAgICAgICBzdHJpY3RGYWlsKHBhcnNlciwgJ1VuYm91bmQgbmFtZXNwYWNlIHByZWZpeDogJyArXG4gICAgICAgICAgSlNPTi5zdHJpbmdpZnkocGFyc2VyLnRhZ05hbWUpKVxuICAgICAgICB0YWcudXJpID0gcW4ucHJlZml4XG4gICAgICB9XG5cbiAgICAgIHZhciBwYXJlbnQgPSBwYXJzZXIudGFnc1twYXJzZXIudGFncy5sZW5ndGggLSAxXSB8fCBwYXJzZXJcbiAgICAgIGlmICh0YWcubnMgJiYgcGFyZW50Lm5zICE9PSB0YWcubnMpIHtcbiAgICAgICAgT2JqZWN0LmtleXModGFnLm5zKS5mb3JFYWNoKGZ1bmN0aW9uIChwKSB7XG4gICAgICAgICAgZW1pdE5vZGUocGFyc2VyLCAnb25vcGVubmFtZXNwYWNlJywge1xuICAgICAgICAgICAgcHJlZml4OiBwLFxuICAgICAgICAgICAgdXJpOiB0YWcubnNbcF1cbiAgICAgICAgICB9KVxuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICAvLyBoYW5kbGUgZGVmZXJyZWQgb25hdHRyaWJ1dGUgZXZlbnRzXG4gICAgICAvLyBOb3RlOiBkbyBub3QgYXBwbHkgZGVmYXVsdCBucyB0byBhdHRyaWJ1dGVzOlxuICAgICAgLy8gICBodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLW5hbWVzLyNkZWZhdWx0aW5nXG4gICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHBhcnNlci5hdHRyaWJMaXN0Lmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICB2YXIgbnYgPSBwYXJzZXIuYXR0cmliTGlzdFtpXVxuICAgICAgICB2YXIgbmFtZSA9IG52WzBdXG4gICAgICAgIHZhciB2YWx1ZSA9IG52WzFdXG4gICAgICAgIHZhciBxdWFsTmFtZSA9IHFuYW1lKG5hbWUsIHRydWUpXG4gICAgICAgIHZhciBwcmVmaXggPSBxdWFsTmFtZS5wcmVmaXhcbiAgICAgICAgdmFyIGxvY2FsID0gcXVhbE5hbWUubG9jYWxcbiAgICAgICAgdmFyIHVyaSA9IHByZWZpeCA9PT0gJycgPyAnJyA6ICh0YWcubnNbcHJlZml4XSB8fCAnJylcbiAgICAgICAgdmFyIGEgPSB7XG4gICAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgcHJlZml4OiBwcmVmaXgsXG4gICAgICAgICAgbG9jYWw6IGxvY2FsLFxuICAgICAgICAgIHVyaTogdXJpXG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiB0aGVyZSdzIGFueSBhdHRyaWJ1dGVzIHdpdGggYW4gdW5kZWZpbmVkIG5hbWVzcGFjZSxcbiAgICAgICAgLy8gdGhlbiBmYWlsIG9uIHRoZW0gbm93LlxuICAgICAgICBpZiAocHJlZml4ICYmIHByZWZpeCAhPT0gJ3htbG5zJyAmJiAhdXJpKSB7XG4gICAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdVbmJvdW5kIG5hbWVzcGFjZSBwcmVmaXg6ICcgK1xuICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkocHJlZml4KSlcbiAgICAgICAgICBhLnVyaSA9IHByZWZpeFxuICAgICAgICB9XG4gICAgICAgIHBhcnNlci50YWcuYXR0cmlidXRlc1tuYW1lXSA9IGFcbiAgICAgICAgZW1pdE5vZGUocGFyc2VyLCAnb25hdHRyaWJ1dGUnLCBhKVxuICAgICAgfVxuICAgICAgcGFyc2VyLmF0dHJpYkxpc3QubGVuZ3RoID0gMFxuICAgIH1cblxuICAgIHBhcnNlci50YWcuaXNTZWxmQ2xvc2luZyA9ICEhc2VsZkNsb3NpbmdcblxuICAgIC8vIHByb2Nlc3MgdGhlIHRhZ1xuICAgIHBhcnNlci5zYXdSb290ID0gdHJ1ZVxuICAgIHBhcnNlci50YWdzLnB1c2gocGFyc2VyLnRhZylcbiAgICBlbWl0Tm9kZShwYXJzZXIsICdvbm9wZW50YWcnLCBwYXJzZXIudGFnKVxuICAgIGlmICghc2VsZkNsb3NpbmcpIHtcbiAgICAgIC8vIHNwZWNpYWwgY2FzZSBmb3IgPHNjcmlwdD4gaW4gbm9uLXN0cmljdCBtb2RlLlxuICAgICAgaWYgKCFwYXJzZXIubm9zY3JpcHQgJiYgcGFyc2VyLnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ3NjcmlwdCcpIHtcbiAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5TQ1JJUFRcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuVEVYVFxuICAgICAgfVxuICAgICAgcGFyc2VyLnRhZyA9IG51bGxcbiAgICAgIHBhcnNlci50YWdOYW1lID0gJydcbiAgICB9XG4gICAgcGFyc2VyLmF0dHJpYk5hbWUgPSBwYXJzZXIuYXR0cmliVmFsdWUgPSAnJ1xuICAgIHBhcnNlci5hdHRyaWJMaXN0Lmxlbmd0aCA9IDBcbiAgfVxuXG4gIGZ1bmN0aW9uIGNsb3NlVGFnIChwYXJzZXIpIHtcbiAgICBpZiAoIXBhcnNlci50YWdOYW1lKSB7XG4gICAgICBzdHJpY3RGYWlsKHBhcnNlciwgJ1dlaXJkIGVtcHR5IGNsb3NlIHRhZy4nKVxuICAgICAgcGFyc2VyLnRleHROb2RlICs9ICc8Lz4nXG4gICAgICBwYXJzZXIuc3RhdGUgPSBTLlRFWFRcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChwYXJzZXIuc2NyaXB0KSB7XG4gICAgICBpZiAocGFyc2VyLnRhZ05hbWUgIT09ICdzY3JpcHQnKSB7XG4gICAgICAgIHBhcnNlci5zY3JpcHQgKz0gJzwvJyArIHBhcnNlci50YWdOYW1lICsgJz4nXG4gICAgICAgIHBhcnNlci50YWdOYW1lID0gJydcbiAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5TQ1JJUFRcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgICBlbWl0Tm9kZShwYXJzZXIsICdvbnNjcmlwdCcsIHBhcnNlci5zY3JpcHQpXG4gICAgICBwYXJzZXIuc2NyaXB0ID0gJydcbiAgICB9XG5cbiAgICAvLyBmaXJzdCBtYWtlIHN1cmUgdGhhdCB0aGUgY2xvc2luZyB0YWcgYWN0dWFsbHkgZXhpc3RzLlxuICAgIC8vIDxhPjxiPjwvYz48L2I+PC9hPiB3aWxsIGNsb3NlIGV2ZXJ5dGhpbmcsIG90aGVyd2lzZS5cbiAgICB2YXIgdCA9IHBhcnNlci50YWdzLmxlbmd0aFxuICAgIHZhciB0YWdOYW1lID0gcGFyc2VyLnRhZ05hbWVcbiAgICBpZiAoIXBhcnNlci5zdHJpY3QpIHtcbiAgICAgIHRhZ05hbWUgPSB0YWdOYW1lW3BhcnNlci5sb29zZUNhc2VdKClcbiAgICB9XG4gICAgdmFyIGNsb3NlVG8gPSB0YWdOYW1lXG4gICAgd2hpbGUgKHQtLSkge1xuICAgICAgdmFyIGNsb3NlID0gcGFyc2VyLnRhZ3NbdF1cbiAgICAgIGlmIChjbG9zZS5uYW1lICE9PSBjbG9zZVRvKSB7XG4gICAgICAgIC8vIGZhaWwgdGhlIGZpcnN0IHRpbWUgaW4gc3RyaWN0IG1vZGVcbiAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdVbmV4cGVjdGVkIGNsb3NlIHRhZycpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGRpZG4ndCBmaW5kIGl0LiAgd2UgYWxyZWFkeSBmYWlsZWQgZm9yIHN0cmljdCwgc28ganVzdCBhYm9ydC5cbiAgICBpZiAodCA8IDApIHtcbiAgICAgIHN0cmljdEZhaWwocGFyc2VyLCAnVW5tYXRjaGVkIGNsb3NpbmcgdGFnOiAnICsgcGFyc2VyLnRhZ05hbWUpXG4gICAgICBwYXJzZXIudGV4dE5vZGUgKz0gJzwvJyArIHBhcnNlci50YWdOYW1lICsgJz4nXG4gICAgICBwYXJzZXIuc3RhdGUgPSBTLlRFWFRcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBwYXJzZXIudGFnTmFtZSA9IHRhZ05hbWVcbiAgICB2YXIgcyA9IHBhcnNlci50YWdzLmxlbmd0aFxuICAgIHdoaWxlIChzLS0gPiB0KSB7XG4gICAgICB2YXIgdGFnID0gcGFyc2VyLnRhZyA9IHBhcnNlci50YWdzLnBvcCgpXG4gICAgICBwYXJzZXIudGFnTmFtZSA9IHBhcnNlci50YWcubmFtZVxuICAgICAgZW1pdE5vZGUocGFyc2VyLCAnb25jbG9zZXRhZycsIHBhcnNlci50YWdOYW1lKVxuXG4gICAgICB2YXIgeCA9IHt9XG4gICAgICBmb3IgKHZhciBpIGluIHRhZy5ucykge1xuICAgICAgICB4W2ldID0gdGFnLm5zW2ldXG4gICAgICB9XG5cbiAgICAgIHZhciBwYXJlbnQgPSBwYXJzZXIudGFnc1twYXJzZXIudGFncy5sZW5ndGggLSAxXSB8fCBwYXJzZXJcbiAgICAgIGlmIChwYXJzZXIub3B0LnhtbG5zICYmIHRhZy5ucyAhPT0gcGFyZW50Lm5zKSB7XG4gICAgICAgIC8vIHJlbW92ZSBuYW1lc3BhY2UgYmluZGluZ3MgaW50cm9kdWNlZCBieSB0YWdcbiAgICAgICAgT2JqZWN0LmtleXModGFnLm5zKS5mb3JFYWNoKGZ1bmN0aW9uIChwKSB7XG4gICAgICAgICAgdmFyIG4gPSB0YWcubnNbcF1cbiAgICAgICAgICBlbWl0Tm9kZShwYXJzZXIsICdvbmNsb3NlbmFtZXNwYWNlJywgeyBwcmVmaXg6IHAsIHVyaTogbiB9KVxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAodCA9PT0gMCkgcGFyc2VyLmNsb3NlZFJvb3QgPSB0cnVlXG4gICAgcGFyc2VyLnRhZ05hbWUgPSBwYXJzZXIuYXR0cmliVmFsdWUgPSBwYXJzZXIuYXR0cmliTmFtZSA9ICcnXG4gICAgcGFyc2VyLmF0dHJpYkxpc3QubGVuZ3RoID0gMFxuICAgIHBhcnNlci5zdGF0ZSA9IFMuVEVYVFxuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VFbnRpdHkgKHBhcnNlcikge1xuICAgIHZhciBlbnRpdHkgPSBwYXJzZXIuZW50aXR5XG4gICAgdmFyIGVudGl0eUxDID0gZW50aXR5LnRvTG93ZXJDYXNlKClcbiAgICB2YXIgbnVtXG4gICAgdmFyIG51bVN0ciA9ICcnXG5cbiAgICBpZiAocGFyc2VyLkVOVElUSUVTW2VudGl0eV0pIHtcbiAgICAgIHJldHVybiBwYXJzZXIuRU5USVRJRVNbZW50aXR5XVxuICAgIH1cbiAgICBpZiAocGFyc2VyLkVOVElUSUVTW2VudGl0eUxDXSkge1xuICAgICAgcmV0dXJuIHBhcnNlci5FTlRJVElFU1tlbnRpdHlMQ11cbiAgICB9XG4gICAgZW50aXR5ID0gZW50aXR5TENcbiAgICBpZiAoZW50aXR5LmNoYXJBdCgwKSA9PT0gJyMnKSB7XG4gICAgICBpZiAoZW50aXR5LmNoYXJBdCgxKSA9PT0gJ3gnKSB7XG4gICAgICAgIGVudGl0eSA9IGVudGl0eS5zbGljZSgyKVxuICAgICAgICBudW0gPSBwYXJzZUludChlbnRpdHksIDE2KVxuICAgICAgICBudW1TdHIgPSBudW0udG9TdHJpbmcoMTYpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbnRpdHkgPSBlbnRpdHkuc2xpY2UoMSlcbiAgICAgICAgbnVtID0gcGFyc2VJbnQoZW50aXR5LCAxMClcbiAgICAgICAgbnVtU3RyID0gbnVtLnRvU3RyaW5nKDEwKVxuICAgICAgfVxuICAgIH1cbiAgICBlbnRpdHkgPSBlbnRpdHkucmVwbGFjZSgvXjArLywgJycpXG4gICAgaWYgKGlzTmFOKG51bSkgfHwgbnVtU3RyLnRvTG93ZXJDYXNlKCkgIT09IGVudGl0eSkge1xuICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdJbnZhbGlkIGNoYXJhY3RlciBlbnRpdHknKVxuICAgICAgcmV0dXJuICcmJyArIHBhcnNlci5lbnRpdHkgKyAnOydcbiAgICB9XG5cbiAgICByZXR1cm4gU3RyaW5nLmZyb21Db2RlUG9pbnQobnVtKVxuICB9XG5cbiAgZnVuY3Rpb24gYmVnaW5XaGl0ZVNwYWNlIChwYXJzZXIsIGMpIHtcbiAgICBpZiAoYyA9PT0gJzwnKSB7XG4gICAgICBwYXJzZXIuc3RhdGUgPSBTLk9QRU5fV0FLQVxuICAgICAgcGFyc2VyLnN0YXJ0VGFnUG9zaXRpb24gPSBwYXJzZXIucG9zaXRpb25cbiAgICB9IGVsc2UgaWYgKCFpc1doaXRlc3BhY2UoYykpIHtcbiAgICAgIC8vIGhhdmUgdG8gcHJvY2VzcyB0aGlzIGFzIGEgdGV4dCBub2RlLlxuICAgICAgLy8gd2VpcmQsIGJ1dCBoYXBwZW5zLlxuICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdOb24td2hpdGVzcGFjZSBiZWZvcmUgZmlyc3QgdGFnLicpXG4gICAgICBwYXJzZXIudGV4dE5vZGUgPSBjXG4gICAgICBwYXJzZXIuc3RhdGUgPSBTLlRFWFRcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjaGFyQXQgKGNodW5rLCBpKSB7XG4gICAgdmFyIHJlc3VsdCA9ICcnXG4gICAgaWYgKGkgPCBjaHVuay5sZW5ndGgpIHtcbiAgICAgIHJlc3VsdCA9IGNodW5rLmNoYXJBdChpKVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0XG4gIH1cblxuICBmdW5jdGlvbiB3cml0ZSAoY2h1bmspIHtcbiAgICB2YXIgcGFyc2VyID0gdGhpc1xuICAgIGlmICh0aGlzLmVycm9yKSB7XG4gICAgICB0aHJvdyB0aGlzLmVycm9yXG4gICAgfVxuICAgIGlmIChwYXJzZXIuY2xvc2VkKSB7XG4gICAgICByZXR1cm4gZXJyb3IocGFyc2VyLFxuICAgICAgICAnQ2Fubm90IHdyaXRlIGFmdGVyIGNsb3NlLiBBc3NpZ24gYW4gb25yZWFkeSBoYW5kbGVyLicpXG4gICAgfVxuICAgIGlmIChjaHVuayA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGVuZChwYXJzZXIpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgY2h1bmsgPT09ICdvYmplY3QnKSB7XG4gICAgICBjaHVuayA9IGNodW5rLnRvU3RyaW5nKClcbiAgICB9XG4gICAgdmFyIGkgPSAwXG4gICAgdmFyIGMgPSAnJ1xuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBjID0gY2hhckF0KGNodW5rLCBpKyspXG4gICAgICBwYXJzZXIuYyA9IGNcblxuICAgICAgaWYgKCFjKSB7XG4gICAgICAgIGJyZWFrXG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJzZXIudHJhY2tQb3NpdGlvbikge1xuICAgICAgICBwYXJzZXIucG9zaXRpb24rK1xuICAgICAgICBpZiAoYyA9PT0gJ1xcbicpIHtcbiAgICAgICAgICBwYXJzZXIubGluZSsrXG4gICAgICAgICAgcGFyc2VyLmNvbHVtbiA9IDBcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwYXJzZXIuY29sdW1uKytcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBzd2l0Y2ggKHBhcnNlci5zdGF0ZSkge1xuICAgICAgICBjYXNlIFMuQkVHSU46XG4gICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5CRUdJTl9XSElURVNQQUNFXG4gICAgICAgICAgaWYgKGMgPT09ICdcXHVGRUZGJykge1xuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9XG4gICAgICAgICAgYmVnaW5XaGl0ZVNwYWNlKHBhcnNlciwgYylcbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5CRUdJTl9XSElURVNQQUNFOlxuICAgICAgICAgIGJlZ2luV2hpdGVTcGFjZShwYXJzZXIsIGMpXG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuVEVYVDpcbiAgICAgICAgICBpZiAocGFyc2VyLnNhd1Jvb3QgJiYgIXBhcnNlci5jbG9zZWRSb290KSB7XG4gICAgICAgICAgICB2YXIgc3RhcnRpID0gaSAtIDFcbiAgICAgICAgICAgIHdoaWxlIChjICYmIGMgIT09ICc8JyAmJiBjICE9PSAnJicpIHtcbiAgICAgICAgICAgICAgYyA9IGNoYXJBdChjaHVuaywgaSsrKVxuICAgICAgICAgICAgICBpZiAoYyAmJiBwYXJzZXIudHJhY2tQb3NpdGlvbikge1xuICAgICAgICAgICAgICAgIHBhcnNlci5wb3NpdGlvbisrXG4gICAgICAgICAgICAgICAgaWYgKGMgPT09ICdcXG4nKSB7XG4gICAgICAgICAgICAgICAgICBwYXJzZXIubGluZSsrXG4gICAgICAgICAgICAgICAgICBwYXJzZXIuY29sdW1uID0gMFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBwYXJzZXIuY29sdW1uKytcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBhcnNlci50ZXh0Tm9kZSArPSBjaHVuay5zdWJzdHJpbmcoc3RhcnRpLCBpIC0gMSlcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGMgPT09ICc8JyAmJiAhKHBhcnNlci5zYXdSb290ICYmIHBhcnNlci5jbG9zZWRSb290ICYmICFwYXJzZXIuc3RyaWN0KSkge1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5PUEVOX1dBS0FcbiAgICAgICAgICAgIHBhcnNlci5zdGFydFRhZ1Bvc2l0aW9uID0gcGFyc2VyLnBvc2l0aW9uXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghaXNXaGl0ZXNwYWNlKGMpICYmICghcGFyc2VyLnNhd1Jvb3QgfHwgcGFyc2VyLmNsb3NlZFJvb3QpKSB7XG4gICAgICAgICAgICAgIHN0cmljdEZhaWwocGFyc2VyLCAnVGV4dCBkYXRhIG91dHNpZGUgb2Ygcm9vdCBub2RlLicpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYyA9PT0gJyYnKSB7XG4gICAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuVEVYVF9FTlRJVFlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHBhcnNlci50ZXh0Tm9kZSArPSBjXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLlNDUklQVDpcbiAgICAgICAgICAvLyBvbmx5IG5vbi1zdHJpY3RcbiAgICAgICAgICBpZiAoYyA9PT0gJzwnKSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlNDUklQVF9FTkRJTkdcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyc2VyLnNjcmlwdCArPSBjXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLlNDUklQVF9FTkRJTkc6XG4gICAgICAgICAgaWYgKGMgPT09ICcvJykge1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5DTE9TRV9UQUdcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyc2VyLnNjcmlwdCArPSAnPCcgKyBjXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlNDUklQVFxuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5PUEVOX1dBS0E6XG4gICAgICAgICAgLy8gZWl0aGVyIGEgLywgPywgISwgb3IgdGV4dCBpcyBjb21pbmcgbmV4dC5cbiAgICAgICAgICBpZiAoYyA9PT0gJyEnKSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlNHTUxfREVDTFxuICAgICAgICAgICAgcGFyc2VyLnNnbWxEZWNsID0gJydcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzV2hpdGVzcGFjZShjKSkge1xuICAgICAgICAgICAgLy8gd2FpdCBmb3IgaXQuLi5cbiAgICAgICAgICB9IGVsc2UgaWYgKGlzTWF0Y2gobmFtZVN0YXJ0LCBjKSkge1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5PUEVOX1RBR1xuICAgICAgICAgICAgcGFyc2VyLnRhZ05hbWUgPSBjXG4gICAgICAgICAgfSBlbHNlIGlmIChjID09PSAnLycpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQ0xPU0VfVEFHXG4gICAgICAgICAgICBwYXJzZXIudGFnTmFtZSA9ICcnXG4gICAgICAgICAgfSBlbHNlIGlmIChjID09PSAnPycpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuUFJPQ19JTlNUXG4gICAgICAgICAgICBwYXJzZXIucHJvY0luc3ROYW1lID0gcGFyc2VyLnByb2NJbnN0Qm9keSA9ICcnXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN0cmljdEZhaWwocGFyc2VyLCAnVW5lbmNvZGVkIDwnKVxuICAgICAgICAgICAgLy8gaWYgdGhlcmUgd2FzIHNvbWUgd2hpdGVzcGFjZSwgdGhlbiBhZGQgdGhhdCBpbi5cbiAgICAgICAgICAgIGlmIChwYXJzZXIuc3RhcnRUYWdQb3NpdGlvbiArIDEgPCBwYXJzZXIucG9zaXRpb24pIHtcbiAgICAgICAgICAgICAgdmFyIHBhZCA9IHBhcnNlci5wb3NpdGlvbiAtIHBhcnNlci5zdGFydFRhZ1Bvc2l0aW9uXG4gICAgICAgICAgICAgIGMgPSBuZXcgQXJyYXkocGFkKS5qb2luKCcgJykgKyBjXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwYXJzZXIudGV4dE5vZGUgKz0gJzwnICsgY1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5URVhUXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLlNHTUxfREVDTDpcbiAgICAgICAgICBpZiAoKHBhcnNlci5zZ21sRGVjbCArIGMpLnRvVXBwZXJDYXNlKCkgPT09IENEQVRBKSB7XG4gICAgICAgICAgICBlbWl0Tm9kZShwYXJzZXIsICdvbm9wZW5jZGF0YScpXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLkNEQVRBXG4gICAgICAgICAgICBwYXJzZXIuc2dtbERlY2wgPSAnJ1xuICAgICAgICAgICAgcGFyc2VyLmNkYXRhID0gJydcbiAgICAgICAgICB9IGVsc2UgaWYgKHBhcnNlci5zZ21sRGVjbCArIGMgPT09ICctLScpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQ09NTUVOVFxuICAgICAgICAgICAgcGFyc2VyLmNvbW1lbnQgPSAnJ1xuICAgICAgICAgICAgcGFyc2VyLnNnbWxEZWNsID0gJydcbiAgICAgICAgICB9IGVsc2UgaWYgKChwYXJzZXIuc2dtbERlY2wgKyBjKS50b1VwcGVyQ2FzZSgpID09PSBET0NUWVBFKSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLkRPQ1RZUEVcbiAgICAgICAgICAgIGlmIChwYXJzZXIuZG9jdHlwZSB8fCBwYXJzZXIuc2F3Um9vdCkge1xuICAgICAgICAgICAgICBzdHJpY3RGYWlsKHBhcnNlcixcbiAgICAgICAgICAgICAgICAnSW5hcHByb3ByaWF0ZWx5IGxvY2F0ZWQgZG9jdHlwZSBkZWNsYXJhdGlvbicpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwYXJzZXIuZG9jdHlwZSA9ICcnXG4gICAgICAgICAgICBwYXJzZXIuc2dtbERlY2wgPSAnJ1xuICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PT0gJz4nKSB7XG4gICAgICAgICAgICBlbWl0Tm9kZShwYXJzZXIsICdvbnNnbWxkZWNsYXJhdGlvbicsIHBhcnNlci5zZ21sRGVjbClcbiAgICAgICAgICAgIHBhcnNlci5zZ21sRGVjbCA9ICcnXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlRFWFRcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzUXVvdGUoYykpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuU0dNTF9ERUNMX1FVT1RFRFxuICAgICAgICAgICAgcGFyc2VyLnNnbWxEZWNsICs9IGNcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyc2VyLnNnbWxEZWNsICs9IGNcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuU0dNTF9ERUNMX1FVT1RFRDpcbiAgICAgICAgICBpZiAoYyA9PT0gcGFyc2VyLnEpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuU0dNTF9ERUNMXG4gICAgICAgICAgICBwYXJzZXIucSA9ICcnXG4gICAgICAgICAgfVxuICAgICAgICAgIHBhcnNlci5zZ21sRGVjbCArPSBjXG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuRE9DVFlQRTpcbiAgICAgICAgICBpZiAoYyA9PT0gJz4nKSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlRFWFRcbiAgICAgICAgICAgIGVtaXROb2RlKHBhcnNlciwgJ29uZG9jdHlwZScsIHBhcnNlci5kb2N0eXBlKVxuICAgICAgICAgICAgcGFyc2VyLmRvY3R5cGUgPSB0cnVlIC8vIGp1c3QgcmVtZW1iZXIgdGhhdCB3ZSBzYXcgaXQuXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBhcnNlci5kb2N0eXBlICs9IGNcbiAgICAgICAgICAgIGlmIChjID09PSAnWycpIHtcbiAgICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5ET0NUWVBFX0RURFxuICAgICAgICAgICAgfSBlbHNlIGlmIChpc1F1b3RlKGMpKSB7XG4gICAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuRE9DVFlQRV9RVU9URURcbiAgICAgICAgICAgICAgcGFyc2VyLnEgPSBjXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLkRPQ1RZUEVfUVVPVEVEOlxuICAgICAgICAgIHBhcnNlci5kb2N0eXBlICs9IGNcbiAgICAgICAgICBpZiAoYyA9PT0gcGFyc2VyLnEpIHtcbiAgICAgICAgICAgIHBhcnNlci5xID0gJydcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuRE9DVFlQRVxuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5ET0NUWVBFX0RURDpcbiAgICAgICAgICBwYXJzZXIuZG9jdHlwZSArPSBjXG4gICAgICAgICAgaWYgKGMgPT09ICddJykge1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5ET0NUWVBFXG4gICAgICAgICAgfSBlbHNlIGlmIChpc1F1b3RlKGMpKSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLkRPQ1RZUEVfRFREX1FVT1RFRFxuICAgICAgICAgICAgcGFyc2VyLnEgPSBjXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLkRPQ1RZUEVfRFREX1FVT1RFRDpcbiAgICAgICAgICBwYXJzZXIuZG9jdHlwZSArPSBjXG4gICAgICAgICAgaWYgKGMgPT09IHBhcnNlci5xKSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLkRPQ1RZUEVfRFREXG4gICAgICAgICAgICBwYXJzZXIucSA9ICcnXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLkNPTU1FTlQ6XG4gICAgICAgICAgaWYgKGMgPT09ICctJykge1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5DT01NRU5UX0VORElOR1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwYXJzZXIuY29tbWVudCArPSBjXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLkNPTU1FTlRfRU5ESU5HOlxuICAgICAgICAgIGlmIChjID09PSAnLScpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQ09NTUVOVF9FTkRFRFxuICAgICAgICAgICAgcGFyc2VyLmNvbW1lbnQgPSB0ZXh0b3B0cyhwYXJzZXIub3B0LCBwYXJzZXIuY29tbWVudClcbiAgICAgICAgICAgIGlmIChwYXJzZXIuY29tbWVudCkge1xuICAgICAgICAgICAgICBlbWl0Tm9kZShwYXJzZXIsICdvbmNvbW1lbnQnLCBwYXJzZXIuY29tbWVudClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBhcnNlci5jb21tZW50ID0gJydcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyc2VyLmNvbW1lbnQgKz0gJy0nICsgY1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5DT01NRU5UXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLkNPTU1FTlRfRU5ERUQ6XG4gICAgICAgICAgaWYgKGMgIT09ICc+Jykge1xuICAgICAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdNYWxmb3JtZWQgY29tbWVudCcpXG4gICAgICAgICAgICAvLyBhbGxvdyA8IS0tIGJsYWggLS0gYmxvbyAtLT4gaW4gbm9uLXN0cmljdCBtb2RlLFxuICAgICAgICAgICAgLy8gd2hpY2ggaXMgYSBjb21tZW50IG9mIFwiIGJsYWggLS0gYmxvbyBcIlxuICAgICAgICAgICAgcGFyc2VyLmNvbW1lbnQgKz0gJy0tJyArIGNcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQ09NTUVOVFxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlRFWFRcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuQ0RBVEE6XG4gICAgICAgICAgaWYgKGMgPT09ICddJykge1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5DREFUQV9FTkRJTkdcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyc2VyLmNkYXRhICs9IGNcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuQ0RBVEFfRU5ESU5HOlxuICAgICAgICAgIGlmIChjID09PSAnXScpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQ0RBVEFfRU5ESU5HXzJcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyc2VyLmNkYXRhICs9ICddJyArIGNcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQ0RBVEFcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuQ0RBVEFfRU5ESU5HXzI6XG4gICAgICAgICAgaWYgKGMgPT09ICc+Jykge1xuICAgICAgICAgICAgaWYgKHBhcnNlci5jZGF0YSkge1xuICAgICAgICAgICAgICBlbWl0Tm9kZShwYXJzZXIsICdvbmNkYXRhJywgcGFyc2VyLmNkYXRhKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZW1pdE5vZGUocGFyc2VyLCAnb25jbG9zZWNkYXRhJylcbiAgICAgICAgICAgIHBhcnNlci5jZGF0YSA9ICcnXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlRFWFRcbiAgICAgICAgICB9IGVsc2UgaWYgKGMgPT09ICddJykge1xuICAgICAgICAgICAgcGFyc2VyLmNkYXRhICs9ICddJ1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwYXJzZXIuY2RhdGEgKz0gJ11dJyArIGNcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQ0RBVEFcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuUFJPQ19JTlNUOlxuICAgICAgICAgIGlmIChjID09PSAnPycpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuUFJPQ19JTlNUX0VORElOR1xuICAgICAgICAgIH0gZWxzZSBpZiAoaXNXaGl0ZXNwYWNlKGMpKSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlBST0NfSU5TVF9CT0RZXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBhcnNlci5wcm9jSW5zdE5hbWUgKz0gY1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5QUk9DX0lOU1RfQk9EWTpcbiAgICAgICAgICBpZiAoIXBhcnNlci5wcm9jSW5zdEJvZHkgJiYgaXNXaGl0ZXNwYWNlKGMpKSB7XG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PT0gJz8nKSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlBST0NfSU5TVF9FTkRJTkdcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyc2VyLnByb2NJbnN0Qm9keSArPSBjXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLlBST0NfSU5TVF9FTkRJTkc6XG4gICAgICAgICAgaWYgKGMgPT09ICc+Jykge1xuICAgICAgICAgICAgZW1pdE5vZGUocGFyc2VyLCAnb25wcm9jZXNzaW5naW5zdHJ1Y3Rpb24nLCB7XG4gICAgICAgICAgICAgIG5hbWU6IHBhcnNlci5wcm9jSW5zdE5hbWUsXG4gICAgICAgICAgICAgIGJvZHk6IHBhcnNlci5wcm9jSW5zdEJvZHlcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBwYXJzZXIucHJvY0luc3ROYW1lID0gcGFyc2VyLnByb2NJbnN0Qm9keSA9ICcnXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlRFWFRcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyc2VyLnByb2NJbnN0Qm9keSArPSAnPycgKyBjXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlBST0NfSU5TVF9CT0RZXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLk9QRU5fVEFHOlxuICAgICAgICAgIGlmIChpc01hdGNoKG5hbWVCb2R5LCBjKSkge1xuICAgICAgICAgICAgcGFyc2VyLnRhZ05hbWUgKz0gY1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZXdUYWcocGFyc2VyKVxuICAgICAgICAgICAgaWYgKGMgPT09ICc+Jykge1xuICAgICAgICAgICAgICBvcGVuVGFnKHBhcnNlcilcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PT0gJy8nKSB7XG4gICAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuT1BFTl9UQUdfU0xBU0hcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmICghaXNXaGl0ZXNwYWNlKGMpKSB7XG4gICAgICAgICAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdJbnZhbGlkIGNoYXJhY3RlciBpbiB0YWcgbmFtZScpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5BVFRSSUJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuT1BFTl9UQUdfU0xBU0g6XG4gICAgICAgICAgaWYgKGMgPT09ICc+Jykge1xuICAgICAgICAgICAgb3BlblRhZyhwYXJzZXIsIHRydWUpXG4gICAgICAgICAgICBjbG9zZVRhZyhwYXJzZXIpXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN0cmljdEZhaWwocGFyc2VyLCAnRm9yd2FyZC1zbGFzaCBpbiBvcGVuaW5nIHRhZyBub3QgZm9sbG93ZWQgYnkgPicpXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLkFUVFJJQlxuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5BVFRSSUI6XG4gICAgICAgICAgLy8gaGF2ZW4ndCByZWFkIHRoZSBhdHRyaWJ1dGUgbmFtZSB5ZXQuXG4gICAgICAgICAgaWYgKGlzV2hpdGVzcGFjZShjKSkge1xuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9IGVsc2UgaWYgKGMgPT09ICc+Jykge1xuICAgICAgICAgICAgb3BlblRhZyhwYXJzZXIpXG4gICAgICAgICAgfSBlbHNlIGlmIChjID09PSAnLycpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuT1BFTl9UQUdfU0xBU0hcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzTWF0Y2gobmFtZVN0YXJ0LCBjKSkge1xuICAgICAgICAgICAgcGFyc2VyLmF0dHJpYk5hbWUgPSBjXG4gICAgICAgICAgICBwYXJzZXIuYXR0cmliVmFsdWUgPSAnJ1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5BVFRSSUJfTkFNRVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdHJpY3RGYWlsKHBhcnNlciwgJ0ludmFsaWQgYXR0cmlidXRlIG5hbWUnKVxuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5BVFRSSUJfTkFNRTpcbiAgICAgICAgICBpZiAoYyA9PT0gJz0nKSB7XG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLkFUVFJJQl9WQUxVRVxuICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PT0gJz4nKSB7XG4gICAgICAgICAgICBzdHJpY3RGYWlsKHBhcnNlciwgJ0F0dHJpYnV0ZSB3aXRob3V0IHZhbHVlJylcbiAgICAgICAgICAgIHBhcnNlci5hdHRyaWJWYWx1ZSA9IHBhcnNlci5hdHRyaWJOYW1lXG4gICAgICAgICAgICBhdHRyaWIocGFyc2VyKVxuICAgICAgICAgICAgb3BlblRhZyhwYXJzZXIpXG4gICAgICAgICAgfSBlbHNlIGlmIChpc1doaXRlc3BhY2UoYykpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQVRUUklCX05BTUVfU0FXX1dISVRFXG4gICAgICAgICAgfSBlbHNlIGlmIChpc01hdGNoKG5hbWVCb2R5LCBjKSkge1xuICAgICAgICAgICAgcGFyc2VyLmF0dHJpYk5hbWUgKz0gY1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdHJpY3RGYWlsKHBhcnNlciwgJ0ludmFsaWQgYXR0cmlidXRlIG5hbWUnKVxuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5BVFRSSUJfTkFNRV9TQVdfV0hJVEU6XG4gICAgICAgICAgaWYgKGMgPT09ICc9Jykge1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5BVFRSSUJfVkFMVUVcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzV2hpdGVzcGFjZShjKSkge1xuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdBdHRyaWJ1dGUgd2l0aG91dCB2YWx1ZScpXG4gICAgICAgICAgICBwYXJzZXIudGFnLmF0dHJpYnV0ZXNbcGFyc2VyLmF0dHJpYk5hbWVdID0gJydcbiAgICAgICAgICAgIHBhcnNlci5hdHRyaWJWYWx1ZSA9ICcnXG4gICAgICAgICAgICBlbWl0Tm9kZShwYXJzZXIsICdvbmF0dHJpYnV0ZScsIHtcbiAgICAgICAgICAgICAgbmFtZTogcGFyc2VyLmF0dHJpYk5hbWUsXG4gICAgICAgICAgICAgIHZhbHVlOiAnJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHBhcnNlci5hdHRyaWJOYW1lID0gJydcbiAgICAgICAgICAgIGlmIChjID09PSAnPicpIHtcbiAgICAgICAgICAgICAgb3BlblRhZyhwYXJzZXIpXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzTWF0Y2gobmFtZVN0YXJ0LCBjKSkge1xuICAgICAgICAgICAgICBwYXJzZXIuYXR0cmliTmFtZSA9IGNcbiAgICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5BVFRSSUJfTkFNRVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdJbnZhbGlkIGF0dHJpYnV0ZSBuYW1lJylcbiAgICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5BVFRSSUJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuQVRUUklCX1ZBTFVFOlxuICAgICAgICAgIGlmIChpc1doaXRlc3BhY2UoYykpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgfSBlbHNlIGlmIChpc1F1b3RlKGMpKSB7XG4gICAgICAgICAgICBwYXJzZXIucSA9IGNcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQVRUUklCX1ZBTFVFX1FVT1RFRFxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdHJpY3RGYWlsKHBhcnNlciwgJ1VucXVvdGVkIGF0dHJpYnV0ZSB2YWx1ZScpXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLkFUVFJJQl9WQUxVRV9VTlFVT1RFRFxuICAgICAgICAgICAgcGFyc2VyLmF0dHJpYlZhbHVlID0gY1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5BVFRSSUJfVkFMVUVfUVVPVEVEOlxuICAgICAgICAgIGlmIChjICE9PSBwYXJzZXIucSkge1xuICAgICAgICAgICAgaWYgKGMgPT09ICcmJykge1xuICAgICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLkFUVFJJQl9WQUxVRV9FTlRJVFlfUVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcGFyc2VyLmF0dHJpYlZhbHVlICs9IGNcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgfVxuICAgICAgICAgIGF0dHJpYihwYXJzZXIpXG4gICAgICAgICAgcGFyc2VyLnEgPSAnJ1xuICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQVRUUklCX1ZBTFVFX0NMT1NFRFxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLkFUVFJJQl9WQUxVRV9DTE9TRUQ6XG4gICAgICAgICAgaWYgKGlzV2hpdGVzcGFjZShjKSkge1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5BVFRSSUJcbiAgICAgICAgICB9IGVsc2UgaWYgKGMgPT09ICc+Jykge1xuICAgICAgICAgICAgb3BlblRhZyhwYXJzZXIpXG4gICAgICAgICAgfSBlbHNlIGlmIChjID09PSAnLycpIHtcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuT1BFTl9UQUdfU0xBU0hcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzTWF0Y2gobmFtZVN0YXJ0LCBjKSkge1xuICAgICAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdObyB3aGl0ZXNwYWNlIGJldHdlZW4gYXR0cmlidXRlcycpXG4gICAgICAgICAgICBwYXJzZXIuYXR0cmliTmFtZSA9IGNcbiAgICAgICAgICAgIHBhcnNlci5hdHRyaWJWYWx1ZSA9ICcnXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLkFUVFJJQl9OQU1FXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN0cmljdEZhaWwocGFyc2VyLCAnSW52YWxpZCBhdHRyaWJ1dGUgbmFtZScpXG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgY2FzZSBTLkFUVFJJQl9WQUxVRV9VTlFVT1RFRDpcbiAgICAgICAgICBpZiAoIWlzQXR0cmliRW5kKGMpKSB7XG4gICAgICAgICAgICBpZiAoYyA9PT0gJyYnKSB7XG4gICAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQVRUUklCX1ZBTFVFX0VOVElUWV9VXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBwYXJzZXIuYXR0cmliVmFsdWUgKz0gY1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9XG4gICAgICAgICAgYXR0cmliKHBhcnNlcilcbiAgICAgICAgICBpZiAoYyA9PT0gJz4nKSB7XG4gICAgICAgICAgICBvcGVuVGFnKHBhcnNlcilcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gUy5BVFRSSUJcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWVcblxuICAgICAgICBjYXNlIFMuQ0xPU0VfVEFHOlxuICAgICAgICAgIGlmICghcGFyc2VyLnRhZ05hbWUpIHtcbiAgICAgICAgICAgIGlmIChpc1doaXRlc3BhY2UoYykpIHtcbiAgICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobm90TWF0Y2gobmFtZVN0YXJ0LCBjKSkge1xuICAgICAgICAgICAgICBpZiAocGFyc2VyLnNjcmlwdCkge1xuICAgICAgICAgICAgICAgIHBhcnNlci5zY3JpcHQgKz0gJzwvJyArIGNcbiAgICAgICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSBTLlNDUklQVFxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHN0cmljdEZhaWwocGFyc2VyLCAnSW52YWxpZCB0YWduYW1lIGluIGNsb3NpbmcgdGFnLicpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHBhcnNlci50YWdOYW1lID0gY1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoYyA9PT0gJz4nKSB7XG4gICAgICAgICAgICBjbG9zZVRhZyhwYXJzZXIpXG4gICAgICAgICAgfSBlbHNlIGlmIChpc01hdGNoKG5hbWVCb2R5LCBjKSkge1xuICAgICAgICAgICAgcGFyc2VyLnRhZ05hbWUgKz0gY1xuICAgICAgICAgIH0gZWxzZSBpZiAocGFyc2VyLnNjcmlwdCkge1xuICAgICAgICAgICAgcGFyc2VyLnNjcmlwdCArPSAnPC8nICsgcGFyc2VyLnRhZ05hbWVcbiAgICAgICAgICAgIHBhcnNlci50YWdOYW1lID0gJydcbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuU0NSSVBUXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghaXNXaGl0ZXNwYWNlKGMpKSB7XG4gICAgICAgICAgICAgIHN0cmljdEZhaWwocGFyc2VyLCAnSW52YWxpZCB0YWduYW1lIGluIGNsb3NpbmcgdGFnJylcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBhcnNlci5zdGF0ZSA9IFMuQ0xPU0VfVEFHX1NBV19XSElURVxuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5DTE9TRV9UQUdfU0FXX1dISVRFOlxuICAgICAgICAgIGlmIChpc1doaXRlc3BhY2UoYykpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChjID09PSAnPicpIHtcbiAgICAgICAgICAgIGNsb3NlVGFnKHBhcnNlcilcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdJbnZhbGlkIGNoYXJhY3RlcnMgaW4gY2xvc2luZyB0YWcnKVxuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZVxuXG4gICAgICAgIGNhc2UgUy5URVhUX0VOVElUWTpcbiAgICAgICAgY2FzZSBTLkFUVFJJQl9WQUxVRV9FTlRJVFlfUTpcbiAgICAgICAgY2FzZSBTLkFUVFJJQl9WQUxVRV9FTlRJVFlfVTpcbiAgICAgICAgICB2YXIgcmV0dXJuU3RhdGVcbiAgICAgICAgICB2YXIgYnVmZmVyXG4gICAgICAgICAgc3dpdGNoIChwYXJzZXIuc3RhdGUpIHtcbiAgICAgICAgICAgIGNhc2UgUy5URVhUX0VOVElUWTpcbiAgICAgICAgICAgICAgcmV0dXJuU3RhdGUgPSBTLlRFWFRcbiAgICAgICAgICAgICAgYnVmZmVyID0gJ3RleHROb2RlJ1xuICAgICAgICAgICAgICBicmVha1xuXG4gICAgICAgICAgICBjYXNlIFMuQVRUUklCX1ZBTFVFX0VOVElUWV9ROlxuICAgICAgICAgICAgICByZXR1cm5TdGF0ZSA9IFMuQVRUUklCX1ZBTFVFX1FVT1RFRFxuICAgICAgICAgICAgICBidWZmZXIgPSAnYXR0cmliVmFsdWUnXG4gICAgICAgICAgICAgIGJyZWFrXG5cbiAgICAgICAgICAgIGNhc2UgUy5BVFRSSUJfVkFMVUVfRU5USVRZX1U6XG4gICAgICAgICAgICAgIHJldHVyblN0YXRlID0gUy5BVFRSSUJfVkFMVUVfVU5RVU9URURcbiAgICAgICAgICAgICAgYnVmZmVyID0gJ2F0dHJpYlZhbHVlJ1xuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChjID09PSAnOycpIHtcbiAgICAgICAgICAgIHBhcnNlcltidWZmZXJdICs9IHBhcnNlRW50aXR5KHBhcnNlcilcbiAgICAgICAgICAgIHBhcnNlci5lbnRpdHkgPSAnJ1xuICAgICAgICAgICAgcGFyc2VyLnN0YXRlID0gcmV0dXJuU3RhdGVcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzTWF0Y2gocGFyc2VyLmVudGl0eS5sZW5ndGggPyBlbnRpdHlCb2R5IDogZW50aXR5U3RhcnQsIGMpKSB7XG4gICAgICAgICAgICBwYXJzZXIuZW50aXR5ICs9IGNcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3RyaWN0RmFpbChwYXJzZXIsICdJbnZhbGlkIGNoYXJhY3RlciBpbiBlbnRpdHkgbmFtZScpXG4gICAgICAgICAgICBwYXJzZXJbYnVmZmVyXSArPSAnJicgKyBwYXJzZXIuZW50aXR5ICsgY1xuICAgICAgICAgICAgcGFyc2VyLmVudGl0eSA9ICcnXG4gICAgICAgICAgICBwYXJzZXIuc3RhdGUgPSByZXR1cm5TdGF0ZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnRpbnVlXG5cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IocGFyc2VyLCAnVW5rbm93biBzdGF0ZTogJyArIHBhcnNlci5zdGF0ZSlcbiAgICAgIH1cbiAgICB9IC8vIHdoaWxlXG5cbiAgICBpZiAocGFyc2VyLnBvc2l0aW9uID49IHBhcnNlci5idWZmZXJDaGVja1Bvc2l0aW9uKSB7XG4gICAgICBjaGVja0J1ZmZlckxlbmd0aChwYXJzZXIpXG4gICAgfVxuICAgIHJldHVybiBwYXJzZXJcbiAgfVxuXG4gIC8qISBodHRwOi8vbXRocy5iZS9mcm9tY29kZXBvaW50IHYwLjEuMCBieSBAbWF0aGlhcyAqL1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICBpZiAoIVN0cmluZy5mcm9tQ29kZVBvaW50KSB7XG4gICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBzdHJpbmdGcm9tQ2hhckNvZGUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlXG4gICAgICB2YXIgZmxvb3IgPSBNYXRoLmZsb29yXG4gICAgICB2YXIgZnJvbUNvZGVQb2ludCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIE1BWF9TSVpFID0gMHg0MDAwXG4gICAgICAgIHZhciBjb2RlVW5pdHMgPSBbXVxuICAgICAgICB2YXIgaGlnaFN1cnJvZ2F0ZVxuICAgICAgICB2YXIgbG93U3Vycm9nYXRlXG4gICAgICAgIHZhciBpbmRleCA9IC0xXG4gICAgICAgIHZhciBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoXG4gICAgICAgIGlmICghbGVuZ3RoKSB7XG4gICAgICAgICAgcmV0dXJuICcnXG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJlc3VsdCA9ICcnXG4gICAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgdmFyIGNvZGVQb2ludCA9IE51bWJlcihhcmd1bWVudHNbaW5kZXhdKVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICFpc0Zpbml0ZShjb2RlUG9pbnQpIHx8IC8vIGBOYU5gLCBgK0luZmluaXR5YCwgb3IgYC1JbmZpbml0eWBcbiAgICAgICAgICAgIGNvZGVQb2ludCA8IDAgfHwgLy8gbm90IGEgdmFsaWQgVW5pY29kZSBjb2RlIHBvaW50XG4gICAgICAgICAgICBjb2RlUG9pbnQgPiAweDEwRkZGRiB8fCAvLyBub3QgYSB2YWxpZCBVbmljb2RlIGNvZGUgcG9pbnRcbiAgICAgICAgICAgIGZsb29yKGNvZGVQb2ludCkgIT09IGNvZGVQb2ludCAvLyBub3QgYW4gaW50ZWdlclxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhyb3cgUmFuZ2VFcnJvcignSW52YWxpZCBjb2RlIHBvaW50OiAnICsgY29kZVBvaW50KVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY29kZVBvaW50IDw9IDB4RkZGRikgeyAvLyBCTVAgY29kZSBwb2ludFxuICAgICAgICAgICAgY29kZVVuaXRzLnB1c2goY29kZVBvaW50KVxuICAgICAgICAgIH0gZWxzZSB7IC8vIEFzdHJhbCBjb2RlIHBvaW50OyBzcGxpdCBpbiBzdXJyb2dhdGUgaGFsdmVzXG4gICAgICAgICAgICAvLyBodHRwOi8vbWF0aGlhc2J5bmVucy5iZS9ub3Rlcy9qYXZhc2NyaXB0LWVuY29kaW5nI3N1cnJvZ2F0ZS1mb3JtdWxhZVxuICAgICAgICAgICAgY29kZVBvaW50IC09IDB4MTAwMDBcbiAgICAgICAgICAgIGhpZ2hTdXJyb2dhdGUgPSAoY29kZVBvaW50ID4+IDEwKSArIDB4RDgwMFxuICAgICAgICAgICAgbG93U3Vycm9nYXRlID0gKGNvZGVQb2ludCAlIDB4NDAwKSArIDB4REMwMFxuICAgICAgICAgICAgY29kZVVuaXRzLnB1c2goaGlnaFN1cnJvZ2F0ZSwgbG93U3Vycm9nYXRlKVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoaW5kZXggKyAxID09PSBsZW5ndGggfHwgY29kZVVuaXRzLmxlbmd0aCA+IE1BWF9TSVpFKSB7XG4gICAgICAgICAgICByZXN1bHQgKz0gc3RyaW5nRnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGNvZGVVbml0cylcbiAgICAgICAgICAgIGNvZGVVbml0cy5sZW5ndGggPSAwXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICAgIH1cbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShTdHJpbmcsICdmcm9tQ29kZVBvaW50Jywge1xuICAgICAgICAgIHZhbHVlOiBmcm9tQ29kZVBvaW50LFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICB3cml0YWJsZTogdHJ1ZVxuICAgICAgICB9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgU3RyaW5nLmZyb21Db2RlUG9pbnQgPSBmcm9tQ29kZVBvaW50XG4gICAgICB9XG4gICAgfSgpKVxuICB9XG59KSh0eXBlb2YgZXhwb3J0cyA9PT0gJ3VuZGVmaW5lZCcgPyB0aGlzLnNheCA9IHt9IDogZXhwb3J0cylcbiIsInZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxuXG4vLyBwcm90b3R5cGUgY2xhc3MgZm9yIGhhc2ggZnVuY3Rpb25zXG5mdW5jdGlvbiBIYXNoIChibG9ja1NpemUsIGZpbmFsU2l6ZSkge1xuICB0aGlzLl9ibG9jayA9IEJ1ZmZlci5hbGxvYyhibG9ja1NpemUpXG4gIHRoaXMuX2ZpbmFsU2l6ZSA9IGZpbmFsU2l6ZVxuICB0aGlzLl9ibG9ja1NpemUgPSBibG9ja1NpemVcbiAgdGhpcy5fbGVuID0gMFxufVxuXG5IYXNoLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSwgZW5jKSB7XG4gIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmMgPSBlbmMgfHwgJ3V0ZjgnXG4gICAgZGF0YSA9IEJ1ZmZlci5mcm9tKGRhdGEsIGVuYylcbiAgfVxuXG4gIHZhciBibG9jayA9IHRoaXMuX2Jsb2NrXG4gIHZhciBibG9ja1NpemUgPSB0aGlzLl9ibG9ja1NpemVcbiAgdmFyIGxlbmd0aCA9IGRhdGEubGVuZ3RoXG4gIHZhciBhY2N1bSA9IHRoaXMuX2xlblxuXG4gIGZvciAodmFyIG9mZnNldCA9IDA7IG9mZnNldCA8IGxlbmd0aDspIHtcbiAgICB2YXIgYXNzaWduZWQgPSBhY2N1bSAlIGJsb2NrU2l6ZVxuICAgIHZhciByZW1haW5kZXIgPSBNYXRoLm1pbihsZW5ndGggLSBvZmZzZXQsIGJsb2NrU2l6ZSAtIGFzc2lnbmVkKVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZW1haW5kZXI7IGkrKykge1xuICAgICAgYmxvY2tbYXNzaWduZWQgKyBpXSA9IGRhdGFbb2Zmc2V0ICsgaV1cbiAgICB9XG5cbiAgICBhY2N1bSArPSByZW1haW5kZXJcbiAgICBvZmZzZXQgKz0gcmVtYWluZGVyXG5cbiAgICBpZiAoKGFjY3VtICUgYmxvY2tTaXplKSA9PT0gMCkge1xuICAgICAgdGhpcy5fdXBkYXRlKGJsb2NrKVxuICAgIH1cbiAgfVxuXG4gIHRoaXMuX2xlbiArPSBsZW5ndGhcbiAgcmV0dXJuIHRoaXNcbn1cblxuSGFzaC5wcm90b3R5cGUuZGlnZXN0ID0gZnVuY3Rpb24gKGVuYykge1xuICB2YXIgcmVtID0gdGhpcy5fbGVuICUgdGhpcy5fYmxvY2tTaXplXG5cbiAgdGhpcy5fYmxvY2tbcmVtXSA9IDB4ODBcblxuICAvLyB6ZXJvIChyZW0gKyAxKSB0cmFpbGluZyBiaXRzLCB3aGVyZSAocmVtICsgMSkgaXMgdGhlIHNtYWxsZXN0XG4gIC8vIG5vbi1uZWdhdGl2ZSBzb2x1dGlvbiB0byB0aGUgZXF1YXRpb24gKGxlbmd0aCArIDEgKyAocmVtICsgMSkpID09PSBmaW5hbFNpemUgbW9kIGJsb2NrU2l6ZVxuICB0aGlzLl9ibG9jay5maWxsKDAsIHJlbSArIDEpXG5cbiAgaWYgKHJlbSA+PSB0aGlzLl9maW5hbFNpemUpIHtcbiAgICB0aGlzLl91cGRhdGUodGhpcy5fYmxvY2spXG4gICAgdGhpcy5fYmxvY2suZmlsbCgwKVxuICB9XG5cbiAgdmFyIGJpdHMgPSB0aGlzLl9sZW4gKiA4XG5cbiAgLy8gdWludDMyXG4gIGlmIChiaXRzIDw9IDB4ZmZmZmZmZmYpIHtcbiAgICB0aGlzLl9ibG9jay53cml0ZVVJbnQzMkJFKGJpdHMsIHRoaXMuX2Jsb2NrU2l6ZSAtIDQpXG5cbiAgLy8gdWludDY0XG4gIH0gZWxzZSB7XG4gICAgdmFyIGxvd0JpdHMgPSAoYml0cyAmIDB4ZmZmZmZmZmYpID4+PiAwXG4gICAgdmFyIGhpZ2hCaXRzID0gKGJpdHMgLSBsb3dCaXRzKSAvIDB4MTAwMDAwMDAwXG5cbiAgICB0aGlzLl9ibG9jay53cml0ZVVJbnQzMkJFKGhpZ2hCaXRzLCB0aGlzLl9ibG9ja1NpemUgLSA4KVxuICAgIHRoaXMuX2Jsb2NrLndyaXRlVUludDMyQkUobG93Qml0cywgdGhpcy5fYmxvY2tTaXplIC0gNClcbiAgfVxuXG4gIHRoaXMuX3VwZGF0ZSh0aGlzLl9ibG9jaylcbiAgdmFyIGhhc2ggPSB0aGlzLl9oYXNoKClcblxuICByZXR1cm4gZW5jID8gaGFzaC50b1N0cmluZyhlbmMpIDogaGFzaFxufVxuXG5IYXNoLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKCkge1xuICB0aHJvdyBuZXcgRXJyb3IoJ191cGRhdGUgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBzdWJjbGFzcycpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gSGFzaFxuIiwidmFyIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIFNIQSAoYWxnb3JpdGhtKSB7XG4gIGFsZ29yaXRobSA9IGFsZ29yaXRobS50b0xvd2VyQ2FzZSgpXG5cbiAgdmFyIEFsZ29yaXRobSA9IGV4cG9ydHNbYWxnb3JpdGhtXVxuICBpZiAoIUFsZ29yaXRobSkgdGhyb3cgbmV3IEVycm9yKGFsZ29yaXRobSArICcgaXMgbm90IHN1cHBvcnRlZCAod2UgYWNjZXB0IHB1bGwgcmVxdWVzdHMpJylcblxuICByZXR1cm4gbmV3IEFsZ29yaXRobSgpXG59XG5cbmV4cG9ydHMuc2hhID0gcmVxdWlyZSgnLi9zaGEnKVxuZXhwb3J0cy5zaGExID0gcmVxdWlyZSgnLi9zaGExJylcbmV4cG9ydHMuc2hhMjI0ID0gcmVxdWlyZSgnLi9zaGEyMjQnKVxuZXhwb3J0cy5zaGEyNTYgPSByZXF1aXJlKCcuL3NoYTI1NicpXG5leHBvcnRzLnNoYTM4NCA9IHJlcXVpcmUoJy4vc2hhMzg0JylcbmV4cG9ydHMuc2hhNTEyID0gcmVxdWlyZSgnLi9zaGE1MTInKVxuIiwiLypcbiAqIEEgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgU2VjdXJlIEhhc2ggQWxnb3JpdGhtLCBTSEEtMCwgYXMgZGVmaW5lZFxuICogaW4gRklQUyBQVUIgMTgwLTFcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgZGVyaXZlZCBmcm9tIHNoYTEuanMgb2YgdGhlIHNhbWUgcmVwb3NpdG9yeS5cbiAqIFRoZSBkaWZmZXJlbmNlIGJldHdlZW4gU0hBLTAgYW5kIFNIQS0xIGlzIGp1c3QgYSBiaXR3aXNlIHJvdGF0ZSBsZWZ0XG4gKiBvcGVyYXRpb24gd2FzIGFkZGVkLlxuICovXG5cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBIYXNoID0gcmVxdWlyZSgnLi9oYXNoJylcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxuXG52YXIgSyA9IFtcbiAgMHg1YTgyNzk5OSwgMHg2ZWQ5ZWJhMSwgMHg4ZjFiYmNkYyB8IDAsIDB4Y2E2MmMxZDYgfCAwXG5dXG5cbnZhciBXID0gbmV3IEFycmF5KDgwKVxuXG5mdW5jdGlvbiBTaGEgKCkge1xuICB0aGlzLmluaXQoKVxuICB0aGlzLl93ID0gV1xuXG4gIEhhc2guY2FsbCh0aGlzLCA2NCwgNTYpXG59XG5cbmluaGVyaXRzKFNoYSwgSGFzaClcblxuU2hhLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9hID0gMHg2NzQ1MjMwMVxuICB0aGlzLl9iID0gMHhlZmNkYWI4OVxuICB0aGlzLl9jID0gMHg5OGJhZGNmZVxuICB0aGlzLl9kID0gMHgxMDMyNTQ3NlxuICB0aGlzLl9lID0gMHhjM2QyZTFmMFxuXG4gIHJldHVybiB0aGlzXG59XG5cbmZ1bmN0aW9uIHJvdGw1IChudW0pIHtcbiAgcmV0dXJuIChudW0gPDwgNSkgfCAobnVtID4+PiAyNylcbn1cblxuZnVuY3Rpb24gcm90bDMwIChudW0pIHtcbiAgcmV0dXJuIChudW0gPDwgMzApIHwgKG51bSA+Pj4gMilcbn1cblxuZnVuY3Rpb24gZnQgKHMsIGIsIGMsIGQpIHtcbiAgaWYgKHMgPT09IDApIHJldHVybiAoYiAmIGMpIHwgKCh+YikgJiBkKVxuICBpZiAocyA9PT0gMikgcmV0dXJuIChiICYgYykgfCAoYiAmIGQpIHwgKGMgJiBkKVxuICByZXR1cm4gYiBeIGMgXiBkXG59XG5cblNoYS5wcm90b3R5cGUuX3VwZGF0ZSA9IGZ1bmN0aW9uIChNKSB7XG4gIHZhciBXID0gdGhpcy5fd1xuXG4gIHZhciBhID0gdGhpcy5fYSB8IDBcbiAgdmFyIGIgPSB0aGlzLl9iIHwgMFxuICB2YXIgYyA9IHRoaXMuX2MgfCAwXG4gIHZhciBkID0gdGhpcy5fZCB8IDBcbiAgdmFyIGUgPSB0aGlzLl9lIHwgMFxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7ICsraSkgV1tpXSA9IE0ucmVhZEludDMyQkUoaSAqIDQpXG4gIGZvciAoOyBpIDwgODA7ICsraSkgV1tpXSA9IFdbaSAtIDNdIF4gV1tpIC0gOF0gXiBXW2kgLSAxNF0gXiBXW2kgLSAxNl1cblxuICBmb3IgKHZhciBqID0gMDsgaiA8IDgwOyArK2opIHtcbiAgICB2YXIgcyA9IH5+KGogLyAyMClcbiAgICB2YXIgdCA9IChyb3RsNShhKSArIGZ0KHMsIGIsIGMsIGQpICsgZSArIFdbal0gKyBLW3NdKSB8IDBcblxuICAgIGUgPSBkXG4gICAgZCA9IGNcbiAgICBjID0gcm90bDMwKGIpXG4gICAgYiA9IGFcbiAgICBhID0gdFxuICB9XG5cbiAgdGhpcy5fYSA9IChhICsgdGhpcy5fYSkgfCAwXG4gIHRoaXMuX2IgPSAoYiArIHRoaXMuX2IpIHwgMFxuICB0aGlzLl9jID0gKGMgKyB0aGlzLl9jKSB8IDBcbiAgdGhpcy5fZCA9IChkICsgdGhpcy5fZCkgfCAwXG4gIHRoaXMuX2UgPSAoZSArIHRoaXMuX2UpIHwgMFxufVxuXG5TaGEucHJvdG90eXBlLl9oYXNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgSCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSgyMClcblxuICBILndyaXRlSW50MzJCRSh0aGlzLl9hIHwgMCwgMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYiB8IDAsIDQpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2MgfCAwLCA4KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9kIHwgMCwgMTIpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2UgfCAwLCAxNilcblxuICByZXR1cm4gSFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNoYVxuIiwiLypcbiAqIEEgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgU2VjdXJlIEhhc2ggQWxnb3JpdGhtLCBTSEEtMSwgYXMgZGVmaW5lZFxuICogaW4gRklQUyBQVUIgMTgwLTFcbiAqIFZlcnNpb24gMi4xYSBDb3B5cmlnaHQgUGF1bCBKb2huc3RvbiAyMDAwIC0gMjAwMi5cbiAqIE90aGVyIGNvbnRyaWJ1dG9yczogR3JlZyBIb2x0LCBBbmRyZXcgS2VwZXJ0LCBZZG5hciwgTG9zdGluZXRcbiAqIERpc3RyaWJ1dGVkIHVuZGVyIHRoZSBCU0QgTGljZW5zZVxuICogU2VlIGh0dHA6Ly9wYWpob21lLm9yZy51ay9jcnlwdC9tZDUgZm9yIGRldGFpbHMuXG4gKi9cblxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIEhhc2ggPSByZXF1aXJlKCcuL2hhc2gnKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG5cbnZhciBLID0gW1xuICAweDVhODI3OTk5LCAweDZlZDllYmExLCAweDhmMWJiY2RjIHwgMCwgMHhjYTYyYzFkNiB8IDBcbl1cblxudmFyIFcgPSBuZXcgQXJyYXkoODApXG5cbmZ1bmN0aW9uIFNoYTEgKCkge1xuICB0aGlzLmluaXQoKVxuICB0aGlzLl93ID0gV1xuXG4gIEhhc2guY2FsbCh0aGlzLCA2NCwgNTYpXG59XG5cbmluaGVyaXRzKFNoYTEsIEhhc2gpXG5cblNoYTEucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2EgPSAweDY3NDUyMzAxXG4gIHRoaXMuX2IgPSAweGVmY2RhYjg5XG4gIHRoaXMuX2MgPSAweDk4YmFkY2ZlXG4gIHRoaXMuX2QgPSAweDEwMzI1NDc2XG4gIHRoaXMuX2UgPSAweGMzZDJlMWYwXG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gcm90bDEgKG51bSkge1xuICByZXR1cm4gKG51bSA8PCAxKSB8IChudW0gPj4+IDMxKVxufVxuXG5mdW5jdGlvbiByb3RsNSAobnVtKSB7XG4gIHJldHVybiAobnVtIDw8IDUpIHwgKG51bSA+Pj4gMjcpXG59XG5cbmZ1bmN0aW9uIHJvdGwzMCAobnVtKSB7XG4gIHJldHVybiAobnVtIDw8IDMwKSB8IChudW0gPj4+IDIpXG59XG5cbmZ1bmN0aW9uIGZ0IChzLCBiLCBjLCBkKSB7XG4gIGlmIChzID09PSAwKSByZXR1cm4gKGIgJiBjKSB8ICgofmIpICYgZClcbiAgaWYgKHMgPT09IDIpIHJldHVybiAoYiAmIGMpIHwgKGIgJiBkKSB8IChjICYgZClcbiAgcmV0dXJuIGIgXiBjIF4gZFxufVxuXG5TaGExLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKE0pIHtcbiAgdmFyIFcgPSB0aGlzLl93XG5cbiAgdmFyIGEgPSB0aGlzLl9hIHwgMFxuICB2YXIgYiA9IHRoaXMuX2IgfCAwXG4gIHZhciBjID0gdGhpcy5fYyB8IDBcbiAgdmFyIGQgPSB0aGlzLl9kIHwgMFxuICB2YXIgZSA9IHRoaXMuX2UgfCAwXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgKytpKSBXW2ldID0gTS5yZWFkSW50MzJCRShpICogNClcbiAgZm9yICg7IGkgPCA4MDsgKytpKSBXW2ldID0gcm90bDEoV1tpIC0gM10gXiBXW2kgLSA4XSBeIFdbaSAtIDE0XSBeIFdbaSAtIDE2XSlcblxuICBmb3IgKHZhciBqID0gMDsgaiA8IDgwOyArK2opIHtcbiAgICB2YXIgcyA9IH5+KGogLyAyMClcbiAgICB2YXIgdCA9IChyb3RsNShhKSArIGZ0KHMsIGIsIGMsIGQpICsgZSArIFdbal0gKyBLW3NdKSB8IDBcblxuICAgIGUgPSBkXG4gICAgZCA9IGNcbiAgICBjID0gcm90bDMwKGIpXG4gICAgYiA9IGFcbiAgICBhID0gdFxuICB9XG5cbiAgdGhpcy5fYSA9IChhICsgdGhpcy5fYSkgfCAwXG4gIHRoaXMuX2IgPSAoYiArIHRoaXMuX2IpIHwgMFxuICB0aGlzLl9jID0gKGMgKyB0aGlzLl9jKSB8IDBcbiAgdGhpcy5fZCA9IChkICsgdGhpcy5fZCkgfCAwXG4gIHRoaXMuX2UgPSAoZSArIHRoaXMuX2UpIHwgMFxufVxuXG5TaGExLnByb3RvdHlwZS5faGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIEggPSBCdWZmZXIuYWxsb2NVbnNhZmUoMjApXG5cbiAgSC53cml0ZUludDMyQkUodGhpcy5fYSB8IDAsIDApXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2IgfCAwLCA0KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9jIHwgMCwgOClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZCB8IDAsIDEyKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9lIHwgMCwgMTYpXG5cbiAgcmV0dXJuIEhcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTaGExXG4iLCIvKipcbiAqIEEgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgU2VjdXJlIEhhc2ggQWxnb3JpdGhtLCBTSEEtMjU2LCBhcyBkZWZpbmVkXG4gKiBpbiBGSVBTIDE4MC0yXG4gKiBWZXJzaW9uIDIuMi1iZXRhIENvcHlyaWdodCBBbmdlbCBNYXJpbiwgUGF1bCBKb2huc3RvbiAyMDAwIC0gMjAwOS5cbiAqIE90aGVyIGNvbnRyaWJ1dG9yczogR3JlZyBIb2x0LCBBbmRyZXcgS2VwZXJ0LCBZZG5hciwgTG9zdGluZXRcbiAqXG4gKi9cblxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKVxudmFyIFNoYTI1NiA9IHJlcXVpcmUoJy4vc2hhMjU2JylcbnZhciBIYXNoID0gcmVxdWlyZSgnLi9oYXNoJylcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxuXG52YXIgVyA9IG5ldyBBcnJheSg2NClcblxuZnVuY3Rpb24gU2hhMjI0ICgpIHtcbiAgdGhpcy5pbml0KClcblxuICB0aGlzLl93ID0gVyAvLyBuZXcgQXJyYXkoNjQpXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDY0LCA1Nilcbn1cblxuaW5oZXJpdHMoU2hhMjI0LCBTaGEyNTYpXG5cblNoYTIyNC5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fYSA9IDB4YzEwNTllZDhcbiAgdGhpcy5fYiA9IDB4MzY3Y2Q1MDdcbiAgdGhpcy5fYyA9IDB4MzA3MGRkMTdcbiAgdGhpcy5fZCA9IDB4ZjcwZTU5MzlcbiAgdGhpcy5fZSA9IDB4ZmZjMDBiMzFcbiAgdGhpcy5fZiA9IDB4Njg1ODE1MTFcbiAgdGhpcy5fZyA9IDB4NjRmOThmYTdcbiAgdGhpcy5faCA9IDB4YmVmYTRmYTRcblxuICByZXR1cm4gdGhpc1xufVxuXG5TaGEyMjQucHJvdG90eXBlLl9oYXNoID0gZnVuY3Rpb24gKCkge1xuICB2YXIgSCA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSgyOClcblxuICBILndyaXRlSW50MzJCRSh0aGlzLl9hLCAwKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9iLCA0KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9jLCA4KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9kLCAxMilcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZSwgMTYpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2YsIDIwKVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9nLCAyNClcblxuICByZXR1cm4gSFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNoYTIyNFxuIiwiLyoqXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFNlY3VyZSBIYXNoIEFsZ29yaXRobSwgU0hBLTI1NiwgYXMgZGVmaW5lZFxuICogaW4gRklQUyAxODAtMlxuICogVmVyc2lvbiAyLjItYmV0YSBDb3B5cmlnaHQgQW5nZWwgTWFyaW4sIFBhdWwgSm9obnN0b24gMjAwMCAtIDIwMDkuXG4gKiBPdGhlciBjb250cmlidXRvcnM6IEdyZWcgSG9sdCwgQW5kcmV3IEtlcGVydCwgWWRuYXIsIExvc3RpbmV0XG4gKlxuICovXG5cbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJylcbnZhciBIYXNoID0gcmVxdWlyZSgnLi9oYXNoJylcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdzYWZlLWJ1ZmZlcicpLkJ1ZmZlclxuXG52YXIgSyA9IFtcbiAgMHg0MjhBMkY5OCwgMHg3MTM3NDQ5MSwgMHhCNUMwRkJDRiwgMHhFOUI1REJBNSxcbiAgMHgzOTU2QzI1QiwgMHg1OUYxMTFGMSwgMHg5MjNGODJBNCwgMHhBQjFDNUVENSxcbiAgMHhEODA3QUE5OCwgMHgxMjgzNUIwMSwgMHgyNDMxODVCRSwgMHg1NTBDN0RDMyxcbiAgMHg3MkJFNUQ3NCwgMHg4MERFQjFGRSwgMHg5QkRDMDZBNywgMHhDMTlCRjE3NCxcbiAgMHhFNDlCNjlDMSwgMHhFRkJFNDc4NiwgMHgwRkMxOURDNiwgMHgyNDBDQTFDQyxcbiAgMHgyREU5MkM2RiwgMHg0QTc0ODRBQSwgMHg1Q0IwQTlEQywgMHg3NkY5ODhEQSxcbiAgMHg5ODNFNTE1MiwgMHhBODMxQzY2RCwgMHhCMDAzMjdDOCwgMHhCRjU5N0ZDNyxcbiAgMHhDNkUwMEJGMywgMHhENUE3OTE0NywgMHgwNkNBNjM1MSwgMHgxNDI5Mjk2NyxcbiAgMHgyN0I3MEE4NSwgMHgyRTFCMjEzOCwgMHg0RDJDNkRGQywgMHg1MzM4MEQxMyxcbiAgMHg2NTBBNzM1NCwgMHg3NjZBMEFCQiwgMHg4MUMyQzkyRSwgMHg5MjcyMkM4NSxcbiAgMHhBMkJGRThBMSwgMHhBODFBNjY0QiwgMHhDMjRCOEI3MCwgMHhDNzZDNTFBMyxcbiAgMHhEMTkyRTgxOSwgMHhENjk5MDYyNCwgMHhGNDBFMzU4NSwgMHgxMDZBQTA3MCxcbiAgMHgxOUE0QzExNiwgMHgxRTM3NkMwOCwgMHgyNzQ4Nzc0QywgMHgzNEIwQkNCNSxcbiAgMHgzOTFDMENCMywgMHg0RUQ4QUE0QSwgMHg1QjlDQ0E0RiwgMHg2ODJFNkZGMyxcbiAgMHg3NDhGODJFRSwgMHg3OEE1NjM2RiwgMHg4NEM4NzgxNCwgMHg4Q0M3MDIwOCxcbiAgMHg5MEJFRkZGQSwgMHhBNDUwNkNFQiwgMHhCRUY5QTNGNywgMHhDNjcxNzhGMlxuXVxuXG52YXIgVyA9IG5ldyBBcnJheSg2NClcblxuZnVuY3Rpb24gU2hhMjU2ICgpIHtcbiAgdGhpcy5pbml0KClcblxuICB0aGlzLl93ID0gVyAvLyBuZXcgQXJyYXkoNjQpXG5cbiAgSGFzaC5jYWxsKHRoaXMsIDY0LCA1Nilcbn1cblxuaW5oZXJpdHMoU2hhMjU2LCBIYXNoKVxuXG5TaGEyNTYucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2EgPSAweDZhMDllNjY3XG4gIHRoaXMuX2IgPSAweGJiNjdhZTg1XG4gIHRoaXMuX2MgPSAweDNjNmVmMzcyXG4gIHRoaXMuX2QgPSAweGE1NGZmNTNhXG4gIHRoaXMuX2UgPSAweDUxMGU1MjdmXG4gIHRoaXMuX2YgPSAweDliMDU2ODhjXG4gIHRoaXMuX2cgPSAweDFmODNkOWFiXG4gIHRoaXMuX2ggPSAweDViZTBjZDE5XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gY2ggKHgsIHksIHopIHtcbiAgcmV0dXJuIHogXiAoeCAmICh5IF4geikpXG59XG5cbmZ1bmN0aW9uIG1haiAoeCwgeSwgeikge1xuICByZXR1cm4gKHggJiB5KSB8ICh6ICYgKHggfCB5KSlcbn1cblxuZnVuY3Rpb24gc2lnbWEwICh4KSB7XG4gIHJldHVybiAoeCA+Pj4gMiB8IHggPDwgMzApIF4gKHggPj4+IDEzIHwgeCA8PCAxOSkgXiAoeCA+Pj4gMjIgfCB4IDw8IDEwKVxufVxuXG5mdW5jdGlvbiBzaWdtYTEgKHgpIHtcbiAgcmV0dXJuICh4ID4+PiA2IHwgeCA8PCAyNikgXiAoeCA+Pj4gMTEgfCB4IDw8IDIxKSBeICh4ID4+PiAyNSB8IHggPDwgNylcbn1cblxuZnVuY3Rpb24gZ2FtbWEwICh4KSB7XG4gIHJldHVybiAoeCA+Pj4gNyB8IHggPDwgMjUpIF4gKHggPj4+IDE4IHwgeCA8PCAxNCkgXiAoeCA+Pj4gMylcbn1cblxuZnVuY3Rpb24gZ2FtbWExICh4KSB7XG4gIHJldHVybiAoeCA+Pj4gMTcgfCB4IDw8IDE1KSBeICh4ID4+PiAxOSB8IHggPDwgMTMpIF4gKHggPj4+IDEwKVxufVxuXG5TaGEyNTYucHJvdG90eXBlLl91cGRhdGUgPSBmdW5jdGlvbiAoTSkge1xuICB2YXIgVyA9IHRoaXMuX3dcblxuICB2YXIgYSA9IHRoaXMuX2EgfCAwXG4gIHZhciBiID0gdGhpcy5fYiB8IDBcbiAgdmFyIGMgPSB0aGlzLl9jIHwgMFxuICB2YXIgZCA9IHRoaXMuX2QgfCAwXG4gIHZhciBlID0gdGhpcy5fZSB8IDBcbiAgdmFyIGYgPSB0aGlzLl9mIHwgMFxuICB2YXIgZyA9IHRoaXMuX2cgfCAwXG4gIHZhciBoID0gdGhpcy5faCB8IDBcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyArK2kpIFdbaV0gPSBNLnJlYWRJbnQzMkJFKGkgKiA0KVxuICBmb3IgKDsgaSA8IDY0OyArK2kpIFdbaV0gPSAoZ2FtbWExKFdbaSAtIDJdKSArIFdbaSAtIDddICsgZ2FtbWEwKFdbaSAtIDE1XSkgKyBXW2kgLSAxNl0pIHwgMFxuXG4gIGZvciAodmFyIGogPSAwOyBqIDwgNjQ7ICsraikge1xuICAgIHZhciBUMSA9IChoICsgc2lnbWExKGUpICsgY2goZSwgZiwgZykgKyBLW2pdICsgV1tqXSkgfCAwXG4gICAgdmFyIFQyID0gKHNpZ21hMChhKSArIG1haihhLCBiLCBjKSkgfCAwXG5cbiAgICBoID0gZ1xuICAgIGcgPSBmXG4gICAgZiA9IGVcbiAgICBlID0gKGQgKyBUMSkgfCAwXG4gICAgZCA9IGNcbiAgICBjID0gYlxuICAgIGIgPSBhXG4gICAgYSA9IChUMSArIFQyKSB8IDBcbiAgfVxuXG4gIHRoaXMuX2EgPSAoYSArIHRoaXMuX2EpIHwgMFxuICB0aGlzLl9iID0gKGIgKyB0aGlzLl9iKSB8IDBcbiAgdGhpcy5fYyA9IChjICsgdGhpcy5fYykgfCAwXG4gIHRoaXMuX2QgPSAoZCArIHRoaXMuX2QpIHwgMFxuICB0aGlzLl9lID0gKGUgKyB0aGlzLl9lKSB8IDBcbiAgdGhpcy5fZiA9IChmICsgdGhpcy5fZikgfCAwXG4gIHRoaXMuX2cgPSAoZyArIHRoaXMuX2cpIHwgMFxuICB0aGlzLl9oID0gKGggKyB0aGlzLl9oKSB8IDBcbn1cblxuU2hhMjU2LnByb3RvdHlwZS5faGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIEggPSBCdWZmZXIuYWxsb2NVbnNhZmUoMzIpXG5cbiAgSC53cml0ZUludDMyQkUodGhpcy5fYSwgMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYiwgNClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fYywgOClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZCwgMTIpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2UsIDE2KVxuICBILndyaXRlSW50MzJCRSh0aGlzLl9mLCAyMClcbiAgSC53cml0ZUludDMyQkUodGhpcy5fZywgMjQpXG4gIEgud3JpdGVJbnQzMkJFKHRoaXMuX2gsIDI4KVxuXG4gIHJldHVybiBIXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2hhMjU2XG4iLCJ2YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgU0hBNTEyID0gcmVxdWlyZSgnLi9zaGE1MTInKVxudmFyIEhhc2ggPSByZXF1aXJlKCcuL2hhc2gnKVxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ3NhZmUtYnVmZmVyJykuQnVmZmVyXG5cbnZhciBXID0gbmV3IEFycmF5KDE2MClcblxuZnVuY3Rpb24gU2hhMzg0ICgpIHtcbiAgdGhpcy5pbml0KClcbiAgdGhpcy5fdyA9IFdcblxuICBIYXNoLmNhbGwodGhpcywgMTI4LCAxMTIpXG59XG5cbmluaGVyaXRzKFNoYTM4NCwgU0hBNTEyKVxuXG5TaGEzODQucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2FoID0gMHhjYmJiOWQ1ZFxuICB0aGlzLl9iaCA9IDB4NjI5YTI5MmFcbiAgdGhpcy5fY2ggPSAweDkxNTkwMTVhXG4gIHRoaXMuX2RoID0gMHgxNTJmZWNkOFxuICB0aGlzLl9laCA9IDB4NjczMzI2NjdcbiAgdGhpcy5fZmggPSAweDhlYjQ0YTg3XG4gIHRoaXMuX2doID0gMHhkYjBjMmUwZFxuICB0aGlzLl9oaCA9IDB4NDdiNTQ4MWRcblxuICB0aGlzLl9hbCA9IDB4YzEwNTllZDhcbiAgdGhpcy5fYmwgPSAweDM2N2NkNTA3XG4gIHRoaXMuX2NsID0gMHgzMDcwZGQxN1xuICB0aGlzLl9kbCA9IDB4ZjcwZTU5MzlcbiAgdGhpcy5fZWwgPSAweGZmYzAwYjMxXG4gIHRoaXMuX2ZsID0gMHg2ODU4MTUxMVxuICB0aGlzLl9nbCA9IDB4NjRmOThmYTdcbiAgdGhpcy5faGwgPSAweGJlZmE0ZmE0XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuU2hhMzg0LnByb3RvdHlwZS5faGFzaCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIEggPSBCdWZmZXIuYWxsb2NVbnNhZmUoNDgpXG5cbiAgZnVuY3Rpb24gd3JpdGVJbnQ2NEJFIChoLCBsLCBvZmZzZXQpIHtcbiAgICBILndyaXRlSW50MzJCRShoLCBvZmZzZXQpXG4gICAgSC53cml0ZUludDMyQkUobCwgb2Zmc2V0ICsgNClcbiAgfVxuXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9haCwgdGhpcy5fYWwsIDApXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9iaCwgdGhpcy5fYmwsIDgpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9jaCwgdGhpcy5fY2wsIDE2KVxuICB3cml0ZUludDY0QkUodGhpcy5fZGgsIHRoaXMuX2RsLCAyNClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2VoLCB0aGlzLl9lbCwgMzIpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9maCwgdGhpcy5fZmwsIDQwKVxuXG4gIHJldHVybiBIXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2hhMzg0XG4iLCJ2YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpXG52YXIgSGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnc2FmZS1idWZmZXInKS5CdWZmZXJcblxudmFyIEsgPSBbXG4gIDB4NDI4YTJmOTgsIDB4ZDcyOGFlMjIsIDB4NzEzNzQ0OTEsIDB4MjNlZjY1Y2QsXG4gIDB4YjVjMGZiY2YsIDB4ZWM0ZDNiMmYsIDB4ZTliNWRiYTUsIDB4ODE4OWRiYmMsXG4gIDB4Mzk1NmMyNWIsIDB4ZjM0OGI1MzgsIDB4NTlmMTExZjEsIDB4YjYwNWQwMTksXG4gIDB4OTIzZjgyYTQsIDB4YWYxOTRmOWIsIDB4YWIxYzVlZDUsIDB4ZGE2ZDgxMTgsXG4gIDB4ZDgwN2FhOTgsIDB4YTMwMzAyNDIsIDB4MTI4MzViMDEsIDB4NDU3MDZmYmUsXG4gIDB4MjQzMTg1YmUsIDB4NGVlNGIyOGMsIDB4NTUwYzdkYzMsIDB4ZDVmZmI0ZTIsXG4gIDB4NzJiZTVkNzQsIDB4ZjI3Yjg5NmYsIDB4ODBkZWIxZmUsIDB4M2IxNjk2YjEsXG4gIDB4OWJkYzA2YTcsIDB4MjVjNzEyMzUsIDB4YzE5YmYxNzQsIDB4Y2Y2OTI2OTQsXG4gIDB4ZTQ5YjY5YzEsIDB4OWVmMTRhZDIsIDB4ZWZiZTQ3ODYsIDB4Mzg0ZjI1ZTMsXG4gIDB4MGZjMTlkYzYsIDB4OGI4Y2Q1YjUsIDB4MjQwY2ExY2MsIDB4NzdhYzljNjUsXG4gIDB4MmRlOTJjNmYsIDB4NTkyYjAyNzUsIDB4NGE3NDg0YWEsIDB4NmVhNmU0ODMsXG4gIDB4NWNiMGE5ZGMsIDB4YmQ0MWZiZDQsIDB4NzZmOTg4ZGEsIDB4ODMxMTUzYjUsXG4gIDB4OTgzZTUxNTIsIDB4ZWU2NmRmYWIsIDB4YTgzMWM2NmQsIDB4MmRiNDMyMTAsXG4gIDB4YjAwMzI3YzgsIDB4OThmYjIxM2YsIDB4YmY1OTdmYzcsIDB4YmVlZjBlZTQsXG4gIDB4YzZlMDBiZjMsIDB4M2RhODhmYzIsIDB4ZDVhNzkxNDcsIDB4OTMwYWE3MjUsXG4gIDB4MDZjYTYzNTEsIDB4ZTAwMzgyNmYsIDB4MTQyOTI5NjcsIDB4MGEwZTZlNzAsXG4gIDB4MjdiNzBhODUsIDB4NDZkMjJmZmMsIDB4MmUxYjIxMzgsIDB4NWMyNmM5MjYsXG4gIDB4NGQyYzZkZmMsIDB4NWFjNDJhZWQsIDB4NTMzODBkMTMsIDB4OWQ5NWIzZGYsXG4gIDB4NjUwYTczNTQsIDB4OGJhZjYzZGUsIDB4NzY2YTBhYmIsIDB4M2M3N2IyYTgsXG4gIDB4ODFjMmM5MmUsIDB4NDdlZGFlZTYsIDB4OTI3MjJjODUsIDB4MTQ4MjM1M2IsXG4gIDB4YTJiZmU4YTEsIDB4NGNmMTAzNjQsIDB4YTgxYTY2NGIsIDB4YmM0MjMwMDEsXG4gIDB4YzI0YjhiNzAsIDB4ZDBmODk3OTEsIDB4Yzc2YzUxYTMsIDB4MDY1NGJlMzAsXG4gIDB4ZDE5MmU4MTksIDB4ZDZlZjUyMTgsIDB4ZDY5OTA2MjQsIDB4NTU2NWE5MTAsXG4gIDB4ZjQwZTM1ODUsIDB4NTc3MTIwMmEsIDB4MTA2YWEwNzAsIDB4MzJiYmQxYjgsXG4gIDB4MTlhNGMxMTYsIDB4YjhkMmQwYzgsIDB4MWUzNzZjMDgsIDB4NTE0MWFiNTMsXG4gIDB4Mjc0ODc3NGMsIDB4ZGY4ZWViOTksIDB4MzRiMGJjYjUsIDB4ZTE5YjQ4YTgsXG4gIDB4MzkxYzBjYjMsIDB4YzVjOTVhNjMsIDB4NGVkOGFhNGEsIDB4ZTM0MThhY2IsXG4gIDB4NWI5Y2NhNGYsIDB4Nzc2M2UzNzMsIDB4NjgyZTZmZjMsIDB4ZDZiMmI4YTMsXG4gIDB4NzQ4ZjgyZWUsIDB4NWRlZmIyZmMsIDB4NzhhNTYzNmYsIDB4NDMxNzJmNjAsXG4gIDB4ODRjODc4MTQsIDB4YTFmMGFiNzIsIDB4OGNjNzAyMDgsIDB4MWE2NDM5ZWMsXG4gIDB4OTBiZWZmZmEsIDB4MjM2MzFlMjgsIDB4YTQ1MDZjZWIsIDB4ZGU4MmJkZTksXG4gIDB4YmVmOWEzZjcsIDB4YjJjNjc5MTUsIDB4YzY3MTc4ZjIsIDB4ZTM3MjUzMmIsXG4gIDB4Y2EyNzNlY2UsIDB4ZWEyNjYxOWMsIDB4ZDE4NmI4YzcsIDB4MjFjMGMyMDcsXG4gIDB4ZWFkYTdkZDYsIDB4Y2RlMGViMWUsIDB4ZjU3ZDRmN2YsIDB4ZWU2ZWQxNzgsXG4gIDB4MDZmMDY3YWEsIDB4NzIxNzZmYmEsIDB4MGE2MzdkYzUsIDB4YTJjODk4YTYsXG4gIDB4MTEzZjk4MDQsIDB4YmVmOTBkYWUsIDB4MWI3MTBiMzUsIDB4MTMxYzQ3MWIsXG4gIDB4MjhkYjc3ZjUsIDB4MjMwNDdkODQsIDB4MzJjYWFiN2IsIDB4NDBjNzI0OTMsXG4gIDB4M2M5ZWJlMGEsIDB4MTVjOWJlYmMsIDB4NDMxZDY3YzQsIDB4OWMxMDBkNGMsXG4gIDB4NGNjNWQ0YmUsIDB4Y2IzZTQyYjYsIDB4NTk3ZjI5OWMsIDB4ZmM2NTdlMmEsXG4gIDB4NWZjYjZmYWIsIDB4M2FkNmZhZWMsIDB4NmM0NDE5OGMsIDB4NGE0NzU4MTdcbl1cblxudmFyIFcgPSBuZXcgQXJyYXkoMTYwKVxuXG5mdW5jdGlvbiBTaGE1MTIgKCkge1xuICB0aGlzLmluaXQoKVxuICB0aGlzLl93ID0gV1xuXG4gIEhhc2guY2FsbCh0aGlzLCAxMjgsIDExMilcbn1cblxuaW5oZXJpdHMoU2hhNTEyLCBIYXNoKVxuXG5TaGE1MTIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX2FoID0gMHg2YTA5ZTY2N1xuICB0aGlzLl9iaCA9IDB4YmI2N2FlODVcbiAgdGhpcy5fY2ggPSAweDNjNmVmMzcyXG4gIHRoaXMuX2RoID0gMHhhNTRmZjUzYVxuICB0aGlzLl9laCA9IDB4NTEwZTUyN2ZcbiAgdGhpcy5fZmggPSAweDliMDU2ODhjXG4gIHRoaXMuX2doID0gMHgxZjgzZDlhYlxuICB0aGlzLl9oaCA9IDB4NWJlMGNkMTlcblxuICB0aGlzLl9hbCA9IDB4ZjNiY2M5MDhcbiAgdGhpcy5fYmwgPSAweDg0Y2FhNzNiXG4gIHRoaXMuX2NsID0gMHhmZTk0ZjgyYlxuICB0aGlzLl9kbCA9IDB4NWYxZDM2ZjFcbiAgdGhpcy5fZWwgPSAweGFkZTY4MmQxXG4gIHRoaXMuX2ZsID0gMHgyYjNlNmMxZlxuICB0aGlzLl9nbCA9IDB4ZmI0MWJkNmJcbiAgdGhpcy5faGwgPSAweDEzN2UyMTc5XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuZnVuY3Rpb24gQ2ggKHgsIHksIHopIHtcbiAgcmV0dXJuIHogXiAoeCAmICh5IF4geikpXG59XG5cbmZ1bmN0aW9uIG1haiAoeCwgeSwgeikge1xuICByZXR1cm4gKHggJiB5KSB8ICh6ICYgKHggfCB5KSlcbn1cblxuZnVuY3Rpb24gc2lnbWEwICh4LCB4bCkge1xuICByZXR1cm4gKHggPj4+IDI4IHwgeGwgPDwgNCkgXiAoeGwgPj4+IDIgfCB4IDw8IDMwKSBeICh4bCA+Pj4gNyB8IHggPDwgMjUpXG59XG5cbmZ1bmN0aW9uIHNpZ21hMSAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxNCB8IHhsIDw8IDE4KSBeICh4ID4+PiAxOCB8IHhsIDw8IDE0KSBeICh4bCA+Pj4gOSB8IHggPDwgMjMpXG59XG5cbmZ1bmN0aW9uIEdhbW1hMCAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxIHwgeGwgPDwgMzEpIF4gKHggPj4+IDggfCB4bCA8PCAyNCkgXiAoeCA+Pj4gNylcbn1cblxuZnVuY3Rpb24gR2FtbWEwbCAoeCwgeGwpIHtcbiAgcmV0dXJuICh4ID4+PiAxIHwgeGwgPDwgMzEpIF4gKHggPj4+IDggfCB4bCA8PCAyNCkgXiAoeCA+Pj4gNyB8IHhsIDw8IDI1KVxufVxuXG5mdW5jdGlvbiBHYW1tYTEgKHgsIHhsKSB7XG4gIHJldHVybiAoeCA+Pj4gMTkgfCB4bCA8PCAxMykgXiAoeGwgPj4+IDI5IHwgeCA8PCAzKSBeICh4ID4+PiA2KVxufVxuXG5mdW5jdGlvbiBHYW1tYTFsICh4LCB4bCkge1xuICByZXR1cm4gKHggPj4+IDE5IHwgeGwgPDwgMTMpIF4gKHhsID4+PiAyOSB8IHggPDwgMykgXiAoeCA+Pj4gNiB8IHhsIDw8IDI2KVxufVxuXG5mdW5jdGlvbiBnZXRDYXJyeSAoYSwgYikge1xuICByZXR1cm4gKGEgPj4+IDApIDwgKGIgPj4+IDApID8gMSA6IDBcbn1cblxuU2hhNTEyLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24gKE0pIHtcbiAgdmFyIFcgPSB0aGlzLl93XG5cbiAgdmFyIGFoID0gdGhpcy5fYWggfCAwXG4gIHZhciBiaCA9IHRoaXMuX2JoIHwgMFxuICB2YXIgY2ggPSB0aGlzLl9jaCB8IDBcbiAgdmFyIGRoID0gdGhpcy5fZGggfCAwXG4gIHZhciBlaCA9IHRoaXMuX2VoIHwgMFxuICB2YXIgZmggPSB0aGlzLl9maCB8IDBcbiAgdmFyIGdoID0gdGhpcy5fZ2ggfCAwXG4gIHZhciBoaCA9IHRoaXMuX2hoIHwgMFxuXG4gIHZhciBhbCA9IHRoaXMuX2FsIHwgMFxuICB2YXIgYmwgPSB0aGlzLl9ibCB8IDBcbiAgdmFyIGNsID0gdGhpcy5fY2wgfCAwXG4gIHZhciBkbCA9IHRoaXMuX2RsIHwgMFxuICB2YXIgZWwgPSB0aGlzLl9lbCB8IDBcbiAgdmFyIGZsID0gdGhpcy5fZmwgfCAwXG4gIHZhciBnbCA9IHRoaXMuX2dsIHwgMFxuICB2YXIgaGwgPSB0aGlzLl9obCB8IDBcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDMyOyBpICs9IDIpIHtcbiAgICBXW2ldID0gTS5yZWFkSW50MzJCRShpICogNClcbiAgICBXW2kgKyAxXSA9IE0ucmVhZEludDMyQkUoaSAqIDQgKyA0KVxuICB9XG4gIGZvciAoOyBpIDwgMTYwOyBpICs9IDIpIHtcbiAgICB2YXIgeGggPSBXW2kgLSAxNSAqIDJdXG4gICAgdmFyIHhsID0gV1tpIC0gMTUgKiAyICsgMV1cbiAgICB2YXIgZ2FtbWEwID0gR2FtbWEwKHhoLCB4bClcbiAgICB2YXIgZ2FtbWEwbCA9IEdhbW1hMGwoeGwsIHhoKVxuXG4gICAgeGggPSBXW2kgLSAyICogMl1cbiAgICB4bCA9IFdbaSAtIDIgKiAyICsgMV1cbiAgICB2YXIgZ2FtbWExID0gR2FtbWExKHhoLCB4bClcbiAgICB2YXIgZ2FtbWExbCA9IEdhbW1hMWwoeGwsIHhoKVxuXG4gICAgLy8gV1tpXSA9IGdhbW1hMCArIFdbaSAtIDddICsgZ2FtbWExICsgV1tpIC0gMTZdXG4gICAgdmFyIFdpN2ggPSBXW2kgLSA3ICogMl1cbiAgICB2YXIgV2k3bCA9IFdbaSAtIDcgKiAyICsgMV1cblxuICAgIHZhciBXaTE2aCA9IFdbaSAtIDE2ICogMl1cbiAgICB2YXIgV2kxNmwgPSBXW2kgLSAxNiAqIDIgKyAxXVxuXG4gICAgdmFyIFdpbCA9IChnYW1tYTBsICsgV2k3bCkgfCAwXG4gICAgdmFyIFdpaCA9IChnYW1tYTAgKyBXaTdoICsgZ2V0Q2FycnkoV2lsLCBnYW1tYTBsKSkgfCAwXG4gICAgV2lsID0gKFdpbCArIGdhbW1hMWwpIHwgMFxuICAgIFdpaCA9IChXaWggKyBnYW1tYTEgKyBnZXRDYXJyeShXaWwsIGdhbW1hMWwpKSB8IDBcbiAgICBXaWwgPSAoV2lsICsgV2kxNmwpIHwgMFxuICAgIFdpaCA9IChXaWggKyBXaTE2aCArIGdldENhcnJ5KFdpbCwgV2kxNmwpKSB8IDBcblxuICAgIFdbaV0gPSBXaWhcbiAgICBXW2kgKyAxXSA9IFdpbFxuICB9XG5cbiAgZm9yICh2YXIgaiA9IDA7IGogPCAxNjA7IGogKz0gMikge1xuICAgIFdpaCA9IFdbal1cbiAgICBXaWwgPSBXW2ogKyAxXVxuXG4gICAgdmFyIG1hamggPSBtYWooYWgsIGJoLCBjaClcbiAgICB2YXIgbWFqbCA9IG1haihhbCwgYmwsIGNsKVxuXG4gICAgdmFyIHNpZ21hMGggPSBzaWdtYTAoYWgsIGFsKVxuICAgIHZhciBzaWdtYTBsID0gc2lnbWEwKGFsLCBhaClcbiAgICB2YXIgc2lnbWExaCA9IHNpZ21hMShlaCwgZWwpXG4gICAgdmFyIHNpZ21hMWwgPSBzaWdtYTEoZWwsIGVoKVxuXG4gICAgLy8gdDEgPSBoICsgc2lnbWExICsgY2ggKyBLW2pdICsgV1tqXVxuICAgIHZhciBLaWggPSBLW2pdXG4gICAgdmFyIEtpbCA9IEtbaiArIDFdXG5cbiAgICB2YXIgY2hoID0gQ2goZWgsIGZoLCBnaClcbiAgICB2YXIgY2hsID0gQ2goZWwsIGZsLCBnbClcblxuICAgIHZhciB0MWwgPSAoaGwgKyBzaWdtYTFsKSB8IDBcbiAgICB2YXIgdDFoID0gKGhoICsgc2lnbWExaCArIGdldENhcnJ5KHQxbCwgaGwpKSB8IDBcbiAgICB0MWwgPSAodDFsICsgY2hsKSB8IDBcbiAgICB0MWggPSAodDFoICsgY2hoICsgZ2V0Q2FycnkodDFsLCBjaGwpKSB8IDBcbiAgICB0MWwgPSAodDFsICsgS2lsKSB8IDBcbiAgICB0MWggPSAodDFoICsgS2loICsgZ2V0Q2FycnkodDFsLCBLaWwpKSB8IDBcbiAgICB0MWwgPSAodDFsICsgV2lsKSB8IDBcbiAgICB0MWggPSAodDFoICsgV2loICsgZ2V0Q2FycnkodDFsLCBXaWwpKSB8IDBcblxuICAgIC8vIHQyID0gc2lnbWEwICsgbWFqXG4gICAgdmFyIHQybCA9IChzaWdtYTBsICsgbWFqbCkgfCAwXG4gICAgdmFyIHQyaCA9IChzaWdtYTBoICsgbWFqaCArIGdldENhcnJ5KHQybCwgc2lnbWEwbCkpIHwgMFxuXG4gICAgaGggPSBnaFxuICAgIGhsID0gZ2xcbiAgICBnaCA9IGZoXG4gICAgZ2wgPSBmbFxuICAgIGZoID0gZWhcbiAgICBmbCA9IGVsXG4gICAgZWwgPSAoZGwgKyB0MWwpIHwgMFxuICAgIGVoID0gKGRoICsgdDFoICsgZ2V0Q2FycnkoZWwsIGRsKSkgfCAwXG4gICAgZGggPSBjaFxuICAgIGRsID0gY2xcbiAgICBjaCA9IGJoXG4gICAgY2wgPSBibFxuICAgIGJoID0gYWhcbiAgICBibCA9IGFsXG4gICAgYWwgPSAodDFsICsgdDJsKSB8IDBcbiAgICBhaCA9ICh0MWggKyB0MmggKyBnZXRDYXJyeShhbCwgdDFsKSkgfCAwXG4gIH1cblxuICB0aGlzLl9hbCA9ICh0aGlzLl9hbCArIGFsKSB8IDBcbiAgdGhpcy5fYmwgPSAodGhpcy5fYmwgKyBibCkgfCAwXG4gIHRoaXMuX2NsID0gKHRoaXMuX2NsICsgY2wpIHwgMFxuICB0aGlzLl9kbCA9ICh0aGlzLl9kbCArIGRsKSB8IDBcbiAgdGhpcy5fZWwgPSAodGhpcy5fZWwgKyBlbCkgfCAwXG4gIHRoaXMuX2ZsID0gKHRoaXMuX2ZsICsgZmwpIHwgMFxuICB0aGlzLl9nbCA9ICh0aGlzLl9nbCArIGdsKSB8IDBcbiAgdGhpcy5faGwgPSAodGhpcy5faGwgKyBobCkgfCAwXG5cbiAgdGhpcy5fYWggPSAodGhpcy5fYWggKyBhaCArIGdldENhcnJ5KHRoaXMuX2FsLCBhbCkpIHwgMFxuICB0aGlzLl9iaCA9ICh0aGlzLl9iaCArIGJoICsgZ2V0Q2FycnkodGhpcy5fYmwsIGJsKSkgfCAwXG4gIHRoaXMuX2NoID0gKHRoaXMuX2NoICsgY2ggKyBnZXRDYXJyeSh0aGlzLl9jbCwgY2wpKSB8IDBcbiAgdGhpcy5fZGggPSAodGhpcy5fZGggKyBkaCArIGdldENhcnJ5KHRoaXMuX2RsLCBkbCkpIHwgMFxuICB0aGlzLl9laCA9ICh0aGlzLl9laCArIGVoICsgZ2V0Q2FycnkodGhpcy5fZWwsIGVsKSkgfCAwXG4gIHRoaXMuX2ZoID0gKHRoaXMuX2ZoICsgZmggKyBnZXRDYXJyeSh0aGlzLl9mbCwgZmwpKSB8IDBcbiAgdGhpcy5fZ2ggPSAodGhpcy5fZ2ggKyBnaCArIGdldENhcnJ5KHRoaXMuX2dsLCBnbCkpIHwgMFxuICB0aGlzLl9oaCA9ICh0aGlzLl9oaCArIGhoICsgZ2V0Q2FycnkodGhpcy5faGwsIGhsKSkgfCAwXG59XG5cblNoYTUxMi5wcm90b3R5cGUuX2hhc2ggPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBIID0gQnVmZmVyLmFsbG9jVW5zYWZlKDY0KVxuXG4gIGZ1bmN0aW9uIHdyaXRlSW50NjRCRSAoaCwgbCwgb2Zmc2V0KSB7XG4gICAgSC53cml0ZUludDMyQkUoaCwgb2Zmc2V0KVxuICAgIEgud3JpdGVJbnQzMkJFKGwsIG9mZnNldCArIDQpXG4gIH1cblxuICB3cml0ZUludDY0QkUodGhpcy5fYWgsIHRoaXMuX2FsLCAwKVxuICB3cml0ZUludDY0QkUodGhpcy5fYmgsIHRoaXMuX2JsLCA4KVxuICB3cml0ZUludDY0QkUodGhpcy5fY2gsIHRoaXMuX2NsLCAxNilcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2RoLCB0aGlzLl9kbCwgMjQpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9laCwgdGhpcy5fZWwsIDMyKVxuICB3cml0ZUludDY0QkUodGhpcy5fZmgsIHRoaXMuX2ZsLCA0MClcbiAgd3JpdGVJbnQ2NEJFKHRoaXMuX2doLCB0aGlzLl9nbCwgNDgpXG4gIHdyaXRlSW50NjRCRSh0aGlzLl9oaCwgdGhpcy5faGwsIDU2KVxuXG4gIHJldHVybiBIXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2hhNTEyXG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW07XG5cbnZhciBFRSA9IHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlcjtcbnZhciBpbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmluaGVyaXRzKFN0cmVhbSwgRUUpO1xuU3RyZWFtLlJlYWRhYmxlID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL3JlYWRhYmxlLmpzJyk7XG5TdHJlYW0uV3JpdGFibGUgPSByZXF1aXJlKCdyZWFkYWJsZS1zdHJlYW0vd3JpdGFibGUuanMnKTtcblN0cmVhbS5EdXBsZXggPSByZXF1aXJlKCdyZWFkYWJsZS1zdHJlYW0vZHVwbGV4LmpzJyk7XG5TdHJlYW0uVHJhbnNmb3JtID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL3RyYW5zZm9ybS5qcycpO1xuU3RyZWFtLlBhc3NUaHJvdWdoID0gcmVxdWlyZSgncmVhZGFibGUtc3RyZWFtL3Bhc3N0aHJvdWdoLmpzJyk7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuNC54XG5TdHJlYW0uU3RyZWFtID0gU3RyZWFtO1xuXG5cblxuLy8gb2xkLXN0eWxlIHN0cmVhbXMuICBOb3RlIHRoYXQgdGhlIHBpcGUgbWV0aG9kICh0aGUgb25seSByZWxldmFudFxuLy8gcGFydCBvZiB0aGlzIGNsYXNzKSBpcyBvdmVycmlkZGVuIGluIHRoZSBSZWFkYWJsZSBjbGFzcy5cblxuZnVuY3Rpb24gU3RyZWFtKCkge1xuICBFRS5jYWxsKHRoaXMpO1xufVxuXG5TdHJlYW0ucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbihkZXN0LCBvcHRpb25zKSB7XG4gIHZhciBzb3VyY2UgPSB0aGlzO1xuXG4gIGZ1bmN0aW9uIG9uZGF0YShjaHVuaykge1xuICAgIGlmIChkZXN0LndyaXRhYmxlKSB7XG4gICAgICBpZiAoZmFsc2UgPT09IGRlc3Qud3JpdGUoY2h1bmspICYmIHNvdXJjZS5wYXVzZSkge1xuICAgICAgICBzb3VyY2UucGF1c2UoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzb3VyY2Uub24oJ2RhdGEnLCBvbmRhdGEpO1xuXG4gIGZ1bmN0aW9uIG9uZHJhaW4oKSB7XG4gICAgaWYgKHNvdXJjZS5yZWFkYWJsZSAmJiBzb3VyY2UucmVzdW1lKSB7XG4gICAgICBzb3VyY2UucmVzdW1lKCk7XG4gICAgfVxuICB9XG5cbiAgZGVzdC5vbignZHJhaW4nLCBvbmRyYWluKTtcblxuICAvLyBJZiB0aGUgJ2VuZCcgb3B0aW9uIGlzIG5vdCBzdXBwbGllZCwgZGVzdC5lbmQoKSB3aWxsIGJlIGNhbGxlZCB3aGVuXG4gIC8vIHNvdXJjZSBnZXRzIHRoZSAnZW5kJyBvciAnY2xvc2UnIGV2ZW50cy4gIE9ubHkgZGVzdC5lbmQoKSBvbmNlLlxuICBpZiAoIWRlc3QuX2lzU3RkaW8gJiYgKCFvcHRpb25zIHx8IG9wdGlvbnMuZW5kICE9PSBmYWxzZSkpIHtcbiAgICBzb3VyY2Uub24oJ2VuZCcsIG9uZW5kKTtcbiAgICBzb3VyY2Uub24oJ2Nsb3NlJywgb25jbG9zZSk7XG4gIH1cblxuICB2YXIgZGlkT25FbmQgPSBmYWxzZTtcbiAgZnVuY3Rpb24gb25lbmQoKSB7XG4gICAgaWYgKGRpZE9uRW5kKSByZXR1cm47XG4gICAgZGlkT25FbmQgPSB0cnVlO1xuXG4gICAgZGVzdC5lbmQoKTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gb25jbG9zZSgpIHtcbiAgICBpZiAoZGlkT25FbmQpIHJldHVybjtcbiAgICBkaWRPbkVuZCA9IHRydWU7XG5cbiAgICBpZiAodHlwZW9mIGRlc3QuZGVzdHJveSA9PT0gJ2Z1bmN0aW9uJykgZGVzdC5kZXN0cm95KCk7XG4gIH1cblxuICAvLyBkb24ndCBsZWF2ZSBkYW5nbGluZyBwaXBlcyB3aGVuIHRoZXJlIGFyZSBlcnJvcnMuXG4gIGZ1bmN0aW9uIG9uZXJyb3IoZXIpIHtcbiAgICBjbGVhbnVwKCk7XG4gICAgaWYgKEVFLmxpc3RlbmVyQ291bnQodGhpcywgJ2Vycm9yJykgPT09IDApIHtcbiAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgc3RyZWFtIGVycm9yIGluIHBpcGUuXG4gICAgfVxuICB9XG5cbiAgc291cmNlLm9uKCdlcnJvcicsIG9uZXJyb3IpO1xuICBkZXN0Lm9uKCdlcnJvcicsIG9uZXJyb3IpO1xuXG4gIC8vIHJlbW92ZSBhbGwgdGhlIGV2ZW50IGxpc3RlbmVycyB0aGF0IHdlcmUgYWRkZWQuXG4gIGZ1bmN0aW9uIGNsZWFudXAoKSB7XG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgb25kYXRhKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdkcmFpbicsIG9uZHJhaW4pO1xuXG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBvbmVuZCk7XG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuXG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG5cbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIGNsZWFudXApO1xuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBjbGVhbnVwKTtcblxuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgY2xlYW51cCk7XG4gIH1cblxuICBzb3VyY2Uub24oJ2VuZCcsIGNsZWFudXApO1xuICBzb3VyY2Uub24oJ2Nsb3NlJywgY2xlYW51cCk7XG5cbiAgZGVzdC5vbignY2xvc2UnLCBjbGVhbnVwKTtcblxuICBkZXN0LmVtaXQoJ3BpcGUnLCBzb3VyY2UpO1xuXG4gIC8vIEFsbG93IGZvciB1bml4LWxpa2UgdXNhZ2U6IEEucGlwZShCKS5waXBlKEMpXG4gIHJldHVybiBkZXN0O1xufTtcbiIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuXG52YXIgaXNCdWZmZXJFbmNvZGluZyA9IEJ1ZmZlci5pc0VuY29kaW5nXG4gIHx8IGZ1bmN0aW9uKGVuY29kaW5nKSB7XG4gICAgICAgc3dpdGNoIChlbmNvZGluZyAmJiBlbmNvZGluZy50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICBjYXNlICdoZXgnOiBjYXNlICd1dGY4JzogY2FzZSAndXRmLTgnOiBjYXNlICdhc2NpaSc6IGNhc2UgJ2JpbmFyeSc6IGNhc2UgJ2Jhc2U2NCc6IGNhc2UgJ3VjczInOiBjYXNlICd1Y3MtMic6IGNhc2UgJ3V0ZjE2bGUnOiBjYXNlICd1dGYtMTZsZSc6IGNhc2UgJ3Jhdyc6IHJldHVybiB0cnVlO1xuICAgICAgICAgZGVmYXVsdDogcmV0dXJuIGZhbHNlO1xuICAgICAgIH1cbiAgICAgfVxuXG5cbmZ1bmN0aW9uIGFzc2VydEVuY29kaW5nKGVuY29kaW5nKSB7XG4gIGlmIChlbmNvZGluZyAmJiAhaXNCdWZmZXJFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZyk7XG4gIH1cbn1cblxuLy8gU3RyaW5nRGVjb2RlciBwcm92aWRlcyBhbiBpbnRlcmZhY2UgZm9yIGVmZmljaWVudGx5IHNwbGl0dGluZyBhIHNlcmllcyBvZlxuLy8gYnVmZmVycyBpbnRvIGEgc2VyaWVzIG9mIEpTIHN0cmluZ3Mgd2l0aG91dCBicmVha2luZyBhcGFydCBtdWx0aS1ieXRlXG4vLyBjaGFyYWN0ZXJzLiBDRVNVLTggaXMgaGFuZGxlZCBhcyBwYXJ0IG9mIHRoZSBVVEYtOCBlbmNvZGluZy5cbi8vXG4vLyBAVE9ETyBIYW5kbGluZyBhbGwgZW5jb2RpbmdzIGluc2lkZSBhIHNpbmdsZSBvYmplY3QgbWFrZXMgaXQgdmVyeSBkaWZmaWN1bHRcbi8vIHRvIHJlYXNvbiBhYm91dCB0aGlzIGNvZGUsIHNvIGl0IHNob3VsZCBiZSBzcGxpdCB1cCBpbiB0aGUgZnV0dXJlLlxuLy8gQFRPRE8gVGhlcmUgc2hvdWxkIGJlIGEgdXRmOC1zdHJpY3QgZW5jb2RpbmcgdGhhdCByZWplY3RzIGludmFsaWQgVVRGLTggY29kZVxuLy8gcG9pbnRzIGFzIHVzZWQgYnkgQ0VTVS04LlxudmFyIFN0cmluZ0RlY29kZXIgPSBleHBvcnRzLlN0cmluZ0RlY29kZXIgPSBmdW5jdGlvbihlbmNvZGluZykge1xuICB0aGlzLmVuY29kaW5nID0gKGVuY29kaW5nIHx8ICd1dGY4JykudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9bLV9dLywgJycpO1xuICBhc3NlcnRFbmNvZGluZyhlbmNvZGluZyk7XG4gIHN3aXRjaCAodGhpcy5lbmNvZGluZykge1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgLy8gQ0VTVS04IHJlcHJlc2VudHMgZWFjaCBvZiBTdXJyb2dhdGUgUGFpciBieSAzLWJ5dGVzXG4gICAgICB0aGlzLnN1cnJvZ2F0ZVNpemUgPSAzO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICAvLyBVVEYtMTYgcmVwcmVzZW50cyBlYWNoIG9mIFN1cnJvZ2F0ZSBQYWlyIGJ5IDItYnl0ZXNcbiAgICAgIHRoaXMuc3Vycm9nYXRlU2l6ZSA9IDI7XG4gICAgICB0aGlzLmRldGVjdEluY29tcGxldGVDaGFyID0gdXRmMTZEZXRlY3RJbmNvbXBsZXRlQ2hhcjtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAvLyBCYXNlLTY0IHN0b3JlcyAzIGJ5dGVzIGluIDQgY2hhcnMsIGFuZCBwYWRzIHRoZSByZW1haW5kZXIuXG4gICAgICB0aGlzLnN1cnJvZ2F0ZVNpemUgPSAzO1xuICAgICAgdGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhciA9IGJhc2U2NERldGVjdEluY29tcGxldGVDaGFyO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRoaXMud3JpdGUgPSBwYXNzVGhyb3VnaFdyaXRlO1xuICAgICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gRW5vdWdoIHNwYWNlIHRvIHN0b3JlIGFsbCBieXRlcyBvZiBhIHNpbmdsZSBjaGFyYWN0ZXIuIFVURi04IG5lZWRzIDRcbiAgLy8gYnl0ZXMsIGJ1dCBDRVNVLTggbWF5IHJlcXVpcmUgdXAgdG8gNiAoMyBieXRlcyBwZXIgc3Vycm9nYXRlKS5cbiAgdGhpcy5jaGFyQnVmZmVyID0gbmV3IEJ1ZmZlcig2KTtcbiAgLy8gTnVtYmVyIG9mIGJ5dGVzIHJlY2VpdmVkIGZvciB0aGUgY3VycmVudCBpbmNvbXBsZXRlIG11bHRpLWJ5dGUgY2hhcmFjdGVyLlxuICB0aGlzLmNoYXJSZWNlaXZlZCA9IDA7XG4gIC8vIE51bWJlciBvZiBieXRlcyBleHBlY3RlZCBmb3IgdGhlIGN1cnJlbnQgaW5jb21wbGV0ZSBtdWx0aS1ieXRlIGNoYXJhY3Rlci5cbiAgdGhpcy5jaGFyTGVuZ3RoID0gMDtcbn07XG5cblxuLy8gd3JpdGUgZGVjb2RlcyB0aGUgZ2l2ZW4gYnVmZmVyIGFuZCByZXR1cm5zIGl0IGFzIEpTIHN0cmluZyB0aGF0IGlzXG4vLyBndWFyYW50ZWVkIHRvIG5vdCBjb250YWluIGFueSBwYXJ0aWFsIG11bHRpLWJ5dGUgY2hhcmFjdGVycy4gQW55IHBhcnRpYWxcbi8vIGNoYXJhY3RlciBmb3VuZCBhdCB0aGUgZW5kIG9mIHRoZSBidWZmZXIgaXMgYnVmZmVyZWQgdXAsIGFuZCB3aWxsIGJlXG4vLyByZXR1cm5lZCB3aGVuIGNhbGxpbmcgd3JpdGUgYWdhaW4gd2l0aCB0aGUgcmVtYWluaW5nIGJ5dGVzLlxuLy9cbi8vIE5vdGU6IENvbnZlcnRpbmcgYSBCdWZmZXIgY29udGFpbmluZyBhbiBvcnBoYW4gc3Vycm9nYXRlIHRvIGEgU3RyaW5nXG4vLyBjdXJyZW50bHkgd29ya3MsIGJ1dCBjb252ZXJ0aW5nIGEgU3RyaW5nIHRvIGEgQnVmZmVyICh2aWEgYG5ldyBCdWZmZXJgLCBvclxuLy8gQnVmZmVyI3dyaXRlKSB3aWxsIHJlcGxhY2UgaW5jb21wbGV0ZSBzdXJyb2dhdGVzIHdpdGggdGhlIHVuaWNvZGVcbi8vIHJlcGxhY2VtZW50IGNoYXJhY3Rlci4gU2VlIGh0dHBzOi8vY29kZXJldmlldy5jaHJvbWl1bS5vcmcvMTIxMTczMDA5LyAuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICB2YXIgY2hhclN0ciA9ICcnO1xuICAvLyBpZiBvdXIgbGFzdCB3cml0ZSBlbmRlZCB3aXRoIGFuIGluY29tcGxldGUgbXVsdGlieXRlIGNoYXJhY3RlclxuICB3aGlsZSAodGhpcy5jaGFyTGVuZ3RoKSB7XG4gICAgLy8gZGV0ZXJtaW5lIGhvdyBtYW55IHJlbWFpbmluZyBieXRlcyB0aGlzIGJ1ZmZlciBoYXMgdG8gb2ZmZXIgZm9yIHRoaXMgY2hhclxuICAgIHZhciBhdmFpbGFibGUgPSAoYnVmZmVyLmxlbmd0aCA+PSB0aGlzLmNoYXJMZW5ndGggLSB0aGlzLmNoYXJSZWNlaXZlZCkgP1xuICAgICAgICB0aGlzLmNoYXJMZW5ndGggLSB0aGlzLmNoYXJSZWNlaXZlZCA6XG4gICAgICAgIGJ1ZmZlci5sZW5ndGg7XG5cbiAgICAvLyBhZGQgdGhlIG5ldyBieXRlcyB0byB0aGUgY2hhciBidWZmZXJcbiAgICBidWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsIHRoaXMuY2hhclJlY2VpdmVkLCAwLCBhdmFpbGFibGUpO1xuICAgIHRoaXMuY2hhclJlY2VpdmVkICs9IGF2YWlsYWJsZTtcblxuICAgIGlmICh0aGlzLmNoYXJSZWNlaXZlZCA8IHRoaXMuY2hhckxlbmd0aCkge1xuICAgICAgLy8gc3RpbGwgbm90IGVub3VnaCBjaGFycyBpbiB0aGlzIGJ1ZmZlcj8gd2FpdCBmb3IgbW9yZSAuLi5cbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICAvLyByZW1vdmUgYnl0ZXMgYmVsb25naW5nIHRvIHRoZSBjdXJyZW50IGNoYXJhY3RlciBmcm9tIHRoZSBidWZmZXJcbiAgICBidWZmZXIgPSBidWZmZXIuc2xpY2UoYXZhaWxhYmxlLCBidWZmZXIubGVuZ3RoKTtcblxuICAgIC8vIGdldCB0aGUgY2hhcmFjdGVyIHRoYXQgd2FzIHNwbGl0XG4gICAgY2hhclN0ciA9IHRoaXMuY2hhckJ1ZmZlci5zbGljZSgwLCB0aGlzLmNoYXJMZW5ndGgpLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcpO1xuXG4gICAgLy8gQ0VTVS04OiBsZWFkIHN1cnJvZ2F0ZSAoRDgwMC1EQkZGKSBpcyBhbHNvIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlclxuICAgIHZhciBjaGFyQ29kZSA9IGNoYXJTdHIuY2hhckNvZGVBdChjaGFyU3RyLmxlbmd0aCAtIDEpO1xuICAgIGlmIChjaGFyQ29kZSA+PSAweEQ4MDAgJiYgY2hhckNvZGUgPD0gMHhEQkZGKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggKz0gdGhpcy5zdXJyb2dhdGVTaXplO1xuICAgICAgY2hhclN0ciA9ICcnO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHRoaXMuY2hhclJlY2VpdmVkID0gdGhpcy5jaGFyTGVuZ3RoID0gMDtcblxuICAgIC8vIGlmIHRoZXJlIGFyZSBubyBtb3JlIGJ5dGVzIGluIHRoaXMgYnVmZmVyLCBqdXN0IGVtaXQgb3VyIGNoYXJcbiAgICBpZiAoYnVmZmVyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGNoYXJTdHI7XG4gICAgfVxuICAgIGJyZWFrO1xuICB9XG5cbiAgLy8gZGV0ZXJtaW5lIGFuZCBzZXQgY2hhckxlbmd0aCAvIGNoYXJSZWNlaXZlZFxuICB0aGlzLmRldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcik7XG5cbiAgdmFyIGVuZCA9IGJ1ZmZlci5sZW5ndGg7XG4gIGlmICh0aGlzLmNoYXJMZW5ndGgpIHtcbiAgICAvLyBidWZmZXIgdGhlIGluY29tcGxldGUgY2hhcmFjdGVyIGJ5dGVzIHdlIGdvdFxuICAgIGJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgMCwgYnVmZmVyLmxlbmd0aCAtIHRoaXMuY2hhclJlY2VpdmVkLCBlbmQpO1xuICAgIGVuZCAtPSB0aGlzLmNoYXJSZWNlaXZlZDtcbiAgfVxuXG4gIGNoYXJTdHIgKz0gYnVmZmVyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcsIDAsIGVuZCk7XG5cbiAgdmFyIGVuZCA9IGNoYXJTdHIubGVuZ3RoIC0gMTtcbiAgdmFyIGNoYXJDb2RlID0gY2hhclN0ci5jaGFyQ29kZUF0KGVuZCk7XG4gIC8vIENFU1UtODogbGVhZCBzdXJyb2dhdGUgKEQ4MDAtREJGRikgaXMgYWxzbyB0aGUgaW5jb21wbGV0ZSBjaGFyYWN0ZXJcbiAgaWYgKGNoYXJDb2RlID49IDB4RDgwMCAmJiBjaGFyQ29kZSA8PSAweERCRkYpIHtcbiAgICB2YXIgc2l6ZSA9IHRoaXMuc3Vycm9nYXRlU2l6ZTtcbiAgICB0aGlzLmNoYXJMZW5ndGggKz0gc2l6ZTtcbiAgICB0aGlzLmNoYXJSZWNlaXZlZCArPSBzaXplO1xuICAgIHRoaXMuY2hhckJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgc2l6ZSwgMCwgc2l6ZSk7XG4gICAgYnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCAwLCAwLCBzaXplKTtcbiAgICByZXR1cm4gY2hhclN0ci5zdWJzdHJpbmcoMCwgZW5kKTtcbiAgfVxuXG4gIC8vIG9yIGp1c3QgZW1pdCB0aGUgY2hhclN0clxuICByZXR1cm4gY2hhclN0cjtcbn07XG5cbi8vIGRldGVjdEluY29tcGxldGVDaGFyIGRldGVybWluZXMgaWYgdGhlcmUgaXMgYW4gaW5jb21wbGV0ZSBVVEYtOCBjaGFyYWN0ZXIgYXRcbi8vIHRoZSBlbmQgb2YgdGhlIGdpdmVuIGJ1ZmZlci4gSWYgc28sIGl0IHNldHMgdGhpcy5jaGFyTGVuZ3RoIHRvIHRoZSBieXRlXG4vLyBsZW5ndGggdGhhdCBjaGFyYWN0ZXIsIGFuZCBzZXRzIHRoaXMuY2hhclJlY2VpdmVkIHRvIHRoZSBudW1iZXIgb2YgYnl0ZXNcbi8vIHRoYXQgYXJlIGF2YWlsYWJsZSBmb3IgdGhpcyBjaGFyYWN0ZXIuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5kZXRlY3RJbmNvbXBsZXRlQ2hhciA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAvLyBkZXRlcm1pbmUgaG93IG1hbnkgYnl0ZXMgd2UgaGF2ZSB0byBjaGVjayBhdCB0aGUgZW5kIG9mIHRoaXMgYnVmZmVyXG4gIHZhciBpID0gKGJ1ZmZlci5sZW5ndGggPj0gMykgPyAzIDogYnVmZmVyLmxlbmd0aDtcblxuICAvLyBGaWd1cmUgb3V0IGlmIG9uZSBvZiB0aGUgbGFzdCBpIGJ5dGVzIG9mIG91ciBidWZmZXIgYW5ub3VuY2VzIGFuXG4gIC8vIGluY29tcGxldGUgY2hhci5cbiAgZm9yICg7IGkgPiAwOyBpLS0pIHtcbiAgICB2YXIgYyA9IGJ1ZmZlcltidWZmZXIubGVuZ3RoIC0gaV07XG5cbiAgICAvLyBTZWUgaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9VVEYtOCNEZXNjcmlwdGlvblxuXG4gICAgLy8gMTEwWFhYWFhcbiAgICBpZiAoaSA9PSAxICYmIGMgPj4gNSA9PSAweDA2KSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSAyO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gMTExMFhYWFhcbiAgICBpZiAoaSA8PSAyICYmIGMgPj4gNCA9PSAweDBFKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSAzO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gMTExMTBYWFhcbiAgICBpZiAoaSA8PSAzICYmIGMgPj4gMyA9PSAweDFFKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSA0O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHRoaXMuY2hhclJlY2VpdmVkID0gaTtcbn07XG5cblN0cmluZ0RlY29kZXIucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICB2YXIgcmVzID0gJyc7XG4gIGlmIChidWZmZXIgJiYgYnVmZmVyLmxlbmd0aClcbiAgICByZXMgPSB0aGlzLndyaXRlKGJ1ZmZlcik7XG5cbiAgaWYgKHRoaXMuY2hhclJlY2VpdmVkKSB7XG4gICAgdmFyIGNyID0gdGhpcy5jaGFyUmVjZWl2ZWQ7XG4gICAgdmFyIGJ1ZiA9IHRoaXMuY2hhckJ1ZmZlcjtcbiAgICB2YXIgZW5jID0gdGhpcy5lbmNvZGluZztcbiAgICByZXMgKz0gYnVmLnNsaWNlKDAsIGNyKS50b1N0cmluZyhlbmMpO1xuICB9XG5cbiAgcmV0dXJuIHJlcztcbn07XG5cbmZ1bmN0aW9uIHBhc3NUaHJvdWdoV3JpdGUoYnVmZmVyKSB7XG4gIHJldHVybiBidWZmZXIudG9TdHJpbmcodGhpcy5lbmNvZGluZyk7XG59XG5cbmZ1bmN0aW9uIHV0ZjE2RGV0ZWN0SW5jb21wbGV0ZUNoYXIoYnVmZmVyKSB7XG4gIHRoaXMuY2hhclJlY2VpdmVkID0gYnVmZmVyLmxlbmd0aCAlIDI7XG4gIHRoaXMuY2hhckxlbmd0aCA9IHRoaXMuY2hhclJlY2VpdmVkID8gMiA6IDA7XG59XG5cbmZ1bmN0aW9uIGJhc2U2NERldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcikge1xuICB0aGlzLmNoYXJSZWNlaXZlZCA9IGJ1ZmZlci5sZW5ndGggJSAzO1xuICB0aGlzLmNoYXJMZW5ndGggPSB0aGlzLmNoYXJSZWNlaXZlZCA/IDMgOiAwO1xufVxuIiwidmFyIG5leHRUaWNrID0gcmVxdWlyZSgncHJvY2Vzcy9icm93c2VyLmpzJykubmV4dFRpY2s7XG52YXIgYXBwbHkgPSBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHk7XG52YXIgc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG52YXIgaW1tZWRpYXRlSWRzID0ge307XG52YXIgbmV4dEltbWVkaWF0ZUlkID0gMDtcblxuLy8gRE9NIEFQSXMsIGZvciBjb21wbGV0ZW5lc3NcblxuZXhwb3J0cy5zZXRUaW1lb3V0ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBuZXcgVGltZW91dChhcHBseS5jYWxsKHNldFRpbWVvdXQsIHdpbmRvdywgYXJndW1lbnRzKSwgY2xlYXJUaW1lb3V0KTtcbn07XG5leHBvcnRzLnNldEludGVydmFsID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBuZXcgVGltZW91dChhcHBseS5jYWxsKHNldEludGVydmFsLCB3aW5kb3csIGFyZ3VtZW50cyksIGNsZWFySW50ZXJ2YWwpO1xufTtcbmV4cG9ydHMuY2xlYXJUaW1lb3V0ID1cbmV4cG9ydHMuY2xlYXJJbnRlcnZhbCA9IGZ1bmN0aW9uKHRpbWVvdXQpIHsgdGltZW91dC5jbG9zZSgpOyB9O1xuXG5mdW5jdGlvbiBUaW1lb3V0KGlkLCBjbGVhckZuKSB7XG4gIHRoaXMuX2lkID0gaWQ7XG4gIHRoaXMuX2NsZWFyRm4gPSBjbGVhckZuO1xufVxuVGltZW91dC5wcm90b3R5cGUudW5yZWYgPSBUaW1lb3V0LnByb3RvdHlwZS5yZWYgPSBmdW5jdGlvbigpIHt9O1xuVGltZW91dC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5fY2xlYXJGbi5jYWxsKHdpbmRvdywgdGhpcy5faWQpO1xufTtcblxuLy8gRG9lcyBub3Qgc3RhcnQgdGhlIHRpbWUsIGp1c3Qgc2V0cyB1cCB0aGUgbWVtYmVycyBuZWVkZWQuXG5leHBvcnRzLmVucm9sbCA9IGZ1bmN0aW9uKGl0ZW0sIG1zZWNzKSB7XG4gIGNsZWFyVGltZW91dChpdGVtLl9pZGxlVGltZW91dElkKTtcbiAgaXRlbS5faWRsZVRpbWVvdXQgPSBtc2Vjcztcbn07XG5cbmV4cG9ydHMudW5lbnJvbGwgPSBmdW5jdGlvbihpdGVtKSB7XG4gIGNsZWFyVGltZW91dChpdGVtLl9pZGxlVGltZW91dElkKTtcbiAgaXRlbS5faWRsZVRpbWVvdXQgPSAtMTtcbn07XG5cbmV4cG9ydHMuX3VucmVmQWN0aXZlID0gZXhwb3J0cy5hY3RpdmUgPSBmdW5jdGlvbihpdGVtKSB7XG4gIGNsZWFyVGltZW91dChpdGVtLl9pZGxlVGltZW91dElkKTtcblxuICB2YXIgbXNlY3MgPSBpdGVtLl9pZGxlVGltZW91dDtcbiAgaWYgKG1zZWNzID49IDApIHtcbiAgICBpdGVtLl9pZGxlVGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiBvblRpbWVvdXQoKSB7XG4gICAgICBpZiAoaXRlbS5fb25UaW1lb3V0KVxuICAgICAgICBpdGVtLl9vblRpbWVvdXQoKTtcbiAgICB9LCBtc2Vjcyk7XG4gIH1cbn07XG5cbi8vIFRoYXQncyBub3QgaG93IG5vZGUuanMgaW1wbGVtZW50cyBpdCBidXQgdGhlIGV4cG9zZWQgYXBpIGlzIHRoZSBzYW1lLlxuZXhwb3J0cy5zZXRJbW1lZGlhdGUgPSB0eXBlb2Ygc2V0SW1tZWRpYXRlID09PSBcImZ1bmN0aW9uXCIgPyBzZXRJbW1lZGlhdGUgOiBmdW5jdGlvbihmbikge1xuICB2YXIgaWQgPSBuZXh0SW1tZWRpYXRlSWQrKztcbiAgdmFyIGFyZ3MgPSBhcmd1bWVudHMubGVuZ3RoIDwgMiA/IGZhbHNlIDogc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gIGltbWVkaWF0ZUlkc1tpZF0gPSB0cnVlO1xuXG4gIG5leHRUaWNrKGZ1bmN0aW9uIG9uTmV4dFRpY2soKSB7XG4gICAgaWYgKGltbWVkaWF0ZUlkc1tpZF0pIHtcbiAgICAgIC8vIGZuLmNhbGwoKSBpcyBmYXN0ZXIgc28gd2Ugb3B0aW1pemUgZm9yIHRoZSBjb21tb24gdXNlLWNhc2VcbiAgICAgIC8vIEBzZWUgaHR0cDovL2pzcGVyZi5jb20vY2FsbC1hcHBseS1zZWd1XG4gICAgICBpZiAoYXJncykge1xuICAgICAgICBmbi5hcHBseShudWxsLCBhcmdzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZuLmNhbGwobnVsbCk7XG4gICAgICB9XG4gICAgICAvLyBQcmV2ZW50IGlkcyBmcm9tIGxlYWtpbmdcbiAgICAgIGV4cG9ydHMuY2xlYXJJbW1lZGlhdGUoaWQpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGlkO1xufTtcblxuZXhwb3J0cy5jbGVhckltbWVkaWF0ZSA9IHR5cGVvZiBjbGVhckltbWVkaWF0ZSA9PT0gXCJmdW5jdGlvblwiID8gY2xlYXJJbW1lZGlhdGUgOiBmdW5jdGlvbihpZCkge1xuICBkZWxldGUgaW1tZWRpYXRlSWRzW2lkXTtcbn07IiwiXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZGVwcmVjYXRlO1xuXG4vKipcbiAqIE1hcmsgdGhhdCBhIG1ldGhvZCBzaG91bGQgbm90IGJlIHVzZWQuXG4gKiBSZXR1cm5zIGEgbW9kaWZpZWQgZnVuY3Rpb24gd2hpY2ggd2FybnMgb25jZSBieSBkZWZhdWx0LlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2Uubm9EZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBpdCBpcyBhIG5vLW9wLlxuICpcbiAqIElmIGBsb2NhbFN0b3JhZ2UudGhyb3dEZXByZWNhdGlvbiA9IHRydWVgIGlzIHNldCwgdGhlbiBkZXByZWNhdGVkIGZ1bmN0aW9uc1xuICogd2lsbCB0aHJvdyBhbiBFcnJvciB3aGVuIGludm9rZWQuXG4gKlxuICogSWYgYGxvY2FsU3RvcmFnZS50cmFjZURlcHJlY2F0aW9uID0gdHJ1ZWAgaXMgc2V0LCB0aGVuIGRlcHJlY2F0ZWQgZnVuY3Rpb25zXG4gKiB3aWxsIGludm9rZSBgY29uc29sZS50cmFjZSgpYCBpbnN0ZWFkIG9mIGBjb25zb2xlLmVycm9yKClgLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gdGhlIGZ1bmN0aW9uIHRvIGRlcHJlY2F0ZVxuICogQHBhcmFtIHtTdHJpbmd9IG1zZyAtIHRoZSBzdHJpbmcgdG8gcHJpbnQgdG8gdGhlIGNvbnNvbGUgd2hlbiBgZm5gIGlzIGludm9rZWRcbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gYSBuZXcgXCJkZXByZWNhdGVkXCIgdmVyc2lvbiBvZiBgZm5gXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGRlcHJlY2F0ZSAoZm4sIG1zZykge1xuICBpZiAoY29uZmlnKCdub0RlcHJlY2F0aW9uJykpIHtcbiAgICByZXR1cm4gZm47XG4gIH1cblxuICB2YXIgd2FybmVkID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGRlcHJlY2F0ZWQoKSB7XG4gICAgaWYgKCF3YXJuZWQpIHtcbiAgICAgIGlmIChjb25maWcoJ3Rocm93RGVwcmVjYXRpb24nKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgIH0gZWxzZSBpZiAoY29uZmlnKCd0cmFjZURlcHJlY2F0aW9uJykpIHtcbiAgICAgICAgY29uc29sZS50cmFjZShtc2cpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS53YXJuKG1zZyk7XG4gICAgICB9XG4gICAgICB3YXJuZWQgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIHJldHVybiBkZXByZWNhdGVkO1xufVxuXG4vKipcbiAqIENoZWNrcyBgbG9jYWxTdG9yYWdlYCBmb3IgYm9vbGVhbiB2YWx1ZXMgZm9yIHRoZSBnaXZlbiBgbmFtZWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEByZXR1cm5zIHtCb29sZWFufVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gY29uZmlnIChuYW1lKSB7XG4gIC8vIGFjY2Vzc2luZyBnbG9iYWwubG9jYWxTdG9yYWdlIGNhbiB0cmlnZ2VyIGEgRE9NRXhjZXB0aW9uIGluIHNhbmRib3hlZCBpZnJhbWVzXG4gIHRyeSB7XG4gICAgaWYgKCFnbG9iYWwubG9jYWxTdG9yYWdlKSByZXR1cm4gZmFsc2U7XG4gIH0gY2F0Y2ggKF8pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHZhbCA9IGdsb2JhbC5sb2NhbFN0b3JhZ2VbbmFtZV07XG4gIGlmIChudWxsID09IHZhbCkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gU3RyaW5nKHZhbCkudG9Mb3dlckNhc2UoKSA9PT0gJ3RydWUnO1xufVxuIiwidmFyIGluZGV4T2YgPSBmdW5jdGlvbiAoeHMsIGl0ZW0pIHtcbiAgICBpZiAoeHMuaW5kZXhPZikgcmV0dXJuIHhzLmluZGV4T2YoaXRlbSk7XG4gICAgZWxzZSBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh4c1tpXSA9PT0gaXRlbSkgcmV0dXJuIGk7XG4gICAgfVxuICAgIHJldHVybiAtMTtcbn07XG52YXIgT2JqZWN0X2tleXMgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgaWYgKE9iamVjdC5rZXlzKSByZXR1cm4gT2JqZWN0LmtleXMob2JqKVxuICAgIGVsc2Uge1xuICAgICAgICB2YXIgcmVzID0gW107XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBvYmopIHJlcy5wdXNoKGtleSlcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG59O1xuXG52YXIgZm9yRWFjaCA9IGZ1bmN0aW9uICh4cywgZm4pIHtcbiAgICBpZiAoeHMuZm9yRWFjaCkgcmV0dXJuIHhzLmZvckVhY2goZm4pXG4gICAgZWxzZSBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGZuKHhzW2ldLCBpLCB4cyk7XG4gICAgfVxufTtcblxudmFyIGRlZmluZVByb3AgPSAoZnVuY3Rpb24oKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCAnXycsIHt9KTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKG9iaiwgbmFtZSwgdmFsdWUpIHtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIG5hbWUsIHtcbiAgICAgICAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlXG4gICAgICAgICAgICB9KVxuICAgICAgICB9O1xuICAgIH0gY2F0Y2goZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24ob2JqLCBuYW1lLCB2YWx1ZSkge1xuICAgICAgICAgICAgb2JqW25hbWVdID0gdmFsdWU7XG4gICAgICAgIH07XG4gICAgfVxufSgpKTtcblxudmFyIGdsb2JhbHMgPSBbJ0FycmF5JywgJ0Jvb2xlYW4nLCAnRGF0ZScsICdFcnJvcicsICdFdmFsRXJyb3InLCAnRnVuY3Rpb24nLFxuJ0luZmluaXR5JywgJ0pTT04nLCAnTWF0aCcsICdOYU4nLCAnTnVtYmVyJywgJ09iamVjdCcsICdSYW5nZUVycm9yJyxcbidSZWZlcmVuY2VFcnJvcicsICdSZWdFeHAnLCAnU3RyaW5nJywgJ1N5bnRheEVycm9yJywgJ1R5cGVFcnJvcicsICdVUklFcnJvcicsXG4nZGVjb2RlVVJJJywgJ2RlY29kZVVSSUNvbXBvbmVudCcsICdlbmNvZGVVUkknLCAnZW5jb2RlVVJJQ29tcG9uZW50JywgJ2VzY2FwZScsXG4nZXZhbCcsICdpc0Zpbml0ZScsICdpc05hTicsICdwYXJzZUZsb2F0JywgJ3BhcnNlSW50JywgJ3VuZGVmaW5lZCcsICd1bmVzY2FwZSddO1xuXG5mdW5jdGlvbiBDb250ZXh0KCkge31cbkNvbnRleHQucHJvdG90eXBlID0ge307XG5cbnZhciBTY3JpcHQgPSBleHBvcnRzLlNjcmlwdCA9IGZ1bmN0aW9uIE5vZGVTY3JpcHQgKGNvZGUpIHtcbiAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU2NyaXB0KSkgcmV0dXJuIG5ldyBTY3JpcHQoY29kZSk7XG4gICAgdGhpcy5jb2RlID0gY29kZTtcbn07XG5cblNjcmlwdC5wcm90b3R5cGUucnVuSW5Db250ZXh0ID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICBpZiAoIShjb250ZXh0IGluc3RhbmNlb2YgQ29udGV4dCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIm5lZWRzIGEgJ2NvbnRleHQnIGFyZ3VtZW50LlwiKTtcbiAgICB9XG4gICAgXG4gICAgdmFyIGlmcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lmcmFtZScpO1xuICAgIGlmICghaWZyYW1lLnN0eWxlKSBpZnJhbWUuc3R5bGUgPSB7fTtcbiAgICBpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICBcbiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGlmcmFtZSk7XG4gICAgXG4gICAgdmFyIHdpbiA9IGlmcmFtZS5jb250ZW50V2luZG93O1xuICAgIHZhciB3RXZhbCA9IHdpbi5ldmFsLCB3RXhlY1NjcmlwdCA9IHdpbi5leGVjU2NyaXB0O1xuXG4gICAgaWYgKCF3RXZhbCAmJiB3RXhlY1NjcmlwdCkge1xuICAgICAgICAvLyB3aW4uZXZhbCgpIG1hZ2ljYWxseSBhcHBlYXJzIHdoZW4gdGhpcyBpcyBjYWxsZWQgaW4gSUU6XG4gICAgICAgIHdFeGVjU2NyaXB0LmNhbGwod2luLCAnbnVsbCcpO1xuICAgICAgICB3RXZhbCA9IHdpbi5ldmFsO1xuICAgIH1cbiAgICBcbiAgICBmb3JFYWNoKE9iamVjdF9rZXlzKGNvbnRleHQpLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIHdpbltrZXldID0gY29udGV4dFtrZXldO1xuICAgIH0pO1xuICAgIGZvckVhY2goZ2xvYmFscywgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICBpZiAoY29udGV4dFtrZXldKSB7XG4gICAgICAgICAgICB3aW5ba2V5XSA9IGNvbnRleHRba2V5XTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIFxuICAgIHZhciB3aW5LZXlzID0gT2JqZWN0X2tleXMod2luKTtcblxuICAgIHZhciByZXMgPSB3RXZhbC5jYWxsKHdpbiwgdGhpcy5jb2RlKTtcbiAgICBcbiAgICBmb3JFYWNoKE9iamVjdF9rZXlzKHdpbiksIGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgLy8gQXZvaWQgY29weWluZyBjaXJjdWxhciBvYmplY3RzIGxpa2UgYHRvcGAgYW5kIGB3aW5kb3dgIGJ5IG9ubHlcbiAgICAgICAgLy8gdXBkYXRpbmcgZXhpc3RpbmcgY29udGV4dCBwcm9wZXJ0aWVzIG9yIG5ldyBwcm9wZXJ0aWVzIGluIHRoZSBgd2luYFxuICAgICAgICAvLyB0aGF0IHdhcyBvbmx5IGludHJvZHVjZWQgYWZ0ZXIgdGhlIGV2YWwuXG4gICAgICAgIGlmIChrZXkgaW4gY29udGV4dCB8fCBpbmRleE9mKHdpbktleXMsIGtleSkgPT09IC0xKSB7XG4gICAgICAgICAgICBjb250ZXh0W2tleV0gPSB3aW5ba2V5XTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgZm9yRWFjaChnbG9iYWxzLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIGlmICghKGtleSBpbiBjb250ZXh0KSkge1xuICAgICAgICAgICAgZGVmaW5lUHJvcChjb250ZXh0LCBrZXksIHdpbltrZXldKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIFxuICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcbiAgICBcbiAgICByZXR1cm4gcmVzO1xufTtcblxuU2NyaXB0LnByb3RvdHlwZS5ydW5JblRoaXNDb250ZXh0ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBldmFsKHRoaXMuY29kZSk7IC8vIG1heWJlLi4uXG59O1xuXG5TY3JpcHQucHJvdG90eXBlLnJ1bkluTmV3Q29udGV4dCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgdmFyIGN0eCA9IFNjcmlwdC5jcmVhdGVDb250ZXh0KGNvbnRleHQpO1xuICAgIHZhciByZXMgPSB0aGlzLnJ1bkluQ29udGV4dChjdHgpO1xuXG4gICAgaWYgKGNvbnRleHQpIHtcbiAgICAgICAgZm9yRWFjaChPYmplY3Rfa2V5cyhjdHgpLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICBjb250ZXh0W2tleV0gPSBjdHhba2V5XTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcztcbn07XG5cbmZvckVhY2goT2JqZWN0X2tleXMoU2NyaXB0LnByb3RvdHlwZSksIGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgZXhwb3J0c1tuYW1lXSA9IFNjcmlwdFtuYW1lXSA9IGZ1bmN0aW9uIChjb2RlKSB7XG4gICAgICAgIHZhciBzID0gU2NyaXB0KGNvZGUpO1xuICAgICAgICByZXR1cm4gc1tuYW1lXS5hcHBseShzLCBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpO1xuICAgIH07XG59KTtcblxuZXhwb3J0cy5pc0NvbnRleHQgPSBmdW5jdGlvbiAoY29udGV4dCkge1xuICAgIHJldHVybiBjb250ZXh0IGluc3RhbmNlb2YgQ29udGV4dDtcbn07XG5cbmV4cG9ydHMuY3JlYXRlU2NyaXB0ID0gZnVuY3Rpb24gKGNvZGUpIHtcbiAgICByZXR1cm4gZXhwb3J0cy5TY3JpcHQoY29kZSk7XG59O1xuXG5leHBvcnRzLmNyZWF0ZUNvbnRleHQgPSBTY3JpcHQuY3JlYXRlQ29udGV4dCA9IGZ1bmN0aW9uIChjb250ZXh0KSB7XG4gICAgdmFyIGNvcHkgPSBuZXcgQ29udGV4dCgpO1xuICAgIGlmKHR5cGVvZiBjb250ZXh0ID09PSAnb2JqZWN0Jykge1xuICAgICAgICBmb3JFYWNoKE9iamVjdF9rZXlzKGNvbnRleHQpLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICBjb3B5W2tleV0gPSBjb250ZXh0W2tleV07XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gY29weTtcbn07XG4iXX0=
 |